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
This commit is contained in:
Timur Alperovich 2017-06-08 23:47:14 -07:00
parent 6d5e87a183
commit 32f6b3c642
2 changed files with 21 additions and 4 deletions

View File

@ -1286,8 +1286,10 @@ def put_object(url, token=None, container=None, name=None, contents=None,
if content_type is not None: if content_type is not None:
headers['Content-Type'] = content_type headers['Content-Type'] = content_type
elif 'Content-Type' not in headers: elif 'Content-Type' not in headers:
# python-requests sets application/x-www-form-urlencoded otherwise if StrictVersion(requests.__version__) < StrictVersion('2.4.0'):
headers['Content-Type'] = '' # python-requests sets application/x-www-form-urlencoded otherwise
# if using python3.
headers['Content-Type'] = ''
if not contents: if not contents:
headers['Content-Length'] = '0' headers['Content-Length'] = '0'

View File

@ -1165,6 +1165,7 @@ class TestHeadObject(MockHttpTest):
class TestPutObject(MockHttpTest): class TestPutObject(MockHttpTest):
@mock.patch('swiftclient.requests.__version__', '2.2.0')
def test_ok(self): def test_ok(self):
c.http_connection = self.fake_http_connection(200) c.http_connection = self.fake_http_connection(200)
args = ('http://www.test.com', 'TOKEN', 'container', 'obj', 'body', 4) args = ('http://www.test.com', 'TOKEN', 'container', 'obj', 'body', 4)
@ -1222,6 +1223,7 @@ class TestPutObject(MockHttpTest):
self.assertEqual(len(w), 1) self.assertEqual(len(w), 1)
self.assertTrue(issubclass(w[-1].category, UserWarning)) self.assertTrue(issubclass(w[-1].category, UserWarning))
@mock.patch('swiftclient.requests.__version__', '2.2.0')
def test_server_error(self): def test_server_error(self):
body = 'c' * 60 body = 'c' * 60
headers = {'foo': 'bar'} headers = {'foo': 'bar'}
@ -1236,7 +1238,8 @@ class TestPutObject(MockHttpTest):
self.assertEqual(e.http_status, 500) self.assertEqual(e.http_status, 500)
self.assertRequests([ self.assertRequests([
('PUT', '/asdf/asdf', 'asdf', { ('PUT', '/asdf/asdf', 'asdf', {
'x-auth-token': 'asdf', 'content-type': ''}), 'x-auth-token': 'asdf',
'content-type': ''}),
]) ])
def test_query_string(self): def test_query_string(self):
@ -1377,7 +1380,8 @@ class TestPutObject(MockHttpTest):
self.assertEqual(request_header['etag'], b'1234-5678') self.assertEqual(request_header['etag'], b'1234-5678')
self.assertEqual(request_header['content-type'], b'text/plain') 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/') conn = c.http_connection(u'http://www.test.com/')
resp = MockHttpResponse(status=200) resp = MockHttpResponse(status=200)
conn[1].getresponse = resp.fake_response conn[1].getresponse = resp.fake_response
@ -1387,6 +1391,17 @@ class TestPutObject(MockHttpTest):
request_header = resp.requests_params['headers'] request_header = resp.requests_params['headers']
self.assertEqual(request_header['content-type'], b'') 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): def test_content_type_in_headers(self):
conn = c.http_connection(u'http://www.test.com/') conn = c.http_connection(u'http://www.test.com/')
resp = MockHttpResponse(status=200) resp = MockHttpResponse(status=200)