s3api: Translate 503 to S3-style 503s

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

Change-Id: Iadb0a40092b8347eb5c04785cc14d1324cc9396f
(cherry picked from commit 7bb7da6d2d)
This commit is contained in:
Tim Burke 2019-08-06 11:11:52 -07:00
parent c04208ec1f
commit 12893195d3
3 changed files with 28 additions and 6 deletions

View File

@ -32,7 +32,8 @@ from swift.common.http import HTTP_OK, HTTP_CREATED, HTTP_ACCEPTED, \
HTTP_CONFLICT, HTTP_UNPROCESSABLE_ENTITY, HTTP_REQUEST_ENTITY_TOO_LARGE, \ HTTP_CONFLICT, HTTP_UNPROCESSABLE_ENTITY, HTTP_REQUEST_ENTITY_TOO_LARGE, \
HTTP_PARTIAL_CONTENT, HTTP_NOT_MODIFIED, HTTP_PRECONDITION_FAILED, \ HTTP_PARTIAL_CONTENT, HTTP_NOT_MODIFIED, HTTP_PRECONDITION_FAILED, \
HTTP_REQUESTED_RANGE_NOT_SATISFIABLE, HTTP_LENGTH_REQUIRED, \ 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.common.constraints import check_utf8
from swift.proxy.controllers.base import get_container_info, \ from swift.proxy.controllers.base import get_container_info, \
@ -51,7 +52,8 @@ from swift.common.middleware.s3api.s3response import AccessDenied, \
InternalError, NoSuchBucket, NoSuchKey, PreconditionFailed, InvalidRange, \ InternalError, NoSuchBucket, NoSuchKey, PreconditionFailed, InvalidRange, \
MissingContentLength, InvalidStorageClass, S3NotImplemented, InvalidURI, \ MissingContentLength, InvalidStorageClass, S3NotImplemented, InvalidURI, \
MalformedXML, InvalidRequest, RequestTimeout, InvalidBucketName, \ MalformedXML, InvalidRequest, RequestTimeout, InvalidBucketName, \
BadDigest, AuthorizationHeaderMalformed, AuthorizationQueryParametersError BadDigest, AuthorizationHeaderMalformed, \
AuthorizationQueryParametersError, ServiceUnavailable
from swift.common.middleware.s3api.exception import NotS3Request, \ from swift.common.middleware.s3api.exception import NotS3Request, \
BadSwiftRequest BadSwiftRequest
from swift.common.middleware.s3api.utils import utf8encode, \ from swift.common.middleware.s3api.utils import utf8encode, \
@ -1358,6 +1360,8 @@ class S3Request(swob.Request):
**self.signature_does_not_match_kwargs()) **self.signature_does_not_match_kwargs())
if status == HTTP_FORBIDDEN: if status == HTTP_FORBIDDEN:
raise AccessDenied() raise AccessDenied()
if status == HTTP_SERVICE_UNAVAILABLE:
raise ServiceUnavailable()
raise InternalError('unexpected status code %d' % status) raise InternalError('unexpected status code %d' % status)

View File

@ -78,6 +78,9 @@ class TestS3ApiBucket(S3ApiTestCase):
'HEAD', '/v1/AUTH_test/junk', swob.HTTPNoContent, {}, None) 'HEAD', '/v1/AUTH_test/junk', swob.HTTPNoContent, {}, None)
self.swift.register( self.swift.register(
'HEAD', '/v1/AUTH_test/nojunk', swob.HTTPNotFound, {}, None) 'HEAD', '/v1/AUTH_test/nojunk', swob.HTTPNotFound, {}, None)
self.swift.register(
'HEAD', '/v1/AUTH_test/unavailable', swob.HTTPServiceUnavailable,
{}, None)
self.swift.register( self.swift.register(
'GET', '/v1/AUTH_test/junk', swob.HTTPOk, 'GET', '/v1/AUTH_test/junk', swob.HTTPOk,
{'Content-Type': 'application/json'}, object_list) {'Content-Type': 'application/json'}, object_list)
@ -121,6 +124,15 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(status.split()[0], '404') self.assertEqual(status.split()[0], '404')
self.assertEqual(body, '') # sanity self.assertEqual(body, '') # 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): def test_bucket_HEAD_slash(self):
req = Request.blank('/junk/', req = Request.blank('/junk/',
environ={'REQUEST_METHOD': 'HEAD'}, environ={'REQUEST_METHOD': 'HEAD'},
@ -145,6 +157,9 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(code, 'AccessDenied') self.assertEqual(code, 'AccessDenied')
code = self._test_method_error('GET', '/bucket', swob.HTTPNotFound) code = self._test_method_error('GET', '/bucket', swob.HTTPNotFound)
self.assertEqual(code, 'NoSuchBucket') 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) code = self._test_method_error('GET', '/bucket', swob.HTTPServerError)
self.assertEqual(code, 'InternalError') self.assertEqual(code, 'InternalError')
@ -604,6 +619,9 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(code, 'BucketAlreadyExists') self.assertEqual(code, 'BucketAlreadyExists')
code = self._test_method_error('PUT', '/bucket', swob.HTTPServerError) code = self._test_method_error('PUT', '/bucket', swob.HTTPServerError)
self.assertEqual(code, 'InternalError') self.assertEqual(code, 'InternalError')
code = self._test_method_error(
'PUT', '/bucket', swob.HTTPServiceUnavailable)
self.assertEqual(code, 'ServiceUnavailable')
code = self._test_method_error( code = self._test_method_error(
'PUT', '/bucket+bucket', swob.HTTPCreated) 'PUT', '/bucket+bucket', swob.HTTPCreated)
self.assertEqual(code, 'InvalidBucketName') self.assertEqual(code, 'InvalidBucketName')

View File

@ -159,7 +159,7 @@ class TestS3ApiObj(S3ApiTestCase):
self.swift.register('HEAD', '/v1/AUTH_test/bucket/object', self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
swob.HTTPServiceUnavailable, {}, None) swob.HTTPServiceUnavailable, {}, None)
status, headers, body = self.call_s3api(req) status, headers, body = self.call_s3api(req)
self.assertEqual(status.split()[0], '500') self.assertEqual(status.split()[0], '503')
self.assertEqual(body, '') # sanity self.assertEqual(body, '') # sanity
def test_object_HEAD(self): def test_object_HEAD(self):
@ -279,7 +279,7 @@ class TestS3ApiObj(S3ApiTestCase):
self.assertEqual(code, 'PreconditionFailed') self.assertEqual(code, 'PreconditionFailed')
code = self._test_method_error('GET', '/bucket/object', code = self._test_method_error('GET', '/bucket/object',
swob.HTTPServiceUnavailable) swob.HTTPServiceUnavailable)
self.assertEqual(code, 'InternalError') self.assertEqual(code, 'ServiceUnavailable')
@s3acl @s3acl
def test_object_GET(self): def test_object_GET(self):
@ -396,7 +396,7 @@ class TestS3ApiObj(S3ApiTestCase):
self.assertEqual(code, 'InternalError') self.assertEqual(code, 'InternalError')
code = self._test_method_error('PUT', '/bucket/object', code = self._test_method_error('PUT', '/bucket/object',
swob.HTTPServiceUnavailable) swob.HTTPServiceUnavailable)
self.assertEqual(code, 'InternalError') self.assertEqual(code, 'ServiceUnavailable')
code = self._test_method_error('PUT', '/bucket/object', code = self._test_method_error('PUT', '/bucket/object',
swob.HTTPCreated, swob.HTTPCreated,
{'X-Amz-Copy-Source': ''}) {'X-Amz-Copy-Source': ''})
@ -956,7 +956,7 @@ class TestS3ApiObj(S3ApiTestCase):
self.assertEqual(code, 'InternalError') self.assertEqual(code, 'InternalError')
code = self._test_method_error('DELETE', '/bucket/object', code = self._test_method_error('DELETE', '/bucket/object',
swob.HTTPServiceUnavailable) swob.HTTPServiceUnavailable)
self.assertEqual(code, 'InternalError') self.assertEqual(code, 'ServiceUnavailable')
with patch( with patch(
'swift.common.middleware.s3api.s3request.get_container_info', 'swift.common.middleware.s3api.s3request.get_container_info',