Changeset 1096
- Timestamp:
- 05/07/06 01:35:03
- Files:
-
- trunk/cherrypy/__init__.py (modified) (1 diff)
- trunk/cherrypy/_cpengine.py (modified) (1 diff)
- trunk/cherrypy/_cprequest.py (modified) (8 diffs)
- trunk/cherrypy/_cptree.py (modified) (3 diffs)
- trunk/cherrypy/_cputil.py (modified) (9 diffs)
- trunk/cherrypy/_cpwsgi.py (modified) (2 diffs)
- trunk/cherrypy/config.py (modified) (8 diffs)
- trunk/cherrypy/lib/cptools.py (modified) (3 diffs)
- trunk/cherrypy/lib/static.py (modified) (3 diffs)
- trunk/cherrypy/lib/wsgiapp.py (modified) (5 diffs)
- trunk/cherrypy/test/benchmark.py (modified) (6 diffs)
- trunk/cherrypy/test/helper.py (modified) (8 diffs)
- trunk/cherrypy/test/standalone_test_alt_script_name.py (modified) (9 diffs)
- trunk/cherrypy/test/test_cache_filter.py (modified) (2 diffs)
- trunk/cherrypy/test/test_combinedfilters.py (modified) (1 diff)
- trunk/cherrypy/test/test_config.py (modified) (6 diffs)
- trunk/cherrypy/test/test_core.py (modified) (12 diffs)
- trunk/cherrypy/test/test_custom_filters.py (modified) (4 diffs)
- trunk/cherrypy/test/test_decodingencoding_filter.py (modified) (1 diff)
- trunk/cherrypy/test/test_gzip_filter.py (modified) (2 diffs)
- trunk/cherrypy/test/test_noserver.py (modified) (1 diff)
- trunk/cherrypy/test/test_objectmapping.py (modified) (13 diffs)
- trunk/cherrypy/test/test_response_headers_filter.py (modified) (1 diff)
- trunk/cherrypy/test/test_session_concurrency.py (modified) (2 diffs)
- trunk/cherrypy/test/test_session_filter.py (modified) (2 diffs)
- trunk/cherrypy/test/test_sessionauthenticate_filter.py (modified) (2 diffs)
- trunk/cherrypy/test/test_states.py (modified) (1 diff)
- trunk/cherrypy/test/test_static_filter.py (modified) (2 diffs)
- trunk/cherrypy/test/test_tutorials.py (modified) (4 diffs)
- trunk/cherrypy/test/test_virtualhost_filter.py (modified) (1 diff)
- trunk/cherrypy/test/test_wsgiapp_filter.py (modified) (3 diffs)
- trunk/cherrypy/test/test_xmlrpc_filter.py (modified) (2 diffs)
- trunk/cherrypy/tools.py (modified) (2 diffs)
- trunk/cherrypy/tutorial/bonus-sqlobject.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut01_helloworld.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut02_expose_methods.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut03_get_and_post.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut04_complex_site.py (modified) (2 diffs)
- trunk/cherrypy/tutorial/tut05_derived_objects.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut06_default_method.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut07_sessions.py (modified) (2 diffs)
- trunk/cherrypy/tutorial/tut08_generators_and_yield.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut09_files.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut10_http_errors.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/__init__.py
r1093 r1096 12 12 import _cptree 13 13 tree = _cptree.Tree() 14 15 root = None16 14 17 15 import _cpengine trunk/cherrypy/_cpengine.py
r1094 r1096 42 42 # Output config options to log 43 43 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() 54 45 55 46 if cherrypy.codecoverage: 56 47 from cherrypy.lib import covercp 57 48 covercp.start() 58 59 # set cgi.maxlen which will limit the size of POST request bodies60 cgi.maxlen = conf('server.max_request_size')61 49 62 50 # Set up the profiler if requested. trunk/cherrypy/_cprequest.py
r1094 r1096 25 25 self.remote_port = remote_port 26 26 self.remote_host = remote_host 27 28 27 self.scheme = scheme 28 29 29 self.closed = False 30 30 … … 85 85 try: 86 86 # This has to be done very early in the request process, 87 # because request. object_pathis used for config lookups87 # because request.path_info is used for config lookups 88 88 # right away. 89 89 self.process_request_line() … … 97 97 self.process_headers() 98 98 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 99 105 self.hooks.run('before_request_body') 100 106 if self.process_request_body: … … 106 112 self.hooks.run('before_main') 107 113 if self.dispatch: 108 self.dispatch(self. object_path)114 self.dispatch(self.path_info) 109 115 break 110 116 except cherrypy.InternalRedirect, ir: 111 self. object_path= ir.path117 self.path_info = ir.path 112 118 113 119 self.hooks.run('before_finalize') … … 129 135 self.handle_error(sys.exc_info()) 130 136 131 def _get_ object_path(self):132 return self._ object_path133 def _set_ object_path(self, value):134 self._ object_path= value137 def _get_path_info(self): 138 return self._path_info 139 def _set_path_info(self, value): 140 self._path_info = value 135 141 self.config = cherrypy.config.request_config() 136 142 … … 144 150 bucket = self.toolmap.setdefault(toolname, {}) 145 151 bucket[".".join(atoms)] = v 146 object_path = property(_get_object_path, _set_object_path,152 path_info = property(_get_path_info, _set_path_info, 147 153 doc="The path to the rendered resource.") 148 154 … … 160 166 self.query_string = qs 161 167 self.protocol = proto 162 163 # Change object_path to change the object that will get rendered164 self.object_path = path165 168 166 169 # Compare request and server HTTP versions, in case our server does … … 183 186 # cherrypy.response.version should be used to determine whether or 184 187 # 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') 186 189 server_v = httptools.Version.from_http(server_v) 187 190 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("/")):] 188 197 189 198 def process_headers(self): trunk/cherrypy/_cptree.py
r1018 r1096 1 1 2 class Root:3 pass4 5 class Branch: 6 pass2 class Application: 3 4 def __init__(self, root, conf): 5 self.root = root 6 self.conf = conf 7 7 8 8 9 9 class 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.""" 17 11 18 12 def __init__(self): 19 self. _mount_points = {}13 self.apps = {} 20 14 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.""" 34 17 import cherrypy 35 18 36 19 if conf and not isinstance(conf, dict): 37 20 conf = cherrypy.config.dict_from_config_file(conf) 21 elif conf is None: 22 conf = {} 38 23 39 if baseurlis None:40 baseurl= "/"24 if script_name is None: 25 script_name = "/" 41 26 if conf: 42 conf_pt = conf.get("global", {}).get(" mount_point")27 conf_pt = conf.get("global", {}).get("script_name") 43 28 if conf_pt: 44 baseurl= conf_pt29 script_name = conf_pt 45 30 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. 65 35 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. 76 37 """ 77 38 … … 79 40 try: 80 41 import cherrypy 81 path = cherrypy.request. object_path42 path = cherrypy.request.path 82 43 except AttributeError: 83 44 return None 84 45 85 46 while path: 86 if path in self. mount_points:47 if path in self.apps: 87 48 return path 88 49 … … 94 55 return None 95 56 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. 98 59 99 If mount_point is None, cherrypy.request.object_path will be used100 to find a mount point.60 If script_name is None, cherrypy.request.path will be used 61 to find a script_name. 101 62 """ 102 63 103 if mount_pointis None:104 mount_point = self.mount_point()105 if mount_pointis None:64 if script_name is None: 65 script_name = self.script_name() 66 if script_name is None: 106 67 return path 107 68 108 69 from cherrypy.lib import httptools 109 return httptools.urljoin( mount_point, path)70 return httptools.urljoin(script_name, path) 110 71 trunk/cherrypy/_cputil.py
r1094 r1096 10 10 11 11 12 def get_object_trail( objectpath=None, root=None):13 """List of (name, object) pairs, from root ( cherrypy.root) down objectpath.12 def get_object_trail(path=None, root=None): 13 """List of (name, object) pairs, from root (app.root) down path. 14 14 15 15 If any named objects are unreachable, (name, None) pairs are used. 16 16 """ 17 17 18 if objectpath is None:18 if path is None: 19 19 try: 20 objectpath = cherrypy.request.object_path20 path = cherrypy.request.path_info 21 21 except AttributeError: 22 22 pass 23 23 24 if objectpath is not None:25 objectpath = objectpath.strip('/')24 if path is not None: 25 path = path.strip('/') 26 26 27 # Convert the objectpath into a list of names28 if not objectpath:27 # Convert the path into a list of names 28 if not path: 29 29 nameList = [] 30 30 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('/') 40 32 41 33 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: 44 37 return [('root', None), ('index', None)] 45 38 … … 48 41 # Convert the list of names into a list of objects 49 42 node = root 50 object Trail = [('root', root)]43 object_trail = [('root', root)] 51 44 for name in nameList: 52 45 # maps virtual names to Python identifiers (replaces '.' with '_') … … 54 47 node = getattr(node, objname, None) 55 48 if node is None: 56 object Trail.append((name, node))49 object_trail.append((name, node)) 57 50 else: 58 object Trail.append((objname, node))51 object_trail.append((objname, node)) 59 52 60 return object Trail53 return object_trail 61 54 62 55 def dispatch(path): … … 76 69 cherrypy.response.body = handler(*vpath, **request.params) 77 70 78 def find_handler( objectpath):71 def find_handler(path): 79 72 """Find the appropriate page handler for the given path.""" 80 object Trail = get_object_trail(objectpath)81 names = [name for name, candidate in object Trail]73 object_trail = get_object_trail(path) 74 names = [name for name, candidate in object_trail] 82 75 83 76 # 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): 86 78 87 name, candidate = object Trail[i]79 name, candidate = object_trail[i] 88 80 89 81 # Try a "default" method on the current leaf. … … 93 85 94 86 # Uncomment the next line to restrict positional params to "default". 95 # if i < len(object Trail) - 2: continue87 # if i < len(object_trail) - 2: continue 96 88 97 89 # Try the current leaf. 98 90 if callable(candidate) and getattr(candidate, 'exposed', False): 99 if i == len(object Trail) - 1:91 if i == len(object_trail) - 1: 100 92 # We found the extra ".index". Check if the original path 101 93 # had a trailing slash (otherwise, do a redirect). 102 if not objectpath.endswith('/'):94 if not path.endswith('/'): 103 95 atoms = cherrypy.request.browser_url.split("?", 1) 104 96 newUrl = atoms.pop(0) + '/' … … 107 99 raise cherrypy.HTTPRedirect(newUrl) 108 100 return candidate, names[:i+1], names[i+1:-1] 109 110 if candidate in mounted_app_roots:111 break112 101 113 102 # We didn't find anything 114 raise cherrypy.NotFound( objectpath)103 raise cherrypy.NotFound(path) 115 104 116 105 … … 121 110 # First, we look in the right-most object to see if this special 122 111 # 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). 124 113 # If it's still not there, we use the implementation from this module. 125 mounted_app_roots = cherrypy.tree.mount_points.values()126 114 objectList = get_object_trail() 127 115 objectList.reverse() … … 129 117 if hasattr(obj, name): 130 118 return getattr(obj, name) 131 if obj in mounted_app_roots:132 break133 119 134 120 try: … … 137 123 msg = "Special attribute %s could not be found" % repr(name) 138 124 raise cherrypy.HTTPError(500, msg) 139 140 def _cpGlobalHandler():141 """Default handler for a Request-URI of '*'."""142 response = cherrypy.response143 response.headers['Content-Type'] = 'text/plain'144 145 # OPTIONS is defined in HTTP 1.1 and greater146 request = cherrypy.request147 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 = True153 154 125 155 126 def logtime(): trunk/cherrypy/_cpwsgi.py
r1094 r1096 161 161 path = "global" 162 162 163 # Prepare the SizeCheckWrapper for the request body164 mbs = int(cherrypy.config.get('server.max_request_body_size',165 100 * 1024 * 1024, path=path))166 163 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 176 166 self.environ["wsgi.input"] = self.rfile 177 167 … … 192 182 conf = cherrypy.config.get 193 183 194 sockFile = c herrypy.config.get('server.socket_file')184 sockFile = conf('server.socket_file') 195 185 if sockFile: 196 186 bind_addr = sockFile 197 187 else: 198 bind_addr = (conf( "server.socket_host"), conf("server.socket_port"))188 bind_addr = (conf('server.socket_host'), conf('server.socket_port')) 199 189 200 pts = cherrypy.tree.mount_points201 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)) 205 195 206 196 s = _cpwsgiserver.CherryPyWSGIServer 207 197 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'), 210 200 request_queue_size = conf('server.socket_queue_size'), 211 201 ) trunk/cherrypy/config.py
r1094 r1096 2 2 3 3 import ConfigParser 4 import os5 _favicon_path = os.path.join(os.path.dirname(__file__), "favicon.ico")6 4 7 5 import cherrypy 8 6 from cherrypy import _cputil 9 7 from 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 }32 8 33 9 environments = { … … 53 29 'autoreload.on': False, 54 30 'log_to_screen': False, 55 'server.init_only': True,56 31 'server.class': None, 57 32 }, 58 33 } 59 34 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: 35 def 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 49 default_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 63 globalconf = default_conf.copy() 64 65 def reset(): 66 globalconf.clear() 67 globalconf.update(default_conf) 68 69 def 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 82 def 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: 110 94 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] 123 97 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 152 99 153 100 def request_config(): 154 101 """Return all configs in effect for the current request in a single dict.""" 155 path = cherrypy.request. object_path156 mounted_app_roots = cherrypy.tree.mount_points.values()102 path = cherrypy.request.path_info 103 app = cherrypy.request.app 157 104 158 105 # Convert the path into a list of names 159 if (not path) or path == " *":106 if (not path) or path == "/": 160 107 nameList = [] 161 108 else: … … 164 111 165 112 curpath = "" 166 node = cherrypy.root113 node = app.root 167 114 conf = getattr(node, "_cp_config", {}).copy() 168 conf.update( configs.get("/", {}))115 conf.update(app.conf.get("/", {})) 169 116 for name in nameList: 170 # Get _cp_config attached to each node on th e cherrypytree.117 # Get _cp_config attached to each node on this app's tree. 171 118 objname = name.replace('.', '_') 172 119 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. 181 123 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() 185 139 base.update(conf) 186 140 return base … … 189 143 def request_config_section(key): 190 144 """Return the (longest) path where the given key is defined (or None).""" 191 path = cherrypy.request. object_path192 mounted_app_roots = cherrypy.tree.mount_points.values()145 path = cherrypy.request.path_info 146 app = cherrypy.request.app 193 147 194 148 # Convert the path into a list of names 195 if (not path) or path == "*":149 if (not path): 196 150 nameList = [] 197 151 else: … … 202 156 203 157 curpath = "" 204 node = cherrypy.root205 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("/", {}): 206 160 foundpath = "/" 207 161 for name in nameList: 208 162 curpath = "/".join((curpath, name)) 209 163 210 # Get _cp_config attached to each node on th e cherrypytree.164 # Get _cp_config attached to each node on this app's tree. 211 165 objname = name.replace('.', '_') 212 166 node = getattr(node, objname, None) 213 167 if node is not None: 214 if node in mounted_app_roots:215 # Dump and start over. This inefficiency should disappear216 # once we make cherrypy.localroot (specific to each request).217 foundpath = None218 168 if key in getattr(node, "_cp_config", {}): 219 foundpath = curpath or "/" 169 foundpath = curpath 170 break 220 171 221 172 # Get values from cherrypy.config for this path. 222 if key in configs.get(curpath, {}):173 if key in app.conf.get(curpath, {}): 223 174 foundpath = curpath 224 175 225 176 if foundpath is None: 226 foundpath = configs.get("global", {}).get(key)177 foundpath = globalconf.get(key) 227 178 return foundpath 228 179 … … 250 201 fp.close() 251 202 252 def dict_from_config_file(config File, raw=False, vars=None):203 def dict_from_config_file(config_file, raw=False, vars=None): 253 204 """Convert an INI file to a dictionary""" 254 205 255 206 # Parse config file 256 207 configParser = CaseSensitiveConfigParser() 257 if hasattr(config File, 'read'):258 configParser.readfp(config File)208 if hasattr(config_file, 'read'): 209 configParser.readfp(config_file) 259 210 else: 260 configParser.read(config File)211 configParser.read(config_file) 261 212 262 213 # Load INI file into a dict … … 279 230 280 231 281 def output ConfigMap():282 """Log server configuration parameters"""232 def output_config_map(): 233 """Log engine configuration parameters.""" 283 234 cherrypy.log("Server parameters:", 'CONFIG') 284 235 … … 295 246 'server.thread_pool', 296 247 ] 297 248 298 249 for var in serverVars: 299 250 cherrypy.log(" %s: %s" % (var, get(var)), 'CONFIG') trunk/cherrypy/lib/cptools.py
r1082 r1096 46 46 from cherrypy.lib.cptools import ExposeItems 47 47 ... 48 cherrypy.root.foo = ExposeItems(mylist)49 cherrypy.root.bar = ExposeItems(mydict)48 root.foo = ExposeItems(mylist) 49 root.bar = ExposeItems(mydict) 50 50 """ 51 51 exposed = True … … 288 288 289 289 def virtual_host(use_x_forwarded_host=True, **domains): 290 """Change the object_pathbased on the Host.290 """Change the path_info based on the Host. 291 291 292 292 Useful when running multiple sites within one CP server. … … 312 312 prefix = domains.get(domain, "") 313 313 if prefix: 314 cherrypy.request. object_path = prefix + "/" + cherrypy.request.object_path314 cherrypy.request.path_info = prefix + "/" + cherrypy.request.path_info 315 315 316 316 def log_traceback(): trunk/cherrypy/lib/static.py
r1094 r1096 170 170 171 171 def 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): 173 173 return False 174 174 … … 185 185 section = "/" 186 186 section = section.rstrip(r"\/") 187 branch = cherrypy.request. object_path[len(section) + 1:]187 branch = cherrypy.request.path_info[len(section) + 1:] 188 188 branch = urllib.unquote(branch.lstrip(r"\/")) 189 189 … … 205 205 206 206 def 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): 208 208 return False 209 209 trunk/cherrypy/lib/
