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:
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
url("/countdown/([0-9]+)", CountdownHandler, name="countdown"),
url("/hang", HangHandler),
url("/hello", HelloWorldHandler),
+ url("/content_length", ContentLengthHandler),
], gzip=True)
def test_singleton(self):
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)