Differentiate between a missing bucket and a missing key

Note that we already have tests to verify the correct behavior for
multipart uploads in test_abort_multi_upload_error.

Related-Change: I6e154594dfda6c3065774c23b24f728625a842bc
Change-Id: If23ea4be53875cbe1db34f7f9b2baa4d3187f3a6
This commit is contained in:
Tim Burke 2016-12-15 23:46:26 +00:00
parent 1d8d305b57
commit 5e08e0be6f
7 changed files with 27 additions and 12 deletions

View File

@ -48,7 +48,7 @@ from swift3.response import AccessDenied, InvalidArgument, InvalidDigest, \
BadDigest, AuthorizationHeaderMalformed, AuthorizationQueryParametersError
from swift3.exception import NotS3Request, BadSwiftRequest
from swift3.utils import utf8encode, LOGGER, check_path_header, S3Timestamp, \
mktime
mktime, MULTIUPLOAD_SUFFIX
from swift3.cfg import CONF
from swift3.subresource import decode_acl, encode_acl
from swift3.utils import sysmeta_header, validate_bucket_name
@ -950,7 +950,7 @@ class Request(swob.Request):
return code_map[method]
def _swift_error_codes(self, method, container, obj):
def _swift_error_codes(self, method, container, obj, env, app):
"""
Returns a dict from expected Swift error codes to the corresponding S3
error responses.
@ -983,13 +983,25 @@ class Request(swob.Request):
}
else:
# Swift object access.
# 404s differ depending upon whether the bucket exists
# Note that base-container-existence checks happen elsewhere for
# multi-part uploads, and get_container_info should be pulling
# from the env cache
def not_found_handler():
if container.endswith(MULTIUPLOAD_SUFFIX) or \
is_success(get_container_info(
env, app, swift_source='S3').get('status')):
return NoSuchKey(obj)
return NoSuchBucket(container)
code_map = {
'HEAD': {
HTTP_NOT_FOUND: (NoSuchKey, obj),
HTTP_NOT_FOUND: not_found_handler,
HTTP_PRECONDITION_FAILED: PreconditionFailed,
},
'GET': {
HTTP_NOT_FOUND: (NoSuchKey, obj),
HTTP_NOT_FOUND: not_found_handler,
HTTP_PRECONDITION_FAILED: PreconditionFailed,
HTTP_REQUESTED_RANGE_NOT_SATISFIABLE: InvalidRange,
},
@ -1001,7 +1013,7 @@ class Request(swob.Request):
HTTP_REQUEST_TIMEOUT: RequestTimeout,
},
'POST': {
HTTP_NOT_FOUND: (NoSuchKey, obj),
HTTP_NOT_FOUND: not_found_handler,
HTTP_PRECONDITION_FAILED: PreconditionFailed,
},
'DELETE': {
@ -1050,7 +1062,8 @@ class Request(swob.Request):
self.user_id = self.access_key
success_codes = self._swift_success_codes(method, container, obj)
error_codes = self._swift_error_codes(method, container, obj)
error_codes = self._swift_error_codes(method, container, obj,
sw_req.environ, app)
if status in success_codes:
return resp

View File

@ -56,7 +56,6 @@ ceph_s3:
s3tests.functional.test_s3.test_object_acl_xml_readacp: {status: KNOWN}
s3tests.functional.test_s3.test_object_acl_xml_write: {status: KNOWN}
s3tests.functional.test_s3.test_object_acl_xml_writeacp: {status: KNOWN}
s3tests.functional.test_s3.test_object_copy_bucket_not_found: {status: KNOWN}
s3tests.functional.test_s3.test_object_copy_canned_acl: {status: KNOWN}
s3tests.functional.test_s3.test_object_copy_not_owned_object_bucket: {status: KNOWN}
s3tests.functional.test_s3.test_object_copy_replacing_metadata: {status: KNOWN}

View File

@ -24,7 +24,6 @@ ceph_s3:
s3tests.functional.test_s3.test_list_buckets_invalid_auth: {status: KNOWN}
s3tests.functional.test_s3.test_logging_toggle: {status: KNOWN}
s3tests.functional.test_s3.test_multipart_resend_first_finishes_last: {status: KNOWN}
s3tests.functional.test_s3.test_object_copy_bucket_not_found: {status: KNOWN}
s3tests.functional.test_s3.test_object_copy_canned_acl: {status: KNOWN}
s3tests.functional.test_s3.test_object_copy_replacing_metadata: {status: KNOWN}
s3tests.functional.test_s3.test_object_header_acl_grants: {status: KNOWN}

View File

@ -445,6 +445,10 @@ class TestSwift3MultiUpload(Swift3FunctionalTestCase):
self.conn.make_request('DELETE', 'nothing', key, query=query)
self.assertEqual(get_error_code(body), 'NoSuchBucket')
status, headers, body = \
self.conn.make_request('DELETE', bucket, 'nothing', query=query)
self.assertEqual(get_error_code(body), 'NoSuchUpload')
query = 'uploadId=%s' % 'nothing'
status, headers, body = \
self.conn.make_request('DELETE', bucket, key, query=query)

View File

@ -194,9 +194,7 @@ class TestSwift3Object(Swift3FunctionalTestCase):
self.assertEqual(headers['content-type'], 'application/xml')
status, headers, body = self.conn.make_request('GET', 'invalid', obj)
# TODO; requires consideration
# self.assertEqual(get_error_code(body), 'NoSuchBucket')
self.assertEqual(get_error_code(body), 'NoSuchKey')
self.assertEqual(get_error_code(body), 'NoSuchBucket')
self.assertEqual(headers['content-type'], 'application/xml')
def test_head_object_error(self):

View File

@ -63,6 +63,8 @@ class Swift3TestCase(unittest.TestCase):
self.swift = self.app.swift
self.swift3 = Swift3Middleware(self.app, CONF)
self.swift.register('HEAD', '/v1/AUTH_test',
swob.HTTPOk, {}, None)
self.swift.register('HEAD', '/v1/AUTH_test/bucket',
swob.HTTPNoContent, {}, None)
self.swift.register('PUT', '/v1/AUTH_test/bucket',

View File

@ -57,7 +57,7 @@ def s3acl(func=None, s3acl_only=False):
# def test_xxxx(self)
with patch('swift3.request.get_container_info',
lambda x, y: {'status': 204}):
return_value={'status': 204}):
func(*args, **kwargs)
except AssertionError:
# Make traceback message to clarify the assertion