]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Unbreak static file paths of '/'.
authorBen Darnell <ben@bendarnell.com>
Sun, 27 Sep 2015 22:44:30 +0000 (18:44 -0400)
committerBen Darnell <ben@bendarnell.com>
Sun, 27 Sep 2015 22:44:30 +0000 (18:44 -0400)
tornado/test/web_test.py
tornado/web.py

index 5938b7b683ccb5d4202c0fdcbb3de446ea977158..829dfe48341cf7f6c04f411bac46ae81b845e8d9 100644 (file)
@@ -967,7 +967,8 @@ class StaticFileTest(WebTestCase):
 
         return [('/static_url/(.*)', StaticUrlHandler),
                 ('/abs_static_url/(.*)', AbsoluteStaticUrlHandler),
-                ('/override_static_url/(.*)', OverrideStaticUrlHandler)]
+                ('/override_static_url/(.*)', OverrideStaticUrlHandler),
+                ('/root_static/(.*)', StaticFileHandler, dict(path='/'))]
 
     def get_app_kwargs(self):
         return dict(static_path=relpath('static'))
@@ -1203,6 +1204,15 @@ class StaticFileTest(WebTestCase):
         # is probably a packaging error).
         self.assertEqual(response.code, 403)
 
+    def test_root_static_path(self):
+        # Sometimes people set the StaticFileHandler's path to '/'
+        # to disable Tornado's path validation (in conjunction with
+        # their own validation in get_absolute_path). Make sure
+        # that the stricter validation in 4.2.1 doesn't break them.
+        path = os.path.join(os.path.dirname(__file__), 'static/robots.txt')
+        response = self.get_and_head('/root_static' + path)
+        self.assertEqual(response.code, 200)
+
 
 @wsgi_safe
 class StaticDefaultFilenameTest(WebTestCase):
index afa9ca5886b7472faca32b1b0b76cccc847887d1..dd0df5efd0726327c4ff2d4043f1c8c503363bc0 100644 (file)
@@ -2404,7 +2404,14 @@ class StaticFileHandler(RequestHandler):
         # We must add it back to `root` so that we only match files
         # in a directory named `root` instead of files starting with
         # that prefix.
-        root = os.path.abspath(root) + os.path.sep
+        root = os.path.abspath(root)
+        if not root.endswith(os.path.sep):
+            # abspath always removes a trailing slash, except when
+            # root is '/'. This is an unusual case, but several projects
+            # have independently discovered this technique to disable
+            # Tornado's path validation and (hopefully) do their own,
+            # so we need to support it.
+            root += os.path.sep
         # The trailing slash also needs to be temporarily added back
         # the requested path so a request to root/ will match.
         if not (absolute_path + os.path.sep).startswith(root):