]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Add a default_handler_class setting for custom 404 pages.
authorBen Darnell <ben@bendarnell.com>
Sun, 8 Sep 2013 16:15:53 +0000 (12:15 -0400)
committerBen Darnell <ben@bendarnell.com>
Sun, 8 Sep 2013 16:15:53 +0000 (12:15 -0400)
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.

tornado/test/web_test.py
tornado/web.py

index 3014b663c684be1054168ba6d475fc4d134d034c..08093c79b6c9b364a28f7c4adc2515037e7306ce 100644 (file)
@@ -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'<html><title>404: Not Found</title>'
+                         b'<body>404: Not Found</body></html>')
+
+@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)
index fe0f2e4038c759c79d10b679413723e1a5780513..140fc1c4427f1fce3af145d54601381b81ec1bae 100644 (file)
@@ -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