From 0c8af4992cb0f7589dcafaad65ada12753c64594 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Wed, 23 Nov 2022 21:14:33 +0300 Subject: initial --- vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php | 242 ++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php (limited to 'vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php') diff --git a/vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php b/vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php new file mode 100644 index 0000000..e78a824 --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/S3/MultipartCopy.php @@ -0,0 +1,242 @@ +/). If the key contains a '?' + * character, instead pass an array of source_key, + * source_bucket, and source_version_id. + * @param array $config Configuration used to perform the upload. + */ + public function __construct( + S3ClientInterface $client, + $source, + array $config = [] + ) { + if (is_array($source)) { + $this->source = $source; + } else { + $this->source = $this->getInputSource($source); + } + parent::__construct( + $client, + array_change_key_case($config) + ['source_metadata' => null] + ); + } + + /** + * An alias of the self::upload method. + * + * @see self::upload + */ + public function copy() + { + return $this->upload(); + } + + protected function loadUploadWorkflowInfo() + { + return [ + 'command' => [ + 'initiate' => 'CreateMultipartUpload', + 'upload' => 'UploadPartCopy', + 'complete' => 'CompleteMultipartUpload', + ], + 'id' => [ + 'bucket' => 'Bucket', + 'key' => 'Key', + 'upload_id' => 'UploadId', + ], + 'part_num' => 'PartNumber', + ]; + } + + protected function getUploadCommands(callable $resultHandler) + { + $parts = ceil($this->getSourceSize() / $this->determinePartSize()); + + for ($partNumber = 1; $partNumber <= $parts; $partNumber++) { + // If we haven't already uploaded this part, yield a new part. + if (!$this->state->hasPartBeenUploaded($partNumber)) { + $command = $this->client->getCommand( + $this->info['command']['upload'], + $this->createPart($partNumber, $parts) + $this->getState()->getId() + ); + $command->getHandlerList()->appendSign($resultHandler, 'mup'); + yield $command; + } + } + } + + private function createPart($partNumber, $partsCount) + { + $data = []; + + // Apply custom params to UploadPartCopy data + $config = $this->getConfig(); + $params = isset($config['params']) ? $config['params'] : []; + foreach ($params as $k => $v) { + $data[$k] = $v; + } + // The source parameter here is usually a string, but can be overloaded as an array + // 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; + } else { + + list($bucket, $key) = explode('/', ltrim($this->source, '/'), 2); + $data['CopySource'] = '/' . $bucket . '/' . implode( + '/', + array_map( + 'urlencode', + explode('/', rawurldecode($key)) + ) + ); + } + $data['PartNumber'] = $partNumber; + if (!empty($this->sourceVersionId)) { + $data['CopySource'] .= "?versionId=" . $this->sourceVersionId; + } + + $defaultPartSize = $this->determinePartSize(); + $startByte = $defaultPartSize * ($partNumber - 1); + $data['ContentLength'] = $partNumber < $partsCount + ? $defaultPartSize + : $this->getSourceSize() - ($defaultPartSize * ($partsCount - 1)); + $endByte = $startByte + $data['ContentLength'] - 1; + $data['CopySourceRange'] = "bytes=$startByte-$endByte"; + + return $data; + } + + protected function extractETag(ResultInterface $result) + { + return $result->search('CopyPartResult.ETag'); + } + + protected function getSourceMimeType() + { + return $this->getSourceMetadata()['ContentType']; + } + + protected function getSourceSize() + { + return $this->getSourceMetadata()['ContentLength']; + } + + private function getSourceMetadata() + { + if (empty($this->sourceMetadata)) { + $this->sourceMetadata = $this->fetchSourceMetadata(); + } + + return $this->sourceMetadata; + } + + private function fetchSourceMetadata() + { + if ($this->config['source_metadata'] instanceof ResultInterface) { + return $this->config['source_metadata']; + } + //if the source variable was overloaded with an array, use the inputs for key and bucket + if (is_array($this->source)) { + $headParams = [ + 'Key' => $this->source['source_key'], + 'Bucket' => $this->source['source_bucket'] + ]; + if (isset($this->source['source_version_id'])) { + $this->sourceVersionId = $this->source['source_version_id']; + $headParams['VersionId'] = $this->sourceVersionId; + } + //otherwise, use the default source parsing behavior + } else { + list($bucket, $key) = explode('/', ltrim($this->source, '/'), 2); + $headParams = [ + 'Bucket' => $bucket, + 'Key' => $key, + ]; + if (strpos($key, '?')) { + list($key, $query) = explode('?', $key, 2); + $headParams['Key'] = $key; + $query = Psr7\Query::parse($query, false); + if (isset($query['versionId'])) { + $this->sourceVersionId = $query['versionId']; + $headParams['VersionId'] = $this->sourceVersionId; + } + } + } + return $this->client->headObject($headParams); + } + + /** + * Get the url decoded input source, starting with a slash if it is not an + * ARN to standardize the source location syntax. + * + * @param string $inputSource The source that was passed to the constructor + * @return string The source, starting with a slash if it's not an arn + */ + private function getInputSource($inputSource) + { + if (ArnParser::isArn($inputSource)) { + $sourceBuilder = ''; + } else { + $sourceBuilder = "/"; + } + $sourceBuilder .= ltrim(rawurldecode($inputSource), '/'); + return $sourceBuilder; + } + +} -- cgit v1.2.3