]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
return 404 when routing delegate is not found
authorandrew <an.sumin@hh.ru>
Fri, 3 Nov 2017 14:17:09 +0000 (17:17 +0300)
committerBen Darnell <ben@bendarnell.com>
Sun, 5 Nov 2017 23:09:33 +0000 (18:09 -0500)
tornado/routing.py
tornado/test/routing_test.py

index 6762dc05bcca4a867bea3eb8c03a9def0a6164a4..f2302a8a539f13b36921d762eceec6bf6408c1aa 100644 (file)
@@ -242,6 +242,11 @@ class _RoutingDelegate(httputil.HTTPMessageDelegate):
             start_line=start_line, headers=headers)
 
         self.delegate = self.router.find_handler(request)
+        if self.delegate is None:
+            app_log.debug("Delegate for %s %s request not found",
+                          start_line.method, start_line.path)
+            self.delegate = _DefaultMessageDelegate(self.request_conn)
+
         return self.delegate.headers_received(start_line, headers)
 
     def data_received(self, chunk):
@@ -254,6 +259,16 @@ class _RoutingDelegate(httputil.HTTPMessageDelegate):
         self.delegate.on_connection_close()
 
 
+class _DefaultMessageDelegate(httputil.HTTPMessageDelegate):
+    def __init__(self, connection):
+        self.connection = connection
+
+    def finish(self):
+        self.connection.write_headers(
+            httputil.ResponseStartLine("HTTP/1.1", 404, "Not Found"), httputil.HTTPHeaders())
+        self.connection.finish()
+
+
 class RuleRouter(Router):
     """Rule-based router implementation."""
 
index a1040df32b1572a9a8e9ca013ab16279941e160f..6a4e0dc667c6e54fefeb39353e478690cddb5156 100644 (file)
@@ -14,8 +14,9 @@
 from __future__ import absolute_import, division, print_function
 
 from tornado.httputil import HTTPHeaders, HTTPMessageDelegate, HTTPServerConnectionDelegate, ResponseStartLine
+from tornado.log import app_log
 from tornado.routing import HostMatches, PathMatches, ReversibleRouter, Router, Rule, RuleRouter
-from tornado.testing import AsyncHTTPTestCase
+from tornado.testing import AsyncHTTPTestCase, ExpectLog
 from tornado.web import Application, HTTPError, RequestHandler
 from tornado.wsgi import WSGIContainer
 
@@ -172,10 +173,16 @@ class RuleRouterTest(AsyncHTTPTestCase):
             request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
             request.finish()
 
+        router = CustomRouter()
+        router.add_routes({
+            "/nested_handler": (app, _get_named_handler("nested_handler"))
+        })
+
         app.add_handlers(".*", [
             (HostMatches("www.example.com"), [
                 (PathMatches("/first_handler"), "tornado.test.routing_test.SecondHandler", {}, "second_handler")
             ]),
+            Rule(PathMatches("/.*handler"), router),
             Rule(PathMatches("/first_handler"), FirstHandler, name="first_handler"),
             Rule(PathMatches("/request_callable"), request_callable),
             ("/connection_delegate", ConnectionDelegate())
@@ -186,9 +193,16 @@ class RuleRouterTest(AsyncHTTPTestCase):
     def test_rule_based_router(self):
         response = self.fetch("/first_handler")
         self.assertEqual(response.body, b"first_handler: /first_handler")
+
         response = self.fetch("/first_handler", headers={'Host': 'www.example.com'})
         self.assertEqual(response.body, b"second_handler: /first_handler")
 
+        response = self.fetch("/nested_handler")
+        self.assertEqual(response.body, b"nested_handler: /nested_handler")
+
+        response = self.fetch("/nested_not_found_handler")
+        self.assertEqual(response.code, 404)
+
         response = self.fetch("/connection_delegate")
         self.assertEqual(response.body, b"OK")
 
@@ -222,3 +236,8 @@ class WSGIContainerTestCase(AsyncHTTPTestCase):
 
         response = self.fetch("/wsgi")
         self.assertEqual(response.body, b"WSGI")
+
+    def test_delegate_not_found(self):
+        with ExpectLog(app_log, "Delegate for GET /404 request not found"):
+            response = self.fetch("/404")
+        self.assertEqual(response.code, 404)