s3api: Block ETag header from CompleteMultipartUpload requests
Change-Id: I7df13e670f702a2956a9c8057fcb971f4bfb7319 Closes-Bug: 1810397
This commit is contained in:
parent
32bf43990c
commit
c51db382cb
@ -73,7 +73,7 @@ from six.moves.urllib.parse import quote, urlparse
|
||||
from swift.common.middleware.s3api.controllers.base import Controller, \
|
||||
bucket_operation, object_operation, check_container_existence
|
||||
from swift.common.middleware.s3api.s3response import InvalidArgument, \
|
||||
ErrorResponse, MalformedXML, \
|
||||
ErrorResponse, MalformedXML, BadDigest, \
|
||||
InvalidPart, BucketAlreadyExists, EntityTooSmall, InvalidPartOrder, \
|
||||
InvalidRequest, HTTPOk, HTTPNoContent, NoSuchKey, NoSuchUpload, \
|
||||
NoSuchBucket, BucketAlreadyOwnedByYou
|
||||
@ -571,6 +571,15 @@ class UploadController(Controller):
|
||||
xml = req.xml(MAX_COMPLETE_UPLOAD_BODY_SIZE)
|
||||
if not xml:
|
||||
raise InvalidRequest(msg='You must specify at least one part')
|
||||
if 'content-md5' in req.headers:
|
||||
# If an MD5 was provided, we need to verify it.
|
||||
# Note that S3Request already took care of translating to ETag
|
||||
if req.headers['etag'] != md5(xml).hexdigest():
|
||||
raise BadDigest(content_md5=req.headers['content-md5'])
|
||||
# We're only interested in the body here, in the
|
||||
# multipart-upload controller -- *don't* let it get
|
||||
# plumbed down to the object-server
|
||||
del req.headers['etag']
|
||||
|
||||
complete_elem = fromstring(
|
||||
xml, 'CompleteMultipartUpload', self.logger)
|
||||
|
@ -114,6 +114,9 @@ class FakeSwift(object):
|
||||
if method == 'PUT' and obj:
|
||||
input = env['wsgi.input'].read()
|
||||
etag = md5(input).hexdigest()
|
||||
if env.get('HTTP_ETAG', etag) != etag:
|
||||
raise Exception('Client sent a bad ETag! Got %r, but '
|
||||
'md5(body) = %r' % (env['HTTP_ETAG'], etag))
|
||||
headers.setdefault('Etag', etag)
|
||||
headers.setdefault('Content-Length', len(input))
|
||||
|
||||
|
@ -667,10 +667,12 @@ class TestS3ApiMultiUpload(S3ApiTestCase):
|
||||
self.assertEqual(self._get_error_code(body), 'NoSuchBucket')
|
||||
|
||||
def test_object_multipart_upload_complete(self):
|
||||
content_md5 = base64.b64encode(hashlib.md5(xml).digest())
|
||||
req = Request.blank('/bucket/object?uploadId=X',
|
||||
environ={'REQUEST_METHOD': 'POST'},
|
||||
headers={'Authorization': 'AWS test:tester:hmac',
|
||||
'Date': self.get_date_header(), },
|
||||
'Date': self.get_date_header(),
|
||||
'Content-MD5': content_md5, },
|
||||
body=xml)
|
||||
status, headers, body = self.call_s3api(req)
|
||||
elem = fromstring(body, 'CompleteMultipartUploadResult')
|
||||
|
Loading…
Reference in New Issue
Block a user