From ad4bca2ae9ba8b046fcb5286de61b8535c8bdf69 Mon Sep 17 00:00:00 2001 From: Wang Yuxin Date: Mon, 23 Apr 2018 17:44:30 +0800 Subject: [PATCH] Fix get_container_info missing some sysmeta info. When get_container_info is called and not authenticated, it will make a HEAD subrequest and get info by passing resp.sw_headers to headers_to_container_info. This will lose all sysmeta stored in resp.sysmeta_headers. The patch fixes this by passing all sw_headers and sysmeta_headers to headers_to_container_info. Change-Id: I125e03a919eaeea8bf044aaaf0e06834d87ad9f9 Closes-Bug: #1765679 --- swift3/request.py | 6 +++++- swift3/test/unit/test_request.py | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/swift3/request.py b/swift3/request.py index 7a2936e0..1e732937 100644 --- a/swift3/request.py +++ b/swift3/request.py @@ -87,6 +87,8 @@ def _header_strip(value): # behave as though it wasn't provided return None return stripped + + _header_strip.re = re.compile('^[\x00-\x20]*|[\x00-\x20]*$') @@ -1262,8 +1264,10 @@ class Request(swob.Request): else: # otherwise we do naive HEAD request with the authentication resp = self.get_response(app, 'HEAD', self.container_name, '') + headers = resp.sw_headers.copy() + headers.update(resp.sysmeta_headers) return headers_to_container_info( - resp.sw_headers, resp.status_int) # pylint: disable-msg=E1101 + headers, resp.status_int) # pylint: disable-msg=E1101 def gen_multipart_manifest_delete_query(self, app): if not CONF.allow_multipart_uploads: diff --git a/swift3/test/unit/test_request.py b/swift3/test/unit/test_request.py index bde7bd27..2b5e143b 100644 --- a/swift3/test/unit/test_request.py +++ b/swift3/test/unit/test_request.py @@ -295,9 +295,14 @@ class TestRequest(Swift3TestCase): self.assertTrue(sw_req.environ['swift.proxy_access_log_made']) def test_get_container_info(self): + swift3_acl = '{"Owner":"owner","Grant":'\ + '[{"Grantee":"owner","Permission":"FULL_CONTROL"}]}' self.swift.register('HEAD', '/v1/AUTH_test/bucket', HTTPNoContent, {'x-container-read': 'foo', 'X-container-object-count': 5, + 'x-container-sysmeta-versions-location': + 'bucket2', + 'x-container-sysmeta-swift3-acl': swift3_acl, 'X-container-meta-foo': 'bar'}, None) req = Request.blank('/bucket', environ={'REQUEST_METHOD': 'GET'}, headers={'Authorization': 'AWS test:tester:hmac', @@ -309,6 +314,9 @@ class TestRequest(Swift3TestCase): self.assertEqual(204, info['status']) # sanity self.assertEqual('foo', info['read_acl']) # sanity self.assertEqual('5', info['object_count']) # sanity + self.assertEqual( + 'bucket2', info['sysmeta']['versions-location']) # sanity + self.assertEqual(swift3_acl, info['sysmeta']['swift3-acl']) # sanity self.assertEqual({'foo': 'bar'}, info['meta']) # sanity with patch('swift3.request.get_container_info', return_value={'status': 204}) as mock_info: @@ -752,5 +760,6 @@ class TestRequest(Swift3TestCase): self.assertTrue(sigv2_req.check_signature( 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY')) + if __name__ == '__main__': unittest.main()