Skip to content

Commit 24d96f0

Browse files
committed
Merge remote-tracking branch 'amorton/master'
Conflicts: tornado/test/simple_httpclient_test.py
2 parents 97b4b15 + 45752bf commit 24d96f0

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

tornado/simple_httpclient.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,12 +380,23 @@ def _on_body(self, data):
380380
self.request)
381381
if (self.request.follow_redirects and
382382
self.request.max_redirects > 0 and
383-
self.code in (301, 302)):
383+
self.code in (301, 302, 303)):
384384
new_request = copy.copy(self.request)
385385
new_request.url = urlparse.urljoin(self.request.url,
386386
self.headers["Location"])
387387
new_request.max_redirects -= 1
388388
del new_request.headers["Host"]
389+
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4
390+
# client SHOULD make a GET request
391+
if self.code == 303:
392+
new_request.method = "GET"
393+
new_request.body = None
394+
for h in ["Content-Length", "Content-Type",
395+
"Content-Encoding", "Transfer-Encoding"]:
396+
try:
397+
del self.request.headers[h]
398+
except KeyError:
399+
pass
389400
new_request.original_request = original_request
390401
final_callback = self.final_callback
391402
self.final_callback = None

tornado/test/simple_httpclient_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ def get(self):
5454
self.set_header("Content-Length", "7")
5555
self.set_status(204)
5656

57+
class SeeOther303PostHandler(RequestHandler):
58+
def post(self):
59+
self.set_header("Location", "/303_get")
60+
self.set_status(303)
61+
62+
class SeeOther303GetHandler(RequestHandler):
63+
def get(self):
64+
self.write("ok")
65+
66+
5767
class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase):
5868
def setUp(self):
5969
super(SimpleHTTPClientTestCase, self).setUp()
@@ -72,6 +82,8 @@ def get_app(self):
7282
url("/content_length", ContentLengthHandler),
7383
url("/head", HeadHandler),
7484
url("/no_content", NoContentHandler),
85+
url("/303_post", SeeOther303PostHandler),
86+
url("/303_get", SeeOther303GetHandler),
7587
], gzip=True)
7688

7789
def test_singleton(self):
@@ -150,6 +162,14 @@ def test_max_redirects(self):
150162
self.assertTrue(response.effective_url.endswith("/countdown/2"))
151163
self.assertTrue(response.headers["Location"].endswith("/countdown/1"))
152164

165+
def test_303_redirect(self):
166+
response = self.fetch("/303_post", method="POST", body="")
167+
self.assertEqual(200, response.code)
168+
self.assertTrue(response.request.url.endswith("/303_post"))
169+
self.assertTrue(response.effective_url.endswith("/303_get"))
170+
#request is the original request, is a POST still
171+
self.assertEqual("POST", response.request.method)
172+
153173
def test_request_timeout(self):
154174
response = self.fetch('/hang', request_timeout=0.1)
155175
self.assertEqual(response.code, 599)

0 commit comments

Comments
 (0)