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 / AwsClient.php

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

389 lines 17.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\ApiProvider;
6 use Dudlewebs\WPMCS\s3\Aws\Api\DocModel;
7 use Dudlewebs\WPMCS\s3\Aws\Api\Service;
8 use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ApiCallAttemptMonitoringMiddleware;
9 use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ApiCallMonitoringMiddleware;
10 use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationProvider;
11 use Dudlewebs\WPMCS\s3\Aws\EndpointDiscovery\EndpointDiscoveryMiddleware;
12 use Dudlewebs\WPMCS\s3\Aws\Signature\SignatureProvider;
13 use Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7\Uri;
14 /**
15 * Default AWS client implementation
16 */
17 class AwsClient implements AwsClientInterface
18 {
19 use AwsClientTrait;
20 /** @var array */
21 private $aliases;
22 /** @var array */
23 private $config;
24 /** @var string */
25 private $region;
26 /** @var string */
27 private $endpoint;
28 /** @var Service */
29 private $api;
30 /** @var callable */
31 private $signatureProvider;
32 /** @var callable */
33 private $credentialProvider;
34 /** @var HandlerList */
35 private $handlerList;
36 /** @var array*/
37 private $defaultRequestOptions;
38 /**
39 * Get an array of client constructor arguments used by the client.
40 *
41 * @return array
42 */
43 public static function getArguments()
44 {
45 return ClientResolver::getDefaultArguments();
46 }
47 /**
48 * The client constructor accepts the following options:
49 *
50 * - api_provider: (callable) An optional PHP callable that accepts a
51 * type, service, and version argument, and returns an array of
52 * corresponding configuration data. The type value can be one of api,
53 * waiter, or paginator.
54 * - credentials:
55 * (Aws\Credentials\CredentialsInterface|array|bool|callable) Specifies
56 * the credentials used to sign requests. Provide an
57 * Aws\Credentials\CredentialsInterface object, an associative array of
58 * "key", "secret", and an optional "token" key, `false` to use null
59 * credentials, or a callable credentials provider used to create
60 * credentials or return null. See Aws\Credentials\CredentialProvider for
61 * a list of built-in credentials providers. If no credentials are
62 * provided, the SDK will attempt to load them from the environment.
63 * - csm:
64 * (Aws\ClientSideMonitoring\ConfigurationInterface|array|callable) Specifies
65 * the credentials used to sign requests. Provide an
66 * Aws\ClientSideMonitoring\ConfigurationInterface object, a callable
67 * configuration provider used to create client-side monitoring configuration,
68 * `false` to disable csm, or an associative array with the following keys:
69 * enabled: (bool) Set to true to enable client-side monitoring, defaults
70 * to false; host: (string) the host location to send monitoring events to,
71 * defaults to 127.0.0.1; port: (int) The port used for the host connection,
72 * defaults to 31000; client_id: (string) An identifier for this project
73 * - debug: (bool|array) Set to true to display debug information when
74 * sending requests. Alternatively, you can provide an associative array
75 * with the following keys: logfn: (callable) Function that is invoked
76 * with log messages; stream_size: (int) When the size of a stream is
77 * greater than this number, the stream data will not be logged (set to
78 * "0" to not log any stream data); scrub_auth: (bool) Set to false to
79 * disable the scrubbing of auth data from the logged messages; http:
80 * (bool) Set to false to disable the "debug" feature of lower level HTTP
81 * adapters (e.g., verbose curl output).
82 * - stats: (bool|array) Set to true to gather transfer statistics on
83 * requests sent. Alternatively, you can provide an associative array with
84 * the following keys: retries: (bool) Set to false to disable reporting
85 * on retries attempted; http: (bool) Set to true to enable collecting
86 * statistics from lower level HTTP adapters (e.g., values returned in
87 * GuzzleHttp\TransferStats). HTTP handlers must support an
88 * `http_stats_receiver` option for this to have an effect; timer: (bool)
89 * Set to true to enable a command timer that reports the total wall clock
90 * time spent on an operation in seconds.
91 * - disable_host_prefix_injection: (bool) Set to true to disable host prefix
92 * injection logic for services that use it. This disables the entire
93 * prefix injection, including the portions supplied by user-defined
94 * parameters. Setting this flag will have no effect on services that do
95 * not use host prefix injection.
96 * - endpoint: (string) The full URI of the webservice. This is only
97 * required when connecting to a custom endpoint (e.g., a local version
98 * of S3).
99 * - endpoint_discovery: (Aws\EndpointDiscovery\ConfigurationInterface,
100 * Aws\CacheInterface, array, callable) Settings for endpoint discovery.
101 * Provide an instance of Aws\EndpointDiscovery\ConfigurationInterface,
102 * an instance Aws\CacheInterface, a callable that provides a promise for
103 * a Configuration object, or an associative array with the following
104 * keys: enabled: (bool) Set to true to enable endpoint discovery, false
105 * to explicitly disable it, defaults to false; cache_limit: (int) The
106 * maximum number of keys in the endpoints cache, defaults to 1000.
107 * - endpoint_provider: (callable) An optional PHP callable that
108 * accepts a hash of options including a "service" and "region" key and
109 * returns NULL or a hash of endpoint data, of which the "endpoint" key
110 * is required. See Aws\Endpoint\EndpointProvider for a list of built-in
111 * providers.
112 * - handler: (callable) A handler that accepts a command object,
113 * request object and returns a promise that is fulfilled with an
114 * Aws\ResultInterface object or rejected with an
115 * Aws\Exception\AwsException. A handler does not accept a next handler
116 * as it is terminal and expected to fulfill a command. If no handler is
117 * provided, a default Guzzle handler will be utilized.
118 * - http: (array, default=array(0)) Set to an array of SDK request
119 * options to apply to each request (e.g., proxy, verify, etc.).
120 * - http_handler: (callable) An HTTP handler is a function that
121 * accepts a PSR-7 request object and returns a promise that is fulfilled
122 * with a PSR-7 response object or rejected with an array of exception
123 * data. NOTE: This option supersedes any provided "handler" option.
124 * - idempotency_auto_fill: (bool|callable) Set to false to disable SDK to
125 * populate parameters that enabled 'idempotencyToken' trait with a random
126 * UUID v4 value on your behalf. Using default value 'true' still allows
127 * parameter value to be overwritten when provided. Note: auto-fill only
128 * works when cryptographically secure random bytes generator functions
129 * (random_bytes, openssl_random_pseudo_bytes or mcrypt_create_iv) can be
130 * found. You may also provide a callable source of random bytes.
131 * - profile: (string) Allows you to specify which profile to use when
132 * credentials are created from the AWS credentials file in your HOME
133 * directory. This setting overrides the AWS_PROFILE environment
134 * variable. Note: Specifying "profile" will cause the "credentials" key
135 * to be ignored.
136 * - region: (string, required) Region to connect to. See
137 * http://docs.aws.amazon.com/general/latest/gr/rande.html for a list of
138 * available regions.
139 * - retries: (int, Aws\Retry\ConfigurationInterface, Aws\CacheInterface,
140 * array, callable) Configures the retry mode and maximum number of
141 * allowed retries for a client (pass 0 to disable retries). Provide an
142 * integer for 'legacy' mode with the specified number of retries.
143 * Otherwise provide an instance of Aws\Retry\ConfigurationInterface, an
144 * instance of Aws\CacheInterface, a callable function, or an array with
145 * the following keys: mode: (string) Set to 'legacy', 'standard' (uses
146 * retry quota management), or 'adapative' (an experimental mode that adds
147 * client-side rate limiting to standard mode); max_attempts (int) The
148 * maximum number of attempts for a given request.
149 * - scheme: (string, default=string(5) "https") URI scheme to use when
150 * connecting connect. The SDK will utilize "https" endpoints (i.e.,
151 * utilize SSL/TLS connections) by default. You can attempt to connect to
152 * a service over an unencrypted "http" endpoint by setting ``scheme`` to
153 * "http".
154 * - signature_provider: (callable) A callable that accepts a signature
155 * version name (e.g., "v4"), a service name, and region, and
156 * returns a SignatureInterface object or null. This provider is used to
157 * create signers utilized by the client. See
158 * Aws\Signature\SignatureProvider for a list of built-in providers
159 * - signature_version: (string) A string representing a custom
160 * signature version to use with a service (e.g., v4). Note that
161 * per/operation signature version MAY override this requested signature
162 * version.
163 * - use_aws_shared_config_files: (bool, default=bool(true)) Set to false to
164 * disable checking for shared config file in '~/.aws/config' and
165 * '~/.aws/credentials'. This will override the AWS_CONFIG_FILE
166 * environment variable.
167 * - validate: (bool, default=bool(true)) Set to false to disable
168 * client-side parameter validation.
169 * - version: (string, required) The version of the webservice to
170 * utilize (e.g., 2006-03-01).
171 *
172 * @param array $args Client configuration arguments.
173 *
174 * @throws \InvalidArgumentException if any required options are missing or
175 * the service is not supported.
176 */
177 public function __construct(array $args)
178 {
179 list($service, $exceptionClass) = $this->parseClass();
180 if (!isset($args['service'])) {
181 $args['service'] = manifest($service)['endpoint'];
182 }
183 if (!isset($args['exception_class'])) {
184 $args['exception_class'] = $exceptionClass;
185 }
186 $this->handlerList = new HandlerList();
187 $resolver = new ClientResolver(static::getArguments());
188 $config = $resolver->resolve($args, $this->handlerList);
189 $this->api = $config['api'];
190 $this->signatureProvider = $config['signature_provider'];
191 $this->endpoint = new Uri($config['endpoint']);
192 $this->credentialProvider = $config['credentials'];
193 $this->region = isset($config['region']) ? $config['region'] : null;
194 $this->config = $config['config'];
195 $this->defaultRequestOptions = $config['http'];
196 $this->addSignatureMiddleware();
197 $this->addInvocationId();
198 $this->addEndpointParameterMiddleware($args);
199 $this->addEndpointDiscoveryMiddleware($config, $args);
200 $this->loadAliases();
201 $this->addStreamRequestPayload();
202 $this->addRecursionDetection();
203 if (isset($args['with_resolved'])) {
204 $args['with_resolved']($config);
205 }
206 }
207 public function getHandlerList()
208 {
209 return $this->handlerList;
210 }
211 public function getConfig($option = null)
212 {
213 return $option === null ? $this->config : (isset($this->config[$option]) ? $this->config[$option] : null);
214 }
215 public function getCredentials()
216 {
217 $fn = $this->credentialProvider;
218 return $fn();
219 }
220 public function getEndpoint()
221 {
222 return $this->endpoint;
223 }
224 public function getRegion()
225 {
226 return $this->region;
227 }
228 public function getApi()
229 {
230 return $this->api;
231 }
232 public function getCommand($name, array $args = [])
233 {
234 // Fail fast if the command cannot be found in the description.
235 if (!isset($this->getApi()['operations'][$name])) {
236 $name = \ucfirst($name);
237 if (!isset($this->getApi()['operations'][$name])) {
238 throw new \InvalidArgumentException("Operation not found: {$name}");
239 }
240 }
241 if (!isset($args['@http'])) {
242 $args['@http'] = $this->defaultRequestOptions;
243 } else {
244 $args['@http'] += $this->defaultRequestOptions;
245 }
246 return new Command($name, $args, clone $this->getHandlerList());
247 }
248 public function __sleep()
249 {
250 throw new \RuntimeException('Instances of ' . static::class . ' cannot be serialized');
251 }
252 /**
253 * Get the signature_provider function of the client.
254 *
255 * @return callable
256 */
257 public final function getSignatureProvider()
258 {
259 return $this->signatureProvider;
260 }
261 /**
262 * Parse the class name and setup the custom exception class of the client
263 * and return the "service" name of the client and "exception_class".
264 *
265 * @return array
266 */
267 private function parseClass()
268 {
269 $klass = \get_class($this);
270 if ($klass === __CLASS__) {
271 return ['', 'Dudlewebs\\WPMCS\\s3\\Aws\\Exception\\AwsException'];
272 }
273 $service = \substr($klass, \strrpos($klass, '\\') + 1, -6);
274 return [\strtolower($service), "Dudlewebs\\WPMCS\\s3\\Aws\\{$service}\\Exception\\{$service}Exception"];
275 }
276 private function addEndpointParameterMiddleware($args)
277 {
278 if (empty($args['disable_host_prefix_injection'])) {
279 $list = $this->getHandlerList();
280 $list->appendBuild(EndpointParameterMiddleware::wrap($this->api), 'endpoint_parameter');
281 }
282 }
283 private function addEndpointDiscoveryMiddleware($config, $args)
284 {
285 $list = $this->getHandlerList();
286 if (!isset($args['endpoint'])) {
287 $list->appendBuild(EndpointDiscoveryMiddleware::wrap($this, $args, $config['endpoint_discovery']), 'EndpointDiscoveryMiddleware');
288 }
289 }
290 private function addSignatureMiddleware()
291 {
292 $api = $this->getApi();
293 $provider = $this->signatureProvider;
294 $version = $this->config['signature_version'];
295 $name = $this->config['signing_name'];
296 $region = $this->config['signing_region'];
297 $resolver = static function (CommandInterface $c) use($api, $provider, $name, $region, $version) {
298 if (!empty($c['@context']['signing_region'])) {
299 $region = $c['@context']['signing_region'];
300 }
301 if (!empty($c['@context']['signing_service'])) {
302 $name = $c['@context']['signing_service'];
303 }
304 $authType = $api->getOperation($c->getName())['authtype'];
305 switch ($authType) {
306 case 'none':
307 $version = 'anonymous';
308 break;
309 case 'v4-unsigned-body':
310 $version = 'v4-unsigned-body';
311 break;
312 }
313 if (isset($c['@context']['signature_version'])) {
314 if ($c['@context']['signature_version'] == 'v4a') {
315 $version = 'v4a';
316 }
317 }
318 return SignatureProvider::resolve($provider, $version, $name, $region);
319 };
320 $this->handlerList->appendSign(Middleware::signer($this->credentialProvider, $resolver), 'signer');
321 }
322 private function addInvocationId()
323 {
324 // Add invocation id to each request
325 $this->handlerList->prependSign(Middleware::invocationId(), 'invocation-id');
326 }
327 private function loadAliases($file = null)
328 {
329 if (!isset($this->aliases)) {
330 if (\is_null($file)) {
331 $file = __DIR__ . '/data/aliases.json';
332 }
333 $aliases = \Dudlewebs\WPMCS\s3\Aws\load_compiled_json($file);
334 $serviceId = $this->api->getServiceId();
335 $version = $this->getApi()->getApiVersion();
336 if (!empty($aliases['operations'][$serviceId][$version])) {
337 $this->aliases = \array_flip($aliases['operations'][$serviceId][$version]);
338 }
339 }
340 }
341 private function addStreamRequestPayload()
342 {
343 $streamRequestPayloadMiddleware = StreamRequestPayloadMiddleware::wrap($this->api);
344 $this->handlerList->prependSign($streamRequestPayloadMiddleware, 'StreamRequestPayloadMiddleware');
345 }
346 private function addRecursionDetection()
347 {
348 // Add recursion detection header to requests
349 // originating in supported Lambda runtimes
350 $this->handlerList->appendBuild(Middleware::recursionDetection(), 'recursion-detection');
351 }
352 /**
353 * Returns a service model and doc model with any necessary changes
354 * applied.
355 *
356 * @param array $api Array of service data being documented.
357 * @param array $docs Array of doc model data.
358 *
359 * @return array Tuple containing a [Service, DocModel]
360 *
361 * @internal This should only used to document the service API.
362 * @codeCoverageIgnore
363 */
364 public static function applyDocFilters(array $api, array $docs)
365 {
366 $aliases = \Dudlewebs\WPMCS\s3\Aws\load_compiled_json(__DIR__ . '/data/aliases.json');
367 $serviceId = $api['metadata']['serviceId'];
368 $version = $api['metadata']['apiVersion'];
369 // Replace names for any operations with SDK aliases
370 if (!empty($aliases['operations'][$serviceId][$version])) {
371 foreach ($aliases['operations'][$serviceId][$version] as $op => $alias) {
372 $api['operations'][$alias] = $api['operations'][$op];
373 $docs['operations'][$alias] = $docs['operations'][$op];
374 unset($api['operations'][$op], $docs['operations'][$op]);
375 }
376 }
377 \ksort($api['operations']);
378 return [new Service($api, ApiProvider::defaultProvider()), new DocModel($docs)];
379 }
380 /**
381 * @deprecated
382 * @return static
383 */
384 public static function factory(array $config = [])
385 {
386 return new static($config);
387 }
388 }
389