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({
url("/optional_path/(.+)?", OptionalPathHandler),
url("/flow_control", FlowControlHandler),
url("/multi_header", MultiHeaderHandler),
+ url("/redirect", RedirectHandler),
]
return Application(urls,
template_loader=loader,
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):
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),