PluginProbe
Media Cloud Sync / 1.2.12
Media Cloud Sync v1.2.12
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 1.3.0 All 34 releases
media-cloud-sync / includes / sdk / s3 / Aws / Middleware.php

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

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