Stop mutating header dicts

Change-Id: Ia1638c216eff9db6fbe416bc0570c27cfdcfe730
This commit is contained in:
Tim Burke 2017-08-25 12:13:12 -07:00
parent f323bb4824
commit ae5fd46e87
2 changed files with 47 additions and 33 deletions

View File

@ -302,7 +302,7 @@ class _RetryBody(_ObjectBody):
self.obj = obj
self.query_string = query_string
self.response_dict = response_dict
self.headers = headers if headers is not None else {}
self.headers = dict(headers) if headers is not None else {}
self.bytes_read = 0
def read(self, length=None):
@ -834,13 +834,15 @@ def post_account(url, token, headers, http_conn=None, response_dict=None,
path = parsed.path
if query_string:
path += '?' + query_string
headers['X-Auth-Token'] = token
req_headers = {'X-Auth-Token': token}
if service_token:
headers['X-Service-Token'] = service_token
conn.request(method, path, data, headers)
req_headers['X-Service-Token'] = service_token
if headers:
req_headers.update(headers)
conn.request(method, path, data, req_headers)
resp = conn.getresponse()
body = resp.read()
http_log((url, method,), {'headers': headers}, resp, body)
http_log((url, method,), {'headers': req_headers}, resp, body)
store_response(resp, response_dict)
@ -882,12 +884,6 @@ def get_container(url, token, container, marker=None, limit=None,
"""
if not http_conn:
http_conn = http_connection(url)
if headers:
headers = dict(headers)
else:
headers = {}
headers['X-Auth-Token'] = token
headers['Accept-Encoding'] = 'gzip'
if full_listing:
rv = get_container(url, token, container, marker, limit, prefix,
delimiter, end_marker, path, http_conn,
@ -922,17 +918,20 @@ def get_container(url, token, container, marker=None, limit=None,
qs += '&path=%s' % quote(path)
if query_string:
qs += '&%s' % query_string.lstrip('?')
req_headers = {'X-Auth-Token': token, 'Accept-Encoding': 'gzip'}
if service_token:
headers['X-Service-Token'] = service_token
req_headers['X-Service-Token'] = service_token
if headers:
req_headers.update(headers)
method = 'GET'
conn.request(method, '%s?%s' % (cont_path, qs), '', headers)
conn.request(method, '%s?%s' % (cont_path, qs), '', req_headers)
resp = conn.getresponse()
body = resp.read()
http_log(('%(url)s%(cont_path)s?%(qs)s' %
{'url': url.replace(parsed.path, ''),
'cont_path': cont_path,
'qs': qs}, method,),
{'headers': headers}, resp, body)
{'headers': req_headers}, resp, body)
if resp.status < 200 or resp.status >= 300:
raise ClientException.from_response(resp, 'Container GET failed', body)
@ -1005,23 +1004,23 @@ def put_container(url, token, container, headers=None, http_conn=None,
parsed, conn = http_connection(url)
path = '%s/%s' % (parsed.path, quote(container))
method = 'PUT'
if not headers:
headers = {}
headers['X-Auth-Token'] = token
req_headers = {'X-Auth-Token': token}
if service_token:
headers['X-Service-Token'] = service_token
if 'content-length' not in (k.lower() for k in headers):
headers['Content-Length'] = '0'
req_headers['X-Service-Token'] = service_token
if headers:
req_headers.update(headers)
if 'content-length' not in (k.lower() for k in req_headers):
req_headers['Content-Length'] = '0'
if query_string:
path += '?' + query_string.lstrip('?')
conn.request(method, path, '', headers)
conn.request(method, path, '', req_headers)
resp = conn.getresponse()
body = resp.read()
store_response(resp, response_dict)
http_log(('%s%s' % (url.replace(parsed.path, ''), path), method,),
{'headers': headers}, resp, body)
{'headers': req_headers}, resp, body)
if resp.status < 200 or resp.status >= 300:
raise ClientException.from_response(resp, 'Container PUT failed', body)
@ -1048,16 +1047,18 @@ def post_container(url, token, container, headers, http_conn=None,
parsed, conn = http_connection(url)
path = '%s/%s' % (parsed.path, quote(container))
method = 'POST'
headers['X-Auth-Token'] = token
req_headers = {'X-Auth-Token': token}
if service_token:
headers['X-Service-Token'] = service_token
req_headers['X-Service-Token'] = service_token
if headers:
req_headers.update(headers)
if 'content-length' not in (k.lower() for k in headers):
headers['Content-Length'] = '0'
conn.request(method, path, '', headers)
req_headers['Content-Length'] = '0'
conn.request(method, path, '', req_headers)
resp = conn.getresponse()
body = resp.read()
http_log(('%s%s' % (url.replace(parsed.path, ''), path), method,),
{'headers': headers}, resp, body)
{'headers': req_headers}, resp, body)
store_response(resp, response_dict)
@ -1352,14 +1353,16 @@ def post_object(url, token, container, name, headers, http_conn=None,
else:
parsed, conn = http_connection(url)
path = '%s/%s/%s' % (parsed.path, quote(container), quote(name))
headers['X-Auth-Token'] = token
req_headers = {'X-Auth-Token': token}
if service_token:
headers['X-Service-Token'] = service_token
conn.request('POST', path, '', headers)
req_headers['X-Service-Token'] = service_token
if headers:
req_headers.update(headers)
conn.request('POST', path, '', req_headers)
resp = conn.getresponse()
body = resp.read()
http_log(('%s%s' % (url.replace(parsed.path, ''), path), 'POST',),
{'headers': headers}, resp, body)
{'headers': req_headers}, resp, body)
store_response(resp, response_dict)

View File

@ -680,9 +680,10 @@ class TestPostAccount(MockHttpTest):
c.http_connection = self.fake_http_connection(200, headers={
'X-Account-Meta-Color': 'blue',
}, body='foo')
headers = {'x-account-meta-shape': 'square'}
resp_headers, body = c.post_account(
'http://www.tests.com/path/to/account', 'asdf',
{'x-account-meta-shape': 'square'}, query_string='bar=baz',
headers, query_string='bar=baz',
data='some data')
self.assertEqual('blue', resp_headers.get('x-account-meta-color'))
self.assertEqual('foo', body)
@ -691,6 +692,8 @@ class TestPostAccount(MockHttpTest):
'some data', {'x-auth-token': 'asdf',
'x-account-meta-shape': 'square'})
])
# Check that we didn't mutate the request ehader dict
self.assertEqual(headers, {'x-account-meta-shape': 'square'})
def test_server_error(self):
body = 'c' * 65
@ -1434,6 +1437,11 @@ class TestPostObject(MockHttpTest):
'X-Object-Meta-Test': 'mymeta',
'X-Delete-At': delete_at}),
])
# Check that the request header dict didn't get mutated
self.assertEqual(args[-1], {
'X-Object-Meta-Test': 'mymeta',
'X-Delete-At': delete_at,
})
def test_unicode_ok(self):
conn = c.http_connection(u'http://www.test.com/')
@ -2996,10 +3004,11 @@ class TestServiceToken(MockHttpTest):
self.assertEqual(conn.attempts, 1)
def test_service_token_post_container(self):
headers = {'X-Container-Meta-Color': 'blue'}
with mock.patch('swiftclient.client.http_connection',
self.fake_http_connection(201)):
conn = self.get_connection()
conn.post_container('container1', {})
conn.post_container('container1', headers)
self.assertEqual(1, len(self.request_log), self.request_log)
for actual in self.iter_request_log():
self.assertEqual('POST', actual['method'])
@ -3009,6 +3018,8 @@ class TestServiceToken(MockHttpTest):
self.assertEqual('http://storage_url.com/container1',
actual['full_path'])
self.assertEqual(conn.attempts, 1)
# Check that we didn't mutate the request header dict
self.assertEqual(headers, {'X-Container-Meta-Color': 'blue'})
def test_service_token_put_container(self):
with mock.patch('swiftclient.client.http_connection',