PluginProbe
Media Cloud Sync / 1.2.13
Media Cloud Sync v1.2.13
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 / Middleware.php

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

326 lines 13.9 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;
4
5 use Dudlewebs\WPMCS\s3\Aws\Api\Service;
6 use Dudlewebs\WPMCS\s3\Aws\Api\Validator;
7 use Dudlewebs\WPMCS\s3\Aws\Credentials\CredentialsInterface;
8 use Dudlewebs\WPMCS\s3\Aws\EndpointV2\EndpointProviderV2;
9 use Dudlewebs\WPMCS\s3\Aws\Exception\AwsException;
10 use Dudlewebs\WPMCS\s3\Aws\Signature\S3ExpressSignature;
11 use Dudlewebs\WPMCS\s3\Aws\Token\TokenAuthorization;
12 use Dudlewebs\WPMCS\s3\Aws\Token\TokenInterface;
13 use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise;
14 use Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7;
15 use Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7\LazyOpenStream;
16 use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface;
17 final class Middleware
18 {
19 /**
20 * Middleware used to allow a command parameter (e.g., "SourceFile") to
21 * be used to specify the source of data for an upload operation.
22 *
23 * @param Service $api
24 * @param string $bodyParameter
25 * @param string $sourceParameter
26 *
27 * @return callable
28 */
29 public static function sourceFile(Service $api, $bodyParameter = 'Body', $sourceParameter = 'SourceFile')
30 {
31 return function (callable $handler) use($api, $bodyParameter, $sourceParameter) {
32 return function (CommandInterface $command, RequestInterface $request = null) use($handler, $api, $bodyParameter, $sourceParameter) {
33 $operation = $api->getOperation($command->getName());
34 $source = $command[$sourceParameter];
35 if ($source !== null && $operation->getInput()->hasMember($bodyParameter)) {
36 $command[$bodyParameter] = new LazyOpenStream($source, 'r');
37 unset($command[$sourceParameter]);
38 }
39 return $handler($command, $request);
40 };
41 };
42 }
43 /**
44 * Adds a middleware that uses client-side validation.
45 *
46 * @param Service $api API being accessed.
47 *
48 * @return callable
49 */
50 public static function validation(Service $api, Validator $validator = null)
51 {
52 $validator = $validator ?: new Validator();
53 return function (callable $handler) use($api, $validator) {
54 return function (CommandInterface $command, RequestInterface $request = null) use($api, $validator, $handler) {
55 if ($api->isModifiedModel()) {
56 $api = new Service($api->getDefinition(), $api->getProvider());
57 }
58 $operation = $api->getOperation($command->getName());
59 $validator->validate($command->getName(), $operation->getInput(), $command->toArray());
60 return $handler($command, $request);
61 };
62 };
63 }
64 /**
65 * Builds an HTTP request for a command.
66 *
67 * @param callable $serializer Function used to serialize a request for a
68 * command.
69 * @param EndpointProviderV2 | null $endpointProvider
70 * @param array $providerArgs
71 * @return callable
72 */
73 public static function requestBuilder($serializer)
74 {
75 return function (callable $handler) use($serializer) {
76 return function (CommandInterface $command, $endpoint = null) use($serializer, $handler) {
77 return $handler($command, $serializer($command, $endpoint));
78 };
79 };
80 }
81 /**
82 * Creates a middleware that signs requests for a command.
83 *
84 * @param callable $credProvider Credentials provider function that
85 * returns a promise that is resolved
86 * with a CredentialsInterface object.
87 * @param callable $signatureFunction Function that accepts a Command
88 * object and returns a
89 * SignatureInterface.
90 *
91 * @return callable
92 */
93 public static function signer(callable $credProvider, callable $signatureFunction, $tokenProvider = null, $config = [])
94 {
95 return function (callable $handler) use($signatureFunction, $credProvider, $tokenProvider, $config) {
96 return function (CommandInterface $command, RequestInterface $request) use($handler, $signatureFunction, $credProvider, $tokenProvider, $config) {
97 $signer = $signatureFunction($command);
98 if ($signer instanceof TokenAuthorization) {
99 return $tokenProvider()->then(function (TokenInterface $token) use($handler, $command, $signer, $request) {
100 return $handler($command, $signer->authorizeRequest($request, $token));
101 });
102 }
103 if ($signer instanceof S3ExpressSignature) {
104 $credentialPromise = $config['s3_express_identity_provider']($command);
105 } else {
106 $credentialPromise = $credProvider();
107 }
108 return $credentialPromise->then(function (CredentialsInterface $creds) use($handler, $command, $signer, $request) {
109 return $handler($command, $signer->signRequest($request, $creds));
110 });
111 };
112 };
113 }
114 /**
115 * Creates a middleware that invokes a callback at a given step.
116 *
117 * The tap callback accepts a CommandInterface and RequestInterface as
118 * arguments but is not expected to return a new value or proxy to
119 * downstream middleware. It's simply a way to "tap" into the handler chain
120 * to debug or get an intermediate value.
121 *
122 * @param callable $fn Tap function
123 *
124 * @return callable
125 */
126 public static function tap(callable $fn)
127 {
128 return function (callable $handler) use($fn) {
129 return function (CommandInterface $command, RequestInterface $request = null) use($handler, $fn) {
130 $fn($command, $request);
131 return $handler($command, $request);
132 };
133 };
134 }
135 /**
136 * Middleware wrapper function that retries requests based on the boolean
137 * result of invoking the provided "decider" function.
138 *
139 * If no delay function is provided, a simple implementation of exponential
140 * backoff will be utilized.
141 *
142 * @param callable $decider Function that accepts the number of retries,
143 * a request, [result], and [exception] and
144 * returns true if the command is to be retried.
145 * @param callable $delay Function that accepts the number of retries and
146 * returns the number of milliseconds to delay.
147 * @param bool $stats Whether to collect statistics on retries and the
148 * associated delay.
149 *
150 * @return callable
151 */
152 public static function retry(callable $decider = null, callable $delay = null, $stats = \false)
153 {
154 $decider = $decider ?: RetryMiddleware::createDefaultDecider();
155 $delay = $delay ?: [RetryMiddleware::class, 'exponentialDelay'];
156 return function (callable $handler) use($decider, $delay, $stats) {
157 return new RetryMiddleware($decider, $delay, $handler, $stats);
158 };
159 }
160 /**
161 * Middleware wrapper function that adds an invocation id header to
162 * requests, which is only applied after the build step.
163 *
164 * This is a uniquely generated UUID to identify initial and subsequent
165 * retries as part of a complete request lifecycle.
166 *
167 * @return callable
168 */
169 public static function invocationId()
170 {
171 return function (callable $handler) {
172 return function (CommandInterface $command, RequestInterface $request) use($handler) {
173 return $handler($command, $request->withHeader('aws-sdk-invocation-id', \md5(\uniqid(\gethostname(), \true))));
174 };
175 };
176 }
177 /**
178 * Middleware wrapper function that adds a Content-Type header to requests.
179 * This is only done when the Content-Type has not already been set, and the
180 * request body's URI is available. It then checks the file extension of the
181 * URI to determine the mime-type.
182 *
183 * @param array $operations Operations that Content-Type should be added to.
184 *
185 * @return callable
186 */
187 public static function contentType(array $operations)
188 {
189 return function (callable $handler) use($operations) {
190 return function (CommandInterface $command, RequestInterface $request = null) use($handler, $operations) {
191 if (!$request->hasHeader('Content-Type') && \in_array($command->getName(), $operations, \true) && ($uri = $request->getBody()->getMetadata('uri'))) {
192 $request = $request->withHeader('Content-Type', Psr7\MimeType::fromFilename($uri) ?: 'application/octet-stream');
193 }
194 return $handler($command, $request);
195 };
196 };
197 }
198 /**
199 * Middleware wrapper function that adds a trace id header to requests
200 * from clients instantiated in supported Lambda runtime environments.
201 *
202 * The purpose for this header is to track and stop Lambda functions
203 * from being recursively invoked due to misconfigured resources.
204 *
205 * @return callable
206 */
207 public static function recursionDetection()
208 {
209 return function (callable $handler) {
210 return function (CommandInterface $command, RequestInterface $request) use($handler) {
211 $isLambda = \getenv('AWS_LAMBDA_FUNCTION_NAME');
212 $traceId = \str_replace('\\e', '\\x1b', \getenv('_X_AMZN_TRACE_ID'));
213 if ($isLambda && $traceId) {
214 if (!$request->hasHeader('X-Amzn-Trace-Id')) {
215 $ignoreChars = ['=', ';', ':', '+', '&', '[', ']', '{', '}', '"', '\'', ','];
216 $traceIdEncoded = \rawurlencode(\stripcslashes($traceId));
217 foreach ($ignoreChars as $char) {
218 $encodedChar = \rawurlencode($char);
219 $traceIdEncoded = \str_replace($encodedChar, $char, $traceIdEncoded);
220 }
221 return $handler($command, $request->withHeader('X-Amzn-Trace-Id', $traceIdEncoded));
222 }
223 }
224 return $handler($command, $request);
225 };
226 };
227 }
228 /**
229 * Tracks command and request history using a history container.
230 *
231 * This is useful for testing.
232 *
233 * @param History $history History container to store entries.
234 *
235 * @return callable
236 */
237 public static function history(History $history)
238 {
239 return function (callable $handler) use($history) {
240 return function (CommandInterface $command, RequestInterface $request = null) use($handler, $history) {
241 $ticket = $history->start($command, $request);
242 return $handler($command, $request)->then(function ($result) use($history, $ticket) {
243 $history->finish($ticket, $result);
244 return $result;
245 }, function ($reason) use($history, $ticket) {
246 $history->finish($ticket, $reason);
247 return Promise\Create::rejectionFor($reason);
248 });
249 };
250 };
251 }
252 /**
253 * Creates a middleware that applies a map function to requests as they
254 * pass through the middleware.
255 *
256 * @param callable $f Map function that accepts a RequestInterface and
257 * returns a RequestInterface.
258 *
259 * @return callable
260 */
261 public static function mapRequest(callable $f)
262 {
263 return function (callable $handler) use($f) {
264 return function (CommandInterface $command, RequestInterface $request = null) use($handler, $f) {
265 return $handler($command, $f($request));
266 };
267 };
268 }
269 /**
270 * Creates a middleware that applies a map function to commands as they
271 * pass through the middleware.
272 *
273 * @param callable $f Map function that accepts a command and returns a
274 * command.
275 *
276 * @return callable
277 */
278 public static function mapCommand(callable $f)
279 {
280 return function (callable $handler) use($f) {
281 return function (CommandInterface $command, RequestInterface $request = null) use($handler, $f) {
282 return $handler($f($command), $request);
283 };
284 };
285 }
286 /**
287 * Creates a middleware that applies a map function to results.
288 *
289 * @param callable $f Map function that accepts an Aws\ResultInterface and
290 * returns an Aws\ResultInterface.
291 *
292 * @return callable
293 */
294 public static function mapResult(callable $f)
295 {
296 return function (callable $handler) use($f) {
297 return function (CommandInterface $command, RequestInterface $request = null) use($handler, $f) {
298 return $handler($command, $request)->then($f);
299 };
300 };
301 }
302 public static function timer()
303 {
304 return function (callable $handler) {
305 return function (CommandInterface $command, RequestInterface $request = null) use($handler) {
306 $start = \microtime(\true);
307 return $handler($command, $request)->then(function (ResultInterface $res) use($start) {
308 if (!isset($res['@metadata'])) {
309 $res['@metadata'] = [];
310 }
311 if (!isset($res['@metadata']['transferStats'])) {
312 $res['@metadata']['transferStats'] = [];
313 }
314 $res['@metadata']['transferStats']['total_time'] = \microtime(\true) - $start;
315 return $res;
316 }, function ($err) use($start) {
317 if ($err instanceof AwsException) {
318 $err->setTransferInfo(['total_time' => \microtime(\true) - $start] + $err->getTransferInfo());
319 }
320 return Promise\Create::rejectionFor($err);
321 });
322 };
323 };
324 }
325 }
326