From b71854163d71b75ab7ec417e65b36bd52567771d Mon Sep 17 00:00:00 2001 From: Steffen Allner Date: Fri, 11 Aug 2017 10:51:24 +0200 Subject: [PATCH] Allow handling of multipart requests in functional doctests using `http`. --- CHANGES.rst | 2 ++ .../zopedoctest/FunctionalDocTest.txt | 35 +++++++++++++++++++ .../ZopeTestCase/zopedoctest/functional.py | 10 ++++-- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 113b7e2344..b61c9cac60 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -11,6 +11,8 @@ https://zope.readthedocs.io/en/2.13/CHANGES.html Bugs Fixed ++++++++++ +- Allow handling of multipart requests in functional doctests using ``http``. + Features Added ++++++++++++++ diff --git a/src/Testing/ZopeTestCase/zopedoctest/FunctionalDocTest.txt b/src/Testing/ZopeTestCase/zopedoctest/FunctionalDocTest.txt index b3b6c19244..fb65ebdb00 100644 --- a/src/Testing/ZopeTestCase/zopedoctest/FunctionalDocTest.txt +++ b/src/Testing/ZopeTestCase/zopedoctest/FunctionalDocTest.txt @@ -163,3 +163,38 @@ Test reading cookies >>> b'baz: oki doki' in response.getBody() True + +Test parsing of multipart body with unicode + + >>> ni_hao = '\xe4\xbd\xa0\xe5\xa5\xbd' # utf-8 encoded + >>> response = http(r""" + ... GET /test_folder_1_/index_html/set_cookie HTTP/1.1 + ... Authorization: %s:%s + ... Content-Type: multipart/form-data; boundary=---------------------------968064918930967154199105236 + ... Content-Length: 418 + ... + ... -----------------------------968064918930967154199105236 + ... Content-Disposition: form-data; name="field.title" + ... + ... %s + ... -----------------------------968064918930967154199105236 + ... Content-Disposition: form-data; name="field.description" + ... + ... Details + ... -----------------------------968064918930967154199105236 + ... Content-Disposition: form-data; name="field.somenumber" + ... + ... 0 + ... -----------------------------968064918930967154199105236 + ... Content-Disposition: form-data; name="UPDATE_SUBMIT" + ... + ... Add + ... -----------------------------968064918930967154199105236 + ... Content-Disposition: form-data; name="add_input_name" + ... + ... unicodetest + ... -----------------------------968064918930967154199105236-- + ... """ % (user_name, user_password, ni_hao)) + + >>> response.status + 200 diff --git a/src/Testing/ZopeTestCase/zopedoctest/functional.py b/src/Testing/ZopeTestCase/zopedoctest/functional.py index c9541d5db4..cfde1d6dd4 100644 --- a/src/Testing/ZopeTestCase/zopedoctest/functional.py +++ b/src/Testing/ZopeTestCase/zopedoctest/functional.py @@ -14,7 +14,7 @@ """ import doctest -import email +import email.parser from functools import partial from io import BytesIO import re @@ -165,10 +165,16 @@ def http(request_string, handle_errors=True): 'bobo-exception-type', 'bobo-exception-file', 'bobo-exception-value', 'bobo-exception-line')) - msg = email.message_from_string(request_string) + # With a HeaderParser the payload is always a string, Parser would create a + # list of messages for multipart messages. + parser = email.parser.HeaderParser() + msg = parser.parsestr(request_string) headers = msg.items() body = msg.get_payload() + if isinstance(body, bytes): + body = body.decode('utf-8') + # Store request body without headers instream = BytesIO(body.encode('utf-8'))