From: Ben Darnell Date: Sun, 15 May 2011 04:29:58 +0000 (-0700) Subject: Convert http request bodies to utf8 earlier so content-length is correct X-Git-Tag: v2.0.0~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a723690edf5ff4485c0651f2dd37f0c83105ed88;p=thirdparty%2Ftornado.git Convert http request bodies to utf8 earlier so content-length is correct --- diff --git a/tornado/httpclient.py b/tornado/httpclient.py index e7a30304e..2caaf21a3 100644 --- a/tornado/httpclient.py +++ b/tornado/httpclient.py @@ -170,7 +170,7 @@ class HTTPRequest(object): self.url = utf8(url) self.method = method self.headers = headers - self.body = body + self.body = utf8(body) self.auth_username = utf8(auth_username) self.auth_password = utf8(auth_password) self.connect_timeout = connect_timeout diff --git a/tornado/simple_httpclient.py b/tornado/simple_httpclient.py index 19645e324..bc3c21203 100644 --- a/tornado/simple_httpclient.py +++ b/tornado/simple_httpclient.py @@ -230,7 +230,7 @@ class _HTTPConnection(object): request_lines.append(line) self.stream.write(b("\r\n").join(request_lines) + b("\r\n\r\n")) if has_body: - self.stream.write(utf8(self.request.body)) + self.stream.write(self.request.body) self.stream.read_until(b("\r\n\r\n"), self._on_headers) @contextlib.contextmanager diff --git a/tornado/test/simple_httpclient_test.py b/tornado/test/simple_httpclient_test.py index 1cff9e5df..ce71b6e99 100644 --- a/tornado/test/simple_httpclient_test.py +++ b/tornado/test/simple_httpclient_test.py @@ -9,6 +9,7 @@ import logging import socket from contextlib import closing +from tornado.escape import utf8 from tornado.ioloop import IOLoop from tornado.simple_httpclient import SimpleAsyncHTTPClient, _DEFAULT_CA_CERTS from tornado.testing import AsyncHTTPTestCase, LogTrapTestCase, get_unused_port @@ -60,6 +61,10 @@ class CountdownHandler(RequestHandler): else: self.write("Zero") +class EchoPostHandler(RequestHandler): + def post(self): + self.write(self.request.body) + class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase): def get_app(self): # callable objects to finish pending /trigger requests @@ -73,6 +78,7 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase): url("/trigger", TriggerHandler, dict(queue=self.triggers, wake_callback=self.stop)), url("/countdown/([0-9]+)", CountdownHandler, name="countdown"), + url("/echopost", EchoPostHandler), ], gzip=True) def setUp(self): @@ -226,3 +232,17 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase): self.assertEqual(b("Basic ") + base64.b64encode(b("me:secret")), response.body) + def test_body_encoding(self): + # unicode string in body gets converted to utf8 + response = self.fetch("/echopost", method="POST", body=u"\xe9") + self.assertEqual(response.body, utf8(u"\xe9")) + + # byte strings pass through directly + response = self.fetch("/echopost", method="POST", body="\xe9") + self.assertEqual(response.body, "\xe9") + + # Mixing unicode in headers and byte string bodies shouldn't + # break anything + response = self.fetch("/echopost", method="POST", body="\xe9", + user_agent=u"foo") + self.assertEqual(response.body, "\xe9")