PluginProbe
Media Cloud Sync / 1.4.1
Media Cloud Sync v1.4.1
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 1.2.9 All 35 releases
media-cloud-sync / includes / sdk / s3 / Aws / S3 / S3Client.php

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

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