]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
web: Add regex support to RedirectHandler 1867/head
authorA. Jesse Jiryu Davis <jesse@mongodb.com>
Fri, 28 Oct 2016 03:03:35 +0000 (23:03 -0400)
committerA. Jesse Jiryu Davis <jesse@mongodb.com>
Fri, 4 Nov 2016 12:12:18 +0000 (08:12 -0400)
The docs had wrongly claimed this was supported before. Implement it,
and update the docs to show the str.format-style syntax we chose.

Closes #1861.

docs/guide/structure.rst
tornado/test/web_test.py
tornado/web.py

index f0829df0a4b1731ed592f6ef8d20d24addc1c7e0..715e080f8495c561bd3250752dea9164d8c70732 100644 (file)
@@ -278,7 +278,7 @@ to the prefix ``/photos/`` instead::
     app = tornado.web.Application([
         url(r"/photos/(.*)", MyPhotoHandler),
         url(r"/pictures/(.*)", tornado.web.RedirectHandler,
-            dict(url=r"/photos/\1")),
+            dict(url=r"/photos/{0}")),
         ])
 
 Unlike `.RequestHandler.redirect`, `.RedirectHandler` uses permanent
index 89f340715360912df9a122e67d89ba455a24a3d9..b09bb9abf7a07fe098cb14ee32fdfc0e87271bd0 100644 (file)
@@ -2866,3 +2866,20 @@ class URLSpecReverseTest(unittest.TestCase):
     def test_reverse_arguments(self):
         self.assertEqual('/api/v1/foo/bar',
                          url(r'^/api/v1/foo/(\w+)$', None).reverse('bar'))
+
+
+class RedirectHandlerTest(WebTestCase):
+    def get_handlers(self):
+        return [
+            ('/src', WebRedirectHandler, {'url': '/dst'}),
+            (r'/(.*?)/(.*?)/(.*)', WebRedirectHandler, {'url': '/{1}/{0}/{2}'})]
+
+    def test_basic_redirect(self):
+        response = self.fetch('/src', follow_redirects=False)
+        self.assertEqual(response.code, 301)
+        self.assertEqual(response.headers['Location'], '/dst')
+
+    def test_redirect_pattern(self):
+        response = self.fetch('/a/b/c', follow_redirects=False)
+        self.assertEqual(response.code, 301)
+        self.assertEqual(response.headers['Location'], '/b/a/c')
index a0cb0e8eb7719a5c6f82f0fb734f7b4822c5a3da..f4c50e3c999b6aeee02a448743009415c088210d 100644 (file)
@@ -2191,13 +2191,29 @@ class RedirectHandler(RequestHandler):
         application = web.Application([
             (r"/oldpath", web.RedirectHandler, {"url": "/newpath"}),
         ])
+
+    `RedirectHandler` supports regular expression substitutions. E.g., to
+    swap the first and second parts of a path while preserving the remainder::
+
+        application = web.Application([
+            (r"/(.*?)/(.*?)/(.*)", web.RedirectHandler, {"url": "/{1}/{0}/{2}"}),
+        ])
+
+    The final URL is formatted with `str.format` and the substrings that match
+    the capturing groups. In the above example, a request to "/a/b/c" would be
+    formatted like::
+
+        str.format("/{1}/{0}/{2}", "a", "b", "c")  # -> "/b/a/c"
+
+    Use Python's :ref:`format string syntax <formatstrings>` to customize how
+    values are substituted.
     """
     def initialize(self, url, permanent=True):
         self._url = url
         self._permanent = permanent
 
-    def get(self):
-        self.redirect(self._url, permanent=self._permanent)
+    def get(self, *args):
+        self.redirect(self._url.format(*args), permanent=self._permanent)
 
 
 class StaticFileHandler(RequestHandler):