diff --git a/doc/source/deployment_guide.rst b/doc/source/deployment_guide.rst index 2bde17febb..8e2564e8a8 100644 --- a/doc/source/deployment_guide.rst +++ b/doc/source/deployment_guide.rst @@ -836,6 +836,13 @@ request_node_count 2 * replicas Set to the number of nodes to given times the number of replicas for the ring being used for the request. +swift_owner_headers up to the auth system in use, + but usually indicates + administrative responsibilities. ============================ =============== ============================= [tempauth] diff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample index fad77f855c..3513ed997d 100644 --- a/etc/proxy-server.conf-sample +++ b/etc/proxy-server.conf-sample @@ -176,6 +176,11 @@ use = egg:swift#proxy # times the number of replicas for the ring being used for the # request. # write_affinity_node_count = 2 * replicas +# +# These are the headers whose values will only be shown to swift_owners. The +# exact definition of a swift_owner is up to the auth system in use, but +# usually indicates administrative responsibilities. +# swift_owner_headers = x-container-read, x-container-write, x-container-sync-key, x-container-sync-to, x-account-meta-temp-url-key, x-account-meta-temp-url-key-2 [filter:tempauth] diff --git a/swift/proxy/controllers/account.py b/swift/proxy/controllers/account.py index 7a312dc086..04af4d1cd9 100644 --- a/swift/proxy/controllers/account.py +++ b/swift/proxy/controllers/account.py @@ -63,8 +63,12 @@ class AccountController(Controller): content_type, error = account_listing_content_type(req) if error: return error - return account_listing_response(self.account_name, req, + resp = account_listing_response(self.account_name, req, content_type) + if not req.environ.get('swift_owner', False): + for key in self.app.swift_owner_headers: + if key in resp.headers: + del resp.headers[key] return resp @public diff --git a/swift/proxy/controllers/container.py b/swift/proxy/controllers/container.py index cf0a615af3..049c289431 100644 --- a/swift/proxy/controllers/container.py +++ b/swift/proxy/controllers/container.py @@ -82,8 +82,7 @@ class ContainerController(Controller): if aresp: return aresp if not req.environ.get('swift_owner', False): - for key in ('x-container-read', 'x-container-write', - 'x-container-sync-key', 'x-container-sync-to'): + for key in self.app.swift_owner_headers: if key in resp.headers: del resp.headers[key] return resp diff --git a/swift/proxy/server.py b/swift/proxy/server.py index b2fefcd1c6..4601a72a9e 100644 --- a/swift/proxy/server.py +++ b/swift/proxy/server.py @@ -155,6 +155,14 @@ class Application(object): else: raise ValueError( 'Invalid write_affinity_node_count value: %r' % ''.join(value)) + swift_owner_headers = conf.get( + 'swift_owner_headers', + 'x-container-read, x-container-write, ' + 'x-container-sync-key, x-container-sync-to, ' + 'x-account-meta-temp-url-key, x-account-meta-temp-url-key-2') + self.swift_owner_headers = [ + name.strip() + for name in swift_owner_headers.split(',') if name.strip()] def get_controller(self, path): """ diff --git a/test/unit/proxy/controllers/test_account.py b/test/unit/proxy/controllers/test_account.py index 4d67d65f79..c364bead1c 100644 --- a/test/unit/proxy/controllers/test_account.py +++ b/test/unit/proxy/controllers/test_account.py @@ -40,6 +40,28 @@ class TestAccountController(unittest.TestCase): self.assertEqual(headers_to_account_info(resp.headers), resp.environ['swift.account/AUTH_bob']) + def test_swift_owner(self): + owner_headers = { + 'x-account-meta-temp-url-key': 'value', + 'x-account-meta-temp-url-key-2': 'value'} + controller = proxy_server.AccountController(self.app, 'a') + + req = Request.blank('/a') + with mock.patch('swift.proxy.controllers.base.http_connect', + fake_http_connect(200, 200, headers=owner_headers)): + resp = controller.HEAD(req) + self.assertEquals(2, resp.status_int // 100) + for key in owner_headers: + self.assertTrue(key not in resp.headers) + + req = Request.blank('/a', environ={'swift_owner': True}) + with mock.patch('swift.proxy.controllers.base.http_connect', + fake_http_connect(200, 200, headers=owner_headers)): + resp = controller.HEAD(req) + self.assertEquals(2, resp.status_int // 100) + for key in owner_headers: + self.assertTrue(key in resp.headers) + if __name__ == '__main__': unittest.main() diff --git a/test/unit/proxy/controllers/test_container.py b/test/unit/proxy/controllers/test_container.py index c2e9483d6b..516b3fd25e 100644 --- a/test/unit/proxy/controllers/test_container.py +++ b/test/unit/proxy/controllers/test_container.py @@ -40,6 +40,28 @@ class TestContainerController(unittest.TestCase): self.assertEqual(headers_to_container_info(resp.headers), resp.environ['swift.container/a/c']) + def test_swift_owner(self): + owner_headers = { + 'x-container-read': 'value', 'x-container-write': 'value', + 'x-container-sync-key': 'value', 'x-container-sync-to': 'value'} + controller = proxy_server.ContainerController(self.app, 'a', 'c') + + req = Request.blank('/a/c') + with mock.patch('swift.proxy.controllers.base.http_connect', + fake_http_connect(200, 200, headers=owner_headers)): + resp = controller.HEAD(req) + self.assertEquals(2, resp.status_int // 100) + for key in owner_headers: + self.assertTrue(key not in resp.headers) + + req = Request.blank('/a/c', environ={'swift_owner': True}) + with mock.patch('swift.proxy.controllers.base.http_connect', + fake_http_connect(200, 200, headers=owner_headers)): + resp = controller.HEAD(req) + self.assertEquals(2, resp.status_int // 100) + for key in owner_headers: + self.assertTrue(key in resp.headers) + if __name__ == '__main__': unittest.main()