From 386382b18caab6a3a8a111fa8e24875dca27b0aa Mon Sep 17 00:00:00 2001 From: Jesse Shapiro Date: Wed, 4 May 2016 20:09:07 -0400 Subject: [PATCH] Encoding JSON requests to bytes for urllib3 to handle; ensuring same with testing. --- AUTHORS.rst | 1 + requests/models.py | 7 +++++-- tests/test_requests.py | 12 ++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index e684d850..37b66698 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -165,3 +165,4 @@ Patches and Suggestions - Brian Samek (`@bsamek `_) - Dmitry Dygalo (`@Stranger6667 `_) - piotrjurkiewicz +- Jesse Shapiro (`@haikuginger `_) diff --git a/requests/models.py b/requests/models.py index fe4bec1b..05ec3e47 100644 --- a/requests/models.py +++ b/requests/models.py @@ -420,8 +420,11 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): length = None if not data and json is not None: - content_type = 'application/json' - body = complexjson.dumps(json) + # When urllib3 uses pyOpenSSL, it can only resume large uploads + # properly if receiving a bytes-like object. In Python 2, json.dumps() + # returns just that, but Python 3 returns a Unicode string. + content_type = 'application/json; charset=utf-8' + body = complexjson.dumps(json).encode('utf-8') is_stream = all([ hasattr(data, '__iter__'), diff --git a/tests/test_requests.py b/tests/test_requests.py index 0a87b52c..427675d5 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -1516,6 +1516,18 @@ class RedirectSession(SessionRedirectMixin): return string +def test_json_encodes_as_bytes(): + # urllib3 expects bodies as bytes-like objects + body = {"key": "value"} + p = PreparedRequest() + p.prepare( + method='GET', + url='https://www.example.com/', + json='body' + ) + assert isinstance(p.body, bytes) + + def test_requests_are_updated_each_time(httpbin): session = RedirectSession([303, 307]) prep = requests.Request('POST', httpbin('post')).prepare()