PluginProbe ʕ •ᴥ•ʔ
Transferito: WP Migration / trunk
Transferito: WP Migration vtrunk
trunk 11.4.0 12.0.0 13.1.0 14.0.0 14.0.11 14.0.7 14.1.0 14.1.1 14.1.2 14.1.3 14.1.4
transferito / vendor / aws / aws-sdk-php / src / S3 / MultipartUploader.php
transferito / vendor / aws / aws-sdk-php / src / S3 Last commit date
Crypto 11 months ago Exception 11 months ago RegionalEndpoint 11 months ago UseArnRegion 11 months ago AmbiguousSuccessParser.php 11 months ago ApplyChecksumMiddleware.php 11 months ago BatchDelete.php 11 months ago BucketEndpointArnMiddleware.php 11 months ago BucketEndpointMiddleware.php 11 months ago CalculatesChecksumTrait.php 11 months ago EndpointRegionHelperTrait.php 11 months ago GetBucketLocationParser.php 11 months ago MultipartCopy.php 11 months ago MultipartUploader.php 11 months ago MultipartUploadingTrait.php 11 months ago ObjectCopier.php 11 months ago ObjectUploader.php 11 months ago PermanentRedirectMiddleware.php 11 months ago PostObject.php 11 months ago PostObjectV4.php 11 months ago PutObjectUrlMiddleware.php 11 months ago RetryableMalformedResponseParser.php 11 months ago S3Client.php 11 months ago S3ClientInterface.php 11 months ago S3ClientTrait.php 11 months ago S3EndpointMiddleware.php 11 months ago S3MultiRegionClient.php 11 months ago S3UriParser.php 11 months ago SSECMiddleware.php 11 months ago StreamWrapper.php 11 months ago Transfer.php 11 months ago ValidateResponseChecksumParser.php 11 months ago
MultipartUploader.php
176 lines
1 <?php
2 namespace Aws\S3;
3
4 use Aws\HashingStream;
5 use Aws\Multipart\AbstractUploader;
6 use Aws\PhpHash;
7 use Aws\ResultInterface;
8 use GuzzleHttp\Psr7;
9 use Psr\Http\Message\StreamInterface as Stream;
10 use Aws\S3\Exception\S3MultipartUploadException;
11
12 /**
13 * Encapsulates the execution of a multipart upload to S3 or Glacier.
14 */
15 class MultipartUploader extends AbstractUploader
16 {
17 use MultipartUploadingTrait;
18
19 const PART_MIN_SIZE = 5242880;
20 const PART_MAX_SIZE = 5368709120;
21 const PART_MAX_NUM = 10000;
22
23 /**
24 * Creates a multipart upload for an S3 object.
25 *
26 * The valid configuration options are as follows:
27 *
28 * - acl: (string) ACL to set on the object being upload. Objects are
29 * private by default.
30 * - before_complete: (callable) Callback to invoke before the
31 * `CompleteMultipartUpload` operation. The callback should have a
32 * function signature like `function (Aws\Command $command) {...}`.
33 * - before_initiate: (callable) Callback to invoke before the
34 * `CreateMultipartUpload` operation. The callback should have a function
35 * signature like `function (Aws\Command $command) {...}`.
36 * - before_upload: (callable) Callback to invoke before any `UploadPart`
37 * operations. The callback should have a function signature like
38 * `function (Aws\Command $command) {...}`.
39 * - bucket: (string, required) Name of the bucket to which the object is
40 * being uploaded, or an S3 access point ARN.
41 * - concurrency: (int, default=int(5)) Maximum number of concurrent
42 * `UploadPart` operations allowed during the multipart upload.
43 * - key: (string, required) Key to use for the object being uploaded.
44 * - params: (array) An array of key/value parameters that will be applied
45 * to each of the sub-commands run by the uploader as a base.
46 * Auto-calculated options will override these parameters. If you need
47 * more granularity over parameters to each sub-command, use the before_*
48 * options detailed above to update the commands directly.
49 * - part_size: (int, default=int(5242880)) Part size, in bytes, to use when
50 * doing a multipart upload. This must between 5 MB and 5 GB, inclusive.
51 * - prepare_data_source: (callable) Callback to invoke before starting the
52 * multipart upload workflow. The callback should have a function
53 * signature like `function () {...}`.
54 * - state: (Aws\Multipart\UploadState) An object that represents the state
55 * of the multipart upload and that is used to resume a previous upload.
56 * When this option is provided, the `bucket`, `key`, and `part_size`
57 * options are ignored.
58 *
59 * @param S3ClientInterface $client Client used for the upload.
60 * @param mixed $source Source of the data to upload.
61 * @param array $config Configuration used to perform the upload.
62 */
63 public function __construct(
64 S3ClientInterface $client,
65 $source,
66 array $config = []
67 ) {
68 parent::__construct($client, $source, array_change_key_case($config) + [
69 'bucket' => null,
70 'key' => null,
71 'exception_class' => S3MultipartUploadException::class,
72 ]);
73 }
74
75 protected function loadUploadWorkflowInfo()
76 {
77 return [
78 'command' => [
79 'initiate' => 'CreateMultipartUpload',
80 'upload' => 'UploadPart',
81 'complete' => 'CompleteMultipartUpload',
82 ],
83 'id' => [
84 'bucket' => 'Bucket',
85 'key' => 'Key',
86 'upload_id' => 'UploadId',
87 ],
88 'part_num' => 'PartNumber',
89 ];
90 }
91
92 protected function createPart($seekable, $number)
93 {
94 // Initialize the array of part data that will be returned.
95 $data = [];
96
97 // Apply custom params to UploadPart data
98 $config = $this->getConfig();
99 $params = isset($config['params']) ? $config['params'] : [];
100 foreach ($params as $k => $v) {
101 $data[$k] = $v;
102 }
103
104 $data['PartNumber'] = $number;
105
106 // Read from the source to create the body stream.
107 if ($seekable) {
108 // Case 1: Source is seekable, use lazy stream to defer work.
109 $body = $this->limitPartStream(
110 new Psr7\LazyOpenStream($this->source->getMetadata('uri'), 'r')
111 );
112 } else {
113 // Case 2: Stream is not seekable; must store in temp stream.
114 $source = $this->limitPartStream($this->source);
115 $source = $this->decorateWithHashes($source, $data);
116 $body = Psr7\Utils::streamFor();
117 Psr7\Utils::copyToStream($source, $body);
118 }
119
120 $contentLength = $body->getSize();
121
122 // Do not create a part if the body size is zero.
123 if ($contentLength === 0) {
124 return false;
125 }
126
127 $body->seek(0);
128 $data['Body'] = $body;
129
130 if (isset($config['add_content_md5'])
131 && $config['add_content_md5'] === true
132 ) {
133 $data['AddContentMD5'] = true;
134 }
135
136 $data['ContentLength'] = $contentLength;
137
138 return $data;
139 }
140
141 protected function extractETag(ResultInterface $result)
142 {
143 return $result['ETag'];
144 }
145
146 protected function getSourceMimeType()
147 {
148 if ($uri = $this->source->getMetadata('uri')) {
149 return Psr7\MimeType::fromFilename($uri)
150 ?: 'application/octet-stream';
151 }
152 }
153
154 protected function getSourceSize()
155 {
156 return $this->source->getSize();
157 }
158
159 /**
160 * Decorates a stream with a sha256 linear hashing stream.
161 *
162 * @param Stream $stream Stream to decorate.
163 * @param array $data Part data to augment with the hash result.
164 *
165 * @return Stream
166 */
167 private function decorateWithHashes(Stream $stream, array &$data)
168 {
169 // Decorate source with a hashing stream
170 $hash = new PhpHash('sha256');
171 return new HashingStream($stream, $hash, function ($result) use (&$data) {
172 $data['ContentSHA256'] = bin2hex($result);
173 });
174 }
175 }
176