Skip to content

Commit

Permalink
Bugfix multipart uploader with flexible checksums (#2754)
Browse files Browse the repository at this point in the history
Enable use of flexible checksums on the multipart uploader and multipart copy
  • Loading branch information
SamRemis committed Aug 9, 2023
1 parent 2f7c7f7 commit 6ad549d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .changes/nextrelease/bugfix-flexible-checksums-multipart.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"type": "feature",
"category": "Multipart",
"description": "Include ChecksumAlgorithm member in Multipart Upload and Copy for flexible checksums"
}
]
12 changes: 8 additions & 4 deletions src/S3/MultipartUploadingTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,14 @@ public static function getStateFromService(

protected function handleResult(CommandInterface $command, ResultInterface $result)
{
$this->getState()->markPartAsUploaded($command['PartNumber'], [
'PartNumber' => $command['PartNumber'],
'ETag' => $this->extractETag($result),
]);
$partData = [];
$partData['PartNumber'] = $command['PartNumber'];
$partData['ETag'] = $this->extractETag($result);
if (isset($command['ChecksumAlgorithm'])) {
$checksumMemberName = 'Checksum' . strtoupper($command['ChecksumAlgorithm']);
$partData[$checksumMemberName] = $result[$checksumMemberName];
}
$this->getState()->markPartAsUploaded($command['PartNumber'], $partData);
}

abstract protected function extractETag(ResultInterface $result);
Expand Down
47 changes: 47 additions & 0 deletions tests/S3/MultipartUploaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,51 @@ public function testAppliesAmbiguousSuccessParsing()
);
$uploader->upload();
}

/**
* @dataProvider testMultipartSuccessStreams
*/
public function testUploaderAddsFlexibleChecksums($stream, $size)
{
/** @var \Aws\S3\S3Client $client */
$client = $this->getTestClient('s3');
$uploadOptions = [
'bucket' => 'foo',
'key' => 'bar',
'add_content_md5' => true,
'params' => [
'RequestPayer' => 'test',
'ChecksumAlgorithm' => 'Sha256'
],
'before_initiate' => function($command) {
$this->assertSame('test', $command['RequestPayer']);
$this->assertSame('Sha256', $command['ChecksumAlgorithm']);
},
'before_upload' => function($command) use ($size) {
$this->assertLessThan($size, $command['ContentLength']);
$this->assertSame('test', $command['RequestPayer']);
$this->assertSame('Sha256', $command['ChecksumAlgorithm']);
},
'before_complete' => function($command) {
$this->assertSame('test', $command['RequestPayer']);
$this->assertSame('Sha256', $command['ChecksumAlgorithm']);
}
];
$url = 'http://foo.s3.amazonaws.com/bar';

$this->addMockResults($client, [
new Result(['UploadId' => 'baz', 'ChecksumSHA256' => 'xyz']),
new Result(['ETag' => 'A', 'ChecksumSHA256' => 'xyz']),
new Result(['ETag' => 'B', 'ChecksumSHA256' => 'xyz']),
new Result(['ETag' => 'C', 'ChecksumSHA256' => 'xyz']),
new Result(['Location' => $url, 'ChecksumSHA256' => 'xyz'])
]);

$uploader = new MultipartUploader($client, $stream, $uploadOptions);
$result = $uploader->upload();

$this->assertTrue($uploader->getState()->isCompleted());
$this->assertSame('xyz', $result['ChecksumSHA256']);
$this->assertSame($url, $result['ObjectURL']);
}
}

0 comments on commit 6ad549d

Please sign in to comment.