diff --git a/swift3/request.py b/swift3/request.py index 758d8d5d..72216532 100644 --- a/swift3/request.py +++ b/swift3/request.py @@ -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 diff --git a/swift3/test/functional/conf/ceph-known-failures-keystone.yaml b/swift3/test/functional/conf/ceph-known-failures-keystone.yaml index 3f0627a0..5f62df1f 100644 --- a/swift3/test/functional/conf/ceph-known-failures-keystone.yaml +++ b/swift3/test/functional/conf/ceph-known-failures-keystone.yaml @@ -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} diff --git a/swift3/test/functional/conf/ceph-known-failures-tempauth.yaml b/swift3/test/functional/conf/ceph-known-failures-tempauth.yaml index b79525c8..897f9cfa 100644 --- a/swift3/test/functional/conf/ceph-known-failures-tempauth.yaml +++ b/swift3/test/functional/conf/ceph-known-failures-tempauth.yaml @@ -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} diff --git a/swift3/test/functional/test_multi_upload.py b/swift3/test/functional/test_multi_upload.py index 51a25e7e..09250ed6 100644 --- a/swift3/test/functional/test_multi_upload.py +++ b/swift3/test/functional/test_multi_upload.py @@ -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) diff --git a/swift3/test/functional/test_object.py b/swift3/test/functional/test_object.py index 636cc94a..04c39c5b 100644 --- a/swift3/test/functional/test_object.py +++ b/swift3/test/functional/test_object.py @@ -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): diff --git a/swift3/test/unit/__init__.py b/swift3/test/unit/__init__.py index 27697e46..9d352a5f 100644 --- a/swift3/test/unit/__init__.py +++ b/swift3/test/unit/__init__.py @@ -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', diff --git a/swift3/test/unit/test_s3_acl.py b/swift3/test/unit/test_s3_acl.py index 4c5c423b..b5fd25ca 100644 --- a/swift3/test/unit/test_s3_acl.py +++ b/swift3/test/unit/test_s3_acl.py @@ -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