Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'jparise/append-handlers' into merge

  • Loading branch information...
commit 4088c8e5ce885d68c812254711243e688f06e117 2 parents 190d47e + 3643216
@bdarnell bdarnell authored
Showing with 42 additions and 8 deletions.
  1. +35 −0 tornado/test/web_test.py
  2. +7 −8 tornado/web.py
View
35 tornado/test/web_test.py
@@ -852,6 +852,41 @@ def test_static_url(self):
wsgi_safe.append(CustomStaticFileTest)
+class HostMatchingTest(WebTestCase):
+ class Handler(RequestHandler):
+ def initialize(self, reply):
+ self.reply = reply
+
+ def get(self):
+ self.write(self.reply)
+
+ def get_handlers(self):
+ return [("/foo", HostMatchingTest.Handler, {"reply": "wildcard"})]
+
+ def test_host_matching(self):
+ self.app.add_handlers("www.example.com",
+ [("/foo", HostMatchingTest.Handler, {"reply": "[0]"})])
+ self.app.add_handlers(r"www\.example\.com",
+ [("/bar", HostMatchingTest.Handler, {"reply": "[1]"})])
+ self.app.add_handlers("www.example.com",
+ [("/baz", HostMatchingTest.Handler, {"reply": "[2]"})])
+
+ response = self.fetch("/foo")
+ self.assertEqual(response.body, b("wildcard"))
+ response = self.fetch("/bar")
+ self.assertEqual(response.code, 404)
+ response = self.fetch("/baz")
+ self.assertEqual(response.code, 404)
+
+ response = self.fetch("/foo", headers={'Host': 'www.example.com'})
+ self.assertEqual(response.body, b("[0]"))
+ response = self.fetch("/bar", headers={'Host': 'www.example.com'})
+ self.assertEqual(response.body, b("[1]"))
+ response = self.fetch("/baz", headers={'Host': 'www.example.com'})
+ self.assertEqual(response.body, b("[2]"))
+wsgi_safe.append(HostMatchingTest)
+
+
class NamedURLSpecGroupsTest(WebTestCase):
def get_handlers(self):
class EchoHandler(RequestHandler):
View
15 tornado/web.py
@@ -1317,10 +1317,8 @@ def listen(self, port, address="", **kwargs):
def add_handlers(self, host_pattern, host_handlers):
"""Appends the given handlers to our handler list.
- Note that host patterns are processed sequentially in the
- order they were added, and only the first matching pattern is
- used. This means that all handlers for a given host must be
- added in a single add_handlers call.
+ Host patterns are processed sequentially in the order they were
+ added. All matching patterns will be considered.
"""
if not host_pattern.endswith("$"):
host_pattern += "$"
@@ -1365,15 +1363,16 @@ def add_transform(self, transform_class):
def _get_host_handlers(self, request):
host = request.host.lower().split(':')[0]
+ matches = []
for pattern, handlers in self.handlers:
if pattern.match(host):
- return handlers
+ matches.extend(handlers)
# Look for default host if not behind load balancer (for debugging)
- if "X-Real-Ip" not in request.headers:
+ if not matches and "X-Real-Ip" not in request.headers:
for pattern, handlers in self.handlers:
if pattern.match(self.default_host):
- return handlers
- return None
+ matches.extend(handlers)
+ return matches or None
def _load_ui_methods(self, methods):
if type(methods) is types.ModuleType:
Please sign in to comment.
Something went wrong with that request. Please try again.