From 08c017418b51ff0a696631b13f1a106cc3eafc87 Mon Sep 17 00:00:00 2001 From: David Goetz Date: Thu, 7 Feb 2013 11:11:32 -0800 Subject: [PATCH] Change the flag set to specify bulk delete and expand archives from a HTTP header to a query parameter. This is needed because query parameters show up in proxy logs and headers do not. With this change it will be easy to determine from any log line that gets created from the original request (of which there is currently none) that the request was a bulk action. Note: This is not backwards compatible with the previous method of setting a header. Because the bulk middleware has not been included in an openstack swift release this should be fine. Change-Id: I0297fa2de9e491bf0b8c430c0781e2e12316ed4b --- swift/common/middleware/bulk.py | 21 ++++++++++----------- test/unit/common/middleware/test_bulk.py | 19 +++++++++++-------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/swift/common/middleware/bulk.py b/swift/common/middleware/bulk.py index 875a4dd432..d5a9a2ab8a 100644 --- a/swift/common/middleware/bulk.py +++ b/swift/common/middleware/bulk.py @@ -49,12 +49,12 @@ class Bulk(object): Extract Archive: Expand tar files into a swift account. Request must be a PUT with the - header X-Extract-Archive specifying the format of archive file. Accepted - formats are tar, tar.gz, and tar.bz2. + query parameter ?extract-archive=format specifying the format of archive + file. Accepted formats are tar, tar.gz, and tar.bz2. For a PUT to the following url: - /v1/AUTH_Account/$UPLOAD_PATH + /v1/AUTH_Account/$UPLOAD_PATH?extract-archive=tar.gz UPLOAD_PATH is where the files will be expanded to. UPLOAD_PATH can be a container, a pseudo-directory within a container, or an empty string. The @@ -82,7 +82,7 @@ class Bulk(object): Bulk Delete: Will delete multiple objects from their account with a single request. - Responds to DELETE requests with a header 'X-Bulk-Delete: true'. + Responds to DELETE requests with query parameter ?bulk-delete set. The Content-Type should be set to text/plain. The body of the DELETE request will be a newline separated list of url encoded objects to delete. You can only delete 1000 (configurable) objects per request. The objects @@ -364,17 +364,16 @@ class Bulk(object): @wsgify def __call__(self, req): - extract_type = \ - req.headers.get('X-Extract-Archive', '').lower().strip('.') - if extract_type and req.method == 'PUT': - archive_type = {'tar': '', 'tar.gz': 'gz', - 'tar.bz2': 'bz2'}.get(extract_type) + extract_type = req.params.get('extract-archive') + if extract_type is not None and req.method == 'PUT': + archive_type = { + 'tar': '', 'tar.gz': 'gz', + 'tar.bz2': 'bz2'}.get(extract_type.lower().strip('.')) if archive_type is not None: return self.handle_extract(req, archive_type) else: return HTTPBadRequest("Unsupported archive format") - if (req.headers.get('X-Bulk-Delete', '').lower() in TRUE_VALUES and - req.method == 'DELETE'): + if 'bulk-delete' in req.params and req.method == 'DELETE': return self.handle_delete(req) return self.app diff --git a/test/unit/common/middleware/test_bulk.py b/test/unit/common/middleware/test_bulk.py index 1447f7b1fc..72cd224a2e 100644 --- a/test/unit/common/middleware/test_bulk.py +++ b/test/unit/common/middleware/test_bulk.py @@ -187,7 +187,7 @@ class TestUntar(unittest.TestCase): def fake_start_response(*args, **kwargs): pass - req = Request.blank('/tar_works/acc/cont/') + req = Request.blank('/tar_works/acc/cont/?extract-archive=tar.gz') req.environ['wsgi.input'] = open( os.path.join(self.testdir, 'tar_works.tar.gz')) self.bulk(req.environ, fake_start_response) @@ -196,14 +196,17 @@ class TestUntar(unittest.TestCase): self.app.calls = 0 req.environ['wsgi.input'] = open( os.path.join(self.testdir, 'tar_works.tar.gz')) - req.headers['x-extract-archive'] = 'tar.gz' req.headers['transfer-encoding'] = 'Chunked' req.method = 'PUT' self.bulk(req.environ, fake_start_response) self.assertEquals(self.app.calls, 7) self.app.calls = 0 - req.headers['x-extract-archive'] = 'bad' + req = Request.blank('/tar_works/acc/cont/?extract-archive=bad') + req.method = 'PUT' + req.headers['transfer-encoding'] = 'Chunked' + req.environ['wsgi.input'] = open( + os.path.join(self.testdir, 'tar_works.tar.gz')) t = self.bulk(req.environ, fake_start_response) self.assertEquals(t[0], "Unsupported archive format") @@ -213,9 +216,11 @@ class TestUntar(unittest.TestCase): tar.add(os.path.join(self.testdir, base_name)) tar.close() self.app.calls = 0 + req = Request.blank('/tar_works/acc/cont/?extract-archive=tar') + req.method = 'PUT' + req.headers['transfer-encoding'] = 'Chunked' req.environ['wsgi.input'] = open( os.path.join(self.testdir, 'tar_works.tar')) - req.headers['x-extract-archive'] = 'tar' t = self.bulk(req.environ, fake_start_response) self.assertEquals(self.app.calls, 7) @@ -434,9 +439,8 @@ class TestDelete(unittest.TestCase): def test_bulk_delete_call(self): def fake_start_response(*args, **kwargs): pass - req = Request.blank('/delete_works/AUTH_Acc') + req = Request.blank('/delete_works/AUTH_Acc?bulk-delete') req.method = 'DELETE' - req.headers['x-bulk-delete'] = 't' req.headers['Transfer-Encoding'] = 'chunked' req.environ['wsgi.input'] = StringIO('/c/f') self.bulk(req.environ, fake_start_response) @@ -488,9 +492,8 @@ class TestDelete(unittest.TestCase): def fake_start_response(*args, **kwargs): self.assertTrue(args[0].startswith('413')) - req = Request.blank('/delete_works/AUTH_Acc') + req = Request.blank('/delete_works/AUTH_Acc?bulk-delete') req.method = 'DELETE' - req.headers['x-bulk-delete'] = 't' data = '\n\n' * self.bulk.max_deletes_per_request req.environ['wsgi.input'] = StringIO(data) req.content_length = len(data)