Fix the deletion of non-existent keys
On vanilla Swift, deleting an object that doesn't exist will 404. On AWS, deleting a key that doesn't exist will either 404 if the bucket doesn't exist (with a NoSuchBucket code) or 204 (because yep, that's not accessible). Change-Id: Ied2a78b56522316bb374f23961621641af3adc83 Related-Change: I6e154594dfda6c3065774c23b24f728625a842bc
This commit is contained in:
parent
53f9fd2b61
commit
bd640cdbae
@ -20,7 +20,7 @@ from swift.common.utils import public
|
||||
from swift.common.middleware.s3api.utils import S3Timestamp
|
||||
from swift.common.middleware.s3api.controllers.base import Controller
|
||||
from swift.common.middleware.s3api.s3response import S3NotImplemented, \
|
||||
InvalidRange, NoSuchKey, InvalidArgument
|
||||
InvalidRange, NoSuchKey, InvalidArgument, HTTPNoContent
|
||||
|
||||
|
||||
class ObjectController(Controller):
|
||||
@ -143,5 +143,6 @@ class ObjectController(Controller):
|
||||
except NoSuchKey:
|
||||
# expect to raise NoSuchBucket when the bucket doesn't exist
|
||||
req.get_container_info(self.app)
|
||||
raise
|
||||
# else -- it's gone! Success.
|
||||
return HTTPNoContent()
|
||||
return resp
|
||||
|
@ -139,6 +139,12 @@ class TestS3ApiObject(S3ApiBase):
|
||||
self.assertEqual(status, 204)
|
||||
self.assertCommonResponseHeaders(headers)
|
||||
|
||||
# DELETE Non-Existent Object
|
||||
status, headers, body = \
|
||||
self.conn.make_request('DELETE', self.bucket, 'does-not-exist')
|
||||
self.assertEqual(status, 204)
|
||||
self.assertCommonResponseHeaders(headers)
|
||||
|
||||
def test_put_object_error(self):
|
||||
auth_error_conn = Connection(aws_secret_key='invalid')
|
||||
status, headers, body = \
|
||||
@ -238,11 +244,6 @@ class TestS3ApiObject(S3ApiBase):
|
||||
self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch')
|
||||
self.assertEqual(headers['content-type'], 'application/xml')
|
||||
|
||||
status, headers, body = \
|
||||
self.conn.make_request('DELETE', self.bucket, 'invalid')
|
||||
self.assertEqual(get_error_code(body), 'NoSuchKey')
|
||||
self.assertEqual(headers['content-type'], 'application/xml')
|
||||
|
||||
status, headers, body = \
|
||||
self.conn.make_request('DELETE', 'invalid', obj)
|
||||
self.assertEqual(get_error_code(body), 'NoSuchBucket')
|
||||
|
@ -17,7 +17,6 @@ import unittest
|
||||
from datetime import datetime
|
||||
from hashlib import md5
|
||||
|
||||
from six.moves import urllib
|
||||
from swift.common import swob
|
||||
from swift.common.swob import Request
|
||||
|
||||
@ -87,11 +86,14 @@ class TestS3ApiMultiDelete(S3ApiTestCase):
|
||||
|
||||
elem = fromstring(body)
|
||||
self.assertEqual(len(elem.findall('Deleted')), 3)
|
||||
_, path, _ = self.swift.calls_with_headers[-1]
|
||||
path, query_string = path.split('?', 1)
|
||||
self.assertEqual(path, '/v1/AUTH_test/bucket/Key3')
|
||||
query = dict(urllib.parse.parse_qsl(query_string))
|
||||
self.assertEqual(query['multipart-manifest'], 'delete')
|
||||
self.assertEqual(self.swift.calls, [
|
||||
('HEAD', '/v1/AUTH_test/bucket'),
|
||||
('HEAD', '/v1/AUTH_test/bucket/Key1'),
|
||||
('DELETE', '/v1/AUTH_test/bucket/Key1'),
|
||||
('HEAD', '/v1/AUTH_test/bucket/Key2'),
|
||||
('HEAD', '/v1/AUTH_test/bucket/Key3'),
|
||||
('DELETE', '/v1/AUTH_test/bucket/Key3?multipart-manifest=delete'),
|
||||
])
|
||||
|
||||
@s3acl
|
||||
def test_object_multi_DELETE_quiet(self):
|
||||
|
@ -767,13 +767,6 @@ class TestS3ApiObj(S3ApiTestCase):
|
||||
swob.HTTPServiceUnavailable)
|
||||
self.assertEqual(code, 'InternalError')
|
||||
|
||||
with patch(
|
||||
'swift.common.middleware.s3api.s3request.get_container_info',
|
||||
return_value={'status': 204}):
|
||||
code = self._test_method_error('DELETE', '/bucket/object',
|
||||
swob.HTTPNotFound)
|
||||
self.assertEqual(code, 'NoSuchKey')
|
||||
|
||||
with patch(
|
||||
'swift.common.middleware.s3api.s3request.get_container_info',
|
||||
return_value={'status': 404}):
|
||||
@ -809,11 +802,27 @@ class TestS3ApiObj(S3ApiTestCase):
|
||||
|
||||
self.assertIn(('HEAD', '/v1/AUTH_test/bucket/object'),
|
||||
self.swift.calls)
|
||||
self.assertIn(('DELETE', '/v1/AUTH_test/bucket/object'),
|
||||
self.swift.calls)
|
||||
self.assertEqual(('DELETE', '/v1/AUTH_test/bucket/object'),
|
||||
self.swift.calls[-1])
|
||||
_, path = self.swift.calls[-1]
|
||||
self.assertEqual(path.count('?'), 0)
|
||||
|
||||
@s3acl
|
||||
def test_object_DELETE_missing(self):
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
|
||||
swob.HTTPNotFound, {}, None)
|
||||
req = Request.blank('/bucket/object',
|
||||
environ={'REQUEST_METHOD': 'DELETE'},
|
||||
headers={'Authorization': 'AWS test:tester:hmac',
|
||||
'Date': self.get_date_header()})
|
||||
status, headers, body = self.call_s3api(req)
|
||||
self.assertEqual(status.split()[0], '204')
|
||||
|
||||
self.assertIn(('HEAD', '/v1/AUTH_test/bucket/object'),
|
||||
self.swift.calls)
|
||||
self.assertNotIn(('DELETE', '/v1/AUTH_test/bucket/object'),
|
||||
self.swift.calls)
|
||||
|
||||
@s3acl
|
||||
def test_slo_object_DELETE(self):
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
|
||||
|
Loading…
Reference in New Issue
Block a user