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

Changeset 1132

Show
Ignore:
Timestamp:
06/09/06 11:48:16
Author:
fumanchu
Message:

Merged _cputil into _cprequest.

Files:

Legend:

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

    r1130 r1132  
    259259    def get_resource(self, path): 
    260260        """Find and call a dispatcher (which sets self.handler and .config).""" 
    261         dispatch = _cputil.dispatch 
     261        dispatch = default_dispatch 
    262262        # First, see if there is a custom dispatch at this URI. Custom 
    263263        # dispatchers can only be specified in app.conf, not in _cp_config 
     
    377377 
    378378 
     379class Dispatcher(object): 
     380     
     381    def __call__(self, path_info): 
     382        """Set handler and config for the current request.""" 
     383        request = cherrypy.request 
     384        func, vpath = self.find_handler(path_info) 
     385         
     386        # Decode any leftover %2F in the virtual_path atoms. 
     387        vpath = [x.replace("%2F", "/") for x in vpath] 
     388         
     389        if func: 
     390            def handler(): 
     391                cherrypy.response.body = func(*vpath, **request.params) 
     392            request.handler = handler 
     393        else: 
     394            def notfound(): 
     395                raise cherrypy.NotFound() 
     396            request.handler = notfound 
     397     
     398    def find_handler(self, path): 
     399        """Find the appropriate page handler for the given path.""" 
     400        request = cherrypy.request 
     401        app = request.app 
     402        root = app.root 
     403         
     404        # Get config for the root object/path. 
     405        curpath = "" 
     406        nodeconf = getattr(root, "_cp_config", {}).copy() 
     407        nodeconf.update(app.conf.get("/", {})) 
     408        object_trail = [('root', root, nodeconf, curpath)] 
     409         
     410        node = root 
     411        names = [x for x in path.strip('/').split('/') if x] + ['index'] 
     412        for name in names: 
     413            # map to legal Python identifiers (replace '.' with '_') 
     414            objname = name.replace('.', '_') 
     415             
     416            nodeconf = {} 
     417            node = getattr(node, objname, None) 
     418            if node is not None: 
     419                # Get _cp_config attached to this node. 
     420                nodeconf = getattr(node, "_cp_config", {}).copy() 
     421             
     422            # Mix in values from app.conf for this path. 
     423            curpath = "/".join((curpath, name)) 
     424            nodeconf.update(app.conf.get(curpath, {})) 
     425             
     426            # Resolve "environment" entries. This must be done node-by-node 
     427            # so that a child's "environment" can override concrete settings 
     428            # of a parent. However, concrete settings in this node will 
     429            # override "environment" settings in the same node. 
     430            env = nodeconf.get("environment") 
     431            if env: 
     432                for k, v in cherrypy.config.environments[env].iteritems(): 
     433                    if k not in nodeconf: 
     434                        nodeconf[k] = v 
     435             
     436            object_trail.append((objname, node, nodeconf, curpath)) 
     437         
     438        def set_conf(): 
     439            """Set cherrypy.request.config.""" 
     440            base = cherrypy.config.globalconf.copy() 
     441            if 'tools.staticdir.dir' in base: 
     442                base['tools.staticdir.section'] = "global" 
     443            for name, obj, conf, curpath in object_trail: 
     444                base.update(conf) 
     445                if 'tools.staticdir.dir' in conf: 
     446                    base['tools.staticdir.section'] = curpath 
     447            request.config = base 
     448         
     449        # Try successive objects (reverse order) 
     450        for i in xrange(len(object_trail) - 1, -1, -1): 
     451             
     452            name, candidate, nodeconf, curpath = object_trail[i] 
     453             
     454            # Try a "default" method on the current leaf. 
     455            defhandler = getattr(candidate, "default", None) 
     456            if callable(defhandler) and getattr(defhandler, 'exposed', False): 
     457                # Insert any extra _cp_config from the default handler. 
     458                conf = getattr(defhandler, "_cp_config", {}) 
     459                object_trail.insert(i+1, ("default", defhandler, conf, curpath)) 
     460                set_conf() 
     461                return defhandler, names[i:-1] 
     462             
     463            # Uncomment the next line to restrict positional params to "default". 
     464            # if i < len(object_trail) - 2: continue 
     465             
     466            # Try the current leaf. 
     467            if callable(candidate) and getattr(candidate, 'exposed', False): 
     468                set_conf() 
     469                if i == len(object_trail) - 1: 
     470                    # We found the extra ".index". Check if the original path 
     471                    # had a trailing slash (otherwise, do a redirect). 
     472                    if not path.endswith('/'): 
     473                        atoms = request.browser_url.split("?", 1) 
     474                        newUrl = atoms.pop(0) + '/' 
     475                        if atoms: 
     476                            newUrl += "?" + atoms[0] 
     477                        raise cherrypy.HTTPRedirect(newUrl) 
     478                return candidate, names[i:-1] 
     479         
     480        # We didn't find anything 
     481        set_conf() 
     482        return None, [] 
     483 
     484default_dispatch = Dispatcher() 
     485 
     486 
    379487def fileGenerator(input, chunkSize=65536): 
    380488    """Yield the given input (a file object) in chunks (default 64k).""" 

Hosted by WebFaction

Log in as guest/cpguest to create tickets