Changeset 1083
- Timestamp:
- 05/01/06 18:58:58
- Files:
-
- trunk/cherrypy/_cprequest.py (modified) (3 diffs)
- trunk/cherrypy/config.py (modified) (1 diff)
- trunk/cherrypy/lib/caching.py (modified) (3 diffs)
- trunk/cherrypy/test/test_core.py (modified) (1 diff)
- trunk/cherrypy/test/test_custom_filters.py (modified) (3 diffs)
- trunk/cherrypy/tools.py (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cprequest.py
r1082 r1083 83 83 84 84 def _run(self): 85 conf = cherrypy.config.get86 87 85 try: 88 86 # This has to be done very early in the request process, … … 90 88 # right away. 91 89 self.process_request_line() 92 self.dispatch = conf("dispatch") or _cputil.dispatch90 self.dispatch = self.config.get("dispatch") or _cputil.dispatch 93 91 self.hooks.setup() 94 92 … … 127 125 raise 128 126 except: 129 if c onf("server.throw_errors", False):127 if cherrypy.config.get("server.throw_errors", False): 130 128 raise 131 129 self.handle_error(sys.exc_info()) 130 131 def _get_object_path(self): 132 return self._object_path 133 def _set_object_path(self, value): 134 self._object_path = value 135 self.config = cherrypy.config.request_config() 136 137 # Get all 'tools.*' config entries as a {toolname: {k: v}} dict. 138 self.toolmap = {} 139 for k, v in self.config.iteritems(): 140 atoms = k.split(".") 141 namespace = atoms.pop(0) 142 if namespace == "tools": 143 toolname = atoms.pop(0) 144 bucket = self.toolmap.setdefault(toolname, {}) 145 bucket[".".join(atoms)] = v 146 object_path = property(_get_object_path, _set_object_path, 147 doc="The path to the rendered resource.") 132 148 133 149 def process_request_line(self): trunk/cherrypy/config.py
r1082 r1083 151 151 return result 152 152 153 def current_config(path=None): 154 """Return all configs in effect for the given path in a single dict.""" 155 if path is None: 156 try: 157 path = cherrypy.request.object_path 158 except AttributeError: 159 # There's no request.object_path yet, so use the global settings. 160 path = "global" 161 162 result = {} 163 result.update(configs.get("global", {})) 153 def request_config(): 154 """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() 157 158 # Convert the path into a list of names 159 if (not path) or path == "*": 160 nameList = [] 161 else: 162 nameList = path.strip('/').split('/') 163 nameList.append('index') 164 164 165 curpath = "" 165 for b in path.split('/'): 166 if curpath == "/": 167 curpath = "" 168 curpath = "/".join((curpath, b)) 169 result.update(configs.get(curpath, {})) 170 return result 166 node = cherrypy.root 167 conf = getattr(node, "_cp_config", {}).copy() 168 conf.update(configs.get("/", {})) 169 for name in nameList: 170 # Get _cp_config attached to each node on the cherrypy tree. 171 objname = name.replace('.', '_') 172 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. 181 curpath = "/".join((curpath, name)) 182 conf.update(configs.get(curpath, {})) 183 184 base = configs.get("global", {}).copy() 185 base.update(conf) 186 return base 187 188 189 def request_config_section(key): 190 """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() 193 194 # Convert the path into a list of names 195 if (not path) or path == "*": 196 nameList = [] 197 else: 198 nameList = path.strip('/').split('/') 199 nameList.append('index') 200 201 foundpath = None 202 203 curpath = "" 204 node = cherrypy.root 205 if key in getattr(node, "_cp_config", {}) or key in configs.get("/", {}): 206 foundpath = "/" 207 for name in nameList: 208 # Get _cp_config attached to each node on the cherrypy tree. 209 objname = name.replace('.', '_') 210 node = getattr(node, objname, None) 211 if node is not None: 212 if node in mounted_app_roots: 213 # Dump and start over. This inefficiency should disappear 214 # once we make cherrypy.localroot (specific to each request). 215 foundpath = None 216 if key in getattr(node, "_cp_config", {}): 217 foundpath = curpath or "/" 218 219 # Get values from cherrypy.config for this path. 220 curpath = "/".join((curpath, name)) 221 if key in configs.get(curpath, {}): 222 foundpath = curpath 223 224 if foundpath is None: 225 foundpath = configs.get("global", {}).get(key) 226 return foundpath 171 227 172 228 trunk/cherrypy/lib/caching.py
r1075 r1083 27 27 28 28 def _key(self): 29 return cherrypy. config.get("hooks.cache.key", cherrypy.request.browser_url)29 return cherrypy.request.config.get("tools.caching.key", cherrypy.request.browser_url) 30 30 key = property(_key) 31 31 32 32 def _maxobjsize(self): 33 return cherrypy. config.get("hooks.cache.maxobjsize", 100000)33 return cherrypy.request.config.get("tools.caching.maxobjsize", 100000) 34 34 maxobjsize = property(_maxobjsize) 35 35 36 36 def _maxsize(self): 37 return cherrypy. config.get("hooks.cache.maxsize", 10000000)37 return cherrypy.request.config.get("tools.caching.maxsize", 10000000) 38 38 maxsize = property(_maxsize) 39 39 40 40 def _maxobjects(self): 41 return cherrypy. config.get("hooks.cache.maxobjects", 1000)41 return cherrypy.request.config.get("tools.caching.maxobjects", 1000) 42 42 maxobjects = property(_maxobjects) 43 43 … … 84 84 # add to the expirationQueue & cache 85 85 try: 86 expirationTime = time.time() + cherrypy. config.get("hooks.cache.delay", 600)86 expirationTime = time.time() + cherrypy.request.config.get("tools.caching.delay", 600) 87 87 objKey = self.key 88 88 self.expirationQueue.put((expirationTime, objSize, objKey)) … … 149 149 return wrapper 150 150 151 def setup( conf):151 def setup(): 152 152 """Hook caching into cherrypy.request using the given conf.""" 153 conf = cherrypy.request.toolmap.get("caching", {}) 153 154 if not getattr(cherrypy, "_cache", None): 154 155 init(conf.get("class", None)) trunk/cherrypy/test/test_core.py
r1082 r1083 105 105 106 106 class Error: 107 _cp_tools = [tools.ErrorRedirect("/errpage")] 107 _cp_config = {"tools.err_redirect.on": True, 108 "tools.err_redirect.url": "/errpage", 109 } 108 110 109 111 def index(self): trunk/cherrypy/test/test_custom_filters.py
r1082 r1083 25 25 26 26 class NumTool(tools.Tool): 27 def setup(self , conf):27 def setup(self): 28 28 def makemap(): 29 m = conf.get("map", {})29 m = self.merged_args().get("map", {}) 30 30 cherrypy.request.numerify_map = m.items() 31 31 cherrypy.request.hooks.attach('on_start_resource', makemap) … … 54 54 self.ended[cherrypy.request.counter] = True 55 55 56 def setup(self , conf=None):56 def setup(self): 57 57 cherrypy.request.counter = self.counter = self.counter + 1 58 58 self.ended[cherrypy.request.counter] = False … … 83 83 84 84 # METHOD ONE: 85 # Use _cp_ tools85 # Use _cp_config 86 86 class Demo(Test): 87 87 88 _cp_ tools = [tools.nadsat]88 _cp_config = {"tools.nadsat.on": True} 89 89 90 90 def index(self): trunk/cherrypy/tools.py
r1082 r1083 47 47 def setup(self): 48 48 """Run tool.setup(conf) for each tool specified in current config.""" 49 toolconf = tool_config()50 51 49 g = globals() 52 for toolname, conf in toolconf.iteritems():50 for toolname, conf in cherrypy.request.toolmap.iteritems(): 53 51 if conf.get("on", False): 54 del conf["on"] 55 tool = g.get(toolname) 56 if tool: 57 tool.setup(conf) 58 59 # Run _cp_tools setup functions. They should be run 60 # in order: first from root to leaf, then in the order 61 # given within each _cp_tools list. However, if the 62 # same tool is mentioned twice, the one farthest from 63 # the root should be used. This allows a leaf node to 64 # override parent nodes and order. 65 mounted_app_roots = cherrypy.tree.mount_points.values() 66 objectList = _cputil.get_object_trail() 67 objectList.reverse() 68 69 # Collect toolsets (up to the app root). 70 toolsets = [] 71 for objname, obj in objectList: 72 toolset = getattr(obj, "_cp_tools", []) 73 if toolset: 74 toolsets.append(toolset) 75 if obj in mounted_app_roots: 76 break 77 78 # Now reverse (and de-dupe) the tool list, and call each setup 79 toolsets.reverse() 80 seen = {} 81 for toolset in toolsets: 82 for tool in toolset: 83 obj_id = id(tool) 84 if obj_id not in seen: 85 seen[obj_id] = None 86 tool.setup(toolconf.get(tool.name, {})) 52 tool = g[toolname] 53 tool.setup() 87 54 88 55 def run(self, point, *args, **kwargs): … … 106 73 callback(*args, **kwargs) 107 74 108 def tool_config():109 """Return all 'tools.*' config entries as a {toolname: {k: v}} dict."""110 toolmap = {}111 for k, v in cherrypy.config.current_config().iteritems():112 atoms = k.split(".")113 namespace = atoms.pop(0)114 if namespace == "tools":115 toolname = atoms.pop(0)116 bucket = toolmap.setdefault(toolname, {})117 bucket[".".join(atoms)] = v118 return toolmap119 120 def merged_config(toolname, d):121 """Merge arguments from tool config into another dict."""122 mergedkw = d.copy()123 mergedkw.update(tool_config().get(toolname, {}))124 if "on" in mergedkw:125 del mergedkw["on"]126 return mergedkw127 128 75 129 76 class Tool(object): 77 """A registered function for use with CherryPy request-processing hooks.""" 130 78 131 79 def __init__(self, point, callable, name=None): … … 141 89 return self.callable(*args, **kwargs) 142 90 91 def merged_args(self, d=None): 92 conf = cherrypy.request.toolmap.get(self.name, {}).copy() 93 conf.update(d or {}) 94 if "on" in conf: 95 del conf["on"] 96 return conf 97 143 98 def wrap(self, *args, **kwargs): 144 99 """Make a decorator for this tool. … … 153 108 def deco(f): 154 109 def wrapper(*a, **kw): 155 self.callable(*args, ** merged_config(self.name,kwargs))110 self.callable(*args, **self.merged_args(kwargs)) 156 111 return f(*a, **kw) 157 112 return wrapper 158 113 return deco 159 114 160 def setup(self , conf=None):161 """Hook this tool into cherrypy.request using the given conf.115 def setup(self): 116 """Hook this tool into cherrypy.request. 162 117 163 118 The standard CherryPy request object will automatically call this 164 119 method when the tool is "turned on" in config. 165 120 """ 121 conf = self.merged_args() 166 122 cherrypy.request.hooks.attach(self.point, self.callable, conf) 167 123 … … 185 141 """ 186 142 def wrapper(*a, **kw): 187 handled = self.callable(*args, ** merged_config(self.name,kwargs))143 handled = self.callable(*args, **self.merged_args(kwargs)) 188 144 if not handled: 189 145 raise cherrypy.NotFound() … … 204 160 def deco(f): 205 161 def wrapper(*a, **kw): 206 handled = self.callable(*args, ** merged_config(self.name,kwargs))162 handled = self.callable(*args, **self.merged_args(kwargs)) 207 163 if handled: 208 164 return cherrypy.response.body … … 212 168 return deco 213 169 214 def setup(self , conf=None):215 """Hook this tool into cherrypy.request using the given conf.170 def setup(self): 171 """Hook this tool into cherrypy.request. 216 172 217 173 The standard CherryPy request object will automatically call this 218 174 method when the tool is "turned on" in config. 219 175 """ 220 conf = conf or {}221 176 def wrapper(): 222 if self.callable(** conf):177 if self.callable(**self.merged_args()): 223 178 cherrypy.request.dispatch = None 224 179 # Don't pass conf (or our wrapper will get wrapped!) … … 232 187 Tool.__init__(self, None, callable, name) 233 188 234 def setup(self , conf=None):235 """Hook this tool into cherrypy.request using the given conf.189 def setup(self): 190 """Hook this tool into cherrypy.request. 236 191 237 192 The standard CherryPy request object will automatically call this … … 239 194 """ 240 195 def wrapper(): 241 self.callable(** conf)196 self.callable(**self.merged_args()) 242 197 cherrypy.request.error_response = wrapper 243 198 … … 253 208 log_tracebacks = Tool('before_error_response', cptools.log_traceback) 254 209 log_headers = Tool('before_error_response', cptools.log_request_headers) 255 256 _redirect = cptools.redirect 257 class ErrorRedirect(Tool): 258 """Tool to redirect on error.""" 259 260 def __init__(self, url): 261 Tool.__init__(self, None, _redirect, "ErrorRedirect") 262 self.url = url 263 264 def setup(self, conf=None): 265 """Hook this tool into cherrypy.request using the given conf. 266 267 The standard CherryPy request object will automatically call this 268 method when the tool is "turned on" in config. 269 """ 270 c = {'url': self.url} 271 c.update(conf or {}) 272 def wrapper(): 273 self.callable(**c) 274 cherrypy.request.error_response = wrapper 275 210 err_redirect = ErrorTool(cptools.redirect, 'err_redirect') 276 211 del cptools 277 212 … … 284 219 from cherrypy.lib import static 285 220 class _StaticDirTool(MainTool): 286 def setup(self , conf=None):221 def setup(self): 287 222 """Hook this tool into cherrypy.request using the given conf.""" 288 # Stick the section where "dir" was defined into the params 289 conf = conf or {} 290 conf['section'] = cherrypy.config.get('tools.staticdir.dir', 291 return_section=True) 292 MainTool.setup(self, conf) 223 # Stick the section where "dir" was defined into the params. 224 conf = self.merged_args() 225 conf['section'] = cherrypy.config.request_config_section('tools.staticdir.dir') 226 def wrapper(): 227 if self.callable(**conf): 228 cherrypy.request.dispatch = None 229 # Don't pass conf (or our wrapper will get wrapped!) 230 cherrypy.request.hooks.attach(self.point, wrapper) 293 231 staticdir = _StaticDirTool(static.staticdir) 294 232 staticfile = MainTool(static.staticfile) … … 306 244 def deco(f): 307 245 def wrapper(*a, **kw): 246 conf = cherrypy.request.toolmap.get(self.name, {}).copy() 247 conf.update(kwargs) 248 308 249 s = cherrypy.request._session = _sessions.Session() 309 for k, v in merged_config(self.name, kwargs).iteritems():250 for k, v in conf.iteritems(): 310 251 setattr(s, str(k), v) 311 252 s.init() … … 320 261 return deco 321 262 322 def setup(self , conf=None):263 def setup(self): 323 264 """Hook this tool into cherrypy.request using the given conf. 324 265 … … 326 267 method when the tool is "turned on" in config. 327 268 """ 328 conf = conf or {}329 269 def init(): 270 conf = cherrypy.request.toolmap.get(self.name, {}) 271 330 272 s = cherrypy.request._session = _sessions.Session() 331 273 for k, v in conf.iteritems(): … … 368 310 369 311 body = handler(*(vpath + rpcparams), **request.params) 370 conf = tool_config().get("xmlrpc", {})312 conf = cherrypy.request.toolmap.get("xmlrpc", {}) 371 313 _xmlrpc.respond(body, 372 314 conf.get('encoding', 'utf-8'), 373 315 conf.get('allow_none', 0)) 374 316 375 def setup(self , conf=None):317 def setup(self): 376 318 """Hook this tool into cherrypy.request using the given conf.""" 377 319 cherrypy.request.dispatch = self.dispatch

