From 1a586323825ca681a7c6739bc6f6fd9131932a2c Mon Sep 17 00:00:00 2001 From: gholt Date: Sat, 11 Jun 2011 04:57:04 +0000 Subject: [PATCH] Fixed so account GETs and HEADs autocreate the account when account_autocreate = true --- swift/proxy/server.py | 36 ++++++++++++++++++++++++++++++++-- test/unit/proxy/test_server.py | 30 ++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/swift/proxy/server.py b/swift/proxy/server.py index 8a451200cf..581eef21c3 100644 --- a/swift/proxy/server.py +++ b/swift/proxy/server.py @@ -1319,8 +1319,26 @@ def __init__(self, app, account_name, **kwargs): def GETorHEAD(self, req): """Handler for HTTP GET/HEAD requests.""" partition, nodes = self.app.account_ring.get_nodes(self.account_name) - return self.GETorHEAD_base(req, _('Account'), partition, nodes, + resp = self.GETorHEAD_base(req, _('Account'), partition, nodes, req.path_info.rstrip('/'), self.app.account_ring.replica_count) + if resp.status_int == 404 and self.app.account_autocreate: + if len(self.account_name) > MAX_ACCOUNT_NAME_LENGTH: + resp = HTTPBadRequest(request=req) + resp.body = 'Account name length of %d longer than %d' % \ + (len(self.account_name), MAX_ACCOUNT_NAME_LENGTH) + return resp + headers = {'X-Timestamp': normalize_timestamp(time.time()), + 'X-Trans-Id': self.trans_id} + resp = self.make_requests( + Request.blank('/v1/' + self.account_name), + self.app.account_ring, partition, 'PUT', + '/' + self.account_name, [headers] * len(nodes)) + if resp.status_int // 100 != 2: + raise Exception('Could not autocreate account %r' % + self.account_name) + resp = self.GETorHEAD_base(req, _('Account'), partition, nodes, + req.path_info.rstrip('/'), self.app.account_ring.replica_count) + return resp @public def PUT(self, req): @@ -1360,9 +1378,23 @@ def POST(self, req): if value[0].lower().startswith('x-account-meta-')) if self.app.memcache: self.app.memcache.delete('account%s' % req.path_info.rstrip('/')) - return self.make_requests(req, self.app.account_ring, + resp = self.make_requests(req, self.app.account_ring, account_partition, 'POST', req.path_info, [headers] * len(accounts)) + if resp.status_int == 404 and self.app.account_autocreate: + if len(self.account_name) > MAX_ACCOUNT_NAME_LENGTH: + resp = HTTPBadRequest(request=req) + resp.body = 'Account name length of %d longer than %d' % \ + (len(self.account_name), MAX_ACCOUNT_NAME_LENGTH) + return resp + resp = self.make_requests( + Request.blank('/v1/' + self.account_name), + self.app.account_ring, account_partition, 'PUT', + '/' + self.account_name, [headers] * len(accounts)) + if resp.status_int // 100 != 2: + raise Exception('Could not autocreate account %r' % + self.account_name) + return resp @public def DELETE(self, req): diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py index eb09ad34dc..b525ea9037 100644 --- a/test/unit/proxy/test_server.py +++ b/test/unit/proxy/test_server.py @@ -3171,6 +3171,16 @@ def test_GET(self): self.app.memcache = FakeMemcacheReturnsNone() self.assert_status_map(controller.GET, (404, 404, 404), 404) + def test_GET_autocreate(self): + with save_globals(): + controller = proxy_server.AccountController(self.app, 'account') + self.app.memcache = FakeMemcacheReturnsNone() + self.assert_status_map(controller.GET, + (404, 404, 404, 201, 201, 201, 204), 404) + controller.app.account_autocreate = True + self.assert_status_map(controller.GET, + (404, 404, 404, 201, 201, 201, 204), 204) + def test_HEAD(self): with save_globals(): controller = proxy_server.AccountController(self.app, 'account') @@ -3189,6 +3199,26 @@ def test_HEAD(self): self.assert_status_map(controller.HEAD, (404, 503, 503), 503) self.assert_status_map(controller.HEAD, (404, 204, 503), 204) + def test_HEAD_autocreate(self): + with save_globals(): + controller = proxy_server.AccountController(self.app, 'account') + self.app.memcache = FakeMemcacheReturnsNone() + self.assert_status_map(controller.HEAD, + (404, 404, 404, 201, 201, 201, 204), 404) + controller.app.account_autocreate = True + self.assert_status_map(controller.HEAD, + (404, 404, 404, 201, 201, 201, 204), 204) + + def test_POST_autocreate(self): + with save_globals(): + controller = proxy_server.AccountController(self.app, 'account') + self.app.memcache = FakeMemcacheReturnsNone() + self.assert_status_map(controller.POST, + (404, 404, 404, 201, 201, 201), 404) + controller.app.account_autocreate = True + self.assert_status_map(controller.POST, + (404, 404, 404, 201, 201, 201), 201) + def test_connection_refused(self): self.app.account_ring.get_nodes('account') for dev in self.app.account_ring.devs.values():