diff --git a/tornado/simple_httpclient.py b/tornado/simple_httpclient.py index 5e4d145559..ad5b7e0987 100644 --- a/tornado/simple_httpclient.py +++ b/tornado/simple_httpclient.py @@ -53,7 +53,7 @@ class SimpleAsyncHTTPClient(AsyncHTTPClient): Some features found in the curl-based AsyncHTTPClient are not yet supported. In particular, proxies are not supported, connections - are not reused, and callers cannot select the network interface to be + are not reused, and callers cannot select the network interface to be used. Python 2.6 or higher is required for HTTPS support. Users of Python 2.5 @@ -310,7 +310,7 @@ def cleanup(self): yield except Exception, e: logging.warning("uncaught exception", exc_info=True) - self._run_callback(HTTPResponse(self.request, 599, error=e, + self._run_callback(HTTPResponse(self.request, 599, error=e, request_time=time.time() - self.start_time, )) @@ -335,7 +335,7 @@ def _on_headers(self, data): # use them but if they differ it's an error. pieces = re.split(r',\s*', self.headers["Content-Length"]) if any(i != pieces[0] for i in pieces): - raise ValueError("Multiple unequal Content-Lengths: %r" % + raise ValueError("Multiple unequal Content-Lengths: %r" % self.headers["Content-Length"]) self.headers["Content-Length"] = pieces[0] content_length = int(self.headers["Content-Length"]) @@ -380,7 +380,7 @@ def _on_body(self, data): self.request) if (self.request.follow_redirects and self.request.max_redirects > 0 and - self.code in (301, 302, 303)): + self.code in (301, 302, 303, 307)): new_request = copy.copy(self.request) new_request.url = urlparse.urljoin(self.request.url, self.headers["Location"]) @@ -391,8 +391,8 @@ def _on_body(self, data): if self.code == 303: new_request.method = "GET" new_request.body = None - for h in ["Content-Length", "Content-Type", - "Content-Encoding", "Transfer-Encoding"]: + for h in ["Content-Length", "Content-Type", + "Content-Encoding", "Transfer-Encoding"]: try: del self.request.headers[h] except KeyError: diff --git a/tornado/test/simple_httpclient_test.py b/tornado/test/simple_httpclient_test.py index f0f9be0fb1..ebb265b916 100644 --- a/tornado/test/simple_httpclient_test.py +++ b/tornado/test/simple_httpclient_test.py @@ -56,14 +56,16 @@ def get(self): class SeeOther303PostHandler(RequestHandler): def post(self): + assert self.request.body == b("blah") self.set_header("Location", "/303_get") self.set_status(303) -class SeeOther303GetHandler(RequestHandler): +class SeeOther303GetHandler(RequestHandler): def get(self): + assert not self.request.body self.write("ok") - - + + class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase): def setUp(self): super(SimpleHTTPClientTestCase, self).setUp() @@ -163,13 +165,13 @@ def test_max_redirects(self): self.assertTrue(response.headers["Location"].endswith("/countdown/1")) def test_303_redirect(self): - response = self.fetch("/303_post", method="POST", body="") + response = self.fetch("/303_post", method="POST", body="blah") self.assertEqual(200, response.code) self.assertTrue(response.request.url.endswith("/303_post")) self.assertTrue(response.effective_url.endswith("/303_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) diff --git a/website/sphinx/releases/next.rst b/website/sphinx/releases/next.rst index 1fd9e82fce..907be793ef 100644 --- a/website/sphinx/releases/next.rst +++ b/website/sphinx/releases/next.rst @@ -74,6 +74,7 @@ Other modules * `SimpleAsyncHTTPClient` no longer hangs on ``HEAD`` requests, responses with no content, or empty ``POST``/``PUT`` response bodies. +* `SimpleAsyncHTTPClient` now supports 303 and 307 redirect codes. * `tornado.platform.twisted` compatibility has been significantly improved. Twisted version 11.1.0 is now supported in addition to 11.0.0. * `tornado.testing.main` supports a new flag ``--exception_on_interrupt``,