Changeset 1118
- Timestamp:
- 06/03/06 14:01:40
- Files:
-
- trunk/cherrypy/_cprequest.py (modified) (8 diffs)
- trunk/cherrypy/lib/cptools.py (modified) (1 diff)
- trunk/cherrypy/tools.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cprequest.py
r1109 r1118 7 7 8 8 import cherrypy 9 from cherrypy import _cputil, _cpcgifs, tools 10 from cherrypy.lib import cptools, httptools, profiler 9 from cherrypy import _cputil, _cpcgifs 10 from cherrypy.lib import httptools, profiler 11 12 13 class HookMap(object): 14 15 def __init__(self, points=None, failsafe=None): 16 points = points or [] 17 self.callbacks = dict([(point, []) for point in points]) 18 self.failsafe = failsafe or [] 19 20 def attach(self, point, callback, conf=None): 21 if not conf: 22 # No point adding a wrapper if there's no conf 23 self.callbacks[point].append(callback) 24 else: 25 def wrapper(): 26 callback(**conf) 27 self.callbacks[point].append(wrapper) 28 29 def run(self, point, *args, **kwargs): 30 """Execute all registered callbacks for the given point.""" 31 failsafe = point in self.failsafe 32 for callback in self.callbacks[point]: 33 # Some hookpoints guarantee all callbacks are run even if 34 # others at the same hookpoint fail. We will still log the 35 # failure, but proceed on to the next callback. The only way 36 # to stop all processing from one of these callbacks is 37 # to raise SystemExit and stop the whole server. So, trap 38 # your own errors in these callbacks! 39 if failsafe: 40 try: 41 callback(*args, **kwargs) 42 except (KeyboardInterrupt, SystemExit): 43 raise 44 except: 45 cherrypy.log(traceback=True) 46 else: 47 callback(*args, **kwargs) 11 48 12 49 … … 35 72 'on_end_resource', 'on_end_request', 36 73 'before_error_response', 'after_error_response'] 37 self.hooks = tools.HookMap(pts)74 self.hooks = HookMap(pts) 38 75 self.hooks.failsafe = ['on_start_resource', 'on_end_resource', 39 76 'on_end_request'] … … 126 163 try: 127 164 self.get_resource(path_info) 128 self. hooks.setup()165 self.tool_up() 129 166 self.hooks.run('on_start_resource') 130 167 … … 221 258 222 259 def get_resource(self, path): 260 """Find and call a dispatcher (which sets self.handler and .config).""" 223 261 dispatch = _cputil.dispatch 224 262 # First, see if there is a custom dispatch at this URI. Custom … … 250 288 # dispatch() should set self.handler and self.config 251 289 dispatch(path) 252 290 291 def tool_up(self): 292 """Populate self.toolmap and set up each tool.""" 253 293 # Get all 'tools.*' config entries as a {toolname: {k: v}} dict. 254 294 self.toolmap = {} … … 260 300 bucket = self.toolmap.setdefault(toolname, {}) 261 301 bucket[".".join(atoms)] = v 302 303 # Run tool.setup(conf) for each tool in the new toolmap. 304 for toolname, conf in self.toolmap.iteritems(): 305 if conf.get("on", False): 306 tool = getattr(cherrypy.tools, toolname) 307 tool.setup() 262 308 263 309 def _get_browser_url(self): … … 331 377 332 378 379 def fileGenerator(input, chunkSize=65536): 380 """Yield the given input (a file object) in chunks (default 64k).""" 381 chunk = input.read(chunkSize) 382 while chunk: 383 yield chunk 384 chunk = input.read(chunkSize) 385 input.close() 386 387 333 388 class Body(object): 334 389 """The body of the HTTP response (the response entity).""" … … 344 399 # Convert the given value to an iterable object. 345 400 if isinstance(value, types.FileType): 346 value = cptools.fileGenerator(value)401 value = fileGenerator(value) 347 402 elif isinstance(value, types.GeneratorType): 348 403 value = flattener(value) trunk/cherrypy/lib/cptools.py
r1117 r1118 56 56 def __getattr__(self, key): 57 57 return self.items[key] 58 59 60 def fileGenerator(input, chunkSize=65536):61 """Yield the given input (a file object) in chunks (default 64k)."""62 chunk = input.read(chunkSize)63 while chunk:64 yield chunk65 chunk = input.read(chunkSize)66 input.close()67 58 68 59 trunk/cherrypy/tools.py
r1117 r1118 16 16 CherryPy hooks: "hooks" are points in the CherryPy request-handling 17 17 process which may hand off control to registered callbacks. The 18 Request object possesses a "hooks" attribute (a tools.HookMap)18 Request object possesses a "hooks" attribute (a HookMap) 19 19 for manipulating this. If a tool exposes a "setup" callable, 20 20 it will be called once per Request (if the feature is enabled … … 29 29 30 30 31 class HookMap(object):32 33 def __init__(self, points=None, failsafe=None):34 points = points or []35 self.callbacks = dict([(point, []) for point in points])36 self.failsafe = failsafe or []37 38 def attach(self, point, callback, conf=None):39 if not conf:40 # No point adding a wrapper if there's no conf41 self.callbacks[point].append(callback)42 else:43 def wrapper():44 callback(**conf)45 self.callbacks[point].append(wrapper)46 47 def setup(self):48 """Run tool.setup(conf) for each tool specified in current config."""49 g = globals()50 for toolname, conf in cherrypy.request.toolmap.iteritems():51 if conf.get("on", False):52 tool = g[toolname]53 tool.setup()54 55 def run(self, point, *args, **kwargs):56 """Execute all registered callbacks for the given point."""57 failsafe = point in self.failsafe58 for callback in self.callbacks[point]:59 # Some hookpoints guarantee all callbacks are run even if60 # others at the same hookpoint fail. We will still log the61 # failure, but proceed on to the next callback. The only way62 # to stop all processing from one of these callbacks is63 # to raise SystemExit and stop the whole server. So, trap64 # your own errors in these callbacks!65 if failsafe:66 try:67 callback(*args, **kwargs)68 except (KeyboardInterrupt, SystemExit):69 raise70 except:71 cherrypy.log(traceback=True)72 else:73 callback(*args, **kwargs)74 31 75 32

