Merge "s3api: Better-handle SHA mismatches during CompleteMultipartUpload"
This commit is contained in:
commit
1cffbe5b8f
|
@ -448,8 +448,8 @@ class SigV4Mixin(object):
|
|||
'x-amz-content-sha256'
|
||||
raise InvalidRequest(msg)
|
||||
else:
|
||||
hashed_payload = self.headers['X-Amz-Content-SHA256']
|
||||
if hashed_payload != 'UNSIGNED-PAYLOAD':
|
||||
hashed_payload = self.headers['X-Amz-Content-SHA256'].lower()
|
||||
if hashed_payload != 'unsigned-payload':
|
||||
if self.content_length == 0:
|
||||
if hashed_payload != sha256().hexdigest():
|
||||
raise BadDigest(
|
||||
|
@ -853,7 +853,15 @@ class S3Request(swob.Request):
|
|||
|
||||
if te or ml:
|
||||
# Limit the read similar to how SLO handles manifests
|
||||
body = self.body_file.read(max_length)
|
||||
try:
|
||||
body = self.body_file.read(max_length)
|
||||
except swob.HTTPException as err:
|
||||
if err.status_int == HTTP_UNPROCESSABLE_ENTITY:
|
||||
# Special case for HashingInput check
|
||||
raise BadDigest(
|
||||
'The X-Amz-Content-SHA56 you specified did not '
|
||||
'match what we received.')
|
||||
raise
|
||||
else:
|
||||
# No (or zero) Content-Length provided, and not chunked transfer;
|
||||
# no body. Assume zero-length, and enforce a required body below.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
import base64
|
||||
import binascii
|
||||
import hashlib
|
||||
from mock import patch
|
||||
import os
|
||||
import time
|
||||
|
@ -1059,6 +1060,45 @@ class TestS3ApiMultiUpload(S3ApiTestCase):
|
|||
self.assertEqual('400 Bad Request', status)
|
||||
self.assertEqual(self._get_error_code(body), 'BadDigest')
|
||||
|
||||
def test_object_multipart_upload_invalid_sha256(self):
|
||||
bad_sha = hashlib.sha256(
|
||||
XML.encode('ascii') + b'some junk').hexdigest()
|
||||
authz_header = 'AWS4-HMAC-SHA256 ' + ', '.join([
|
||||
'Credential=test:tester/%s/us-east-1/s3/aws4_request' %
|
||||
self.get_v4_amz_date_header().split('T', 1)[0],
|
||||
'SignedHeaders=host;x-amz-date',
|
||||
'Signature=X',
|
||||
])
|
||||
req = Request.blank(
|
||||
'/bucket/object?uploadId=X',
|
||||
environ={'REQUEST_METHOD': 'POST'},
|
||||
headers={'Authorization': authz_header,
|
||||
'X-Amz-Date': self.get_v4_amz_date_header(),
|
||||
'X-Amz-Content-SHA256': bad_sha, },
|
||||
body=XML)
|
||||
status, headers, body = self.call_s3api(req)
|
||||
self.assertEqual('400 Bad Request', status)
|
||||
self.assertEqual(self._get_error_code(body), 'BadDigest')
|
||||
|
||||
def test_object_multipart_upload_upper_sha256(self):
|
||||
upper_sha = hashlib.sha256(
|
||||
XML.encode('ascii')).hexdigest().upper()
|
||||
authz_header = 'AWS4-HMAC-SHA256 ' + ', '.join([
|
||||
'Credential=test:tester/%s/us-east-1/s3/aws4_request' %
|
||||
self.get_v4_amz_date_header().split('T', 1)[0],
|
||||
'SignedHeaders=host;x-amz-date',
|
||||
'Signature=X',
|
||||
])
|
||||
req = Request.blank(
|
||||
'/bucket/object?uploadId=X',
|
||||
environ={'REQUEST_METHOD': 'POST'},
|
||||
headers={'Authorization': authz_header,
|
||||
'X-Amz-Date': self.get_v4_amz_date_header(),
|
||||
'X-Amz-Content-SHA256': upper_sha, },
|
||||
body=XML)
|
||||
status, headers, body = self.call_s3api(req)
|
||||
self.assertEqual('200 OK', status)
|
||||
|
||||
@patch('swift.common.middleware.s3api.controllers.multi_upload.time')
|
||||
def test_object_multipart_upload_complete_with_heartbeat(self, mock_time):
|
||||
self.swift.register(
|
||||
|
|
Loading…
Reference in New Issue