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

Changeset 1096

Show
Ignore:
Timestamp:
05/07/06 01:35:03
Author:
fumanchu
Message:

Root and config are now isolated per app:

  1. object_path is now called path_info, and there's a new request.script_name attribute. This should equal the mount point of the current application.
  2. cherrypy.root is gone, use cherrypy.request.app.root for now instead. Perhaps cherrypy.root will reappear and point to that.
  3. cherrypy.tree.mount_points has been replaced with cherrypy.tree.apps, a dict of the form {script_name: Application(root, conf)}.
  4. The [global] config namespace is now contained in a flat cherrypy.config.globalconf dict.
  5. Got rid of handling favicon.ico and the "*" URI (although they may return someday).
  6. Upshot is that e.g. test_objectmapping.py takes 1/3 the time as CP 2.2.
  7. Moved request body size check into _cprequest from _cpwsgi.
  8. Fixed lib/wsgiapp and made a tool for it.
Files:

Legend:

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

    r1093 r1096  
    1212import _cptree 
    1313tree = _cptree.Tree() 
    14  
    15 root = None 
    1614 
    1715import _cpengine 
  • trunk/cherrypy/_cpengine.py

    r1094 r1096  
    4242        # Output config options to log 
    4343        if conf("log_config_options", True): 
    44             cherrypy.config.outputConfigMap() 
    45          
    46         # Hmmm...we *could* check config in _start instead, but I think 
    47         # most people would like CP to fail before autoreload kicks in. 
    48         err = cherrypy.WrongConfigValue 
    49         for name, section in cherrypy.config.configs.iteritems(): 
    50             for k, v in section.iteritems(): 
    51                 if k == "environment": 
    52                     if v and v not in cherrypy.config.environments: 
    53                         raise err("'%s' is not a registered environment." % v) 
     44            cherrypy.config.output_config_map() 
    5445         
    5546        if cherrypy.codecoverage: 
    5647            from cherrypy.lib import covercp 
    5748            covercp.start() 
    58          
    59         # set cgi.maxlen which will limit the size of POST request bodies 
    60         cgi.maxlen = conf('server.max_request_size') 
    6149         
    6250        # Set up the profiler if requested. 
  • trunk/cherrypy/_cprequest.py

    r1094 r1096  
    2525        self.remote_port = remote_port 
    2626        self.remote_host = remote_host 
    27          
    2827        self.scheme = scheme 
     28         
    2929        self.closed = False 
    3030         
     
    8585        try: 
    8686            # This has to be done very early in the request process, 
    87             # because request.object_path is used for config lookups 
     87            # because request.path_info is used for config lookups 
    8888            # right away. 
    8989            self.process_request_line() 
     
    9797                    self.process_headers() 
    9898                     
     99                    # Prepare the SizeCheckWrapper for the request body 
     100                    mbs = int(self.config.get('server.max_request_body_size', 
     101                                              100 * 1024 * 1024)) 
     102                    if mbs > 0: 
     103                        self.rfile = httptools.SizeCheckWrapper(self.rfile, mbs) 
     104                     
    99105                    self.hooks.run('before_request_body') 
    100106                    if self.process_request_body: 
     
    106112                            self.hooks.run('before_main') 
    107113                            if self.dispatch: 
    108                                 self.dispatch(self.object_path
     114                                self.dispatch(self.path_info
    109115                            break 
    110116                        except cherrypy.InternalRedirect, ir: 
    111                             self.object_path = ir.path 
     117                            self.path_info = ir.path 
    112118                     
    113119                    self.hooks.run('before_finalize') 
     
    129135            self.handle_error(sys.exc_info()) 
    130136     
    131     def _get_object_path(self): 
    132         return self._object_path 
    133     def _set_object_path(self, value): 
    134         self._object_path = value 
     137    def _get_path_info(self): 
     138        return self._path_info 
     139    def _set_path_info(self, value): 
     140        self._path_info = value 
    135141        self.config = cherrypy.config.request_config() 
    136142         
     
    144150                bucket = self.toolmap.setdefault(toolname, {}) 
    145151                bucket[".".join(atoms)] = v 
    146     object_path = property(_get_object_path, _set_object_path
     152    path_info = property(_get_path_info, _set_path_info
    147153                           doc="The path to the rendered resource.") 
    148154     
     
    160166        self.query_string = qs 
    161167        self.protocol = proto 
    162          
    163         # Change object_path to change the object that will get rendered 
    164         self.object_path = path 
    165168         
    166169        # Compare request and server HTTP versions, in case our server does 
     
    183186        # cherrypy.response.version should be used to determine whether or 
    184187        # not to include a given HTTP/1.1 feature in the response content. 
    185         server_v = cherrypy.config.get("server.protocol_version", "HTTP/1.0"
     188        server_v = cherrypy.config.get('server.protocol_version', 'HTTP/1.0'
    186189        server_v = httptools.Version.from_http(server_v) 
    187190        cherrypy.response.version = min(self.version, server_v) 
     191         
     192        # Change path_info to change the object that will get rendered. 
     193        # path_info should be the path from the app root to the handler. 
     194        self.script_name = r = cherrypy.tree.script_name(path) 
     195        self.app = cherrypy.tree.apps[r] 
     196        self.path_info = path[len(r.rstrip("/")):] 
    188197     
    189198    def process_headers(self): 
  • trunk/cherrypy/_cptree.py

    r1018 r1096  
    11 
    2 class Root
    3     pass 
    4  
    5 class Branch: 
    6     pass 
     2class Application
     3     
     4    def __init__(self, root, conf): 
     5        self.root = root 
     6        self.conf = conf 
    77 
    88 
    99class Tree: 
    10     """A scaffold for cherrypy.root. 
    11      
    12     This class works together with cherrypy.root, providing helper methods 
    13     for mounting applications at diverse points. "Trellis" would be a more 
    14     accurate name (but too hard to remember, and perhaps in CP 3.0 this 
    15     class will become cherrypy.root). 
    16     """ 
     10    """A registry of mounted applications at diverse points.""" 
    1711     
    1812    def __init__(self): 
    19         self._mount_points = {} 
     13        self.apps = {} 
    2014     
    21     def _get_mount_points(self): 
    22         m = self._mount_points 
    23         if "/" not in m: 
    24             import cherrypy 
    25             if cherrypy.root is not None and not isinstance(cherrypy.root, Root): 
    26                 m["/"] = cherrypy.root 
    27         return m 
    28     def _set_mount_points(self, newvalue): 
    29         self._mount_points = newvalue 
    30     mount_points = property(_get_mount_points, _set_mount_points) 
    31      
    32     def mount(self, app_root, baseurl=None, conf=None): 
    33         """Mount the given app_root at the given baseurl (relative to root).""" 
     15    def mount(self, root, script_name=None, conf=None): 
     16        """Mount the given application root object at the given script_name.""" 
    3417        import cherrypy 
    3518         
    3619        if conf and not isinstance(conf, dict): 
    3720            conf = cherrypy.config.dict_from_config_file(conf) 
     21        elif conf is None: 
     22            conf = {} 
    3823         
    39         if baseurl is None: 
    40             baseurl = "/" 
     24        if script_name is None: 
     25            script_name = "/" 
    4126            if conf: 
    42                 conf_pt = conf.get("global", {}).get("mount_point") 
     27                conf_pt = conf.get("global", {}).get("script_name") 
    4328                if conf_pt: 
    44                     baseurl = conf_pt 
     29                    script_name = conf_pt 
    4530         
    46         point = baseurl.lstrip("/") 
    47         if point: 
    48             node = cherrypy.root 
    49             if node is None: 
    50                 node = cherrypy.root = Root() 
    51             atoms = point.split("/") 
    52             tail = atoms.pop() 
    53             for atom in atoms: 
    54                 if not hasattr(node, atom): 
    55                     setattr(node, atom, Branch()) 
    56                 node = getattr(node, atom) 
    57             if hasattr(node, tail): 
    58                 raise ValueError("The url '%s' is already mounted." % baseurl) 
    59         else: 
    60             # Mount the app_root at cherrypy.root. 
    61             if cherrypy.root is not None: 
    62                 raise ValueError("The url '%s' is already mounted." % baseurl) 
    63             node = cherrypy 
    64             tail = "root" 
     31        self.apps[script_name] = Application(root, conf) 
     32     
     33    def script_name(self, path=None): 
     34        """The script_name of the app at the given path, or None. 
    6535         
    66         setattr(node, tail, app_root) 
    67         self.mount_points[baseurl] = app_root 
    68          
    69         if conf is not None: 
    70             cherrypy.config.update(updateMap=conf, baseurl=baseurl) 
    71      
    72     def mount_point(self, path=None): 
    73         """The 'root path' of the app which governs the given path, or None. 
    74          
    75         If path is None, cherrypy.request.object_path is used. 
     36        If path is None, cherrypy.request.path is used. 
    7637        """ 
    7738         
     
    7940            try: 
    8041                import cherrypy 
    81                 path = cherrypy.request.object_path 
     42                path = cherrypy.request.path 
    8243            except AttributeError: 
    8344                return None 
    8445         
    8546        while path: 
    86             if path in self.mount_points: 
     47            if path in self.apps: 
    8748                return path 
    8849             
     
    9455        return None 
    9556     
    96     def url(self, path, mount_point=None): 
    97         """Return 'path', prefixed with mount_point
     57    def url(self, path, script_name=None): 
     58        """Return 'path', prefixed with script_name
    9859         
    99         If mount_point is None, cherrypy.request.object_path will be used 
    100         to find a mount point
     60        If script_name is None, cherrypy.request.path will be used 
     61        to find a script_name
    10162        """ 
    10263         
    103         if mount_point is None: 
    104             mount_point = self.mount_point() 
    105             if mount_point is None: 
     64        if script_name is None: 
     65            script_name = self.script_name() 
     66            if script_name is None: 
    10667                return path 
    10768         
    10869        from cherrypy.lib import httptools 
    109         return httptools.urljoin(mount_point, path) 
     70        return httptools.urljoin(script_name, path) 
    11071 
  • trunk/cherrypy/_cputil.py

    r1094 r1096  
    1010 
    1111 
    12 def get_object_trail(objectpath=None, root=None): 
    13     """List of (name, object) pairs, from root (cherrypy.root) down objectpath. 
     12def get_object_trail(path=None, root=None): 
     13    """List of (name, object) pairs, from root (app.root) down path. 
    1414     
    1515    If any named objects are unreachable, (name, None) pairs are used. 
    1616    """ 
    1717     
    18     if objectpath is None: 
     18    if path is None: 
    1919        try: 
    20             objectpath = cherrypy.request.object_path 
     20            path = cherrypy.request.path_info 
    2121        except AttributeError: 
    2222            pass 
    2323     
    24     if objectpath is not None: 
    25         objectpath = objectpath.strip('/') 
     24    if path is not None: 
     25        path = path.strip('/') 
    2626     
    27     # Convert the objectpath into a list of names 
    28     if not objectpath: 
     27    # Convert the path into a list of names 
     28    if not path: 
    2929        nameList = [] 
    3030    else: 
    31         nameList = objectpath.split('/') 
    32      
    33     if nameList == ['global']: 
    34         # Special-case a Request-URI of * to allow for our default handler. 
    35         root = getattr(cherrypy, 'root', None) 
    36         if root is None: 
    37             return [('root', None), ('global_', None), ('index', None)] 
    38         gh = getattr(root, 'global_', _cpGlobalHandler) 
    39         return [('root', cherrypy.root), ('global_', gh), ('index', None)] 
     31        nameList = path.split('/') 
    4032     
    4133    if root is None: 
    42         root = getattr(cherrypy, 'root', None) 
    43         if root is None: 
     34        try: 
     35            root = cherrypy.request.app.root 
     36        except AttributeError: 
    4437            return [('root', None), ('index', None)] 
    4538     
     
    4841    # Convert the list of names into a list of objects 
    4942    node = root 
    50     objectTrail = [('root', root)] 
     43    object_trail = [('root', root)] 
    5144    for name in nameList: 
    5245        # maps virtual names to Python identifiers (replaces '.' with '_') 
     
    5447        node = getattr(node, objname, None) 
    5548        if node is None: 
    56             objectTrail.append((name, node)) 
     49            object_trail.append((name, node)) 
    5750        else: 
    58             objectTrail.append((objname, node)) 
     51            object_trail.append((objname, node)) 
    5952     
    60     return objectTrail 
     53    return object_trail 
    6154 
    6255def dispatch(path): 
     
    7669    cherrypy.response.body = handler(*vpath, **request.params) 
    7770 
    78 def find_handler(objectpath): 
     71def find_handler(path): 
    7972    """Find the appropriate page handler for the given path.""" 
    80     objectTrail = get_object_trail(objectpath) 
    81     names = [name for name, candidate in objectTrail] 
     73    object_trail = get_object_trail(path) 
     74    names = [name for name, candidate in object_trail] 
    8275     
    8376    # Try successive objects (reverse order) 
    84     mounted_app_roots = cherrypy.tree.mount_points.values() 
    85     for i in xrange(len(objectTrail) - 1, -1, -1): 
     77    for i in xrange(len(object_trail) - 1, -1, -1): 
    8678         
    87         name, candidate = objectTrail[i] 
     79        name, candidate = object_trail[i] 
    8880         
    8981        # Try a "default" method on the current leaf. 
     
    9385         
    9486        # Uncomment the next line to restrict positional params to "default". 
    95         # if i < len(objectTrail) - 2: continue 
     87        # if i < len(object_trail) - 2: continue 
    9688         
    9789        # Try the current leaf. 
    9890        if callable(candidate) and getattr(candidate, 'exposed', False): 
    99             if i == len(objectTrail) - 1: 
     91            if i == len(object_trail) - 1: 
    10092                # We found the extra ".index". Check if the original path 
    10193                # had a trailing slash (otherwise, do a redirect). 
    102                 if not objectpath.endswith('/'): 
     94                if not path.endswith('/'): 
    10395                    atoms = cherrypy.request.browser_url.split("?", 1) 
    10496                    newUrl = atoms.pop(0) + '/' 
     
    10799                    raise cherrypy.HTTPRedirect(newUrl) 
    108100            return candidate, names[:i+1], names[i+1:-1] 
    109          
    110         if candidate in mounted_app_roots: 
    111             break 
    112101     
    113102    # We didn't find anything 
    114     raise cherrypy.NotFound(objectpath) 
     103    raise cherrypy.NotFound(path) 
    115104 
    116105 
     
    121110    # First, we look in the right-most object to see if this special 
    122111    # attribute is implemented. If not, then we try the previous object, 
    123     # and so on until we reach cherrypy.root, or a mount point
     112    # and so on until we reach app.root (a mount point)
    124113    # If it's still not there, we use the implementation from this module. 
    125     mounted_app_roots = cherrypy.tree.mount_points.values() 
    126114    objectList = get_object_trail() 
    127115    objectList.reverse() 
     
    129117        if hasattr(obj, name): 
    130118            return getattr(obj, name) 
    131         if obj in mounted_app_roots: 
    132             break 
    133119     
    134120    try: 
     
    137123        msg = "Special attribute %s could not be found" % repr(name) 
    138124        raise cherrypy.HTTPError(500, msg) 
    139  
    140 def _cpGlobalHandler(): 
    141     """Default handler for a Request-URI of '*'.""" 
    142     response = cherrypy.response 
    143     response.headers['Content-Type'] = 'text/plain' 
    144      
    145     # OPTIONS is defined in HTTP 1.1 and greater 
    146     request = cherrypy.request 
    147     if request.method == 'OPTIONS' and request.version >= 1.1: 
    148         response.headers['Allow'] = 'HEAD, GET, POST, PUT, OPTIONS' 
    149     else: 
    150         response.headers['Allow'] = 'HEAD, GET, POST' 
    151     return "" 
    152 _cpGlobalHandler.exposed = True 
    153  
    154125 
    155126def logtime(): 
  • trunk/cherrypy/_cpwsgi.py

    r1094 r1096  
    161161                    path = "global" 
    162162                 
    163                 # Prepare the SizeCheckWrapper for the request body 
    164                 mbs = int(cherrypy.config.get('server.max_request_body_size', 
    165                                               100 * 1024 * 1024, path=path)) 
    166163                if isinstance(self.rfile, httptools.SizeCheckWrapper): 
    167                     if mbs > 0: 
    168                         self.rfile.bytes_read = 0 
    169                         self.rfile.maxlen = mbs 
    170                     else: 
    171                         # Unwrap the rfile 
    172                         self.rfile = self.rfile.rfile 
    173                 else: 
    174                     if mbs > 0: 
    175                         self.rfile = httptools.SizeCheckWrapper(self.rfile, mbs) 
     164                    # Unwrap the rfile 
     165                    self.rfile = self.rfile.rfile 
    176166                self.environ["wsgi.input"] = self.rfile 
    177167 
     
    192182        conf = cherrypy.config.get 
    193183         
    194         sockFile = cherrypy.config.get('server.socket_file') 
     184        sockFile = conf('server.socket_file') 
    195185        if sockFile: 
    196186            bind_addr = sockFile 
    197187        else: 
    198             bind_addr = (conf("server.socket_host"), conf("server.socket_port")) 
     188            bind_addr = (conf('server.socket_host'), conf('server.socket_port')) 
    199189         
    200         pts = cherrypy.tree.mount_points 
    201         if pts: 
    202             apps = [(base, wsgiApp) for base in pts.keys()] 
    203         else: 
    204             apps = [("", wsgiApp)] 
     190        apps = [] 
     191        for base in cherrypy.tree.apps: 
     192            if base == "/": 
     193                base = "" 
     194            apps.append((base, wsgiApp)) 
    205195         
    206196        s = _cpwsgiserver.CherryPyWSGIServer 
    207197        s.__init__(self, bind_addr, apps, 
    208                    conf("server.thread_pool"), 
    209                    conf("server.socket_host"), 
     198                   conf('server.thread_pool'), 
     199                   conf('server.socket_host'), 
    210200                   request_queue_size = conf('server.socket_queue_size'), 
    211201                   ) 
  • trunk/cherrypy/config.py

    r1094 r1096  
    22 
    33import ConfigParser 
    4 import os 
    5 _favicon_path = os.path.join(os.path.dirname(__file__), "favicon.ico") 
    64 
    75import cherrypy 
    86from cherrypy import _cputil 
    97from cherrypy.lib import autoreload, cptools, httptools 
    10  
    11  
    12 # This configs dict holds the settings metadata for all cherrypy objects. 
    13 # Keys are URL paths, and values are dicts. 
    14 configs = {} 
    15  
    16 default_global = { 
    17     'server.socket_port': 8080, 
    18     'server.socket_host': '', 
    19     'server.socket_file': '', 
    20     'server.socket_queue_size': 5, 
    21     'server.protocol_version': 'HTTP/1.0', 
    22     'log_to_screen': True, 
    23     'log_file': '', 
    24     'tools.log_tracebacks.on': True, 
    25     'server.reverse_dns': False, 
    26     'server.thread_pool': 10, 
    27     'environment': "development", 
    28      
    29     '/favicon.ico': {'tools.staticfile.on': True, 
    30                      'tools.staticfile.filename': _favicon_path}, 
    31     } 
    328 
    339environments = { 
     
    5329        'autoreload.on': False, 
    5430        'log_to_screen': False, 
    55         'server.init_only': True, 
    5631        'server.class': None, 
    5732        }, 
    5833    } 
    5934 
    60 def update(updateMap=None, file=None, overwrite=True, baseurl=""): 
    61     """Update configs from a dictionary or a config file. 
    62      
    63     If overwrite is False then the update will not modify values 
    64     already defined in the configs. 
    65     """ 
    66     if updateMap is None: 
    67         updateMap = {} 
    68      
    69     if file: 
    70         if file not in autoreload.reloadFiles: 
    71             autoreload.reloadFiles.append(file) 
    72         updateMap = updateMap.copy() 
    73         updateMap.update(dict_from_config_file(file)) 
    74      
    75     # Load new conf into cherrypy.configs 
    76     for section, valueMap in updateMap.iteritems(): 
    77         # Handle shortcut syntax for "global" section 
    78         #   example: update({'server.socket_port': 80}) 
    79         if not isinstance(valueMap, dict): 
    80             valueMap = {section: valueMap} 
    81             section = 'global' 
    82          
    83         if baseurl and section.startswith("/"): 
    84             if section == "/": 
    85                 section = baseurl 
    86             else: 
    87                 section = httptools.urljoin(baseurl, section) 
    88          
    89         bucket = configs.setdefault(section, {}) 
    90         if overwrite: 
    91             bucket.update(valueMap) 
    92         else: 
    93             for key, value in valueMap.iteritems(): 
    94                 bucket.setdefault(key, value) 
    95  
    96 def reset(useDefaults=True): 
    97     """Clear configuration and restore defaults""" 
    98     configs.clear() 
    99     if useDefaults: 
    100         update(default_global) 
    101 reset() 
    102  
    103 def get(key, default_value=None, return_section=False, path=None): 
    104     """Return the configuration value corresponding to key 
    105     If specified, return default_value on lookup failure. If return_section is 
    106     specified, return the path to the value, instead of the value itself. 
    107     """ 
    108      
    109     if path is None: 
     35def merge(base, other): 
     36    """Merge one config (from a dict, file, or filename) into another.""" 
     37    if isinstance(other, basestring): 
     38        if other not in autoreload.reloadFiles: 
     39            autoreload.reloadFiles.append(other) 
     40        other = dict_from_config_file(other) 
     41    elif hasattr(other, 'read'): 
     42        other = dict_from_config_file(other) 
     43     
     44    # Load other into base 
     45    for section, value_map in other.iteritems(): 
     46        base.setdefault(section, {}).update(value_map) 
     47 
     48 
     49default_conf = { 
     50    'server.socket_port': 8080, 
     51    'server.socket_host': '', 
     52    'server.socket_file': '', 
     53    'server.socket_queue_size': 5, 
     54    'server.protocol_version': 'HTTP/1.0', 
     55    'server.reverse_dns': False, 
     56    'server.thread_pool': 10, 
     57    'log_to_screen': True, 
     58    'log_file': '', 
     59    'tools.log_tracebacks.on': True, 
     60    'environment': "development", 
     61    } 
     62 
     63globalconf = default_conf.copy() 
     64 
     65def reset(): 
     66    globalconf.clear() 
     67    globalconf.update(default_conf) 
     68 
     69def update(conf): 
     70    """Update globalconf from a dict, file or filename.""" 
     71    if isinstance(conf, basestring): 
     72        if conf not in autoreload.reloadFiles: 
     73            autoreload.reloadFiles.append(conf) 
     74        conf = dict_from_config_file(conf) 
     75    elif hasattr(conf, 'read'): 
     76        conf = dict_from_config_file(conf) 
     77    if isinstance(conf.get("global", None), dict): 
     78        conf = conf["global"] 
     79    globalconf.update(conf) 
     80 
     81 
     82def get(key, default=None): 
     83    """Return the config value corresponding to key, or default.""" 
     84     
     85    try: 
     86        conf = cherrypy.request.config 
     87    except AttributeError: 
     88        # There's no request, so just use globalconf. 
     89        conf = globalconf 
     90     
     91    try: 
     92        return conf[key] 
     93    except KeyError: 
    11094        try: 
    111             path = cherrypy.request.object_path 
    112         except AttributeError: 
    113             # There's no request.object_path yet, so use the global settings. 
    114             path = "global" 
    115      
    116     while True: 
    117         if path == "": 
    118             path = "/" 
    119          
    120         try: 
    121             result = configs[path][key] 
    122             break 
     95            env = conf["environment"] 
     96            return environments[env][key] 
    12397        except KeyError: 
    124             pass 
    125          
    126         try: 
    127             env = configs[path]["environment"] 
    128             result = environments[env][key] 
    129             break 
    130         except KeyError: 
    131             pass 
    132         pass 
    133  
    134         if path == "global": 
    135             result = default_value 
    136             break 
    137          
    138         # Move one node up the tree and try again. 
    139         if path == "/": 
    140             path = "global" 
    141         elif path in cherrypy.tree.mount_points: 
    142             # We've reached the mount point for an application, 
    143             # and should skip the rest of the tree (up to "global"). 
    144             path = "global" 
    145         else: 
    146             path = path[:path.rfind("/")] 
    147      
    148     if return_section: 
    149         return path 
    150     else: 
    151         return result 
     98            return default 
    15299 
    153100def request_config(): 
    154101    """Return all configs in effect for the current request in a single dict.""" 
    155     path = cherrypy.request.object_path 
    156     mounted_app_roots = cherrypy.tree.mount_points.values() 
     102    path = cherrypy.request.path_info 
     103    app = cherrypy.request.app 
    157104     
    158105    # Convert the path into a list of names 
    159     if (not path) or path == "*": 
     106    if (not path) or path == "/": 
    160107        nameList = [] 
    161108    else: 
     
    164111     
    165112    curpath = "" 
    166     node = cherrypy.root 
     113    node = app.root 
    167114    conf = getattr(node, "_cp_config", {}).copy() 
    168     conf.update(configs.get("/", {})) 
     115    conf.update(app.conf.get("/", {})) 
    169116    for name in nameList: 
    170         # Get _cp_config attached to each node on the cherrypy tree. 
     117        # Get _cp_config attached to each node on this app's tree. 
    171118        objname = name.replace('.', '_') 
    172119        node = getattr(node, objname, None) 
    173         if node is not None: 
    174             if node in mounted_app_roots: 
    175                 # Dump and start over. This inefficiency should disappear 
    176                 # once we make cherrypy.localroot (specific to each request). 
    177                 conf = {} 
    178             conf.update(getattr(node, "_cp_config", {})) 
    179          
    180         # Get values from cherrypy.config for this path. 
     120        nodeconf = getattr(node, "_cp_config", {}) 
     121         
     122        # Get values from app.config for this path. 
    181123        curpath = "/".join((curpath, name)) 
    182         conf.update(configs.get(curpath, {})) 
    183      
    184     base = configs.get("global", {}).copy() 
     124        nodeconf.update(app.conf.get(curpath, {})) 
     125         
     126        # Resolve "environment" entries. This must be done node-by-node 
     127        # so that a child's "environment" can override concrete settings 
     128        # of a parent. However, concrete settings in this node will 
     129        # override "environment" settings in the same node. 
     130        env = nodeconf.get("environment") 
     131        if env: 
     132            for k, v in environments[env].iteritems(): 
     133                if k not in nodeconf: 
     134                    nodeconf[k] = v 
     135         
     136        conf.update(nodeconf) 
     137     
     138    base = globalconf.copy() 
    185139    base.update(conf) 
    186140    return base 
     
    189143def request_config_section(key): 
    190144    """Return the (longest) path where the given key is defined (or None).""" 
    191     path = cherrypy.request.object_path 
    192     mounted_app_roots = cherrypy.tree.mount_points.values() 
     145    path = cherrypy.request.path_info 
     146    app = cherrypy.request.app 
    193147     
    194148    # Convert the path into a list of names 
    195     if (not path) or path == "*"
     149    if (not path)
    196150        nameList = [] 
    197151    else: 
     
    202156     
    203157    curpath = "" 
    204     node = cherrypy.root 
    205     if key in getattr(node, "_cp_config", {}) or key in configs.get("/", {}): 
     158    node = app.root 
     159    if key in getattr(node, "_cp_config", {}) or key in app.conf.get("/", {}): 
    206160        foundpath = "/" 
    207161    for name in nameList: 
    208162        curpath = "/".join((curpath, name)) 
    209163         
    210         # Get _cp_config attached to each node on the cherrypy tree. 
     164        # Get _cp_config attached to each node on this app's tree. 
    211165        objname = name.replace('.', '_') 
    212166        node = getattr(node, objname, None) 
    213167        if node is not None: 
    214             if node in mounted_app_roots: 
    215                 # Dump and start over. This inefficiency should disappear 
    216                 # once we make cherrypy.localroot (specific to each request). 
    217                 foundpath = None 
    218168            if key in getattr(node, "_cp_config", {}): 
    219                 foundpath = curpath or "/" 
     169                foundpath = curpath 
     170                break 
    220171         
    221172        # Get values from cherrypy.config for this path. 
    222         if key in configs.get(curpath, {}): 
     173        if key in app.conf.get(curpath, {}): 
    223174            foundpath = curpath 
    224175     
    225176    if foundpath is None: 
    226         foundpath = configs.get("global", {}).get(key) 
     177        foundpath = globalconf.get(key) 
    227178    return foundpath 
    228179 
     
    250201                fp.close() 
    251202 
    252 def dict_from_config_file(configFile, raw=False, vars=None): 
     203def dict_from_config_file(config_file, raw=False, vars=None): 
    253204    """Convert an INI file to a dictionary""" 
    254205     
    255206    # Parse config file 
    256207    configParser = CaseSensitiveConfigParser() 
    257     if hasattr(configFile, 'read'): 
    258         configParser.readfp(configFile) 
     208    if hasattr(config_file, 'read'): 
     209        configParser.readfp(config_file) 
    259210    else: 
    260         configParser.read(configFile) 
     211        configParser.read(config_file) 
    261212     
    262213    # Load INI file into a dict 
     
    279230 
    280231 
    281 def outputConfigMap(): 
    282     """Log server configuration parameters""" 
     232def output_config_map(): 
     233    """Log engine configuration parameters.""" 
    283234    cherrypy.log("Server parameters:", 'CONFIG') 
    284235     
     
    295246                  'server.thread_pool', 
    296247                 ] 
    297  
     248     
    298249    for var in serverVars: 
    299250        cherrypy.log("  %s: %s" % (var, get(var)), 'CONFIG') 
  • trunk/cherrypy/lib/cptools.py

    r1082 r1096  
    4646    from cherrypy.lib.cptools import ExposeItems 
    4747    ... 
    48     cherrypy.root.foo = ExposeItems(mylist) 
    49     cherrypy.root.bar = ExposeItems(mydict) 
     48    root.foo = ExposeItems(mylist) 
     49    root.bar = ExposeItems(mydict) 
    5050    """ 
    5151    exposed = True 
     
    288288 
    289289def virtual_host(use_x_forwarded_host=True, **domains): 
    290     """Change the object_path based on the Host. 
     290    """Change the path_info based on the Host. 
    291291     
    292292    Useful when running multiple sites within one CP server. 
     
    312312    prefix = domains.get(domain, "") 
    313313    if prefix: 
    314         cherrypy.request.object_path = prefix + "/" + cherrypy.request.object_path 
     314        cherrypy.request.path_info = prefix + "/" + cherrypy.request.path_info 
    315315 
    316316def log_traceback(): 
  • trunk/cherrypy/lib/static.py

    r1094 r1096  
    170170 
    171171def staticdir(section, dir, root="", match="", content_types=None, index=""): 
    172     if match and not re.search(match, cherrypy.request.object_path): 
     172    if match and not re.search(match, cherrypy.request.path_info): 
    173173        return False 
    174174     
     
    185185        section = "/" 
    186186    section = section.rstrip(r"\/") 
    187     branch = cherrypy.request.object_path[len(section) + 1:] 
     187    branch = cherrypy.request.path_info[len(section) + 1:] 
    188188    branch = urllib.unquote(branch.lstrip(r"\/")) 
    189189     
     
    205205 
    206206def staticfile(filename, root=None, match="", content_types=None): 
    207     if match and not re.search(match, cherrypy.request.object_path): 
     207    if match and not re.search(match, cherrypy.request.path_info): 
    208208        return False 
    209209     
  • trunk/cherrypy/lib/