web/views/apacherewrite.py
changeset 0 b97547f5f1fa
child 661 4f61eb8a96b7
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 """provide class to do Apache rewrite rules'job inside cubicweb (though functionnalities
       
     2 are much more limited for the moment)
       
     3 
       
     4 :organization: Logilab
       
     5 :copyright: 2007-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     7 """
       
     8 
       
     9 __docformat__ = "restructuredtext en"
       
    10 
       
    11 from re import compile
       
    12 
       
    13 from cubicweb.web import Redirect
       
    14 from cubicweb.web.component import SingletonComponent
       
    15 
       
    16 class RewriteCond(object):
       
    17     def __init__(self, condition, match='host', rules=(), action='rewrite'):
       
    18         self.condition = compile(condition)
       
    19         assert match in ('host', 'path'), match
       
    20         self.match_part = match
       
    21         self.rules = []
       
    22         for rule, replace in rules:
       
    23             rulergx = compile(rule)
       
    24             self.rules.append( (rulergx, replace) )
       
    25         assert action in ('rewrite', 'redirect', 'stop'), action
       
    26         self.process = getattr(self, 'action_%s' % action)
       
    27 
       
    28     def match(self, **kwargs):
       
    29         self._match = self.condition.match(kwargs[self.match_part])
       
    30         return not self._match is None
       
    31     
       
    32     def action_rewrite(self, path):
       
    33         for rgx, replace in self.rules:
       
    34             if not rgx.match(path) is None:
       
    35                 matchdict = self._match.groupdict() or None
       
    36                 if not matchdict is None:
       
    37                     replace = replace % matchdict
       
    38                 return rgx.sub(replace, path)
       
    39         return path
       
    40 
       
    41     def action_redirect(self, path):
       
    42         url = self.action_rewrite(path)
       
    43         raise Redirect(url)
       
    44 
       
    45     def action_stop(self, path):
       
    46         return path
       
    47 
       
    48     
       
    49 class ApacheURLRewrite(SingletonComponent):
       
    50     """inherit from this class with actual rules to activate apache style rewriting
       
    51 
       
    52     rules should have the form :
       
    53 
       
    54     [('condition pattern 1', [('rule1 pattern', 'replace expression'),
       
    55                               ('rule2 pattern', 'replace expression')],
       
    56      ('condition pattern 2', [('rule1 pattern', 'replace expression'),
       
    57                               ('rule2 pattern', 'replace expression')]
       
    58     ]
       
    59 
       
    60     for instance the equivalent of the following apache rules:
       
    61 
       
    62         RewriteCond %{HTTP_HOST} ^logilab\.fr
       
    63         RewriteRule ^/(.*) http://www.logilab.fr/$1 [L,R=301]
       
    64 
       
    65         RewriteCond %{HTTP_HOST} ^www\.logilab\.fr
       
    66         RewriteRule ^/(.*) http://localhost:8080/$1 [L,P]
       
    67 
       
    68         RewriteCond %{HTTP_HOST} ^(.+)\.logilab\.fr
       
    69         RewriteRule ^/(data/.*) http://localhost:8080/$1 [L,P]
       
    70         RewriteRule ^/(json.*) http://localhost:8080/$1 [L,P]
       
    71         RewriteRule ^/(.*) http://localhost:8080/m_%1/$1 [L,P]
       
    72     
       
    73     could be written (considering that no "host rewritting" is necessary):
       
    74 
       
    75       class MyAppRules(ApacheURLRewrite): 
       
    76         rules = [
       
    77           RewriteCond('logilab\.fr', match='host',
       
    78                       rules=[('/(.*)', r'http://www.logilab.fr/\1')],
       
    79                       action='redirect'),
       
    80           RewriteCond('(www)\.logilab\.fr', match='host', action='stop'),
       
    81           RewriteCond('/(data|json)/', match='path', action='stop'),
       
    82           RewriteCond('(?P<cat>.*)\.logilab\.fr', match='host', 
       
    83                       rules=[('/(.*)', r'/m_%(cat)s/\1')]),
       
    84         ]
       
    85     """
       
    86     __abstract__ = True
       
    87     id = 'urlrewriter'
       
    88     rules = []
       
    89         
       
    90     def rewrite(self, host, path):
       
    91         for cond in self.rules:
       
    92             if cond.match(host=host, path=path):
       
    93                 return cond.process(path)
       
    94         return path