PluginProbe
Media Cloud Sync / 1.2.13
Media Cloud Sync v1.2.13
1.4.2 1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 All 36 releases
media-cloud-sync / includes / sdk / s3 / Aws / S3 / S3Client.php

S3Client.php in Media Cloud Sync 1.2.13, at includes/sdk/s3/Aws/S3/S3Client.php

809 lines 49.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Dudlewebs\WPMCS\s3\Aws\S3;
4
5 use Dudlewebs\WPMCS\s3\Aws\Api\ApiProvider;
6 use Dudlewebs\WPMCS\s3\Aws\Api\DocModel;
7 use Dudlewebs\WPMCS\s3\Aws\Api\Service;
8 use Dudlewebs\WPMCS\s3\Aws\AwsClient;
9 use Dudlewebs\WPMCS\s3\Aws\CacheInterface;
10 use Dudlewebs\WPMCS\s3\Aws\ClientResolver;
11 use Dudlewebs\WPMCS\s3\Aws\Command;
12 use Dudlewebs\WPMCS\s3\Aws\CommandInterface;
13 use Dudlewebs\WPMCS\s3\Aws\Configuration\ConfigurationResolver;
14 use Dudlewebs\WPMCS\s3\Aws\Exception\AwsException;
15 use Dudlewebs\WPMCS\s3\Aws\HandlerList;
16 use Dudlewebs\WPMCS\s3\Aws\Identity\S3\S3ExpressIdentityProvider;
17 use Dudlewebs\WPMCS\s3\Aws\InputValidationMiddleware;
18 use Dudlewebs\WPMCS\s3\Aws\Middleware;
19 use Dudlewebs\WPMCS\s3\Aws\ResultInterface;
20 use Dudlewebs\WPMCS\s3\Aws\Retry\QuotaManager;
21 use Dudlewebs\WPMCS\s3\Aws\RetryMiddleware;
22 use Dudlewebs\WPMCS\s3\Aws\RetryMiddlewareV2;
23 use Dudlewebs\WPMCS\s3\Aws\S3\Parser\GetBucketLocationResultMutator;
24 use Dudlewebs\WPMCS\s3\Aws\S3\Parser\S3Parser;
25 use Dudlewebs\WPMCS\s3\Aws\S3\Parser\ValidateResponseChecksumResultMutator;
26 use Dudlewebs\WPMCS\s3\Aws\S3\RegionalEndpoint\ConfigurationProvider;
27 use Dudlewebs\WPMCS\s3\Aws\S3\UseArnRegion\Configuration;
28 use Dudlewebs\WPMCS\s3\Aws\S3\UseArnRegion\ConfigurationInterface;
29 use Dudlewebs\WPMCS\s3\Aws\S3\UseArnRegion\ConfigurationProvider as UseArnRegionConfigurationProvider;
30 use Dudlewebs\WPMCS\s3\GuzzleHttp\Exception\RequestException;
31 use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise\PromiseInterface;
32 use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface;
33 /**
34 * Client used to interact with **Amazon Simple Storage Service (Amazon S3)**.
35 *
36 * @method \Aws\Result abortMultipartUpload(array $args = [])
37 * @method \GuzzleHttp\Promise\Promise abortMultipartUploadAsync(array $args = [])
38 * @method \Aws\Result completeMultipartUpload(array $args = [])
39 * @method \GuzzleHttp\Promise\Promise completeMultipartUploadAsync(array $args = [])
40 * @method \Aws\Result copyObject(array $args = [])
41 * @method \GuzzleHttp\Promise\Promise copyObjectAsync(array $args = [])
42 * @method \Aws\Result createBucket(array $args = [])
43 * @method \GuzzleHttp\Promise\Promise createBucketAsync(array $args = [])
44 * @method \Aws\Result createMultipartUpload(array $args = [])
45 * @method \GuzzleHttp\Promise\Promise createMultipartUploadAsync(array $args = [])
46 * @method \Aws\Result createSession(array $args = [])
47 * @method \GuzzleHttp\Promise\Promise createSessionAsync(array $args = [])
48 * @method \Aws\Result deleteBucket(array $args = [])
49 * @method \GuzzleHttp\Promise\Promise deleteBucketAsync(array $args = [])
50 * @method \Aws\Result deleteBucketAnalyticsConfiguration(array $args = [])
51 * @method \GuzzleHttp\Promise\Promise deleteBucketAnalyticsConfigurationAsync(array $args = [])
52 * @method \Aws\Result deleteBucketCors(array $args = [])
53 * @method \GuzzleHttp\Promise\Promise deleteBucketCorsAsync(array $args = [])
54 * @method \Aws\Result deleteBucketEncryption(array $args = [])
55 * @method \GuzzleHttp\Promise\Promise deleteBucketEncryptionAsync(array $args = [])
56 * @method \Aws\Result deleteBucketIntelligentTieringConfiguration(array $args = [])
57 * @method \GuzzleHttp\Promise\Promise deleteBucketIntelligentTieringConfigurationAsync(array $args = [])
58 * @method \Aws\Result deleteBucketInventoryConfiguration(array $args = [])
59 * @method \GuzzleHttp\Promise\Promise deleteBucketInventoryConfigurationAsync(array $args = [])
60 * @method \Aws\Result deleteBucketLifecycle(array $args = [])
61 * @method \GuzzleHttp\Promise\Promise deleteBucketLifecycleAsync(array $args = [])
62 * @method \Aws\Result deleteBucketMetricsConfiguration(array $args = [])
63 * @method \GuzzleHttp\Promise\Promise deleteBucketMetricsConfigurationAsync(array $args = [])
64 * @method \Aws\Result deleteBucketOwnershipControls(array $args = [])
65 * @method \GuzzleHttp\Promise\Promise deleteBucketOwnershipControlsAsync(array $args = [])
66 * @method \Aws\Result deleteBucketPolicy(array $args = [])
67 * @method \GuzzleHttp\Promise\Promise deleteBucketPolicyAsync(array $args = [])
68 * @method \Aws\Result deleteBucketReplication(array $args = [])
69 * @method \GuzzleHttp\Promise\Promise deleteBucketReplicationAsync(array $args = [])
70 * @method \Aws\Result deleteBucketTagging(array $args = [])
71 * @method \GuzzleHttp\Promise\Promise deleteBucketTaggingAsync(array $args = [])
72 * @method \Aws\Result deleteBucketWebsite(array $args = [])
73 * @method \GuzzleHttp\Promise\Promise deleteBucketWebsiteAsync(array $args = [])
74 * @method \Aws\Result deleteObject(array $args = [])
75 * @method \GuzzleHttp\Promise\Promise deleteObjectAsync(array $args = [])
76 * @method \Aws\Result deleteObjectTagging(array $args = [])
77 * @method \GuzzleHttp\Promise\Promise deleteObjectTaggingAsync(array $args = [])
78 * @method \Aws\Result deleteObjects(array $args = [])
79 * @method \GuzzleHttp\Promise\Promise deleteObjectsAsync(array $args = [])
80 * @method \Aws\Result deletePublicAccessBlock(array $args = [])
81 * @method \GuzzleHttp\Promise\Promise deletePublicAccessBlockAsync(array $args = [])
82 * @method \Aws\Result getBucketAccelerateConfiguration(array $args = [])
83 * @method \GuzzleHttp\Promise\Promise getBucketAccelerateConfigurationAsync(array $args = [])
84 * @method \Aws\Result getBucketAcl(array $args = [])
85 * @method \GuzzleHttp\Promise\Promise getBucketAclAsync(array $args = [])
86 * @method \Aws\Result getBucketAnalyticsConfiguration(array $args = [])
87 * @method \GuzzleHttp\Promise\Promise getBucketAnalyticsConfigurationAsync(array $args = [])
88 * @method \Aws\Result getBucketCors(array $args = [])
89 * @method \GuzzleHttp\Promise\Promise getBucketCorsAsync(array $args = [])
90 * @method \Aws\Result getBucketEncryption(array $args = [])
91 * @method \GuzzleHttp\Promise\Promise getBucketEncryptionAsync(array $args = [])
92 * @method \Aws\Result getBucketIntelligentTieringConfiguration(array $args = [])
93 * @method \GuzzleHttp\Promise\Promise getBucketIntelligentTieringConfigurationAsync(array $args = [])
94 * @method \Aws\Result getBucketInventoryConfiguration(array $args = [])
95 * @method \GuzzleHttp\Promise\Promise getBucketInventoryConfigurationAsync(array $args = [])
96 * @method \Aws\Result getBucketLifecycle(array $args = [])
97 * @method \GuzzleHttp\Promise\Promise getBucketLifecycleAsync(array $args = [])
98 * @method \Aws\Result getBucketLifecycleConfiguration(array $args = [])
99 * @method \GuzzleHttp\Promise\Promise getBucketLifecycleConfigurationAsync(array $args = [])
100 * @method \Aws\Result getBucketLocation(array $args = [])
101 * @method \GuzzleHttp\Promise\Promise getBucketLocationAsync(array $args = [])
102 * @method \Aws\Result getBucketLogging(array $args = [])
103 * @method \GuzzleHttp\Promise\Promise getBucketLoggingAsync(array $args = [])
104 * @method \Aws\Result getBucketMetricsConfiguration(array $args = [])
105 * @method \GuzzleHttp\Promise\Promise getBucketMetricsConfigurationAsync(array $args = [])
106 * @method \Aws\Result getBucketNotification(array $args = [])
107 * @method \GuzzleHttp\Promise\Promise getBucketNotificationAsync(array $args = [])
108 * @method \Aws\Result getBucketNotificationConfiguration(array $args = [])
109 * @method \GuzzleHttp\Promise\Promise getBucketNotificationConfigurationAsync(array $args = [])
110 * @method \Aws\Result getBucketOwnershipControls(array $args = [])
111 * @method \GuzzleHttp\Promise\Promise getBucketOwnershipControlsAsync(array $args = [])
112 * @method \Aws\Result getBucketPolicy(array $args = [])
113 * @method \GuzzleHttp\Promise\Promise getBucketPolicyAsync(array $args = [])
114 * @method \Aws\Result getBucketPolicyStatus(array $args = [])
115 * @method \GuzzleHttp\Promise\Promise getBucketPolicyStatusAsync(array $args = [])
116 * @method \Aws\Result getBucketReplication(array $args = [])
117 * @method \GuzzleHttp\Promise\Promise getBucketReplicationAsync(array $args = [])
118 * @method \Aws\Result getBucketRequestPayment(array $args = [])
119 * @method \GuzzleHttp\Promise\Promise getBucketRequestPaymentAsync(array $args = [])
120 * @method \Aws\Result getBucketTagging(array $args = [])
121 * @method \GuzzleHttp\Promise\Promise getBucketTaggingAsync(array $args = [])
122 * @method \Aws\Result getBucketVersioning(array $args = [])
123 * @method \GuzzleHttp\Promise\Promise getBucketVersioningAsync(array $args = [])
124 * @method \Aws\Result getBucketWebsite(array $args = [])
125 * @method \GuzzleHttp\Promise\Promise getBucketWebsiteAsync(array $args = [])
126 * @method \Aws\Result getObject(array $args = [])
127 * @method \GuzzleHttp\Promise\Promise getObjectAsync(array $args = [])
128 * @method \Aws\Result getObjectAcl(array $args = [])
129 * @method \GuzzleHttp\Promise\Promise getObjectAclAsync(array $args = [])
130 * @method \Aws\Result getObjectAttributes(array $args = [])
131 * @method \GuzzleHttp\Promise\Promise getObjectAttributesAsync(array $args = [])
132 * @method \Aws\Result getObjectLegalHold(array $args = [])
133 * @method \GuzzleHttp\Promise\Promise getObjectLegalHoldAsync(array $args = [])
134 * @method \Aws\Result getObjectLockConfiguration(array $args = [])
135 * @method \GuzzleHttp\Promise\Promise getObjectLockConfigurationAsync(array $args = [])
136 * @method \Aws\Result getObjectRetention(array $args = [])
137 * @method \GuzzleHttp\Promise\Promise getObjectRetentionAsync(array $args = [])
138 * @method \Aws\Result getObjectTagging(array $args = [])
139 * @method \GuzzleHttp\Promise\Promise getObjectTaggingAsync(array $args = [])
140 * @method \Aws\Result getObjectTorrent(array $args = [])
141 * @method \GuzzleHttp\Promise\Promise getObjectTorrentAsync(array $args = [])
142 * @method \Aws\Result getPublicAccessBlock(array $args = [])
143 * @method \GuzzleHttp\Promise\Promise getPublicAccessBlockAsync(array $args = [])
144 * @method \Aws\Result headBucket(array $args = [])
145 * @method \GuzzleHttp\Promise\Promise headBucketAsync(array $args = [])
146 * @method \Aws\Result headObject(array $args = [])
147 * @method \GuzzleHttp\Promise\Promise headObjectAsync(array $args = [])
148 * @method \Aws\Result listBucketAnalyticsConfigurations(array $args = [])
149 * @method \GuzzleHttp\Promise\Promise listBucketAnalyticsConfigurationsAsync(array $args = [])
150 * @method \Aws\Result listBucketIntelligentTieringConfigurations(array $args = [])
151 * @method \GuzzleHttp\Promise\Promise listBucketIntelligentTieringConfigurationsAsync(array $args = [])
152 * @method \Aws\Result listBucketInventoryConfigurations(array $args = [])
153 * @method \GuzzleHttp\Promise\Promise listBucketInventoryConfigurationsAsync(array $args = [])
154 * @method \Aws\Result listBucketMetricsConfigurations(array $args = [])
155 * @method \GuzzleHttp\Promise\Promise listBucketMetricsConfigurationsAsync(array $args = [])
156 * @method \Aws\Result listBuckets(array $args = [])
157 * @method \GuzzleHttp\Promise\Promise listBucketsAsync(array $args = [])
158 * @method \Aws\Result listDirectoryBuckets(array $args = [])
159 * @method \GuzzleHttp\Promise\Promise listDirectoryBucketsAsync(array $args = [])
160 * @method \Aws\Result listMultipartUploads(array $args = [])
161 * @method \GuzzleHttp\Promise\Promise listMultipartUploadsAsync(array $args = [])
162 * @method \Aws\Result listObjectVersions(array $args = [])
163 * @method \GuzzleHttp\Promise\Promise listObjectVersionsAsync(array $args = [])
164 * @method \Aws\Result listObjects(array $args = [])
165 * @method \GuzzleHttp\Promise\Promise listObjectsAsync(array $args = [])
166 * @method \Aws\Result listObjectsV2(array $args = [])
167 * @method \GuzzleHttp\Promise\Promise listObjectsV2Async(array $args = [])
168 * @method \Aws\Result listParts(array $args = [])
169 * @method \GuzzleHttp\Promise\Promise listPartsAsync(array $args = [])
170 * @method \Aws\Result putBucketAccelerateConfiguration(array $args = [])
171 * @method \GuzzleHttp\Promise\Promise putBucketAccelerateConfigurationAsync(array $args = [])
172 * @method \Aws\Result putBucketAcl(array $args = [])
173 * @method \GuzzleHttp\Promise\Promise putBucketAclAsync(array $args = [])
174 * @method \Aws\Result putBucketAnalyticsConfiguration(array $args = [])
175 * @method \GuzzleHttp\Promise\Promise putBucketAnalyticsConfigurationAsync(array $args = [])
176 * @method \Aws\Result putBucketCors(array $args = [])
177 * @method \GuzzleHttp\Promise\Promise putBucketCorsAsync(array $args = [])
178 * @method \Aws\Result putBucketEncryption(array $args = [])
179 * @method \GuzzleHttp\Promise\Promise putBucketEncryptionAsync(array $args = [])
180 * @method \Aws\Result putBucketIntelligentTieringConfiguration(array $args = [])
181 * @method \GuzzleHttp\Promise\Promise putBucketIntelligentTieringConfigurationAsync(array $args = [])
182 * @method \Aws\Result putBucketInventoryConfiguration(array $args = [])
183 * @method \GuzzleHttp\Promise\Promise putBucketInventoryConfigurationAsync(array $args = [])
184 * @method \Aws\Result putBucketLifecycle(array $args = [])
185 * @method \GuzzleHttp\Promise\Promise putBucketLifecycleAsync(array $args = [])
186 * @method \Aws\Result putBucketLifecycleConfiguration(array $args = [])
187 * @method \GuzzleHttp\Promise\Promise putBucketLifecycleConfigurationAsync(array $args = [])
188 * @method \Aws\Result putBucketLogging(array $args = [])
189 * @method \GuzzleHttp\Promise\Promise putBucketLoggingAsync(array $args = [])
190 * @method \Aws\Result putBucketMetricsConfiguration(array $args = [])
191 * @method \GuzzleHttp\Promise\Promise putBucketMetricsConfigurationAsync(array $args = [])
192 * @method \Aws\Result putBucketNotification(array $args = [])
193 * @method \GuzzleHttp\Promise\Promise putBucketNotificationAsync(array $args = [])
194 * @method \Aws\Result putBucketNotificationConfiguration(array $args = [])
195 * @method \GuzzleHttp\Promise\Promise putBucketNotificationConfigurationAsync(array $args = [])
196 * @method \Aws\Result putBucketOwnershipControls(array $args = [])
197 * @method \GuzzleHttp\Promise\Promise putBucketOwnershipControlsAsync(array $args = [])
198 * @method \Aws\Result putBucketPolicy(array $args = [])
199 * @method \GuzzleHttp\Promise\Promise putBucketPolicyAsync(array $args = [])
200 * @method \Aws\Result putBucketReplication(array $args = [])
201 * @method \GuzzleHttp\Promise\Promise putBucketReplicationAsync(array $args = [])
202 * @method \Aws\Result putBucketRequestPayment(array $args = [])
203 * @method \GuzzleHttp\Promise\Promise putBucketRequestPaymentAsync(array $args = [])
204 * @method \Aws\Result putBucketTagging(array $args = [])
205 * @method \GuzzleHttp\Promise\Promise putBucketTaggingAsync(array $args = [])
206 * @method \Aws\Result putBucketVersioning(array $args = [])
207 * @method \GuzzleHttp\Promise\Promise putBucketVersioningAsync(array $args = [])
208 * @method \Aws\Result putBucketWebsite(array $args = [])
209 * @method \GuzzleHttp\Promise\Promise putBucketWebsiteAsync(array $args = [])
210 * @method \Aws\Result putObject(array $args = [])
211 * @method \GuzzleHttp\Promise\Promise putObjectAsync(array $args = [])
212 * @method \Aws\Result putObjectAcl(array $args = [])
213 * @method \GuzzleHttp\Promise\Promise putObjectAclAsync(array $args = [])
214 * @method \Aws\Result putObjectLegalHold(array $args = [])
215 * @method \GuzzleHttp\Promise\Promise putObjectLegalHoldAsync(array $args = [])
216 * @method \Aws\Result putObjectLockConfiguration(array $args = [])
217 * @method \GuzzleHttp\Promise\Promise putObjectLockConfigurationAsync(array $args = [])
218 * @method \Aws\Result putObjectRetention(array $args = [])
219 * @method \GuzzleHttp\Promise\Promise putObjectRetentionAsync(array $args = [])
220 * @method \Aws\Result putObjectTagging(array $args = [])
221 * @method \GuzzleHttp\Promise\Promise putObjectTaggingAsync(array $args = [])
222 * @method \Aws\Result putPublicAccessBlock(array $args = [])
223 * @method \GuzzleHttp\Promise\Promise putPublicAccessBlockAsync(array $args = [])
224 * @method \Aws\Result restoreObject(array $args = [])
225 * @method \GuzzleHttp\Promise\Promise restoreObjectAsync(array $args = [])
226 * @method \Aws\Result selectObjectContent(array $args = [])
227 * @method \GuzzleHttp\Promise\Promise selectObjectContentAsync(array $args = [])
228 * @method \Aws\Result uploadPart(array $args = [])
229 * @method \GuzzleHttp\Promise\Promise uploadPartAsync(array $args = [])
230 * @method \Aws\Result uploadPartCopy(array $args = [])
231 * @method \GuzzleHttp\Promise\Promise uploadPartCopyAsync(array $args = [])
232 * @method \Aws\Result writeGetObjectResponse(array $args = [])
233 * @method \GuzzleHttp\Promise\Promise writeGetObjectResponseAsync(array $args = [])
234 */
235 class S3Client extends AwsClient implements S3ClientInterface
236 {
237 use S3ClientTrait;
238 /** @var array */
239 private static $mandatoryAttributes = ['Bucket', 'Key'];
240 public static function getArguments()
241 {
242 $args = parent::getArguments();
243 $args['retries']['fn'] = [__CLASS__, '_applyRetryConfig'];
244 $args['api_provider']['fn'] = [__CLASS__, '_applyApiProvider'];
245 return $args + ['bucket_endpoint' => ['type' => 'config', 'valid' => ['bool'], 'doc' => '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.'], 'use_arn_region' => ['type' => 'config', 'valid' => ['bool', Configuration::class, CacheInterface::class, 'callable'], 'doc' => 'Set to true to allow passed in ARNs to override' . ' client region. Accepts...', 'fn' => [__CLASS__, '_apply_use_arn_region'], 'default' => [UseArnRegionConfigurationProvider::class, 'defaultProvider']], 'use_accelerate_endpoint' => ['type' => 'config', 'valid' => ['bool'], 'doc' => 'Set to true to send requests to an S3 Accelerate' . ' endpoint by default. Can be enabled or disabled on' . ' individual operations by setting' . ' \'@use_accelerate_endpoint\' to true or false. Note:' . ' you must enable S3 Accelerate on a bucket before it can' . ' be accessed via an Accelerate endpoint.', 'default' => \false], 'use_path_style_endpoint' => ['type' => 'config', 'valid' => ['bool'], 'doc' => 'Set to true to send requests to an S3 path style' . ' endpoint by default.' . ' Can be enabled or disabled on individual operations by setting' . ' \'@use_path_style_endpoint\' to true or false.', 'default' => \false], 'disable_multiregion_access_points' => ['type' => 'config', 'valid' => ['bool'], 'doc' => 'Set to true to disable the usage of' . ' multi region access points. These are enabled by default.' . ' Can be enabled or disabled on individual operations by setting' . ' \'@disable_multiregion_access_points\' to true or false.', 'default' => \false], 'disable_express_session_auth' => ['type' => 'config', 'valid' => ['bool'], 'doc' => 'Set to true to disable the usage of' . ' s3 express session authentication. This is enabled by default.', 'default' => [__CLASS__, '_default_disable_express_session_auth']], 's3_express_identity_provider' => ['type' => 'config', 'valid' => ['bool', 'callable'], 'doc' => 'Specifies the provider used to generate identities to sign s3 express requests. ' . 'Set to `false` to disable s3 express auth, or a callable provider used to create s3 express ' . 'identities or return null.', 'default' => [__CLASS__, '_default_s3_express_identity_provider']]];
246 }
247 /**
248 * {@inheritdoc}
249 *
250 * In addition to the options available to
251 * {@see Aws\AwsClient::__construct}, S3Client accepts the following
252 * options:
253 *
254 * - bucket_endpoint: (bool) Set to true to send requests to a
255 * hardcoded bucket endpoint rather than create an endpoint as a result
256 * of injecting the bucket into the URL. This option is useful for
257 * interacting with CNAME endpoints. Note: if you are using version 2.243.0
258 * and above and do not expect the bucket name to appear in the host, you will
259 * also need to set `use_path_style_endpoint` to `true`.
260 * - calculate_md5: (bool) Set to false to disable calculating an MD5
261 * for all Amazon S3 signed uploads.
262 * - s3_us_east_1_regional_endpoint:
263 * (Aws\S3\RegionalEndpoint\ConfigurationInterface|Aws\CacheInterface\|callable|string|array)
264 * Specifies whether to use regional or legacy endpoints for the us-east-1
265 * region. Provide an Aws\S3\RegionalEndpoint\ConfigurationInterface object, an
266 * instance of Aws\CacheInterface, a callable configuration provider used
267 * to create endpoint configuration, a string value of `legacy` or
268 * `regional`, or an associative array with the following keys:
269 * endpoint_types: (string) Set to `legacy` or `regional`, defaults to
270 * `legacy`
271 * - use_accelerate_endpoint: (bool) Set to true to send requests to an S3
272 * Accelerate endpoint by default. Can be enabled or disabled on
273 * individual operations by setting '@use_accelerate_endpoint' to true or
274 * false. Note: you must enable S3 Accelerate on a bucket before it can be
275 * accessed via an Accelerate endpoint.
276 * - use_arn_region: (Aws\S3\UseArnRegion\ConfigurationInterface,
277 * Aws\CacheInterface, bool, callable) Set to true to enable the client
278 * to use the region from a supplied ARN argument instead of the client's
279 * region. Provide an instance of Aws\S3\UseArnRegion\ConfigurationInterface,
280 * an instance of Aws\CacheInterface, a callable that provides a promise for
281 * a Configuration object, or a boolean value. Defaults to false (i.e.
282 * the SDK will not follow the ARN region if it conflicts with the client
283 * region and instead throw an error).
284 * - use_dual_stack_endpoint: (bool) Set to true to send requests to an S3
285 * Dual Stack endpoint by default, which enables IPv6 Protocol.
286 * Can be enabled or disabled on individual operations by setting
287 * '@use_dual_stack_endpoint\' to true or false. Note:
288 * you cannot use it together with an accelerate endpoint.
289 * - use_path_style_endpoint: (bool) Set to true to send requests to an S3
290 * path style endpoint by default.
291 * Can be enabled or disabled on individual operations by setting
292 * '@use_path_style_endpoint\' to true or false. Note:
293 * you cannot use it together with an accelerate endpoint.
294 * - disable_multiregion_access_points: (bool) Set to true to disable
295 * sending multi region requests. They are enabled by default.
296 * Can be enabled or disabled on individual operations by setting
297 * '@disable_multiregion_access_points\' to true or false. Note:
298 * you cannot use it together with an accelerate or dualstack endpoint.
299 *
300 * @param array $args
301 */
302 public function __construct(array $args)
303 {
304 if (!isset($args['s3_us_east_1_regional_endpoint']) || $args['s3_us_east_1_regional_endpoint'] instanceof CacheInterface) {
305 $args['s3_us_east_1_regional_endpoint'] = ConfigurationProvider::defaultProvider($args);
306 }
307 $this->addBuiltIns($args);
308 parent::__construct($args);
309 $stack = $this->getHandlerList();
310 $stack->appendInit(SSECMiddleware::wrap($this->getEndpoint()->getScheme()), 's3.ssec');
311 $stack->appendBuild(ApplyChecksumMiddleware::wrap($this->getApi()), 's3.checksum');
312 $stack->appendBuild(Middleware::contentType(['PutObject', 'UploadPart']), 's3.content_type');
313 if ($this->getConfig('bucket_endpoint')) {
314 $stack->appendBuild(BucketEndpointMiddleware::wrap(), 's3.bucket_endpoint');
315 } elseif (!$this->isUseEndpointV2()) {
316 $stack->appendBuild(S3EndpointMiddleware::wrap($this->getRegion(), $this->getConfig('endpoint_provider'), ['accelerate' => $this->getConfig('use_accelerate_endpoint'), 'path_style' => $this->getConfig('use_path_style_endpoint'), 'use_fips_endpoint' => $this->getConfig('use_fips_endpoint'), 'dual_stack' => $this->getConfig('use_dual_stack_endpoint')->isUseDualStackEndpoint()]), 's3.endpoint_middleware');
317 }
318 $stack->appendBuild(BucketEndpointArnMiddleware::wrap($this->getApi(), $this->getRegion(), ['use_arn_region' => $this->getConfig('use_arn_region'), 'accelerate' => $this->getConfig('use_accelerate_endpoint'), 'path_style' => $this->getConfig('use_path_style_endpoint'), 'dual_stack' => $this->getConfig('use_dual_stack_endpoint')->isUseDualStackEndpoint(), 'use_fips_endpoint' => $this->getConfig('use_fips_endpoint'), 'disable_multiregion_access_points' => $this->getConfig('disable_multiregion_access_points'), 'endpoint' => $args['endpoint'] ?? null], $this->isUseEndpointV2()), 's3.bucket_endpoint_arn');
319 if ($this->getConfig('disable_express_session_auth')) {
320 $stack->prependSign($this->getDisableExpressSessionAuthMiddleware(), 's3.disable_express_session_auth');
321 }
322 $stack->appendValidate(InputValidationMiddleware::wrap($this->getApi(), self::$mandatoryAttributes), 'input_validation_middleware');
323 $stack->appendSign(ExpiresParsingMiddleware::wrap(), 's3.expires_parsing');
324 $stack->appendSign(PutObjectUrlMiddleware::wrap(), 's3.put_object_url');
325 $stack->appendSign(PermanentRedirectMiddleware::wrap(), 's3.permanent_redirect');
326 $stack->appendInit(Middleware::sourceFile($this->getApi()), 's3.source_file');
327 $stack->appendInit($this->getSaveAsParameter(), 's3.save_as');
328 $stack->appendInit($this->getLocationConstraintMiddleware(), 's3.location');
329 $stack->appendInit($this->getEncodingTypeMiddleware(), 's3.auto_encode');
330 $stack->appendInit($this->getHeadObjectMiddleware(), 's3.head_object');
331 $this->processModel($this->isUseEndpointV2());
332 if ($this->isUseEndpointV2()) {
333 $stack->after('builder', 's3.check_empty_path_with_query', $this->getEmptyPathWithQuery());
334 }
335 }
336 /**
337 * Determine if a string is a valid name for a DNS compatible Amazon S3
338 * bucket.
339 *
340 * DNS compatible bucket names can be used as a subdomain in a URL (e.g.,
341 * "<bucket>.s3.amazonaws.com").
342 *
343 * @param string $bucket Bucket name to check.
344 *
345 * @return bool
346 */
347 public static function isBucketDnsCompatible($bucket)
348 {
349 if (!\is_string($bucket)) {
350 return \false;
351 }
352 $bucketLen = \strlen($bucket);
353 return $bucketLen >= 3 && $bucketLen <= 63 && !\filter_var($bucket, \FILTER_VALIDATE_IP) && \preg_match('/^[a-z0-9]([a-z0-9\\-\\.]*[a-z0-9])?$/', $bucket);
354 }
355 public static function _apply_use_arn_region($value, array &$args, HandlerList $list)
356 {
357 if ($value instanceof CacheInterface) {
358 $value = UseArnRegionConfigurationProvider::defaultProvider($args);
359 }
360 if (\is_callable($value)) {
361 $value = $value();
362 }
363 if ($value instanceof PromiseInterface) {
364 $value = $value->wait();
365 }
366 if ($value instanceof ConfigurationInterface) {
367 $args['use_arn_region'] = $value;
368 } else {
369 // The Configuration class itself will validate other inputs
370 $args['use_arn_region'] = new Configuration($value);
371 }
372 }
373 public function createPresignedRequest(CommandInterface $command, $expires, array $options = [])
374 {
375 $command = clone $command;
376 $command->getHandlerList()->remove('signer');
377 $request = \Dudlewebs\WPMCS\s3\Aws\serialize($command);
378 $signing_name = $command['@context']['signing_service'] ?? $this->getSigningName($request->getUri()->getHost());
379 $signature_version = $this->getSignatureVersionFromCommand($command);
380 /** @var \Aws\Signature\SignatureInterface $signer */
381 $signer = \call_user_func($this->getSignatureProvider(), $signature_version, $signing_name, $this->getConfig('signing_region'));
382 if ($signature_version == 'v4-s3express') {
383 $provider = $this->getConfig('s3_express_identity_provider');
384 $credentials = $provider($command)->wait();
385 } else {
386 $credentials = $this->getCredentials()->wait();
387 }
388 return $signer->presign($request, $credentials, $expires, $options);
389 }
390 /**
391 * Returns the URL to an object identified by its bucket and key.
392 *
393 * The URL returned by this method is not signed nor does it ensure that the
394 * bucket and key given to the method exist. If you need a signed URL, then
395 * use the {@see \Aws\S3\S3Client::createPresignedRequest} method and get
396 * the URI of the signed request.
397 *
398 * @param string $bucket The name of the bucket where the object is located
399 * @param string $key The key of the object
400 *
401 * @return string The URL to the object
402 */
403 public function getObjectUrl($bucket, $key)
404 {
405 $command = $this->getCommand('GetObject', ['Bucket' => $bucket, 'Key' => $key]);
406 return (string) \Dudlewebs\WPMCS\s3\Aws\serialize($command)->getUri();
407 }
408 /**
409 * Raw URL encode a key and allow for '/' characters
410 *
411 * @param string $key Key to encode
412 *
413 * @return string Returns the encoded key
414 */
415 public static function encodeKey($key)
416 {
417 return \str_replace('%2F', '/', \rawurlencode($key));
418 }
419 /**
420 * Provides a middleware that removes the need to specify LocationConstraint on CreateBucket.
421 *
422 * @return \Closure
423 */
424 private function getLocationConstraintMiddleware()
425 {
426 $region = $this->getRegion();
427 return static function (callable $handler) use($region) {
428 return function (Command $command, $request = null) use($handler, $region) {
429 if ($command->getName() === 'CreateBucket') {
430 $locationConstraint = $command['CreateBucketConfiguration']['LocationConstraint'] ?? null;
431 if ($locationConstraint === 'us-east-1') {
432 unset($command['CreateBucketConfiguration']);
433 } elseif ('us-east-1' !== $region && empty($locationConstraint)) {
434 $command['CreateBucketConfiguration'] = ['LocationConstraint' => $region];
435 }
436 }
437 return $handler($command, $request);
438 };
439 };
440 }
441 /**
442 * Provides a middleware that supports the `SaveAs` parameter.
443 *
444 * @return \Closure
445 */
446 private function getSaveAsParameter()
447 {
448 return static function (callable $handler) {
449 return function (Command $command, $request = null) use($handler) {
450 if ($command->getName() === 'GetObject' && isset($command['SaveAs'])) {
451 $command['@http']['sink'] = $command['SaveAs'];
452 unset($command['SaveAs']);
453 }
454 return $handler($command, $request);
455 };
456 };
457 }
458 /**
459 * Provides a middleware that disables content decoding on HeadObject
460 * commands.
461 *
462 * @return \Closure
463 */
464 private function getHeadObjectMiddleware()
465 {
466 return static function (callable $handler) {
467 return function (CommandInterface $command, RequestInterface $request = null) use($handler) {
468 if ($command->getName() === 'HeadObject' && !isset($command['@http']['decode_content'])) {
469 $command['@http']['decode_content'] = \false;
470 }
471 return $handler($command, $request);
472 };
473 };
474 }
475 /**
476 * Provides a middleware that autopopulates the EncodingType parameter on
477 * ListObjects commands.
478 *
479 * @return \Closure
480 */
481 private function getEncodingTypeMiddleware()
482 {
483 return static function (callable $handler) {
484 return function (Command $command, $request = null) use($handler) {
485 $autoSet = \false;
486 if ($command->getName() === 'ListObjects' && empty($command['EncodingType'])) {
487 $command['EncodingType'] = 'url';
488 $autoSet = \true;
489 }
490 return $handler($command, $request)->then(function (ResultInterface $result) use($autoSet) {
491 if ($result['EncodingType'] === 'url' && $autoSet) {
492 static $topLevel = ['Delimiter', 'Marker', 'NextMarker', 'Prefix'];
493 static $nested = [['Contents', 'Key'], ['CommonPrefixes', 'Prefix']];
494 foreach ($topLevel as $key) {
495 if (isset($result[$key])) {
496 $result[$key] = \urldecode($result[$key]);
497 }
498 }
499 foreach ($nested as $steps) {
500 if (isset($result[$steps[0]])) {
501 foreach ($result[$steps[0]] as $key => $part) {
502 if (isset($part[$steps[1]])) {
503 $result[$steps[0]][$key][$steps[1]] = \urldecode($part[$steps[1]]);
504 }
505 }
506 }
507 }
508 }
509 return $result;
510 });
511 };
512 };
513 }
514 /**
515 * Provides a middleware that checks for an empty path and a
516 * non-empty query string.
517 *
518 * @return \Closure
519 */
520 private function getEmptyPathWithQuery()
521 {
522 return static function (callable $handler) {
523 return function (Command $command, RequestInterface $request) use($handler) {
524 $uri = $request->getUri();
525 if (empty($uri->getPath()) && !empty($uri->getQuery())) {
526 $uri = $uri->withPath('/');
527 $request = $request->withUri($uri);
528 }
529 return $handler($command, $request);
530 };
531 };
532 }
533 /**
534 * Provides a middleware that disables express session auth when
535 * customers opt out of it.
536 *
537 * @return \Closure
538 */
539 private function getDisableExpressSessionAuthMiddleware()
540 {
541 return function (callable $handler) {
542 return function (CommandInterface $command, RequestInterface $request = null) use($handler) {
543 if (!empty($command['@context']['signature_version']) && $command['@context']['signature_version'] === 'v4-s3express') {
544 $command['@context']['signature_version'] = 's3v4';
545 }
546 return $handler($command, $request);
547 };
548 };
549 }
550 /**
551 * Special handling for when the service name is s3-object-lambda.
552 * So, if the host contains s3-object-lambda, then the service name
553 * returned is s3-object-lambda, otherwise the default signing service is returned.
554 * @param string $host The host to validate if is a s3-object-lambda URL.
555 * @return string returns the signing service name to be used
556 */
557 private function getSigningName($host)
558 {
559 if (\strpos($host, 's3-object-lambda')) {
560 return 's3-object-lambda';
561 }
562 return $this->getConfig('signing_name');
563 }
564 public static function _default_disable_express_session_auth(array &$args)
565 {
566 return ConfigurationResolver::resolve('s3_disable_express_session_auth', \false, 'bool', $args);
567 }
568 public static function _default_s3_express_identity_provider(array $args)
569 {
570 if ($args['config']['disable_express_session_auth']) {
571 return \false;
572 }
573 return new S3ExpressIdentityProvider($args['region']);
574 }
575 /**
576 * If EndpointProviderV2 is used, removes `Bucket` from request URIs.
577 * This is now handled by the endpoint ruleset.
578 *
579 * Additionally adds a synthetic shape `ExpiresString` and modifies
580 * `Expires` type to ensure it remains set to `timestamp`.
581 *
582 * @param array $args
583 * @return void
584 *
585 * @internal
586 */
587 private function processModel(bool $isUseEndpointV2) : void
588 {
589 $definition = $this->getApi()->getDefinition();
590 if ($isUseEndpointV2) {
591 foreach ($definition['operations'] as &$operation) {
592 if (isset($operation['http']['requestUri'])) {
593 $requestUri = $operation['http']['requestUri'];
594 if ($requestUri === "/{Bucket}") {
595 $requestUri = \str_replace('/{Bucket}', '/', $requestUri);
596 } else {
597 $requestUri = \str_replace('/{Bucket}', '', $requestUri);
598 }
599 $operation['http']['requestUri'] = $requestUri;
600 }
601 }
602 }
603 foreach ($definition['shapes'] as $key => &$value) {
604 $suffix = 'Output';
605 if (\substr($key, -\strlen($suffix)) === $suffix) {
606 if (isset($value['members']['Expires'])) {
607 $value['members']['Expires']['deprecated'] = \true;
608 $value['members']['ExpiresString'] = ['shape' => 'ExpiresString', 'location' => 'header', 'locationName' => 'Expires'];
609 }
610 }
611 }
612 $definition['shapes']['ExpiresString']['type'] = 'string';
613 $definition['shapes']['Expires']['type'] = 'timestamp';
614 $this->getApi()->setDefinition($definition);
615 }
616 /**
617 * Adds service-specific client built-in values
618 *
619 * @return void
620 */
621 private function addBuiltIns($args)
622 {
623 if (isset($args['region']) && $args['region'] !== 'us-east-1') {
624 return \false;
625 }
626 if (!isset($args['region']) && ConfigurationResolver::resolve('region', '', 'string') !== 'us-east-1') {
627 return \false;
628 }
629 $key = 'AWS::S3::UseGlobalEndpoint';
630 $result = $args['s3_us_east_1_regional_endpoint'] instanceof \Closure ? $args['s3_us_east_1_regional_endpoint']()->wait() : $args['s3_us_east_1_regional_endpoint'];
631 if (\is_string($result)) {
632 if ($result === 'regional') {
633 $value = \false;
634 } else {
635 if ($result === 'legacy') {
636 $value = \true;
637 } else {
638 return;
639 }
640 }
641 } else {
642 if ($result->isFallback() || $result->getEndpointsType() === 'legacy') {
643 $value = \true;
644 } else {
645 $value = \false;
646 }
647 }
648 $this->clientBuiltIns[$key] = $value;
649 }
650 /** @internal */
651 public static function _applyRetryConfig($value, $args, HandlerList $list)
652 {
653 if ($value) {
654 $config = \Dudlewebs\WPMCS\s3\Aws\Retry\ConfigurationProvider::unwrap($value);
655 if ($config->getMode() === 'legacy') {
656 $maxRetries = $config->getMaxAttempts() - 1;
657 $decider = RetryMiddleware::createDefaultDecider($maxRetries);
658 $decider = function ($retries, $command, $request, $result, $error) use($decider, $maxRetries) {
659 $maxRetries = $command['@retries'] ?? $maxRetries;
660 if ($decider($retries, $command, $request, $result, $error)) {
661 return \true;
662 }
663 if ($error instanceof AwsException && $retries < $maxRetries) {
664 if ($error->getResponse() && $error->getResponse()->getStatusCode() >= 400) {
665 return \strpos($error->getResponse()->getBody(), 'Your socket connection to the server') !== \false;
666 }
667 if ($error->getPrevious() instanceof RequestException) {
668 // All commands except CompleteMultipartUpload are
669 // idempotent and may be retried without worry if a
670 // networking error has occurred.
671 return $command->getName() !== 'CompleteMultipartUpload';
672 }
673 }
674 return \false;
675 };
676 $delay = [RetryMiddleware::class, 'exponentialDelay'];
677 $list->appendSign(Middleware::retry($decider, $delay), 'retry');
678 } else {
679 $defaultDecider = RetryMiddlewareV2::createDefaultDecider(new QuotaManager(), $config->getMaxAttempts());
680 $list->appendSign(RetryMiddlewareV2::wrap($config, ['collect_stats' => $args['stats']['retries'], 'decider' => function ($attempts, CommandInterface $cmd, $result) use($defaultDecider, $config) {
681 $isRetryable = $defaultDecider($attempts, $cmd, $result);
682 if (!$isRetryable && $result instanceof AwsException && $attempts < $config->getMaxAttempts()) {
683 if (!empty($result->getResponse()) && $result->getResponse()->getStatusCode() >= 400) {
684 return \strpos($result->getResponse()->getBody(), 'Your socket connection to the server') !== \false;
685 }
686 if ($result->getPrevious() instanceof RequestException && $cmd->getName() !== 'CompleteMultipartUpload') {
687 $isRetryable = \true;
688 }
689 }
690 return $isRetryable;
691 }]), 'retry');
692 }
693 }
694 }
695 /** @internal */
696 public static function _applyApiProvider($value, array &$args, HandlerList $list)
697 {
698 ClientResolver::_apply_api_provider($value, $args);
699 $s3Parser = new S3Parser($args['parser'], $args['error_parser'], $args['api'], $args['exception_class']);
700 $s3Parser->addS3ResultMutator('get-bucket-location', new GetBucketLocationResultMutator());
701 $s3Parser->addS3ResultMutator('validate-response-checksum', new ValidateResponseChecksumResultMutator($args['api']));
702 $args['parser'] = $s3Parser;
703 }
704 /**
705 * @internal
706 * @codeCoverageIgnore
707 */
708 public static function applyDocFilters(array $api, array $docs)
709 {
710 $b64 = '<div class="alert alert-info">This value will be base64 encoded on your behalf.</div>';
711 $opt = '<div class="alert alert-info">This value will be computed for you it is not supplied.</div>';
712 // Add a note on the CopyObject docs
713 $s3ExceptionRetryMessage = "<p>Additional info on response behavior: if there is" . " an internal error in S3 after the request was successfully recieved," . " a 200 response will be returned with an <code>S3Exception</code> embedded" . " in it; this will still be caught and retried by" . " <code>RetryMiddleware.</code></p>";
714 $docs['operations']['CopyObject'] .= $s3ExceptionRetryMessage;
715 $docs['operations']['CompleteMultipartUpload'] .= $s3ExceptionRetryMessage;
716 $docs['operations']['UploadPartCopy'] .= $s3ExceptionRetryMessage;
717 $docs['operations']['UploadPart'] .= $s3ExceptionRetryMessage;
718 // Add note about stream ownership in the putObject call
719 $guzzleStreamMessage = "<p>Additional info on behavior of the stream" . " parameters: Psr7 takes ownership of streams and will automatically close" . " streams when this method is called with a stream as the <code>Body</code>" . " parameter. To prevent this, set the <code>Body</code> using" . " <code>GuzzleHttp\\Psr7\\stream_for</code> method with a is an instance of" . " <code>Psr\\Http\\Message\\StreamInterface</code>, and it will be returned" . " unmodified. This will allow you to keep the stream in scope. </p>";
720 $docs['operations']['PutObject'] .= $guzzleStreamMessage;
721 // Add the SourceFile parameter.
722 $docs['shapes']['SourceFile']['base'] = 'The path to a file on disk to use instead of the Body parameter.';
723 $api['shapes']['SourceFile'] = ['type' => 'string'];
724 $api['shapes']['PutObjectRequest']['members']['SourceFile'] = ['shape' => 'SourceFile'];
725 $api['shapes']['UploadPartRequest']['members']['SourceFile'] = ['shape' => 'SourceFile'];
726 // Add the ContentSHA256 parameter.
727 $docs['shapes']['ContentSHA256']['base'] = 'A SHA256 hash of the body content of the request.';
728 $api['shapes']['ContentSHA256'] = ['type' => 'string'];
729 $api['shapes']['PutObjectRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256'];
730 $api['shapes']['UploadPartRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256'];
731 $docs['shapes']['ContentSHA256']['append'] = $opt;
732 // Add the AddContentMD5 parameter.
733 $docs['shapes']['AddContentMD5']['base'] = 'Set to true to calculate the ContentMD5 for the upload.';
734 $api['shapes']['AddContentMD5'] = ['type' => 'boolean'];
735 $api['shapes']['PutObjectRequest']['members']['AddContentMD5'] = ['shape' => 'AddContentMD5'];
736 $api['shapes']['UploadPartRequest']['members']['AddContentMD5'] = ['shape' => 'AddContentMD5'];
737 // Add the SaveAs parameter.
738 $docs['shapes']['SaveAs']['base'] = 'The path to a file on disk to save the object data.';
739 $api['shapes']['SaveAs'] = ['type' => 'string'];
740 $api['shapes']['GetObjectRequest']['members']['SaveAs'] = ['shape' => 'SaveAs'];
741 // Several SSECustomerKey documentation updates.
742 $docs['shapes']['SSECustomerKey']['append'] = $b64;
743 $docs['shapes']['CopySourceSSECustomerKey']['append'] = $b64;
744 $docs['shapes']['SSECustomerKeyMd5']['append'] = $opt;
745 // Add the ObjectURL to various output shapes and documentation.
746 $docs['shapes']['ObjectURL']['base'] = 'The URI of the created object.';
747 $api['shapes']['ObjectURL'] = ['type' => 'string'];
748 $api['shapes']['PutObjectOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
749 $api['shapes']['CopyObjectOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
750 $api['shapes']['CompleteMultipartUploadOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
751 // Fix references to Location Constraint.
752 unset($api['shapes']['CreateBucketRequest']['payload']);
753 $api['shapes']['BucketLocationConstraint']['enum'] = ["ap-northeast-1", "ap-southeast-2", "ap-southeast-1", "cn-north-1", "eu-central-1", "eu-west-1", "us-east-1", "us-west-1", "us-west-2", "sa-east-1"];
754 // Add a note that the ContentMD5 is automatically computed, except for with PutObject and UploadPart
755 $docs['shapes']['ContentMD5']['append'] = '<div class="alert alert-info">The value will be computed on ' . 'your behalf.</div>';
756 $docs['shapes']['ContentMD5']['excludeAppend'] = ['PutObjectRequest', 'UploadPartRequest'];
757 //Add a note to ContentMD5 for PutObject and UploadPart that specifies the value is required
758 // When uploading to a bucket with object lock enabled and that it is not computed automatically
759 $objectLock = '<div class="alert alert-info">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.</div>';
760 $docs['shapes']['ContentMD5']['appendOnly'] = ['message' => $objectLock, 'shapes' => ['PutObjectRequest', 'UploadPartRequest']];
761 // Add `ExpiresString` shape to output structures which contain `Expires`
762 // Deprecate existing `Expires` shapes in output structures
763 // Add/Update documentation for both `ExpiresString` and `Expires`
764 // Ensure `Expires` type remains timestamp
765 foreach ($api['shapes'] as $key => &$value) {
766 $suffix = 'Output';
767 if (\substr($key, -\strlen($suffix)) === $suffix) {
768 if (isset($value['members']['Expires'])) {
769 $value['members']['Expires']['deprecated'] = \true;
770 $value['members']['ExpiresString'] = ['shape' => 'ExpiresString', 'location' => 'header', 'locationName' => 'Expires'];
771 $docs['shapes']['Expires']['refs'][$key . '$Expires'] .= '<p>This output shape has been deprecated. Please refer to <code>ExpiresString</code> instead.</p>.';
772 }
773 }
774 }
775 $api['shapes']['ExpiresString']['type'] = 'string';
776 $docs['shapes']['ExpiresString']['base'] = 'The unparsed string value of the <code>Expires</code> output member.';
777 $api['shapes']['Expires']['type'] = 'timestamp';
778 return [new Service($api, ApiProvider::defaultProvider()), new DocModel($docs)];
779 }
780 /**
781 * @internal
782 * @codeCoverageIgnore
783 */
784 public static function addDocExamples($examples)
785 {
786 $getObjectExample = ['input' => ['Bucket' => 'arn:aws:s3:us-east-1:123456789012:accesspoint:myaccesspoint', 'Key' => 'my-key'], 'output' => ['Body' => 'class GuzzleHttp\\Psr7\\Stream#208 (7) {...}', 'ContentLength' => '11', 'ContentType' => 'application/octet-stream'], 'comments' => ['input' => '', 'output' => 'Simplified example output'], 'description' => 'The following example retrieves an object by referencing the bucket via an S3 accesss point ARN. Result output is simplified for the example.', 'id' => '', 'title' => 'To get an object via an S3 access point ARN'];
787 if (isset($examples['GetObject'])) {
788 $examples['GetObject'][] = $getObjectExample;
789 } else {
790 $examples['GetObject'] = [$getObjectExample];
791 }
792 $putObjectExample = ['input' => ['Bucket' => 'arn:aws:s3:us-east-1:123456789012:accesspoint:myaccesspoint', 'Key' => 'my-key', 'Body' => 'my-body'], 'output' => ['ObjectURL' => 'https://my-bucket.s3.us-east-1.amazonaws.com/my-key'], 'comments' => ['input' => '', 'output' => 'Simplified example output'], 'description' => 'The following example uploads an object by referencing the bucket via an S3 accesss point ARN. Result output is simplified for the example.', 'id' => '', 'title' => 'To upload an object via an S3 access point ARN'];
793 if (isset($examples['PutObject'])) {
794 $examples['PutObject'][] = $putObjectExample;
795 } else {
796 $examples['PutObject'] = [$putObjectExample];
797 }
798 return $examples;
799 }
800 /**
801 * @param CommandInterface $command
802 * @return array|mixed|null
803 */
804 private function getSignatureVersionFromCommand(CommandInterface $command)
805 {
806 return $command['@context']['signature_version'] ?? $this->getConfig('signature_version');
807 }
808 }
809