self.request)
if (self.request.follow_redirects and
self.request.max_redirects > 0 and
- self.code in (301, 302)):
+ self.code in (301, 302, 303)):
new_request = copy.copy(self.request)
new_request.url = urlparse.urljoin(self.request.url,
self.headers["Location"])
new_request.max_redirects -= 1
del new_request.headers["Host"]
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4
+ # client SHOULD make a GET request
+ if self.code == 303:
+ new_request.method = "GET"
+ new_request.body = None
new_request.original_request = original_request
final_callback = self.final_callback
self.final_callback = None
self.set_header("Content-Length", self.get_argument("value"))
self.write("ok")
+class PRGPostHandler(RequestHandler):
+ def post(self):
+ self.set_header("Location", "/prg_get")
+ self.set_status(303)
+
+class PRGGetHandler(RequestHandler):
+ def get(self):
+ self.write("ok")
+
+
class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase):
def get_app(self):
# callable objects to finish pending /trigger requests
url("/hang", HangHandler),
url("/hello", HelloWorldHandler),
url("/content_length", ContentLengthHandler),
+ url("/prg_post", PRGPostHandler),
+ url("/prg_get", PRGGetHandler),
], gzip=True)
def test_singleton(self):
self.assertTrue(response.effective_url.endswith("/countdown/2"))
self.assertTrue(response.headers["Location"].endswith("/countdown/1"))
+ def test_303_redirect(self):
+ response = self.fetch("/prg_post", method="POST", body="")
+ self.assertEqual(200, response.code)
+ self.assertTrue(response.request.url.endswith("/prg_post"))
+ self.assertTrue(response.effective_url.endswith("/prg_get"))
+ #request is the original request, is a POST still
+ self.assertEqual("POST", response.request.method)
+
def test_request_timeout(self):
response = self.fetch('/hang', request_timeout=0.1)
self.assertEqual(response.code, 599)