From: Ben Darnell Date: Sun, 8 Sep 2013 16:15:53 +0000 (-0400) Subject: Add a default_handler_class setting for custom 404 pages. X-Git-Tag: v3.2.0b1~83 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51c9796b10b8b141454f8fe4d080e76962a9ad57;p=thirdparty%2Ftornado.git Add a default_handler_class setting for custom 404 pages. The previous solution for custom 404s (a r'.*' rule at the end of the handlers list) proved to be undiscoverable for many users, and it could be nontrivial to put the rule in the right place in the presence of multiple add_handlers calls and the implicit StaticFileHandler rules. --- diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 3014b663c..08093c79b 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -1653,3 +1653,48 @@ class FinishInPrepareTest(SimpleHandlerTestCase): def test_finish_in_prepare(self): response = self.fetch('/') self.assertEqual(response.body, b'done') + + +@wsgi_safe +class Default404Test(WebTestCase): + def get_handlers(self): + # If there are no handlers at all a default redirect handler gets added. + return [('/foo', RequestHandler)] + + def test_404(self): + response = self.fetch('/') + self.assertEqual(response.code, 404) + self.assertEqual(response.body, + b'404: Not Found' + b'404: Not Found') + +@wsgi_safe +class Custom404Test(WebTestCase): + def get_handlers(self): + return [('/foo', RequestHandler)] + + def get_app_kwargs(self): + class Custom404Handler(RequestHandler): + def get(self): + self.set_status(404) + self.write('custom 404 response') + + return dict(default_handler_class=Custom404Handler) + + def test_404(self): + response = self.fetch('/') + self.assertEqual(response.code, 404) + self.assertEqual(response.body, b'custom 404 response') + +@wsgi_safe +class DefaultHandlerArgumentsTest(WebTestCase): + def get_handlers(self): + return [('/foo', RequestHandler)] + + def get_app_kwargs(self): + return dict(default_handler_class=ErrorHandler, + default_handler_args=dict(status_code=403)) + + def test_403(self): + response = self.fetch('/') + self.assertEqual(response.code, 403) diff --git a/tornado/web.py b/tornado/web.py index fe0f2e403..140fc1c44 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1597,7 +1597,14 @@ class Application(object): args = [unquote(s) for s in match.groups()] break if not handler: - handler = ErrorHandler(self, request, status_code=404) + if self.settings.get('default_handler_class'): + handler_class = self.settings['default_handler_class'] + handler_args = self.settings.get( + 'default_handler_args', {}) + else: + handler_class = ErrorHandler + handler_args = dict(status_code=404) + handler = handler_class(self, request, **handler_args) # In debug mode, re-compile templates and reload static files on every # request so you don't need to restart to see changes