Support Content-Length headers that have been duplicated by a proxy.
Closes #249.
This commit is contained in:
parent
5c6a91ddc7
commit
6fcc459e43
|
@ -309,6 +309,15 @@ class _HTTPConnection(object):
|
|||
self.chunks = []
|
||||
self.stream.read_until(b("\r\n"), self._on_chunk_length)
|
||||
elif "Content-Length" in self.headers:
|
||||
if "," in self.headers["Content-Length"]:
|
||||
# Proxies sometimes cause Content-Length headers to get
|
||||
# duplicated. If all the values are identical then we can
|
||||
# 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" %
|
||||
self.headers["Content-Length"])
|
||||
self.headers["Content-Length"] = pieces[0]
|
||||
self.stream.read_bytes(int(self.headers["Content-Length"]),
|
||||
self._on_body)
|
||||
else:
|
||||
|
|
|
@ -40,6 +40,11 @@ class HangHandler(RequestHandler):
|
|||
def get(self):
|
||||
pass
|
||||
|
||||
class ContentLengthHandler(RequestHandler):
|
||||
def get(self):
|
||||
self.set_header("Content-Length", self.get_argument("value"))
|
||||
self.write("ok")
|
||||
|
||||
class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase):
|
||||
def get_app(self):
|
||||
# callable objects to finish pending /trigger requests
|
||||
|
@ -51,6 +56,7 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase):
|
|||
url("/countdown/([0-9]+)", CountdownHandler, name="countdown"),
|
||||
url("/hang", HangHandler),
|
||||
url("/hello", HelloWorldHandler),
|
||||
url("/content_length", ContentLengthHandler),
|
||||
], gzip=True)
|
||||
|
||||
def test_singleton(self):
|
||||
|
@ -161,3 +167,13 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase):
|
|||
response = self.wait()
|
||||
self.assertEqual(response.body, b("Hello world!"))
|
||||
|
||||
def test_multiple_content_length_accepted(self):
|
||||
response = self.fetch("/content_length?value=2,2")
|
||||
self.assertEqual(response.body, b("ok"))
|
||||
response = self.fetch("/content_length?value=2,%202,2")
|
||||
self.assertEqual(response.body, b("ok"))
|
||||
|
||||
response = self.fetch("/content_length?value=2,4")
|
||||
self.assertEqual(response.code, 599)
|
||||
response = self.fetch("/content_length?value=2,%202,3")
|
||||
self.assertEqual(response.code, 599)
|
||||
|
|
Loading…
Reference in New Issue