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)