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 / ObjectUploader.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
ObjectUploader.php
151 lines
1 <?php
2 namespace Aws\S3;
3
4 use GuzzleHttp\Promise\PromiseInterface;
5 use GuzzleHttp\Promise\PromisorInterface;
6 use GuzzleHttp\Psr7;
7 use Psr\Http\Message\StreamInterface;
8
9 /**
10 * Uploads an object to S3, using a PutObject command or a multipart upload as
11 * appropriate.
12 */
13 class ObjectUploader implements PromisorInterface
14 {
15 const DEFAULT_MULTIPART_THRESHOLD = 16777216;
16
17 private $client;
18 private $bucket;
19 private $key;
20 private $body;
21 private $acl;
22 private $options;
23 private static $defaults = [
24 'before_upload' => null,
25 'concurrency' => 3,
26 'mup_threshold' => self::DEFAULT_MULTIPART_THRESHOLD,
27 'params' => [],
28 'part_size' => null,
29 ];
30 private $addContentMD5;
31
32 /**
33 * @param S3ClientInterface $client The S3 Client used to execute
34 * the upload command(s).
35 * @param string $bucket Bucket to upload the object, or
36 * an S3 access point ARN.
37 * @param string $key Key of the object.
38 * @param mixed $body Object data to upload. Can be a
39 * StreamInterface, PHP stream
40 * resource, or a string of data to
41 * upload.
42 * @param string $acl ACL to apply to the copy
43 * (default: private).
44 * @param array $options Options used to configure the
45 * copy process. Options passed in
46 * through 'params' are added to
47 * the sub command(s).
48 */
49 public function __construct(
50 S3ClientInterface $client,
51 $bucket,
52 $key,
53 $body,
54 $acl = 'private',
55 array $options = []
56 ) {
57 $this->client = $client;
58 $this->bucket = $bucket;
59 $this->key = $key;
60 $this->body = Psr7\Utils::streamFor($body);
61 $this->acl = $acl;
62 $this->options = $options + self::$defaults;
63 // Handle "add_content_md5" option.
64 $this->addContentMD5 = isset($options['add_content_md5'])
65 && $options['add_content_md5'] === true;
66 }
67
68 /**
69 * @return PromiseInterface
70 */
71 public function promise(): PromiseInterface
72 {
73 /** @var int $mup_threshold */
74 $mup_threshold = $this->options['mup_threshold'];
75 if ($this->requiresMultipart($this->body, $mup_threshold)) {
76 // Perform a multipart upload.
77 return (new MultipartUploader($this->client, $this->body, [
78 'bucket' => $this->bucket,
79 'key' => $this->key,
80 'acl' => $this->acl
81 ] + $this->options))->promise();
82 }
83
84 // Perform a regular PutObject operation.
85 $command = $this->client->getCommand('PutObject', [
86 'Bucket' => $this->bucket,
87 'Key' => $this->key,
88 'Body' => $this->body,
89 'ACL' => $this->acl,
90 'AddContentMD5' => $this->addContentMD5
91 ] + $this->options['params']);
92 if (is_callable($this->options['before_upload'])) {
93 $this->options['before_upload']($command);
94 }
95 return $this->client->executeAsync($command);
96 }
97
98 public function upload()
99 {
100 return $this->promise()->wait();
101 }
102
103 /**
104 * Determines if the body should be uploaded using PutObject or the
105 * Multipart Upload System. It also modifies the passed-in $body as needed
106 * to support the upload.
107 *
108 * @param StreamInterface $body Stream representing the body.
109 * @param integer $threshold Minimum bytes before using Multipart.
110 *
111 * @return bool
112 */
113 private function requiresMultipart(StreamInterface &$body, $threshold)
114 {
115 // If body size known, compare to threshold to determine if Multipart.
116 if ($body->getSize() !== null) {
117 return $body->getSize() >= $threshold;
118 }
119
120 /**
121 * Handle the situation where the body size is unknown.
122 * Read up to 5MB into a buffer to determine how to upload the body.
123 * @var StreamInterface $buffer
124 */
125 $buffer = Psr7\Utils::streamFor();
126 Psr7\Utils::copyToStream($body, $buffer, MultipartUploader::PART_MIN_SIZE);
127
128 // If body < 5MB, use PutObject with the buffer.
129 if ($buffer->getSize() < MultipartUploader::PART_MIN_SIZE) {
130 $buffer->seek(0);
131 $body = $buffer;
132 return false;
133 }
134
135 // If body >= 5 MB, then use multipart. [YES]
136 if ($body->isSeekable() && $body->getMetadata('uri') !== 'php://input') {
137 // If the body is seekable, just rewind the body.
138 $body->seek(0);
139 } else {
140 // If the body is non-seekable, stitch the rewind the buffer and
141 // the partially read body together into one stream. This avoids
142 // unnecessary disc usage and does not require seeking on the
143 // original stream.
144 $buffer->seek(0);
145 $body = new Psr7\AppendStream([$buffer, $body]);
146 }
147
148 return true;
149 }
150 }
151