From: Ben Darnell Date: Sun, 3 Jun 2018 03:17:20 +0000 (-0400) Subject: httputil: Fix rfc2231 for python2 X-Git-Tag: v5.1.0b1~5^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F2411%2Fhead;p=thirdparty%2Ftornado.git httputil: Fix rfc2231 for python2 Add a test that goes through parse_multipart_form_data --- diff --git a/tornado/httputil.py b/tornado/httputil.py index e6f3fc975..eabe11b08 100644 --- a/tornado/httputil.py +++ b/tornado/httputil.py @@ -891,7 +891,8 @@ def parse_response_start_line(line): # The original 2.7 version of this code did not correctly support some # combinations of semicolons and double quotes. # It has also been modified to support valueless parameters as seen in -# websocket extension negotiations. +# websocket extension negotiations, and to support non-ascii values in +# RFC 2231/5987 format. def _parseparam(s): @@ -912,8 +913,10 @@ def _parse_header(line): Return the main content-type and a dictionary of options. - >>> d = "CD: fd; foo=\"b\\\\a\\\"r\"; file*=utf-8''T%C3%A4st" - >>> d = _parse_header(d)[1] + >>> d = "form-data; foo=\"b\\\\a\\\"r\"; file*=utf-8''T%C3%A4st" + >>> ct, d = _parse_header(d) + >>> ct + 'form-data' >>> d['file'] == r'T\u00e4st'.encode('ascii').decode('unicode_escape') True >>> d['foo'] @@ -928,9 +931,9 @@ def _parse_header(line): if i >= 0: name = p[:i].strip().lower() value = p[i + 1:].strip() - params.append((name, value)) + params.append((name, native_str(value))) params = email.utils.decode_params(params) - params.pop(0) # get rid of the dummy again + params.pop(0) # get rid of the dummy again pdict = {} for name, value in params: value = email.utils.collapse_rfc2231_value(value) diff --git a/tornado/test/httputil_test.py b/tornado/test/httputil_test.py index bd5832bcd..faf7717fe 100644 --- a/tornado/test/httputil_test.py +++ b/tornado/test/httputil_test.py @@ -176,6 +176,20 @@ Foo self.assertEqual(file["filename"], filename) self.assertEqual(file["body"], b"Foo") + def test_non_ascii_filename(self): + data = b"""\ +--1234 +Content-Disposition: form-data; name="files"; filename="ab.txt"; filename*=UTF-8''%C3%A1b.txt + +Foo +--1234--""".replace(b"\n", b"\r\n") + args = {} + files = {} + parse_multipart_form_data(b"1234", data, args, files) + file = files["files"][0] + self.assertEqual(file["filename"], u"áb.txt") + self.assertEqual(file["body"], b"Foo") + def test_boundary_starts_and_ends_with_quotes(self): data = b'''\ --1234