From 7bb7da6d2dc4267f8279170b6d326e81777d3c06 Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Tue, 6 Aug 2019 11:11:52 -0700 Subject: [PATCH] s3api: Translate 503 to S3-style 503s ...instead of logging tracebacks about unexpected status codes. Change-Id: Iadb0a40092b8347eb5c04785cc14d1324cc9396f --- swift/common/middleware/s3api/s3request.py | 8 ++++++-- .../common/middleware/s3api/test_bucket.py | 19 +++++++++++++++++-- test/unit/common/middleware/s3api/test_obj.py | 8 ++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/swift/common/middleware/s3api/s3request.py b/swift/common/middleware/s3api/s3request.py index 1caca1f34b..3c9542eb93 100644 --- a/swift/common/middleware/s3api/s3request.py +++ b/swift/common/middleware/s3api/s3request.py @@ -33,7 +33,8 @@ from swift.common.http import HTTP_OK, HTTP_CREATED, HTTP_ACCEPTED, \ HTTP_CONFLICT, HTTP_UNPROCESSABLE_ENTITY, HTTP_REQUEST_ENTITY_TOO_LARGE, \ HTTP_PARTIAL_CONTENT, HTTP_NOT_MODIFIED, HTTP_PRECONDITION_FAILED, \ HTTP_REQUESTED_RANGE_NOT_SATISFIABLE, HTTP_LENGTH_REQUIRED, \ - HTTP_BAD_REQUEST, HTTP_REQUEST_TIMEOUT, is_success + HTTP_BAD_REQUEST, HTTP_REQUEST_TIMEOUT, HTTP_SERVICE_UNAVAILABLE, \ + is_success from swift.common.constraints import check_utf8 from swift.proxy.controllers.base import get_container_info, \ @@ -52,7 +53,8 @@ from swift.common.middleware.s3api.s3response import AccessDenied, \ InternalError, NoSuchBucket, NoSuchKey, PreconditionFailed, InvalidRange, \ MissingContentLength, InvalidStorageClass, S3NotImplemented, InvalidURI, \ MalformedXML, InvalidRequest, RequestTimeout, InvalidBucketName, \ - BadDigest, AuthorizationHeaderMalformed, AuthorizationQueryParametersError + BadDigest, AuthorizationHeaderMalformed, \ + AuthorizationQueryParametersError, ServiceUnavailable from swift.common.middleware.s3api.exception import NotS3Request, \ BadSwiftRequest from swift.common.middleware.s3api.utils import utf8encode, \ @@ -1369,6 +1371,8 @@ class S3Request(swob.Request): **self.signature_does_not_match_kwargs()) if status == HTTP_FORBIDDEN: raise AccessDenied() + if status == HTTP_SERVICE_UNAVAILABLE: + raise ServiceUnavailable() raise InternalError('unexpected status code %d' % status) diff --git a/test/unit/common/middleware/s3api/test_bucket.py b/test/unit/common/middleware/s3api/test_bucket.py index e8d7314912..f021368740 100644 --- a/test/unit/common/middleware/s3api/test_bucket.py +++ b/test/unit/common/middleware/s3api/test_bucket.py @@ -84,6 +84,9 @@ class TestS3ApiBucket(S3ApiTestCase): 'HEAD', '/v1/AUTH_test/junk', swob.HTTPNoContent, {}, None) self.swift.register( 'HEAD', '/v1/AUTH_test/nojunk', swob.HTTPNotFound, {}, None) + self.swift.register( + 'HEAD', '/v1/AUTH_test/unavailable', swob.HTTPServiceUnavailable, + {}, None) self.swift.register( 'GET', '/v1/AUTH_test/junk', swob.HTTPOk, {'Content-Type': 'application/json'}, object_list) @@ -127,6 +130,15 @@ class TestS3ApiBucket(S3ApiTestCase): self.assertEqual(status.split()[0], '404') self.assertEqual(body, b'') # sanity + def test_bucket_HEAD_503(self): + req = Request.blank('/unavailable', + environ={'REQUEST_METHOD': 'HEAD'}, + headers={'Authorization': 'AWS test:tester:hmac', + 'Date': self.get_date_header()}) + status, headers, body = self.call_s3api(req) + self.assertEqual(status.split()[0], '503') + self.assertEqual(body, b'') # sanity + def test_bucket_HEAD_slash(self): req = Request.blank('/junk/', environ={'REQUEST_METHOD': 'HEAD'}, @@ -151,6 +163,9 @@ class TestS3ApiBucket(S3ApiTestCase): self.assertEqual(code, 'AccessDenied') code = self._test_method_error('GET', '/bucket', swob.HTTPNotFound) self.assertEqual(code, 'NoSuchBucket') + code = self._test_method_error('GET', '/bucket', + swob.HTTPServiceUnavailable) + self.assertEqual(code, 'ServiceUnavailable') code = self._test_method_error('GET', '/bucket', swob.HTTPServerError) self.assertEqual(code, 'InternalError') @@ -621,7 +636,7 @@ class TestS3ApiBucket(S3ApiTestCase): self.assertEqual(code, 'InternalError') code = self._test_method_error( 'PUT', '/bucket', swob.HTTPServiceUnavailable) - self.assertEqual(code, 'InternalError') + self.assertEqual(code, 'ServiceUnavailable') code = self._test_method_error( 'PUT', '/bucket+bucket', swob.HTTPCreated) self.assertEqual(code, 'InvalidBucketName') @@ -673,7 +688,7 @@ class TestS3ApiBucket(S3ApiTestCase): headers={'Authorization': 'AWS test:tester:hmac', 'Date': self.get_date_header()}) status, headers, body = self.call_s3api(req) - self.assertEqual(status, '500 Internal Server Error') + self.assertEqual(status, '503 Service Unavailable') # The last call was PUT not POST for acl set self.assertEqual(self.swift.calls, [ ('PUT', '/v1/AUTH_test/bucket'), diff --git a/test/unit/common/middleware/s3api/test_obj.py b/test/unit/common/middleware/s3api/test_obj.py index 9ce62cfd4c..aab5a7af01 100644 --- a/test/unit/common/middleware/s3api/test_obj.py +++ b/test/unit/common/middleware/s3api/test_obj.py @@ -161,7 +161,7 @@ class TestS3ApiObj(S3ApiTestCase): self.swift.register('HEAD', '/v1/AUTH_test/bucket/object', swob.HTTPServiceUnavailable, {}, None) status, headers, body = self.call_s3api(req) - self.assertEqual(status.split()[0], '500') + self.assertEqual(status.split()[0], '503') self.assertEqual(body, b'') # sanity def test_object_HEAD(self): @@ -281,7 +281,7 @@ class TestS3ApiObj(S3ApiTestCase): self.assertEqual(code, 'PreconditionFailed') code = self._test_method_error('GET', '/bucket/object', swob.HTTPServiceUnavailable) - self.assertEqual(code, 'InternalError') + self.assertEqual(code, 'ServiceUnavailable') @s3acl def test_object_GET(self): @@ -398,7 +398,7 @@ class TestS3ApiObj(S3ApiTestCase): self.assertEqual(code, 'InternalError') code = self._test_method_error('PUT', '/bucket/object', swob.HTTPServiceUnavailable) - self.assertEqual(code, 'InternalError') + self.assertEqual(code, 'ServiceUnavailable') code = self._test_method_error('PUT', '/bucket/object', swob.HTTPCreated, {'X-Amz-Copy-Source': ''}) @@ -964,7 +964,7 @@ class TestS3ApiObj(S3ApiTestCase): self.assertEqual(code, 'InternalError') code = self._test_method_error('DELETE', '/bucket/object', swob.HTTPServiceUnavailable) - self.assertEqual(code, 'InternalError') + self.assertEqual(code, 'ServiceUnavailable') with patch( 'swift.common.middleware.s3api.s3request.get_container_info',