From 0d1b42007b9be753c4724bfa5a42d66eeb9c4c64 Mon Sep 17 00:00:00 2001 From: Michael Barton Date: Fri, 2 Nov 2012 12:02:02 -0700 Subject: [PATCH] Set content-type on account/container head Change-Id: Ib54fa5adb7539bebfbd6644064be9d7f4d7af9db --- swift/account/server.py | 14 +++++++- swift/container/server.py | 14 +++++++- test/unit/account/test_server.py | 33 ++++++++++++++++++ test/unit/container/test_server.py | 55 ++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 2 deletions(-) diff --git a/swift/account/server.py b/swift/account/server.py index 0385319746..d8dd442b0d 100644 --- a/swift/account/server.py +++ b/swift/account/server.py @@ -194,8 +194,20 @@ class AccountController(object): headers.update((key, value) for key, (value, timestamp) in broker.metadata.iteritems() if value != '') + if get_param(req, 'format'): + req.accept = FORMAT2CONTENT_TYPE.get( + get_param(req, 'format').lower(), FORMAT2CONTENT_TYPE['plain']) + try: + headers['Content-Type'] = req.accept.best_match( + ['text/plain', 'application/json', 'application/xml', + 'text/xml'], + default_match='text/plain') + except AssertionError, err: + self.logger.increment('HEAD.errors') + return HTTPBadRequest(body='bad accept header: %s' % req.accept, + content_type='text/plain', request=req) self.logger.timing_since('HEAD.timing', start_time) - return HTTPNoContent(request=req, headers=headers) + return HTTPNoContent(request=req, headers=headers, charset='utf-8') @public def GET(self, req): diff --git a/swift/container/server.py b/swift/container/server.py index fb0d77ce07..984692245f 100644 --- a/swift/container/server.py +++ b/swift/container/server.py @@ -296,8 +296,20 @@ class ContainerController(object): for key, (value, timestamp) in broker.metadata.iteritems() if value != '' and (key.lower() in self.save_headers or key.lower().startswith('x-container-meta-'))) + if get_param(req, 'format'): + req.accept = FORMAT2CONTENT_TYPE.get( + get_param(req, 'format').lower(), FORMAT2CONTENT_TYPE['plain']) + try: + headers['Content-Type'] = req.accept.best_match( + ['text/plain', 'application/json', 'application/xml', + 'text/xml'], + default_match='text/plain') + except AssertionError, err: + self.logger.increment('HEAD.errors') + return HTTPBadRequest(body='bad accept header: %s' % req.accept, + content_type='text/plain', request=req) self.logger.timing_since('HEAD.timing', start_time) - return HTTPNoContent(request=req, headers=headers) + return HTTPNoContent(request=req, headers=headers, charset='utf-8') @public def GET(self, req): diff --git a/test/unit/account/test_server.py b/test/unit/account/test_server.py index b5eed2b65a..79f6af585d 100644 --- a/test/unit/account/test_server.py +++ b/test/unit/account/test_server.py @@ -1037,6 +1037,39 @@ class TestAccountController(unittest.TestCase): environ={'REQUEST_METHOD': 'PUT'}, headers=dict(headers))) self.assertEquals(resp.status_int, 404) + def test_content_type_on_HEAD(self): + self.controller.PUT(Request.blank('/sda1/p/a', + headers={'X-Timestamp': normalize_timestamp(1)}, + environ={'REQUEST_METHOD': 'PUT'})) + + env = {'REQUEST_METHOD': 'HEAD'} + + req = Request.blank('/sda1/p/a?format=xml', environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/xml') + + req = Request.blank('/sda1/p/a?format=json', environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/json') + self.assertEquals(resp.charset, 'utf-8') + + req = Request.blank('/sda1/p/a', environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'text/plain') + self.assertEquals(resp.charset, 'utf-8') + + req = Request.blank( + '/sda1/p/a', headers={'Accept': 'application/json'}, environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/json') + self.assertEquals(resp.charset, 'utf-8') + + req = Request.blank( + '/sda1/p/a', headers={'Accept': 'application/xml'}, environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/xml') + self.assertEquals(resp.charset, 'utf-8') + if __name__ == '__main__': unittest.main() diff --git a/test/unit/container/test_server.py b/test/unit/container/test_server.py index 912c51bd75..a26a932faa 100644 --- a/test/unit/container/test_server.py +++ b/test/unit/container/test_server.py @@ -585,6 +585,9 @@ class TestContainerController(unittest.TestCase): self.assertEquals(eval(resp.body), json_body) self.assertEquals(resp.charset, 'utf-8') + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/json') + for accept in ('application/json', 'application/json;q=1.0,*/*;q=0.9', '*/*;q=0.9,application/json;q=1.0', 'application/*'): req = Request.blank('/sda1/p/a/jsonc', @@ -596,6 +599,10 @@ class TestContainerController(unittest.TestCase): self.assertEquals(resp.content_type, 'application/json', 'Invalid content_type for Accept: %s' % accept) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/json', + 'Invalid content_type for Accept: %s' % accept) + def test_GET_plain(self): # make a container req = Request.blank('/sda1/p/a/plainc', environ={'REQUEST_METHOD': 'PUT', @@ -624,6 +631,9 @@ class TestContainerController(unittest.TestCase): self.assertEquals(resp.body, plain_body) self.assertEquals(resp.charset, 'utf-8') + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'text/plain') + for accept in ('', 'text/plain', 'application/xml;q=0.8,*/*;q=0.9', '*/*;q=0.9,application/xml;q=0.8', '*/*', 'text/plain,application/xml'): @@ -636,6 +646,10 @@ class TestContainerController(unittest.TestCase): self.assertEquals(resp.content_type, 'text/plain', 'Invalid content_type for Accept: %s' % accept) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'text/plain', + 'Invalid content_type for Accept: %s' % accept) + # test conflicting formats req = Request.blank('/sda1/p/a/plainc?format=plain', environ={'REQUEST_METHOD': 'GET'}) @@ -725,6 +739,9 @@ class TestContainerController(unittest.TestCase): self.assertEquals(resp.body, xml_body) self.assertEquals(resp.charset, 'utf-8') + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/xml') + for xml_accept in ('application/xml', 'application/xml;q=1.0,*/*;q=0.9', '*/*;q=0.9,application/xml;q=1.0', 'application/xml,text/xml'): req = Request.blank('/sda1/p/a/xmlc', @@ -736,6 +753,10 @@ class TestContainerController(unittest.TestCase): self.assertEquals(resp.content_type, 'application/xml', 'Invalid content_type for Accept: %s' % xml_accept) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/xml', + 'Invalid content_type for Accept: %s' % xml_accept) + req = Request.blank('/sda1/p/a/xmlc', environ={'REQUEST_METHOD': 'GET'}) req.accept = 'text/xml' @@ -1025,6 +1046,40 @@ class TestContainerController(unittest.TestCase): environ={'REQUEST_METHOD': 'DELETE'}, headers=dict(headers))) self.assertEquals(resp.status_int, 404) + def test_content_type_on_HEAD(self): + self.controller.PUT(Request.blank('/sda1/p/a/o', + headers={'X-Timestamp': normalize_timestamp(1)}, + environ={'REQUEST_METHOD': 'PUT'})) + + env = {'REQUEST_METHOD': 'HEAD'} + + req = Request.blank('/sda1/p/a/o?format=xml', environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/xml') + self.assertEquals(resp.charset, 'utf-8') + + req = Request.blank('/sda1/p/a/o?format=json', environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/json') + self.assertEquals(resp.charset, 'utf-8') + + req = Request.blank('/sda1/p/a/o', environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'text/plain') + self.assertEquals(resp.charset, 'utf-8') + + req = Request.blank( + '/sda1/p/a/o', headers={'Accept': 'application/json'}, environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/json') + self.assertEquals(resp.charset, 'utf-8') + + req = Request.blank( + '/sda1/p/a/o', headers={'Accept': 'application/xml'}, environ=env) + resp = self.controller.HEAD(req) + self.assertEquals(resp.content_type, 'application/xml') + self.assertEquals(resp.charset, 'utf-8') + if __name__ == '__main__': unittest.main()