Merge "Change the flag set to specify bulk delete and expand archives from a HTTP header to a query parameter."

This commit is contained in:
Jenkins 2013-02-08 18:18:29 +00:00 committed by Gerrit Code Review
commit 9de643e453
2 changed files with 21 additions and 19 deletions

View File

@ -49,12 +49,12 @@ class Bulk(object):
Extract Archive: Extract Archive:
Expand tar files into a swift account. Request must be a PUT with the 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 query parameter ?extract-archive=format specifying the format of archive
formats are tar, tar.gz, and tar.bz2. file. Accepted formats are tar, tar.gz, and tar.bz2.
For a PUT to the following url: 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 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 container, a pseudo-directory within a container, or an empty string. The
@ -82,7 +82,7 @@ class Bulk(object):
Bulk Delete: Bulk Delete:
Will delete multiple objects from their account with a single request. 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 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. request will be a newline separated list of url encoded objects to delete.
You can only delete 1000 (configurable) objects per request. The objects You can only delete 1000 (configurable) objects per request. The objects
@ -364,17 +364,16 @@ class Bulk(object):
@wsgify @wsgify
def __call__(self, req): def __call__(self, req):
extract_type = \ extract_type = req.params.get('extract-archive')
req.headers.get('X-Extract-Archive', '').lower().strip('.') if extract_type is not None and req.method == 'PUT':
if extract_type and req.method == 'PUT': archive_type = {
archive_type = {'tar': '', 'tar.gz': 'gz', 'tar': '', 'tar.gz': 'gz',
'tar.bz2': 'bz2'}.get(extract_type) 'tar.bz2': 'bz2'}.get(extract_type.lower().strip('.'))
if archive_type is not None: if archive_type is not None:
return self.handle_extract(req, archive_type) return self.handle_extract(req, archive_type)
else: else:
return HTTPBadRequest("Unsupported archive format") return HTTPBadRequest("Unsupported archive format")
if (req.headers.get('X-Bulk-Delete', '').lower() in TRUE_VALUES and if 'bulk-delete' in req.params and req.method == 'DELETE':
req.method == 'DELETE'):
return self.handle_delete(req) return self.handle_delete(req)
return self.app return self.app

View File

@ -187,7 +187,7 @@ class TestUntar(unittest.TestCase):
def fake_start_response(*args, **kwargs): def fake_start_response(*args, **kwargs):
pass pass
req = Request.blank('/tar_works/acc/cont/') req = Request.blank('/tar_works/acc/cont/?extract-archive=tar.gz')
req.environ['wsgi.input'] = open( req.environ['wsgi.input'] = open(
os.path.join(self.testdir, 'tar_works.tar.gz')) os.path.join(self.testdir, 'tar_works.tar.gz'))
self.bulk(req.environ, fake_start_response) self.bulk(req.environ, fake_start_response)
@ -196,14 +196,17 @@ class TestUntar(unittest.TestCase):
self.app.calls = 0 self.app.calls = 0
req.environ['wsgi.input'] = open( req.environ['wsgi.input'] = open(
os.path.join(self.testdir, 'tar_works.tar.gz')) os.path.join(self.testdir, 'tar_works.tar.gz'))
req.headers['x-extract-archive'] = 'tar.gz'
req.headers['transfer-encoding'] = 'Chunked' req.headers['transfer-encoding'] = 'Chunked'
req.method = 'PUT' req.method = 'PUT'
self.bulk(req.environ, fake_start_response) self.bulk(req.environ, fake_start_response)
self.assertEquals(self.app.calls, 7) self.assertEquals(self.app.calls, 7)
self.app.calls = 0 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) t = self.bulk(req.environ, fake_start_response)
self.assertEquals(t[0], "Unsupported archive format") 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.add(os.path.join(self.testdir, base_name))
tar.close() tar.close()
self.app.calls = 0 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( req.environ['wsgi.input'] = open(
os.path.join(self.testdir, 'tar_works.tar')) os.path.join(self.testdir, 'tar_works.tar'))
req.headers['x-extract-archive'] = 'tar'
t = self.bulk(req.environ, fake_start_response) t = self.bulk(req.environ, fake_start_response)
self.assertEquals(self.app.calls, 7) self.assertEquals(self.app.calls, 7)
@ -434,9 +439,8 @@ class TestDelete(unittest.TestCase):
def test_bulk_delete_call(self): def test_bulk_delete_call(self):
def fake_start_response(*args, **kwargs): def fake_start_response(*args, **kwargs):
pass pass
req = Request.blank('/delete_works/AUTH_Acc') req = Request.blank('/delete_works/AUTH_Acc?bulk-delete')
req.method = 'DELETE' req.method = 'DELETE'
req.headers['x-bulk-delete'] = 't'
req.headers['Transfer-Encoding'] = 'chunked' req.headers['Transfer-Encoding'] = 'chunked'
req.environ['wsgi.input'] = StringIO('/c/f') req.environ['wsgi.input'] = StringIO('/c/f')
self.bulk(req.environ, fake_start_response) self.bulk(req.environ, fake_start_response)
@ -488,9 +492,8 @@ class TestDelete(unittest.TestCase):
def fake_start_response(*args, **kwargs): def fake_start_response(*args, **kwargs):
self.assertTrue(args[0].startswith('413')) 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.method = 'DELETE'
req.headers['x-bulk-delete'] = 't'
data = '\n\n' * self.bulk.max_deletes_per_request data = '\n\n' * self.bulk.max_deletes_per_request
req.environ['wsgi.input'] = StringIO(data) req.environ['wsgi.input'] = StringIO(data)
req.content_length = len(data) req.content_length = len(data)