Changeset 911
- Timestamp:
- 01/03/06 21:08:59
- Files:
-
- trunk/cherrypy/_cphttptools.py (modified) (3 diffs)
- trunk/cherrypy/filters/__init__.py (modified) (2 diffs)
- trunk/cherrypy/test/test_custom_filters.py (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cphttptools.py
r910 r911 33 33 if not self.closed: 34 34 self.closed = True 35 try: 36 applyFilters('on_end_request') 37 except (KeyboardInterrupt, SystemExit): 38 raise 39 except: 40 cherrypy.log(traceback=True) 35 applyFilters('on_end_request', failsafe=True) 41 36 42 37 def run(self, requestLine, headers, rfile): … … 87 82 88 83 try: 89 applyFilters('on_start_resource' )84 applyFilters('on_start_resource', failsafe=True) 90 85 91 86 try: … … 118 113 cherrypy.response.finalize() 119 114 finally: 120 applyFilters('on_end_resource' )115 applyFilters('on_end_resource', failsafe=True) 121 116 except (KeyboardInterrupt, SystemExit): 122 117 raise trunk/cherrypy/filters/__init__.py
r903 r911 95 95 96 96 97 def applyFilters(method_name ):97 def applyFilters(method_name, failsafe=False): 98 98 """Execute the given method for all registered filters.""" 99 99 special_methods = [] … … 106 106 if method: 107 107 special_methods.append(method) 108 108 109 109 if method_name in _input_methods: 110 110 # Run special filters after defaults. 111 for method in _filterhooks[method_name] + special_methods: 112 method() 111 methods = _filterhooks[method_name] + special_methods 113 112 else: 114 113 # Run special filters before defaults. 115 for method in special_methods + _filterhooks[method_name]: 114 methods = special_methods + _filterhooks[method_name] 115 116 for method in methods: 117 # The on_start_resource, on_end_resource, and on_end_request methods 118 # are guaranteed to run even if other methods of the same name fail. 119 # We will still log the failure, but proceed on to the next method. 120 # The only way to stop all processing from one of these methods is 121 # to raise SystemExit and stop the whole server. So, trap your own 122 # errors in these methods! 123 if failsafe: 124 try: 125 method() 126 except (KeyboardInterrupt, SystemExit): 127 raise 128 except: 129 cherrypy.log(traceback=True) 130 else: 116 131 method() 132 trunk/cherrypy/test/test_custom_filters.py
r903 r911 12 12 class Numerify(BaseFilter): 13 13 14 def on_start_resource(self): 15 m = cherrypy.config.get("numerify_filter.map", {}) 16 cherrypy.request.numerify_map = m.items() 17 14 18 def before_finalize(self): 15 19 if not cherrypy.config.get("numerify_filter.on", False): … … 18 22 def number_it(body): 19 23 for chunk in body: 20 chunk = chunk.replace("pie", "3.14159") 24 for k, v in cherrypy.request.numerify_map: 25 chunk = chunk.replace(k, v) 21 26 yield chunk 22 27 cherrypy.response.body = number_it(cherrypy.response.body) … … 92 97 def restricted(self): 93 98 return "Welcome!" 99 100 def err_in_onstart(self): 101 return "success!" 94 102 95 103 … … 105 113 '/cpfilterlist': { 106 114 'numerify_filter.on': True, 115 'numerify_filter.map': {"pie": "3.14159"} 107 116 }, 108 117 '/cpfilterlist/restricted': { … … 112 121 '/cpfilterlist/errinstream': { 113 122 'streamResponse': True, 123 }, 124 '/cpfilterlist/err_in_onstart': { 125 # Because this isn't a dict, on_start_resource will error. 126 'numerify_filter.map': "pie->3.14159" 114 127 }, 115 128 }) … … 119 132 # You can also insert a string, but we're effectively testing 120 133 # using-a-string via the config file. 134 filters.input_filters.insert(0, Numerify) 121 135 filters.output_filters.insert(0, Numerify) 122 136 … … 169 183 self.getPage("/cpfilterlist/restricted") 170 184 self.assertErrorPage(401) 185 186 def testGuaranteedFilters(self): 187 # The on_start_resource and on_end_request filter methods are all 188 # guaranteed to run, even if there are failures in other on_start 189 # or on_end methods. This is NOT true of the other filter methods. 190 # Here, we have set up a failure in NumerifyFilter.on_start_resource, 191 # but because that failure is logged and passed over, the error 192 # page we obtain in the user agent should be from before_finalize. 193 ignore = helper.webtest.ignored_exceptions 194 ignore.append(AttributeError) 195 try: 196 self.getPage("/cpfilterlist/err_in_onstart") 197 self.assertErrorPage(500) 198 self.assertInBody("AttributeError: 'Request' object has no " 199 "attribute 'numerify_map'") 200 finally: 201 ignore.pop() 171 202 172 203

