AwsClient.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. <?php
  2. namespace Aws;
  3. use Aws\Api\ApiProvider;
  4. use Aws\Api\DocModel;
  5. use Aws\Api\Service;
  6. use Aws\Auth\AuthSelectionMiddleware;
  7. use Aws\Auth\AuthSchemeResolverInterface;
  8. use Aws\EndpointDiscovery\EndpointDiscoveryMiddleware;
  9. use Aws\EndpointV2\EndpointProviderV2;
  10. use Aws\EndpointV2\EndpointV2Middleware;
  11. use Aws\Exception\AwsException;
  12. use Aws\Signature\SignatureProvider;
  13. use 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 $signingRegionSet;
  28. /** @var string */
  29. private $endpoint;
  30. /** @var Service */
  31. private $api;
  32. /** @var callable */
  33. private $signatureProvider;
  34. /** @var AuthSchemeResolverInterface */
  35. private $authSchemeResolver;
  36. /** @var callable */
  37. private $credentialProvider;
  38. /** @var callable */
  39. private $tokenProvider;
  40. /** @var HandlerList */
  41. private $handlerList;
  42. /** @var array*/
  43. private $defaultRequestOptions;
  44. /** @var array*/
  45. private $clientContextParams = [];
  46. /** @var array*/
  47. protected $clientBuiltIns = [];
  48. /** @var EndpointProviderV2 | callable */
  49. protected $endpointProvider;
  50. /** @var callable */
  51. protected $serializer;
  52. /**
  53. * Get an array of client constructor arguments used by the client.
  54. *
  55. * @return array
  56. */
  57. public static function getArguments()
  58. {
  59. return ClientResolver::getDefaultArguments();
  60. }
  61. /**
  62. * The client constructor accepts the following options:
  63. *
  64. * - api_provider: (callable) An optional PHP callable that accepts a
  65. * type, service, and version argument, and returns an array of
  66. * corresponding configuration data. The type value can be one of api,
  67. * waiter, or paginator.
  68. * - credentials:
  69. * (Aws\Credentials\CredentialsInterface|array|bool|callable) Specifies
  70. * the credentials used to sign requests. Provide an
  71. * Aws\Credentials\CredentialsInterface object, an associative array of
  72. * "key", "secret", and an optional "token" key, `false` to use null
  73. * credentials, or a callable credentials provider used to create
  74. * credentials or return null. See Aws\Credentials\CredentialProvider for
  75. * a list of built-in credentials providers. If no credentials are
  76. * provided, the SDK will attempt to load them from the environment.
  77. * - token:
  78. * (Aws\Token\TokenInterface|array|bool|callable) Specifies
  79. * the token used to authorize requests. Provide an
  80. * Aws\Token\TokenInterface object, an associative array of
  81. * "token" and an optional "expires" key, `false` to use no
  82. * token, or a callable token provider used to create a
  83. * token or return null. See Aws\Token\TokenProvider for
  84. * a list of built-in token providers. If no token is
  85. * provided, the SDK will attempt to load one from the environment.
  86. * - csm:
  87. * (Aws\ClientSideMonitoring\ConfigurationInterface|array|callable) Specifies
  88. * the credentials used to sign requests. Provide an
  89. * Aws\ClientSideMonitoring\ConfigurationInterface object, a callable
  90. * configuration provider used to create client-side monitoring configuration,
  91. * `false` to disable csm, or an associative array with the following keys:
  92. * enabled: (bool) Set to true to enable client-side monitoring, defaults
  93. * to false; host: (string) the host location to send monitoring events to,
  94. * defaults to 127.0.0.1; port: (int) The port used for the host connection,
  95. * defaults to 31000; client_id: (string) An identifier for this project
  96. * - debug: (bool|array) Set to true to display debug information when
  97. * sending requests. Alternatively, you can provide an associative array
  98. * with the following keys: logfn: (callable) Function that is invoked
  99. * with log messages; stream_size: (int) When the size of a stream is
  100. * greater than this number, the stream data will not be logged (set to
  101. * "0" to not log any stream data); scrub_auth: (bool) Set to false to
  102. * disable the scrubbing of auth data from the logged messages; http:
  103. * (bool) Set to false to disable the "debug" feature of lower level HTTP
  104. * adapters (e.g., verbose curl output).
  105. * - stats: (bool|array) Set to true to gather transfer statistics on
  106. * requests sent. Alternatively, you can provide an associative array with
  107. * the following keys: retries: (bool) Set to false to disable reporting
  108. * on retries attempted; http: (bool) Set to true to enable collecting
  109. * statistics from lower level HTTP adapters (e.g., values returned in
  110. * GuzzleHttp\TransferStats). HTTP handlers must support an
  111. * `http_stats_receiver` option for this to have an effect; timer: (bool)
  112. * Set to true to enable a command timer that reports the total wall clock
  113. * time spent on an operation in seconds.
  114. * - disable_host_prefix_injection: (bool) Set to true to disable host prefix
  115. * injection logic for services that use it. This disables the entire
  116. * prefix injection, including the portions supplied by user-defined
  117. * parameters. Setting this flag will have no effect on services that do
  118. * not use host prefix injection.
  119. * - endpoint: (string) The full URI of the webservice. This is only
  120. * required when connecting to a custom endpoint (e.g., a local version
  121. * of S3).
  122. * - endpoint_discovery: (Aws\EndpointDiscovery\ConfigurationInterface,
  123. * Aws\CacheInterface, array, callable) Settings for endpoint discovery.
  124. * Provide an instance of Aws\EndpointDiscovery\ConfigurationInterface,
  125. * an instance Aws\CacheInterface, a callable that provides a promise for
  126. * a Configuration object, or an associative array with the following
  127. * keys: enabled: (bool) Set to true to enable endpoint discovery, false
  128. * to explicitly disable it, defaults to false; cache_limit: (int) The
  129. * maximum number of keys in the endpoints cache, defaults to 1000.
  130. * - endpoint_provider: (callable) An optional PHP callable that
  131. * accepts a hash of options including a "service" and "region" key and
  132. * returns NULL or a hash of endpoint data, of which the "endpoint" key
  133. * is required. See Aws\Endpoint\EndpointProvider for a list of built-in
  134. * providers.
  135. * - handler: (callable) A handler that accepts a command object,
  136. * request object and returns a promise that is fulfilled with an
  137. * Aws\ResultInterface object or rejected with an
  138. * Aws\Exception\AwsException. A handler does not accept a next handler
  139. * as it is terminal and expected to fulfill a command. If no handler is
  140. * provided, a default Guzzle handler will be utilized.
  141. * - http: (array, default=array(0)) Set to an array of SDK request
  142. * options to apply to each request (e.g., proxy, verify, etc.).
  143. * - http_handler: (callable) An HTTP handler is a function that
  144. * accepts a PSR-7 request object and returns a promise that is fulfilled
  145. * with a PSR-7 response object or rejected with an array of exception
  146. * data. NOTE: This option supersedes any provided "handler" option.
  147. * - idempotency_auto_fill: (bool|callable) Set to false to disable SDK to
  148. * populate parameters that enabled 'idempotencyToken' trait with a random
  149. * UUID v4 value on your behalf. Using default value 'true' still allows
  150. * parameter value to be overwritten when provided. Note: auto-fill only
  151. * works when cryptographically secure random bytes generator functions
  152. * (random_bytes, openssl_random_pseudo_bytes or mcrypt_create_iv) can be
  153. * found. You may also provide a callable source of random bytes.
  154. * - profile: (string) Allows you to specify which profile to use when
  155. * credentials are created from the AWS credentials file in your HOME
  156. * directory. This setting overrides the AWS_PROFILE environment
  157. * variable. Note: Specifying "profile" will cause the "credentials" key
  158. * to be ignored.
  159. * - region: (string, required) Region to connect to. See
  160. * http://docs.aws.amazon.com/general/latest/gr/rande.html for a list of
  161. * available regions.
  162. * - retries: (int, Aws\Retry\ConfigurationInterface, Aws\CacheInterface,
  163. * array, callable) Configures the retry mode and maximum number of
  164. * allowed retries for a client (pass 0 to disable retries). Provide an
  165. * integer for 'legacy' mode with the specified number of retries.
  166. * Otherwise provide an instance of Aws\Retry\ConfigurationInterface, an
  167. * instance of Aws\CacheInterface, a callable function, or an array with
  168. * the following keys: mode: (string) Set to 'legacy', 'standard' (uses
  169. * retry quota management), or 'adapative' (an experimental mode that adds
  170. * client-side rate limiting to standard mode); max_attempts (int) The
  171. * maximum number of attempts for a given request.
  172. * - scheme: (string, default=string(5) "https") URI scheme to use when
  173. * connecting connect. The SDK will utilize "https" endpoints (i.e.,
  174. * utilize SSL/TLS connections) by default. You can attempt to connect to
  175. * a service over an unencrypted "http" endpoint by setting ``scheme`` to
  176. * "http".
  177. * - signature_provider: (callable) A callable that accepts a signature
  178. * version name (e.g., "v4"), a service name, and region, and
  179. * returns a SignatureInterface object or null. This provider is used to
  180. * create signers utilized by the client. See
  181. * Aws\Signature\SignatureProvider for a list of built-in providers
  182. * - signature_version: (string) A string representing a custom
  183. * signature version to use with a service (e.g., v4). Note that
  184. * per/operation signature version MAY override this requested signature
  185. * version.
  186. * - use_aws_shared_config_files: (bool, default=bool(true)) Set to false to
  187. * disable checking for shared config file in '~/.aws/config' and
  188. * '~/.aws/credentials'. This will override the AWS_CONFIG_FILE
  189. * environment variable.
  190. * - validate: (bool, default=bool(true)) Set to false to disable
  191. * client-side parameter validation.
  192. * - version: (string, required) The version of the webservice to
  193. * utilize (e.g., 2006-03-01).
  194. * - account_id_endpoint_mode: (string, default(preferred)) this option
  195. * decides whether credentials should resolve an accountId value,
  196. * which is going to be used as part of the endpoint resolution.
  197. * The valid values for this option are:
  198. * - preferred: when this value is set then, a warning is logged when
  199. * accountId is empty in the resolved identity.
  200. * - required: when this value is set then, an exception is thrown when
  201. * accountId is empty in the resolved identity.
  202. * - disabled: when this value is set then, the validation for if accountId
  203. * was resolved or not, is ignored.
  204. * - ua_append: (string, array) To pass custom user agent parameters.
  205. * - app_id: (string) an optional application specific identifier that can be set.
  206. * When set it will be appended to the User-Agent header of every request
  207. * in the form of App/{AppId}. This variable is sourced from environment
  208. * variable AWS_SDK_UA_APP_ID or the shared config profile attribute sdk_ua_app_id.
  209. * See https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html for
  210. * more information on environment variables and shared config settings.
  211. *
  212. * @param array $args Client configuration arguments.
  213. *
  214. * @throws \InvalidArgumentException if any required options are missing or
  215. * the service is not supported.
  216. */
  217. public function __construct(array $args)
  218. {
  219. list($service, $exceptionClass) = $this->parseClass();
  220. if (!isset($args['service'])) {
  221. $args['service'] = manifest($service)['endpoint'];
  222. }
  223. if (!isset($args['exception_class'])) {
  224. $args['exception_class'] = $exceptionClass;
  225. }
  226. $this->handlerList = new HandlerList();
  227. $resolver = new ClientResolver(static::getArguments());
  228. $config = $resolver->resolve($args, $this->handlerList);
  229. $this->api = $config['api'];
  230. $this->signatureProvider = $config['signature_provider'];
  231. $this->authSchemeResolver = $config['auth_scheme_resolver'];
  232. $this->endpoint = new Uri($config['endpoint']);
  233. $this->credentialProvider = $config['credentials'];
  234. $this->tokenProvider = $config['token'];
  235. $this->region = $config['region'] ?? null;
  236. $this->signingRegionSet = $config['sigv4a_signing_region_set'] ?? null;
  237. $this->config = $config['config'];
  238. $this->setClientBuiltIns($args, $config);
  239. $this->clientContextParams = $this->setClientContextParams($args);
  240. $this->defaultRequestOptions = $config['http'];
  241. $this->endpointProvider = $config['endpoint_provider'];
  242. $this->serializer = $config['serializer'];
  243. $this->addSignatureMiddleware($args);
  244. $this->addInvocationId();
  245. $this->addEndpointParameterMiddleware($args);
  246. $this->addEndpointDiscoveryMiddleware($config, $args);
  247. $this->addRequestCompressionMiddleware($config);
  248. $this->loadAliases();
  249. $this->addStreamRequestPayload();
  250. $this->addRecursionDetection();
  251. if ($this->isUseEndpointV2()) {
  252. $this->addEndpointV2Middleware();
  253. }
  254. $this->addAuthSelectionMiddleware();
  255. if (!is_null($this->api->getMetadata('awsQueryCompatible'))) {
  256. $this->addQueryCompatibleInputMiddleware($this->api);
  257. }
  258. if (isset($args['with_resolved'])) {
  259. $args['with_resolved']($config);
  260. }
  261. }
  262. public function getHandlerList()
  263. {
  264. return $this->handlerList;
  265. }
  266. public function getConfig($option = null)
  267. {
  268. return $option === null
  269. ? $this->config
  270. : $this->config[$option] ?? null;
  271. }
  272. public function getCredentials()
  273. {
  274. $fn = $this->credentialProvider;
  275. return $fn();
  276. }
  277. public function getEndpoint()
  278. {
  279. return $this->endpoint;
  280. }
  281. public function getRegion()
  282. {
  283. return $this->region;
  284. }
  285. public function getApi()
  286. {
  287. return $this->api;
  288. }
  289. public function getCommand($name, array $args = [])
  290. {
  291. // Fail fast if the command cannot be found in the description.
  292. if (!isset($this->getApi()['operations'][$name])) {
  293. $name = ucfirst($name);
  294. if (!isset($this->getApi()['operations'][$name])) {
  295. throw new \InvalidArgumentException("Operation not found: $name");
  296. }
  297. }
  298. if (!isset($args['@http'])) {
  299. $args['@http'] = $this->defaultRequestOptions;
  300. } else {
  301. $args['@http'] += $this->defaultRequestOptions;
  302. }
  303. return new Command($name, $args, clone $this->getHandlerList());
  304. }
  305. public function getEndpointProvider()
  306. {
  307. return $this->endpointProvider;
  308. }
  309. /**
  310. * Provides the set of service context parameter
  311. * key-value pairs used for endpoint resolution.
  312. *
  313. * @return array
  314. */
  315. public function getClientContextParams()
  316. {
  317. return $this->clientContextParams;
  318. }
  319. /**
  320. * Provides the set of built-in keys and values
  321. * used for endpoint resolution
  322. *
  323. * @return array
  324. */
  325. public function getClientBuiltIns()
  326. {
  327. return $this->clientBuiltIns;
  328. }
  329. public function __sleep()
  330. {
  331. throw new \RuntimeException('Instances of ' . static::class
  332. . ' cannot be serialized');
  333. }
  334. /**
  335. * Get the signature_provider function of the client.
  336. *
  337. * @return callable
  338. */
  339. final public function getSignatureProvider()
  340. {
  341. return $this->signatureProvider;
  342. }
  343. /**
  344. * Parse the class name and setup the custom exception class of the client
  345. * and return the "service" name of the client and "exception_class".
  346. *
  347. * @return array
  348. */
  349. private function parseClass()
  350. {
  351. $klass = get_class($this);
  352. if ($klass === __CLASS__) {
  353. return ['', AwsException::class];
  354. }
  355. $service = substr($klass, strrpos($klass, '\\') + 1, -6);
  356. return [
  357. strtolower($service),
  358. "Aws\\{$service}\\Exception\\{$service}Exception"
  359. ];
  360. }
  361. private function addEndpointParameterMiddleware($args)
  362. {
  363. if (empty($args['disable_host_prefix_injection'])) {
  364. $list = $this->getHandlerList();
  365. $list->appendBuild(
  366. EndpointParameterMiddleware::wrap(
  367. $this->api
  368. ),
  369. 'endpoint_parameter'
  370. );
  371. }
  372. }
  373. private function addEndpointDiscoveryMiddleware($config, $args)
  374. {
  375. $list = $this->getHandlerList();
  376. if (!isset($args['endpoint'])) {
  377. $list->appendBuild(
  378. EndpointDiscoveryMiddleware::wrap(
  379. $this,
  380. $args,
  381. $config['endpoint_discovery']
  382. ),
  383. 'EndpointDiscoveryMiddleware'
  384. );
  385. }
  386. }
  387. private function addSignatureMiddleware(array $args)
  388. {
  389. $api = $this->getApi();
  390. $provider = $this->signatureProvider;
  391. $signatureVersion = $this->config['signature_version'];
  392. $name = $this->config['signing_name'];
  393. $region = $this->config['signing_region'];
  394. $signingRegionSet = $this->signingRegionSet;
  395. if (isset($args['signature_version'])
  396. || isset($this->config['configured_signature_version'])
  397. ) {
  398. $configuredSignatureVersion = true;
  399. } else {
  400. $configuredSignatureVersion = false;
  401. }
  402. $resolver = static function (
  403. CommandInterface $c
  404. ) use (
  405. $api,
  406. $provider,
  407. $name,
  408. $region,
  409. $signatureVersion,
  410. $configuredSignatureVersion,
  411. $signingRegionSet
  412. ) {
  413. if (!$configuredSignatureVersion) {
  414. if (!empty($c['@context']['signing_region'])) {
  415. $region = $c['@context']['signing_region'];
  416. }
  417. if (!empty($c['@context']['signing_service'])) {
  418. $name = $c['@context']['signing_service'];
  419. }
  420. if (!empty($c['@context']['signature_version'])) {
  421. $signatureVersion = $c['@context']['signature_version'];
  422. }
  423. $authType = $api->getOperation($c->getName())['authtype'];
  424. switch ($authType){
  425. case 'none':
  426. $signatureVersion = 'anonymous';
  427. break;
  428. case 'v4-unsigned-body':
  429. $signatureVersion = 'v4-unsigned-body';
  430. break;
  431. case 'bearer':
  432. $signatureVersion = 'bearer';
  433. break;
  434. }
  435. }
  436. if ($signatureVersion === 'v4a') {
  437. $commandSigningRegionSet = !empty($c['@context']['signing_region_set'])
  438. ? implode(', ', $c['@context']['signing_region_set'])
  439. : null;
  440. $region = $signingRegionSet
  441. ?? $commandSigningRegionSet
  442. ?? $region;
  443. }
  444. return SignatureProvider::resolve($provider, $signatureVersion, $name, $region);
  445. };
  446. $this->handlerList->appendSign(
  447. Middleware::signer($this->credentialProvider,
  448. $resolver,
  449. $this->tokenProvider,
  450. $this->getConfig()
  451. ),
  452. 'signer'
  453. );
  454. }
  455. private function addRequestCompressionMiddleware($config)
  456. {
  457. if (empty($config['disable_request_compression'])) {
  458. $list = $this->getHandlerList();
  459. $list->appendBuild(
  460. RequestCompressionMiddleware::wrap($config),
  461. 'request-compression'
  462. );
  463. }
  464. }
  465. private function addQueryCompatibleInputMiddleware(Service $api)
  466. {
  467. $list = $this->getHandlerList();
  468. $list->appendValidate(
  469. QueryCompatibleInputMiddleware::wrap($api),
  470. 'query-compatible-input'
  471. );
  472. }
  473. private function addInvocationId()
  474. {
  475. // Add invocation id to each request
  476. $this->handlerList->prependSign(Middleware::invocationId(), 'invocation-id');
  477. }
  478. private function loadAliases($file = null)
  479. {
  480. if (!isset($this->aliases)) {
  481. if (is_null($file)) {
  482. $file = __DIR__ . '/data/aliases.json';
  483. }
  484. $aliases = \Aws\load_compiled_json($file);
  485. $serviceId = $this->api->getServiceId();
  486. $version = $this->getApi()->getApiVersion();
  487. if (!empty($aliases['operations'][$serviceId][$version])) {
  488. $this->aliases = array_flip($aliases['operations'][$serviceId][$version]);
  489. }
  490. }
  491. }
  492. private function addStreamRequestPayload()
  493. {
  494. $streamRequestPayloadMiddleware = StreamRequestPayloadMiddleware::wrap(
  495. $this->api
  496. );
  497. $this->handlerList->prependSign(
  498. $streamRequestPayloadMiddleware,
  499. 'StreamRequestPayloadMiddleware'
  500. );
  501. }
  502. private function addRecursionDetection()
  503. {
  504. // Add recursion detection header to requests
  505. // originating in supported Lambda runtimes
  506. $this->handlerList->appendBuild(
  507. Middleware::recursionDetection(), 'recursion-detection'
  508. );
  509. }
  510. private function addAuthSelectionMiddleware()
  511. {
  512. $list = $this->getHandlerList();
  513. $list->prependBuild(
  514. AuthSelectionMiddleware::wrap(
  515. $this->authSchemeResolver,
  516. $this->getApi()
  517. ),
  518. 'auth-selection'
  519. );
  520. }
  521. private function addEndpointV2Middleware()
  522. {
  523. $list = $this->getHandlerList();
  524. $endpointArgs = $this->getEndpointProviderArgs();
  525. $list->prependBuild(
  526. EndpointV2Middleware::wrap(
  527. $this->endpointProvider,
  528. $this->getApi(),
  529. $endpointArgs,
  530. $this->credentialProvider
  531. ),
  532. 'endpoint-resolution'
  533. );
  534. }
  535. /**
  536. * Retrieves client context param definition from service model,
  537. * creates mapping of client context param names with client-provided
  538. * values.
  539. *
  540. * @return array
  541. */
  542. private function setClientContextParams($args)
  543. {
  544. $api = $this->getApi();
  545. $resolvedParams = [];
  546. if (!empty($paramDefinitions = $api->getClientContextParams())) {
  547. foreach($paramDefinitions as $paramName => $paramValue) {
  548. if (isset($args[$paramName])) {
  549. $resolvedParams[$paramName] = $args[$paramName];
  550. }
  551. }
  552. }
  553. return $resolvedParams;
  554. }
  555. /**
  556. * Retrieves and sets default values used for endpoint resolution.
  557. */
  558. private function setClientBuiltIns($args, $resolvedConfig)
  559. {
  560. $builtIns = [];
  561. $config = $resolvedConfig['config'];
  562. $service = $args['service'];
  563. $builtIns['SDK::Endpoint'] = null;
  564. if (!empty($args['endpoint'])) {
  565. $builtIns['SDK::Endpoint'] = $args['endpoint'];
  566. } elseif (isset($config['configured_endpoint_url'])) {
  567. $builtIns['SDK::Endpoint'] = (string) $this->getEndpoint();
  568. }
  569. $builtIns['AWS::Region'] = $this->getRegion();
  570. $builtIns['AWS::UseFIPS'] = $config['use_fips_endpoint']->isUseFipsEndpoint();
  571. $builtIns['AWS::UseDualStack'] = $config['use_dual_stack_endpoint']->isUseDualstackEndpoint();
  572. if ($service === 's3' || $service === 's3control'){
  573. $builtIns['AWS::S3::UseArnRegion'] = $config['use_arn_region']->isUseArnRegion();
  574. }
  575. if ($service === 's3') {
  576. $builtIns['AWS::S3::UseArnRegion'] = $config['use_arn_region']->isUseArnRegion();
  577. $builtIns['AWS::S3::Accelerate'] = $config['use_accelerate_endpoint'];
  578. $builtIns['AWS::S3::ForcePathStyle'] = $config['use_path_style_endpoint'];
  579. $builtIns['AWS::S3::DisableMultiRegionAccessPoints'] = $config['disable_multiregion_access_points'];
  580. }
  581. $builtIns['AWS::Auth::AccountIdEndpointMode'] = $resolvedConfig['account_id_endpoint_mode'];
  582. $this->clientBuiltIns += $builtIns;
  583. }
  584. /**
  585. * Retrieves arguments to be used in endpoint resolution.
  586. *
  587. * @return array
  588. */
  589. public function getEndpointProviderArgs()
  590. {
  591. return $this->normalizeEndpointProviderArgs();
  592. }
  593. /**
  594. * Combines built-in and client context parameter values in
  595. * order of specificity. Client context parameter values supersede
  596. * built-in values.
  597. *
  598. * @return array
  599. */
  600. private function normalizeEndpointProviderArgs()
  601. {
  602. $normalizedBuiltIns = [];
  603. foreach($this->clientBuiltIns as $name => $value) {
  604. $normalizedName = explode('::', $name);
  605. $normalizedName = $normalizedName[count($normalizedName) - 1];
  606. $normalizedBuiltIns[$normalizedName] = $value;
  607. }
  608. return array_merge($normalizedBuiltIns, $this->getClientContextParams());
  609. }
  610. protected function isUseEndpointV2()
  611. {
  612. return $this->endpointProvider instanceof EndpointProviderV2;
  613. }
  614. public static function emitDeprecationWarning() {
  615. trigger_error(
  616. "This method is deprecated. It will be removed in an upcoming release."
  617. , E_USER_DEPRECATED
  618. );
  619. $phpVersion = PHP_VERSION_ID;
  620. if ($phpVersion < 70205) {
  621. $phpVersionString = phpversion();
  622. @trigger_error(
  623. "This installation of the SDK is using PHP version"
  624. . " {$phpVersionString}, which will be deprecated on August"
  625. . " 15th, 2023. Please upgrade your PHP version to a minimum of"
  626. . " 7.2.5 before then to continue receiving updates to the AWS"
  627. . " SDK for PHP. To disable this warning, set"
  628. . " suppress_php_deprecation_warning to true on the client constructor"
  629. . " or set the environment variable AWS_SUPPRESS_PHP_DEPRECATION_WARNING"
  630. . " to true.",
  631. E_USER_DEPRECATED
  632. );
  633. }
  634. }
  635. /**
  636. * Returns a service model and doc model with any necessary changes
  637. * applied.
  638. *
  639. * @param array $api Array of service data being documented.
  640. * @param array $docs Array of doc model data.
  641. *
  642. * @return array Tuple containing a [Service, DocModel]
  643. *
  644. * @internal This should only used to document the service API.
  645. * @codeCoverageIgnore
  646. */
  647. public static function applyDocFilters(array $api, array $docs)
  648. {
  649. $aliases = \Aws\load_compiled_json(__DIR__ . '/data/aliases.json');
  650. $serviceId = $api['metadata']['serviceId'] ?? '';
  651. $version = $api['metadata']['apiVersion'];
  652. // Replace names for any operations with SDK aliases
  653. if (!empty($aliases['operations'][$serviceId][$version])) {
  654. foreach ($aliases['operations'][$serviceId][$version] as $op => $alias) {
  655. $api['operations'][$alias] = $api['operations'][$op];
  656. $docs['operations'][$alias] = $docs['operations'][$op];
  657. unset($api['operations'][$op], $docs['operations'][$op]);
  658. }
  659. }
  660. ksort($api['operations']);
  661. return [
  662. new Service($api, ApiProvider::defaultProvider()),
  663. new DocModel($docs)
  664. ];
  665. }
  666. /**
  667. * @deprecated
  668. * @return static
  669. */
  670. public static function factory(array $config = [])
  671. {
  672. return new static($config);
  673. }
  674. }