From 32f6b3c642fd5830a63e06ea4fac86956160312f Mon Sep 17 00:00:00 2001 From: Timur Alperovich Date: Thu, 8 Jun 2017 23:47:14 -0700 Subject: [PATCH] Do not set Content-Type to '' with new requests. Previously, python-swiftclient worked around a requests issue where Content-Type could be set to application/x-www-form-urlencoded when using python3. This issue has been resolved and a fix released in requests 2.4 (fixed in subsequent releases as well). The patch makes the workaround conditional on the requests version, so that with sufficiently new requests libraries, the Content-Type is not set. For reference, requests 2.4 was released August 29th, 2014. The specific issue filed in the requests tracker is: https://github.com/requests/requests/issues/2071. Related-Change: I035f8b4b9c9ccdc79820b907770a48f86d0343b4 Closes-Bug: #1433767 Change-Id: Ieb2243d2ff5326920a27ce8c3c6f0f5c396701ed --- swiftclient/client.py | 6 ++++-- tests/unit/test_swiftclient.py | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/swiftclient/client.py b/swiftclient/client.py index 80b6eda2..80bc4a3a 100644 --- a/swiftclient/client.py +++ b/swiftclient/client.py @@ -1286,8 +1286,10 @@ def put_object(url, token=None, container=None, name=None, contents=None, if content_type is not None: headers['Content-Type'] = content_type elif 'Content-Type' not in headers: - # python-requests sets application/x-www-form-urlencoded otherwise - headers['Content-Type'] = '' + if StrictVersion(requests.__version__) < StrictVersion('2.4.0'): + # python-requests sets application/x-www-form-urlencoded otherwise + # if using python3. + headers['Content-Type'] = '' if not contents: headers['Content-Length'] = '0' diff --git a/tests/unit/test_swiftclient.py b/tests/unit/test_swiftclient.py index d4a704e1..9e9280d7 100644 --- a/tests/unit/test_swiftclient.py +++ b/tests/unit/test_swiftclient.py @@ -1165,6 +1165,7 @@ class TestHeadObject(MockHttpTest): class TestPutObject(MockHttpTest): + @mock.patch('swiftclient.requests.__version__', '2.2.0') def test_ok(self): c.http_connection = self.fake_http_connection(200) args = ('http://www.test.com', 'TOKEN', 'container', 'obj', 'body', 4) @@ -1222,6 +1223,7 @@ class TestPutObject(MockHttpTest): self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[-1].category, UserWarning)) + @mock.patch('swiftclient.requests.__version__', '2.2.0') def test_server_error(self): body = 'c' * 60 headers = {'foo': 'bar'} @@ -1236,7 +1238,8 @@ class TestPutObject(MockHttpTest): self.assertEqual(e.http_status, 500) self.assertRequests([ ('PUT', '/asdf/asdf', 'asdf', { - 'x-auth-token': 'asdf', 'content-type': ''}), + 'x-auth-token': 'asdf', + 'content-type': ''}), ]) def test_query_string(self): @@ -1377,7 +1380,8 @@ class TestPutObject(MockHttpTest): self.assertEqual(request_header['etag'], b'1234-5678') self.assertEqual(request_header['content-type'], b'text/plain') - def test_no_content_type(self): + @mock.patch('swiftclient.requests.__version__', '2.2.0') + def test_no_content_type_old_requests(self): conn = c.http_connection(u'http://www.test.com/') resp = MockHttpResponse(status=200) conn[1].getresponse = resp.fake_response @@ -1387,6 +1391,17 @@ class TestPutObject(MockHttpTest): request_header = resp.requests_params['headers'] self.assertEqual(request_header['content-type'], b'') + @mock.patch('swiftclient.requests.__version__', '2.4.0') + def test_no_content_type_new_requests(self): + conn = c.http_connection(u'http://www.test.com/') + resp = MockHttpResponse(status=200) + conn[1].getresponse = resp.fake_response + conn[1]._request = resp._fake_request + + c.put_object(url='http://www.test.com', http_conn=conn) + request_header = resp.requests_params['headers'] + self.assertNotIn('content-type', request_header) + def test_content_type_in_headers(self): conn = c.http_connection(u'http://www.test.com/') resp = MockHttpResponse(status=200)