From 8bec661288b276c98bdb0e773e5f4d5275dc4c87 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Fri, 20 Oct 2023 16:44:35 +0300 Subject: update AWK SDK --- .../aws-sdk-php/src/S3/ApplyChecksumMiddleware.php | 13 +++- vendor/aws/aws-sdk-php/src/S3/BatchDelete.php | 2 +- .../src/S3/BucketEndpointMiddleware.php | 44 +++++++++++--- .../aws-sdk-php/src/S3/CalculatesChecksumTrait.php | 5 +- vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php | 28 ++++----- .../aws/aws-sdk-php/src/S3/MultipartUploader.php | 7 +++ .../aws-sdk-php/src/S3/MultipartUploadingTrait.php | 12 ++-- vendor/aws/aws-sdk-php/src/S3/ObjectCopier.php | 9 ++- vendor/aws/aws-sdk-php/src/S3/ObjectUploader.php | 7 ++- vendor/aws/aws-sdk-php/src/S3/S3Client.php | 70 ++++++++++++++++++---- .../aws/aws-sdk-php/src/S3/S3ClientInterface.php | 4 +- vendor/aws/aws-sdk-php/src/S3/StreamWrapper.php | 1 + vendor/aws/aws-sdk-php/src/S3/Transfer.php | 9 ++- 13 files changed, 161 insertions(+), 50 deletions(-) (limited to 'vendor/aws/aws-sdk-php/src/S3') diff --git a/vendor/aws/aws-sdk-php/src/S3/ApplyChecksumMiddleware.php b/vendor/aws/aws-sdk-php/src/S3/ApplyChecksumMiddleware.php index 9279d22..1cca0ad 100644 --- a/vendor/aws/aws-sdk-php/src/S3/ApplyChecksumMiddleware.php +++ b/vendor/aws/aws-sdk-php/src/S3/ApplyChecksumMiddleware.php @@ -17,7 +17,7 @@ use Psr\Http\Message\RequestInterface; class ApplyChecksumMiddleware { use CalculatesChecksumTrait; - private static $sha256 = [ + private static $sha256AndMd5 = [ 'PutObject', 'UploadPart', ]; @@ -54,6 +54,11 @@ class ApplyChecksumMiddleware $name = $command->getName(); $body = $request->getBody(); + //Checks if AddContentMD5 has been specified for PutObject or UploadPart + $addContentMD5 = isset($command['AddContentMD5']) + ? $command['AddContentMD5'] + : null; + $op = $this->api->getOperation($command->getName()); $checksumInfo = isset($op['httpChecksum']) @@ -94,7 +99,9 @@ class ApplyChecksumMiddleware $checksumRequired = isset($checksumInfo['requestChecksumRequired']) ? $checksumInfo['requestChecksumRequired'] : null; - if (!empty($checksumRequired) && !$request->hasHeader('Content-MD5')) { + if ((!empty($checksumRequired) && !$request->hasHeader('Content-MD5')) + || (in_array($name, self::$sha256AndMd5) && $addContentMD5) + ) { // Set the content MD5 header for operations that require it. $request = $request->withHeader( 'Content-MD5', @@ -104,7 +111,7 @@ class ApplyChecksumMiddleware } } - if (in_array($name, self::$sha256) && $command['ContentSHA256']) { + if (in_array($name, self::$sha256AndMd5) && $command['ContentSHA256']) { // Set the content hash header if provided in the parameters. $request = $request->withHeader( 'X-Amz-Content-Sha256', diff --git a/vendor/aws/aws-sdk-php/src/S3/BatchDelete.php b/vendor/aws/aws-sdk-php/src/S3/BatchDelete.php index 9243911..db81beb 100644 --- a/vendor/aws/aws-sdk-php/src/S3/BatchDelete.php +++ b/vendor/aws/aws-sdk-php/src/S3/BatchDelete.php @@ -115,7 +115,7 @@ class BatchDelete implements PromisorInterface /** * @return PromiseInterface */ - public function promise() + public function promise(): PromiseInterface { if (!$this->cachedPromise) { $this->cachedPromise = $this->createPromise(); diff --git a/vendor/aws/aws-sdk-php/src/S3/BucketEndpointMiddleware.php b/vendor/aws/aws-sdk-php/src/S3/BucketEndpointMiddleware.php index 19cb969..1a915ca 100644 --- a/vendor/aws/aws-sdk-php/src/S3/BucketEndpointMiddleware.php +++ b/vendor/aws/aws-sdk-php/src/S3/BucketEndpointMiddleware.php @@ -46,12 +46,23 @@ class BucketEndpointMiddleware return $nextHandler($command, $request); } - private function removeBucketFromPath($path, $bucket) + /** + * Performs a one-time removal of Bucket from path, then if + * the bucket name is duplicated in the path, performs additional + * removal which is dependent on the number of occurrences of the bucket + * name in a path-like format in the key name. + * + * @return string + */ + private function removeBucketFromPath($path, $bucket, $key) { - $len = strlen($bucket) + 1; - if (substr($path, 0, $len) === "/{$bucket}") { - $path = substr($path, $len); - } + $occurrencesInKey = $this->getBucketNameOccurrencesInKey($key, $bucket); + do { + $len = strlen($bucket) + 1; + if (substr($path, 0, $len) === "/{$bucket}") { + $path = substr($path, $len); + } + } while (substr_count($path, "/{$bucket}") > $occurrencesInKey + 1); return $path ?: '/'; } @@ -68,25 +79,42 @@ class BucketEndpointMiddleware return $host; } + private function getBucketNameOccurrencesInKey($key, $bucket) + { + $occurrences = 0; + if (empty($key)) { + return $occurrences; + } + + $segments = explode('/', $key); + foreach($segments as $segment) { + if (strpos($segment, $bucket) === 0) { + $occurrences++; + } + } + return $occurrences; + } + private function modifyRequest( RequestInterface $request, CommandInterface $command ) { + $key = isset($command['Key']) ? $command['Key'] : null; $uri = $request->getUri(); $path = $uri->getPath(); $host = $uri->getHost(); $bucket = $command['Bucket']; - $path = $this->removeBucketFromPath($path, $bucket); + $path = $this->removeBucketFromPath($path, $bucket, $key); $host = $this->removeDuplicateBucketFromHost($host, $bucket); // Modify the Key to make sure the key is encoded, but slashes are not. - if ($command['Key']) { + if ($key) { $path = S3Client::encodeKey(rawurldecode($path)); } return $request->withUri( $uri->withHost($host) - ->withPath($path) + ->withPath($path) ); } } diff --git a/vendor/aws/aws-sdk-php/src/S3/CalculatesChecksumTrait.php b/vendor/aws/aws-sdk-php/src/S3/CalculatesChecksumTrait.php index a8f5884..3d0179e 100644 --- a/vendor/aws/aws-sdk-php/src/S3/CalculatesChecksumTrait.php +++ b/vendor/aws/aws-sdk-php/src/S3/CalculatesChecksumTrait.php @@ -17,11 +17,12 @@ trait CalculatesChecksumTrait $requestedAlgorithm = strtolower($requestedAlgorithm); $useCrt = extension_loaded('awscrt'); if ($useCrt) { + $crt = new Crt(); switch ($requestedAlgorithm) { case 'crc32c': - return CRT::crc32c($value); + return base64_encode(pack('N*',($crt->crc32c($value)))); case 'crc32': - return CRT::crc32($value); + return base64_encode(pack('N*',($crt->crc32($value)))); case 'sha256': case 'sha1': return base64_encode(Psr7\Utils::hash($value, $requestedAlgorithm, true)); diff --git a/vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php b/vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php index e78a824..5b26dea 100644 --- a/vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php +++ b/vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php @@ -70,6 +70,7 @@ class MultipartCopy extends AbstractUploadManager } else { $this->source = $this->getInputSource($source); } + parent::__construct( $client, array_change_key_case($config) + ['source_metadata' => null] @@ -134,18 +135,21 @@ class MultipartCopy extends AbstractUploadManager // if the key contains a '?' character to specify where the query parameters start if (is_array($this->source)) { $key = str_replace('%2F', '/', rawurlencode($this->source['source_key'])); - $data['CopySource'] = '/' . $this->source['source_bucket'] . '/' . $key; + $bucket = $this->source['source_bucket']; } else { - list($bucket, $key) = explode('/', ltrim($this->source, '/'), 2); - $data['CopySource'] = '/' . $bucket . '/' . implode( - '/', - array_map( - 'urlencode', - explode('/', rawurldecode($key)) - ) - ); + $key = implode( + '/', + array_map( + 'urlencode', + explode('/', rawurldecode($key)) + ) + ); } + + $uri = ArnParser::isArn($bucket) ? '' : '/'; + $uri .= $bucket . '/' . $key; + $data['CopySource'] = $uri; $data['PartNumber'] = $partNumber; if (!empty($this->sourceVersionId)) { $data['CopySource'] .= "?versionId=" . $this->sourceVersionId; @@ -230,11 +234,7 @@ class MultipartCopy extends AbstractUploadManager */ private function getInputSource($inputSource) { - if (ArnParser::isArn($inputSource)) { - $sourceBuilder = ''; - } else { - $sourceBuilder = "/"; - } + $sourceBuilder = ArnParser::isArn($inputSource) ? '' : '/'; $sourceBuilder .= ltrim(rawurldecode($inputSource), '/'); return $sourceBuilder; } diff --git a/vendor/aws/aws-sdk-php/src/S3/MultipartUploader.php b/vendor/aws/aws-sdk-php/src/S3/MultipartUploader.php index 9235ee9..ae47d7e 100644 --- a/vendor/aws/aws-sdk-php/src/S3/MultipartUploader.php +++ b/vendor/aws/aws-sdk-php/src/S3/MultipartUploader.php @@ -126,6 +126,13 @@ class MultipartUploader extends AbstractUploader $body->seek(0); $data['Body'] = $body; + + if (isset($config['add_content_md5']) + && $config['add_content_md5'] === true + ) { + $data['AddContentMD5'] = true; + } + $data['ContentLength'] = $contentLength; return $data; diff --git a/vendor/aws/aws-sdk-php/src/S3/MultipartUploadingTrait.php b/vendor/aws/aws-sdk-php/src/S3/MultipartUploadingTrait.php index baccf58..002bd43 100644 --- a/vendor/aws/aws-sdk-php/src/S3/MultipartUploadingTrait.php +++ b/vendor/aws/aws-sdk-php/src/S3/MultipartUploadingTrait.php @@ -51,10 +51,14 @@ trait MultipartUploadingTrait 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); diff --git a/vendor/aws/aws-sdk-php/src/S3/ObjectCopier.php b/vendor/aws/aws-sdk-php/src/S3/ObjectCopier.php index 79493df..66e4446 100644 --- a/vendor/aws/aws-sdk-php/src/S3/ObjectCopier.php +++ b/vendor/aws/aws-sdk-php/src/S3/ObjectCopier.php @@ -7,6 +7,7 @@ use Aws\Exception\MultipartUploadException; use Aws\Result; use Aws\S3\Exception\S3Exception; use GuzzleHttp\Promise\Coroutine; +use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Promise\PromisorInterface; use InvalidArgumentException; @@ -79,7 +80,7 @@ class ObjectCopier implements PromisorInterface * * @return Coroutine */ - public function promise() + public function promise(): PromiseInterface { return Coroutine::of(function () { $headObjectCommand = $this->client->getCommand( @@ -144,20 +145,22 @@ class ObjectCopier implements PromisorInterface private function getSourcePath() { + $path = "/{$this->source['Bucket']}/"; if (ArnParser::isArn($this->source['Bucket'])) { try { new AccessPointArn($this->source['Bucket']); + $path = "{$this->source['Bucket']}/object/"; } catch (\Exception $e) { throw new \InvalidArgumentException( 'Provided ARN was a not a valid S3 access point ARN (' - . $e->getMessage() . ')', + . $e->getMessage() . ')', 0, $e ); } } - $sourcePath = "/{$this->source['Bucket']}/" . rawurlencode($this->source['Key']); + $sourcePath = $path . rawurlencode($this->source['Key']); if (isset($this->source['VersionId'])) { $sourcePath .= "?versionId={$this->source['VersionId']}"; } diff --git a/vendor/aws/aws-sdk-php/src/S3/ObjectUploader.php b/vendor/aws/aws-sdk-php/src/S3/ObjectUploader.php index 5a9ebe8..b73b7b1 100644 --- a/vendor/aws/aws-sdk-php/src/S3/ObjectUploader.php +++ b/vendor/aws/aws-sdk-php/src/S3/ObjectUploader.php @@ -27,6 +27,7 @@ class ObjectUploader implements PromisorInterface 'params' => [], 'part_size' => null, ]; + private $addContentMD5; /** * @param S3ClientInterface $client The S3 Client used to execute @@ -59,12 +60,15 @@ class ObjectUploader implements PromisorInterface $this->body = Psr7\Utils::streamFor($body); $this->acl = $acl; $this->options = $options + self::$defaults; + // Handle "add_content_md5" option. + $this->addContentMD5 = isset($options['add_content_md5']) + && $options['add_content_md5'] === true; } /** * @return PromiseInterface */ - public function promise() + public function promise(): PromiseInterface { /** @var int $mup_threshold */ $mup_threshold = $this->options['mup_threshold']; @@ -83,6 +87,7 @@ class ObjectUploader implements PromisorInterface 'Key' => $this->key, 'Body' => $this->body, 'ACL' => $this->acl, + 'AddContentMD5' => $this->addContentMD5 ] + $this->options['params']); if (is_callable($this->options['before_upload'])) { $this->options['before_upload']($command); diff --git a/vendor/aws/aws-sdk-php/src/S3/S3Client.php b/vendor/aws/aws-sdk-php/src/S3/S3Client.php index 00173f7..b82bbc5 100644 --- a/vendor/aws/aws-sdk-php/src/S3/S3Client.php +++ b/vendor/aws/aws-sdk-php/src/S3/S3Client.php @@ -301,7 +301,9 @@ class S3Client extends AwsClient implements S3ClientInterface * - bucket_endpoint: (bool) Set to true to send requests to a * hardcoded bucket endpoint rather than create an endpoint as a result * of injecting the bucket into the URL. This option is useful for - * interacting with CNAME endpoints. + * interacting with CNAME endpoints. Note: if you are using version 2.243.0 + * and above and do not expect the bucket name to appear in the host, you will + * also need to set `use_path_style_endpoint` to `true`. * - calculate_md5: (bool) Set to false to disable calculating an MD5 * for all Amazon S3 signed uploads. * - s3_us_east_1_regional_endpoint: @@ -417,6 +419,9 @@ class S3Client extends AwsClient implements S3ClientInterface $stack->appendInit($this->getHeadObjectMiddleware(), 's3.head_object'); if ($this->isUseEndpointV2()) { $this->processEndpointV2Model(); + $stack->after('builderV2', + 's3.check_empty_path_with_query', + $this->getEmptyPathWithQuery()); } } @@ -468,12 +473,17 @@ class S3Client extends AwsClient implements S3ClientInterface $command = clone $command; $command->getHandlerList()->remove('signer'); $request = \Aws\serialize($command); - $signing_name = $this->getSigningName($request->getUri()->getHost()); + $signing_name = empty($command->getAuthSchemes()) + ? $this->getSigningName($request->getUri()->getHost()) + : $command->getAuthSchemes()['name']; + $signature_version = empty($command->getAuthSchemes()) + ? $this->getConfig('signature_version') + : $command->getAuthSchemes()['version']; /** @var \Aws\Signature\SignatureInterface $signer */ $signer = call_user_func( $this->getSignatureProvider(), - $this->getConfig('signature_version'), + $signature_version, $signing_name, $this->getConfig('signing_region') ); @@ -647,6 +657,27 @@ class S3Client extends AwsClient implements S3ClientInterface }; } + /** + * Provides a middleware that checks for an empty path and a + * non-empty query string. + * + * @return \Closure + */ + private function getEmptyPathWithQuery() + { + return static function (callable $handler) { + return function (Command $command, RequestInterface $request) use ($handler) { + $uri = $request->getUri(); + if (empty($uri->getPath()) && !empty($uri->getQuery())) { + $uri = $uri->withPath('/'); + $request = $request->withUri($uri); + } + + return $handler($command, $request); + }; + }; + } + /** * Special handling for when the service name is s3-object-lambda. * So, if the host contains s3-object-lambda, then the service name @@ -788,19 +819,21 @@ class S3Client extends AwsClient implements S3ClientInterface && $attempts < $config->getMaxAttempts() ) { if (!empty($result->getResponse()) - && strpos( - $result->getResponse()->getBody(), - 'Your socket connection to the server' - ) !== false + && $result->getResponse()->getStatusCode() >= 400 ) { - $isRetryable = false; + return strpos( + $result->getResponse()->getBody(), + 'Your socket connection to the server' + ) !== false; } + if ($result->getPrevious() instanceof RequestException && $cmd->getName() !== 'CompleteMultipartUpload' ) { $isRetryable = true; } } + return $isRetryable; } ] @@ -872,10 +905,14 @@ class S3Client extends AwsClient implements S3ClientInterface $api['shapes']['ContentSHA256'] = ['type' => 'string']; $api['shapes']['PutObjectRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256']; $api['shapes']['UploadPartRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256']; - unset($api['shapes']['PutObjectRequest']['members']['ContentMD5']); - unset($api['shapes']['UploadPartRequest']['members']['ContentMD5']); $docs['shapes']['ContentSHA256']['append'] = $opt; + // Add the AddContentMD5 parameter. + $docs['shapes']['AddContentMD5']['base'] = 'Set to true to calculate the ContentMD5 for the upload.'; + $api['shapes']['AddContentMD5'] = ['type' => 'boolean']; + $api['shapes']['PutObjectRequest']['members']['AddContentMD5'] = ['shape' => 'AddContentMD5']; + $api['shapes']['UploadPartRequest']['members']['AddContentMD5'] = ['shape' => 'AddContentMD5']; + // Add the SaveAs parameter. $docs['shapes']['SaveAs']['base'] = 'The path to a file on disk to save the object data.'; $api['shapes']['SaveAs'] = ['type' => 'string']; @@ -908,9 +945,20 @@ class S3Client extends AwsClient implements S3ClientInterface "sa-east-1", ]; - // Add a note that the ContentMD5 is optional. + // Add a note that the ContentMD5 is automatically computed, except for with PutObject and UploadPart $docs['shapes']['ContentMD5']['append'] = '
The value will be computed on ' . 'your behalf.
'; + $docs['shapes']['ContentMD5']['excludeAppend'] = ['PutObjectRequest', 'UploadPartRequest']; + + //Add a note to ContentMD5 for PutObject and UploadPart that specifies the value is required + // When uploading to a bucket with object lock enabled and that it is not computed automatically + $objectLock = '
This value is required if uploading to a bucket ' + . 'which has Object Lock enabled. It will not be calculated for you automatically. If you wish to have ' + . 'the value calculated for you, use the `AddContentMD5` parameter.
'; + $docs['shapes']['ContentMD5']['appendOnly'] = [ + 'message' => $objectLock, + 'shapes' => ['PutObjectRequest', 'UploadPartRequest'] + ]; return [ new Service($api, ApiProvider::defaultProvider()), diff --git a/vendor/aws/aws-sdk-php/src/S3/S3ClientInterface.php b/vendor/aws/aws-sdk-php/src/S3/S3ClientInterface.php index 4b1d3aa..261d7dd 100644 --- a/vendor/aws/aws-sdk-php/src/S3/S3ClientInterface.php +++ b/vendor/aws/aws-sdk-php/src/S3/S3ClientInterface.php @@ -63,7 +63,7 @@ interface S3ClientInterface extends AwsClientInterface * cause an exception to be thrown instead. * * @return bool - * @throws S3Exception|Exception if there is an unhandled exception + * @throws S3Exception|\Exception if there is an unhandled exception */ public function doesBucketExistV2($bucket, $accept403); @@ -95,7 +95,7 @@ interface S3ClientInterface extends AwsClientInterface * operation (e.g., VersionId). * * @return bool - * @throws S3Exception|Exception if there is an unhandled exception + * @throws S3Exception|\Exception if there is an unhandled exception */ public function doesObjectExistV2($bucket, $key, $includeDeleteMarkers = false, array $options = []); diff --git a/vendor/aws/aws-sdk-php/src/S3/StreamWrapper.php b/vendor/aws/aws-sdk-php/src/S3/StreamWrapper.php index 4f89cba..a70e5cd 100644 --- a/vendor/aws/aws-sdk-php/src/S3/StreamWrapper.php +++ b/vendor/aws/aws-sdk-php/src/S3/StreamWrapper.php @@ -817,6 +817,7 @@ class StreamWrapper return $this->triggerError("Bucket already exists: {$path}"); } + unset($params['ACL']); return $this->boolCall(function () use ($params, $path) { $this->getClient()->createBucket($params); $this->clearCacheKey($path); diff --git a/vendor/aws/aws-sdk-php/src/S3/Transfer.php b/vendor/aws/aws-sdk-php/src/S3/Transfer.php index 68b6736..600f441 100644 --- a/vendor/aws/aws-sdk-php/src/S3/Transfer.php +++ b/vendor/aws/aws-sdk-php/src/S3/Transfer.php @@ -27,6 +27,7 @@ class Transfer implements PromisorInterface private $mupThreshold; private $before; private $s3Args = []; + private $addContentMD5; /** * When providing the $source argument, you may provide a string referencing @@ -134,6 +135,10 @@ class Transfer implements PromisorInterface $this->addDebugToBefore($options['debug']); } } + + // Handle "add_content_md5" option. + $this->addContentMD5 = isset($options['add_content_md5']) + && $options['add_content_md5'] === true; } /** @@ -141,7 +146,7 @@ class Transfer implements PromisorInterface * * @return PromiseInterface */ - public function promise() + public function promise(): PromiseInterface { // If the promise has been created, just return it. if (!$this->promise) { @@ -342,6 +347,7 @@ class Transfer implements PromisorInterface $args = $this->s3Args; $args['SourceFile'] = $filename; $args['Key'] = $this->createS3Key($filename); + $args['AddContentMD5'] = $this->addContentMD5; $command = $this->client->getCommand('PutObject', $args); $this->before and call_user_func($this->before, $command); @@ -361,6 +367,7 @@ class Transfer implements PromisorInterface 'before_upload' => $this->before, 'before_complete' => $this->before, 'concurrency' => $this->concurrency, + 'add_content_md5' => $this->addContentMD5 ]))->promise(); } -- cgit v1.2.3