From: Ben Darnell Date: Sun, 14 Feb 2016 19:00:00 +0000 (-0500) Subject: Handle non-ascii headers correctly in curl_httpclient. X-Git-Tag: v4.4.0b1~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d7d9c467cda38f4c9352172ba7411edc29a85196;p=thirdparty%2Ftornado.git Handle non-ascii headers correctly in curl_httpclient. Fixes #1608 --- diff --git a/tornado/curl_httpclient.py b/tornado/curl_httpclient.py index 6dadedd9f..664cb492c 100644 --- a/tornado/curl_httpclient.py +++ b/tornado/curl_httpclient.py @@ -462,7 +462,7 @@ class CurlAsyncHTTPClient(AsyncHTTPClient): request.prepare_curl_callback(curl) def _curl_header_callback(self, headers, header_callback, header_line): - header_line = native_str(header_line) + header_line = native_str(header_line.decode('latin1')) if header_callback is not None: self.io_loop.add_callback(header_callback, header_line) # header_line as returned by curl includes the end-of-line characters. diff --git a/tornado/test/httpclient_test.py b/tornado/test/httpclient_test.py index 9e8e62c6f..8c9a99d9f 100644 --- a/tornado/test/httpclient_test.py +++ b/tornado/test/httpclient_test.py @@ -12,7 +12,7 @@ import threading import datetime from io import BytesIO -from tornado.escape import utf8 +from tornado.escape import utf8, native_str from tornado import gen from tornado.httpclient import HTTPRequest, HTTPResponse, _RequestProxy, HTTPError, HTTPClient from tornado.httpserver import HTTPServer @@ -113,6 +113,15 @@ class AllMethodsHandler(RequestHandler): get = post = put = delete = options = patch = other = method + +class SetHeaderHandler(RequestHandler): + def get(self): + # Use get_arguments for keys to get strings, but + # request.arguments for values to get bytes. + for k, v in zip(self.get_arguments('k'), + self.request.arguments['v']): + self.set_header(k, v) + # These tests end up getting run redundantly: once here with the default # HTTPClient implementation, and then again in each implementation's own # test suite. @@ -133,6 +142,7 @@ class HTTPClientCommonTestCase(AsyncHTTPTestCase): url("/304_with_content_length", ContentLength304Handler), url("/all_methods", AllMethodsHandler), url('/patch', PatchHandler), + url('/set_header', SetHeaderHandler), ], gzip=True) def test_patch_receives_payload(self): @@ -520,6 +530,12 @@ X-XSS-Protection: 1; response.rethrow() self.assertEqual(response.body, b"Put body: hello") + def test_non_ascii_header(self): + # Non-ascii headers are sent as latin1. + response = self.fetch("/set_header?k=foo&v=%E9") + response.rethrow() + self.assertEqual(response.headers["Foo"], native_str(u"\u00e9")) + class RequestProxyTest(unittest.TestCase): def test_request_set(self):