s3api: Translate 503 to S3-style 503s

...instead of logging tracebacks about unexpected status codes.

Change-Id: Iadb0a40092b8347eb5c04785cc14d1324cc9396f
This commit is contained in:
Tim Burke 2019-08-06 11:11:52 -07:00
parent 489a35db82
commit 7bb7da6d2d
3 changed files with 27 additions and 8 deletions

View File

@ -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)

View File

@ -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'),

View File

@ -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',