Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1056

Show
Ignore:
Timestamp:
04/22/06 15:22:44
Author:
fumanchu
Message:

Fixed static tool and test.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/lib/static.py

    r1055 r1056  
    6060    # That is, CherryPy should not guess where the application root is. 
    6161    # It certainly should *not* use cwd (since CP may be invoked from a 
    62     # variety of paths). If using static_filter, you can make your relative 
    63     # paths become absolute by supplying a value for "static_filter.root". 
     62    # variety of paths). If using tools.static, you can make your relative 
     63    # paths become absolute by supplying a value for "tools.static.root". 
    6464    if not os.path.isabs(path): 
    6565        raise ValueError("'%s' is not an absolute path." % path) 
     
    149149 
    150150 
    151 def get_dir(root, dir, match="", content_types=None, index=""): 
    152     request = cherrypy.request 
    153     path = request.object_path 
    154      
    155     if match and not re.search(match, path): 
    156         return False 
    157      
    158     if root == 'global': 
    159         root = "/" 
    160     root = root.rstrip(r"\/") 
    161      
    162     branch = urllib.unquote(path[len(root) + 1:].lstrip(r"\/")) 
    163      
    164     # If branch is "", file will end in a slash 
    165     file = os.path.join(dir, branch) 
    166      
    167     # There's a chance that the branch pulled from the URL might 
    168     # have ".." or similar uplevel attacks in it. Check that the final 
    169     # file is a child of dir. 
    170     if not os.path.normpath(file).startswith(os.path.normpath(dir)): 
    171         raise cherrypy.HTTPError(403) # Forbidden 
    172      
    173     if not os.path.isabs(file): 
    174         msg = "static directory requires an absolute path (got '%s')." % file 
    175         raise cherrypy.WrongConfigValue(msg) 
    176      
    177     def attempt(fname): 
     151 
     152def _attempt(filename, content_types): 
     153    try: 
    178154        # you can set the content types for a 
    179155        # complete directory per extension 
    180156        content_type = None 
    181157        if content_types: 
    182             r, ext = os.path.splitext(fname) 
    183             content_type = content_types.get(ext[1:], None) 
    184         serve_file(fname, contentType=content_type) 
    185      
    186     try: 
    187         attempt(file) 
    188         return True 
    189     except cherrypy.NotFound: 
    190         # If we didn't find the static file, continue handling the 
    191         # request. We might find a dynamic handler instead. 
    192          
    193         # But first check for an index file if a folder was requested. 
    194         if index and file[-1] in (r"\/"): 
    195             try: 
    196                 attempt(os.path.join(file, index)) 
    197                 return True 
    198             except cherrypy.NotFound: 
    199                 pass 
    200     return False 
    201  
    202  
    203 def get_file(filename, match="", content_types=None): 
    204     if not os.path.isabs(filename): 
    205         msg = "static file requires an absolute path." 
    206         raise cherrypy.WrongConfigValue(msg) 
    207      
    208     request = cherrypy.request 
    209     path = request.object_path 
    210      
    211     if match and not re.search(match, path): 
    212         return False 
    213      
    214     try: 
    215         # you can set the content types for a complete directory per extension 
    216         content_type = None 
    217         if content_types: 
    218             root, ext = os.path.splitext(filename) 
     158            r, ext = os.path.splitext(filename) 
    219159            content_type = content_types.get(ext[1:], None) 
    220160        serve_file(filename, contentType=content_type) 
     
    224164        # request. We might find a dynamic handler instead. 
    225165        return False 
     166 
     167def get_dir(section, dir, root="", match="", content_types=None, index=""): 
     168    if match and not re.search(match, cherrypy.request.object_path): 
     169        return False 
     170     
     171    # If dir is relative, make absolute using "root". 
     172    if not os.path.isabs(dir): 
     173        if not root: 
     174            msg = "Static tool requires an absolute dir or root." 
     175            raise cherrypy.WrongConfigValue(msg) 
     176        dir = os.path.join(root, dir) 
     177     
     178    # Determine where we are in the object tree relative to 'section' 
     179    # (where the static tool was defined). 
     180    if section == 'global': 
     181        section = "/" 
     182    section = section.rstrip(r"\/") 
     183    branch = cherrypy.request.object_path[len(section) + 1:] 
     184    branch = urllib.unquote(branch.lstrip(r"\/")) 
     185     
     186    # If branch is "", filename will end in a slash 
     187    filename = os.path.join(dir, branch) 
     188     
     189    # There's a chance that the branch pulled from the URL might 
     190    # have ".." or similar uplevel attacks in it. Check that the final 
     191    # filename is a child of dir. 
     192    if not os.path.normpath(filename).startswith(os.path.normpath(dir)): 
     193        raise cherrypy.HTTPError(403) # Forbidden 
     194     
     195    handled = _attempt(filename, content_types) 
     196    if not handled: 
     197        # Check for an index file if a folder was requested. 
     198        if index and filename[-1] in (r"\/"): 
     199            handled = _attempt(os.path.join(filename, index), content_types) 
     200    return handled 
     201 
     202def get_file(filename, root=None, match="", content_types=None): 
     203    if match and not re.search(match, cherrypy.request.object_path): 
     204        return False 
     205     
     206    # If filename is relative, make absolute using "root". 
     207    if not os.path.isabs(filename): 
     208        if not root: 
     209            msg = "Static tool requires an absolute filename (got '%s')." % filename 
     210            raise cherrypy.WrongConfigValue(msg) 
     211        filename = os.path.join(root, filename) 
     212     
     213    return _attempt(filename, content_types) 
  • trunk/cherrypy/test/test_static_filter.py

    r1052 r1056  
    3030    cherrypy.config.update({ 
    3131        'global': { 
    32             'server.log_to_screen': True, 
     32            'server.log_to_screen': False, 
    3333            'server.environment': 'production', 
    3434        }, 
     
    4040        '/style.css': { 
    4141            'tools.staticfile.on': True, 
    42             'tools.staticfile.file': os.path.join(curdir, 'style.css'), 
     42            'tools.staticfile.filename': os.path.join(curdir, 'style.css'), 
    4343        }, 
    4444        '/docroot': { 
     
    106106        self.assertBody('Hello, world\r\n') 
    107107         
    108         # Check that we get a WrongConfigValue error if no .file or .dir 
     108        # Check that we get an error if no .file or .dir 
    109109        self.getPage("/error/thing.html") 
    110110        self.assertErrorPage(500) 
    111         self.assertInBody("WrongConfigValue: StaticFilter requires either " 
    112                           "static_filter.file or static_filter.dir " 
    113                           "(/error/thing.html)") 
     111        self.assertInBody("TypeError: get_dir() takes at least 2 " 
     112                          "non-keyword arguments (1 given)") 
    114113         
    115114        # Test up-level security 
  • trunk/cherrypy/tools.py

    r1055 r1056  
    2626 
    2727import cherrypy 
    28 from cherrypy.lib import cptools, encodings, static 
    29  
    30 # These modules are themselves Tools 
    31 from cherrypy.lib import caching, xmlrpc 
    3228 
    3329 
     
    9490 
    9591 
     92#                              Builtin tools                              # 
     93 
     94from cherrypy.lib import cptools, encodings, static 
     95 
    9696base_url = Tool('before_request_body', cptools.base_url) 
    9797response_headers = Tool('before_finalize', cptools.response_headers) 
     
    102102gzip = Tool('before_finalize', encodings.gzip) 
    103103 
    104 staticdir = MainTool(static.get_dir) 
     104class _StaticDirTool(MainTool): 
     105    def setup(self, conf): 
     106        """Hook this tool into cherrypy.request using the given conf.""" 
     107        section = cherrypy.config.get('tools.staticdir.dir', return_section=True) 
     108        conf['section'] = section 
     109        def wrapper(): 
     110            if self.callable(**conf): 
     111                cherrypy.request.execute_main = False 
     112        # Don't pass conf (or our wrapper will get wrapped!) 
     113        cherrypy.request.hooks.attach(self.point, wrapper) 
     114 
     115staticdir = _StaticDirTool(static.get_dir) 
    105116staticfile = MainTool(static.get_file) 
    106117 
     118# These modules are themselves Tools 
     119from cherrypy.lib import caching, xmlrpc 

Hosted by WebFaction

Log in as guest/cpguest to create tickets