diff --git a/swift/common/middleware/s3api/s3request.py b/swift/common/middleware/s3api/s3request.py index ed453fb55f..2d1f7f2871 100644 --- a/swift/common/middleware/s3api/s3request.py +++ b/swift/common/middleware/s3api/s3request.py @@ -55,7 +55,7 @@ from swift.common.middleware.s3api.s3response import AccessDenied, \ MissingContentLength, InvalidStorageClass, S3NotImplemented, InvalidURI, \ MalformedXML, InvalidRequest, RequestTimeout, InvalidBucketName, \ BadDigest, AuthorizationHeaderMalformed, SlowDown, \ - AuthorizationQueryParametersError, ServiceUnavailable + AuthorizationQueryParametersError, ServiceUnavailable, BrokenMPU from swift.common.middleware.s3api.exception import NotS3Request, \ BadSwiftRequest from swift.common.middleware.s3api.utils import utf8encode, \ @@ -1405,6 +1405,9 @@ class S3Request(swob.Request): if self.conf.ratelimit_as_client_error: raise SlowDown(status='429 Slow Down') raise SlowDown() + if resp.status_int == HTTP_CONFLICT: + # TODO: validate that this actually came up out of SLO + raise BrokenMPU() raise InternalError('unexpected status code %d' % status) diff --git a/swift/common/middleware/s3api/s3response.py b/swift/common/middleware/s3api/s3response.py index 3ba4018a65..e32793f0fa 100644 --- a/swift/common/middleware/s3api/s3response.py +++ b/swift/common/middleware/s3api/s3response.py @@ -731,3 +731,9 @@ class UserKeyMustBeSpecified(ErrorResponse): _status = '400 Bad Request' _msg = 'The bucket POST must contain the specified field name. If it is ' \ 'specified, please check the order of the fields.' + + +class BrokenMPU(ErrorResponse): + # This is very much a Swift-ism, and we wish we didn't need it + _status = '409 Conflict' + _msg = 'Multipart upload has broken segment data.' diff --git a/test/unit/common/middleware/s3api/test_obj.py b/test/unit/common/middleware/s3api/test_obj.py index 5acf191635..92e2482c16 100644 --- a/test/unit/common/middleware/s3api/test_obj.py +++ b/test/unit/common/middleware/s3api/test_obj.py @@ -307,6 +307,9 @@ class TestS3ApiObj(S3ApiTestCase): code = self._test_method_error('GET', '/bucket/object', swob.HTTPServiceUnavailable) self.assertEqual(code, 'ServiceUnavailable') + code = self._test_method_error('GET', '/bucket/object', + swob.HTTPConflict) + self.assertEqual(code, 'BrokenMPU') code = self._test_method_error( 'GET', '/bucket/object',