From: Ben Darnell Date: Sat, 31 Dec 2011 04:20:25 +0000 (-0800) Subject: Support status codes other than 301 and 302 in RequestHandler.redirect(). X-Git-Tag: v2.2.0~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad6326533859497d0704a1934704ff38ae4e0e01;p=thirdparty%2Ftornado.git Support status codes other than 301 and 302 in RequestHandler.redirect(). Closes #228. Closes #424. --- diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index c5ae99a37..fccd3fc1d 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -325,6 +325,16 @@ class MultiHeaderHandler(RequestHandler): self.add_header("x-multi", 3) self.add_header("x-multi", "4") +class RedirectHandler(RequestHandler): + def get(self): + if self.get_argument('permanent', None) is not None: + self.redirect('/', permanent=int(self.get_argument('permanent'))) + elif self.get_argument('status', None) is not None: + self.redirect('/', status=int(self.get_argument('status'))) + else: + raise Exception("didn't get permanent or status arguments") + + class WebTest(AsyncHTTPTestCase, LogTrapTestCase): def get_app(self): loader = DictLoader({ @@ -348,6 +358,7 @@ class WebTest(AsyncHTTPTestCase, LogTrapTestCase): url("/optional_path/(.+)?", OptionalPathHandler), url("/flow_control", FlowControlHandler), url("/multi_header", MultiHeaderHandler), + url("/redirect", RedirectHandler), ] return Application(urls, template_loader=loader, @@ -433,6 +444,14 @@ js_embed() self.assertEqual(response.headers["x-overwrite"], "2") self.assertEqual(response.headers.get_list("x-multi"), ["3", "4"]) + def test_redirect(self): + response = self.fetch("/redirect?permanent=1", follow_redirects=False) + self.assertEqual(response.code, 301) + response = self.fetch("/redirect?permanent=0", follow_redirects=False) + self.assertEqual(response.code, 302) + response = self.fetch("/redirect?status=307", follow_redirects=False) + self.assertEqual(response.code, 307) + class ErrorResponseTest(AsyncHTTPTestCase, LogTrapTestCase): def get_app(self): diff --git a/tornado/web.py b/tornado/web.py index dfafbcc34..b403afe24 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -410,11 +410,21 @@ class RequestHandler(object): return decode_signed_value(self.application.settings["cookie_secret"], name, value, max_age_days=max_age_days) - def redirect(self, url, permanent=False): - """Sends a redirect to the given (optionally relative) URL.""" + def redirect(self, url, permanent=False, status=None): + """Sends a redirect to the given (optionally relative) URL. + + If the ``status`` argument is specified, that value is used as the + HTTP status code; otherwise either 301 (permanent) or 302 + (temporary) is chosen based on the ``permanent`` argument. + The default is 302 (temporary). + """ if self._headers_written: raise Exception("Cannot redirect after headers have been written") - self.set_status(301 if permanent else 302) + if status is None: + status = 301 if permanent else 302 + else: + assert isinstance(status, int) and 300 <= status <= 399 + self.set_status(status) # Remove whitespace url = re.sub(b(r"[\x00-\x20]+"), "", utf8(url)) self.set_header("Location", urlparse.urljoin(utf8(self.request.uri),