]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Fix byte strings as header values in curl_httpclient and python3.
authorBen Darnell <ben@bendarnell.com>
Sat, 11 Oct 2014 15:25:36 +0000 (11:25 -0400)
committerBen Darnell <ben@bendarnell.com>
Sat, 11 Oct 2014 15:47:03 +0000 (11:47 -0400)
Add the -bb flag to all py3 tests, which uncovered this bug.

tornado/curl_httpclient.py
tornado/test/httpclient_test.py
tox.ini

index d51ae3502ae779ee22eb5e7beb40d49c2c6b3121..68047cc94880560e21a6e36af0c1010948abe3f2 100644 (file)
@@ -280,13 +280,9 @@ class CurlAsyncHTTPClient(AsyncHTTPClient):
         if "Pragma" not in request.headers:
             request.headers["Pragma"] = ""
 
-        # Request headers may be either a regular dict or HTTPHeaders object
-        if isinstance(request.headers, httputil.HTTPHeaders):
-            curl.setopt(pycurl.HTTPHEADER,
-                        [native_str("%s: %s" % i) for i in request.headers.get_all()])
-        else:
-            curl.setopt(pycurl.HTTPHEADER,
-                        [native_str("%s: %s" % i) for i in request.headers.items()])
+        curl.setopt(pycurl.HTTPHEADER,
+                    ["%s: %s" % (native_str(k), native_str(v))
+                     for k, v in request.headers.get_all()])
 
         curl.setopt(pycurl.HEADERFUNCTION,
                     functools.partial(self._curl_header_callback,
index 36fdeb0c77c12d9f11452b5d81b61512351cbc23..bfb50d878d05bbbc6926959c2f48955b529b9cf5 100644 (file)
@@ -23,7 +23,7 @@ from tornado.testing import AsyncHTTPTestCase, bind_unused_port, gen_test, Expec
 from tornado.test.util import unittest, skipOnTravis
 from tornado.util import u
 from tornado.web import Application, RequestHandler, url
-from tornado.httputil import format_timestamp
+from tornado.httputil import format_timestamp, HTTPHeaders
 
 
 class HelloWorldHandler(RequestHandler):
@@ -347,6 +347,21 @@ Transfer-Encoding: chunked
         finally:
             client.close()
 
+    def test_header_types(self):
+        # Header values may be passed as character or utf8 byte strings,
+        # in a plain dictionary or an HTTPHeaders object.
+        # Keys must always be the native str type.
+        # All combinations should have the same results on the wire.
+        for value in [u("MyUserAgent"), b"MyUserAgent"]:
+            for container in [dict, HTTPHeaders]:
+                headers = container()
+                headers['User-Agent'] = value
+                resp = self.fetch('/user_agent', headers=headers)
+                self.assertEqual(
+                    resp.body, b"MyUserAgent",
+                    "response=%r, value=%r, container=%r" %
+                    (resp.body, value, container))
+
     def test_304_with_content_length(self):
         # According to the spec 304 responses SHOULD NOT include
         # Content-Length or other entity headers, but some servers do it
diff --git a/tox.ini b/tox.ini
index 7d9197c9a8281c6bfb49e45520c6f65e5a16b917..443448caa76ff577800131f66a67b31f622fe6c2 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -103,7 +103,7 @@ commands =
          python \
          # py3*: -b turns on an extra warning when calling
          # str(bytes), and -bb makes it an error.
-         {py32,py33,py34,pypy3}: -bb \
+         {py3,py32,py33,py34,pypy3}: -bb \
          # Python's optimized mode disables the assert statement, so
          # run the tests in this mode to ensure we haven't fallen into
          # the trap of relying on an assertion's side effects or using