| @@ -1,34 +1,44 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace Dudlewebs\WPMCS\s3\Aws; |
| 4 | 4 | |
| 5 | -use Dudlewebs\WPMCS\s3\Aws\Api\Validator; | |
| 6 | 5 | use Dudlewebs\WPMCS\s3\Aws\Api\ApiProvider; |
| 7 | 6 | use Dudlewebs\WPMCS\s3\Aws\Api\Service; |
| 7 | +use Dudlewebs\WPMCS\s3\Aws\Api\Validator; | |
| 8 | +use Dudlewebs\WPMCS\s3\Aws\Auth\AuthResolver; | |
| 9 | +use Dudlewebs\WPMCS\s3\Aws\Auth\AuthSchemeResolver; | |
| 10 | +use Dudlewebs\WPMCS\s3\Aws\Auth\AuthSchemeResolverInterface; | |
| 8 | 11 | use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ApiCallAttemptMonitoringMiddleware; |
| 9 | 12 | use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ApiCallMonitoringMiddleware; |
| 10 | 13 | use Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\Configuration; |
| 14 | +use Dudlewebs\WPMCS\s3\Aws\Configuration\ConfigurationResolver; | |
| 15 | +use Dudlewebs\WPMCS\s3\Aws\Credentials\CredentialProvider; | |
| 11 | 16 | use Dudlewebs\WPMCS\s3\Aws\Credentials\Credentials; |
| 12 | 17 | use Dudlewebs\WPMCS\s3\Aws\Credentials\CredentialsInterface; |
| 18 | +use Dudlewebs\WPMCS\s3\Aws\DefaultsMode\ConfigurationInterface as ConfigModeInterface; | |
| 19 | +use Dudlewebs\WPMCS\s3\Aws\DefaultsMode\ConfigurationProvider as ConfigModeProvider; | |
| 20 | +use Dudlewebs\WPMCS\s3\Aws\Endpoint\EndpointProvider; | |
| 13 | 21 | use Dudlewebs\WPMCS\s3\Aws\Endpoint\PartitionEndpointProvider; |
| 22 | +use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseDualstackEndpoint\Configuration as UseDualStackEndpointConfiguration; | |
| 23 | +use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseDualstackEndpoint\ConfigurationInterface as UseDualStackEndpointConfigurationInterface; | |
| 24 | +use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseDualstackEndpoint\ConfigurationProvider as UseDualStackConfigProvider; | |
| 14 | 25 | use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseFipsEndpoint\Configuration as UseFipsEndpointConfiguration; |
| 26 | +use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseFipsEndpoint\ConfigurationInterface as UseFipsEndpointConfigurationInterface; | |
| 15 | 27 | use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseFipsEndpoint\ConfigurationProvider as UseFipsConfigProvider; |
| 16 | -use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseFipsEndpoint\ConfigurationInterface as UseFipsEndpointConfigurationInterface; | |
| 17 | -use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseDualstackEndpoint\Configuration as UseDualStackEndpointConfiguration; | |
| 18 | -use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseDualstackEndpoint\ConfigurationProvider as UseDualStackConfigProvider; | |
| 19 | -use Dudlewebs\WPMCS\s3\Aws\Endpoint\UseDualstackEndpoint\ConfigurationInterface as UseDualStackEndpointConfigurationInterface; | |
| 20 | 28 | use Dudlewebs\WPMCS\s3\Aws\EndpointDiscovery\ConfigurationInterface; |
| 21 | 29 | use Dudlewebs\WPMCS\s3\Aws\EndpointDiscovery\ConfigurationProvider; |
| 30 | +use Dudlewebs\WPMCS\s3\Aws\EndpointV2\EndpointDefinitionProvider; | |
| 31 | +use Dudlewebs\WPMCS\s3\Aws\Exception\AwsException; | |
| 22 | 32 | use Dudlewebs\WPMCS\s3\Aws\Exception\InvalidRegionException; |
| 23 | 33 | use Dudlewebs\WPMCS\s3\Aws\Retry\ConfigurationInterface as RetryConfigInterface; |
| 24 | 34 | use Dudlewebs\WPMCS\s3\Aws\Retry\ConfigurationProvider as RetryConfigProvider; |
| 25 | -use Dudlewebs\WPMCS\s3\Aws\DefaultsMode\ConfigurationInterface as ConfigModeInterface; | |
| 26 | -use Dudlewebs\WPMCS\s3\Aws\DefaultsMode\ConfigurationProvider as ConfigModeProvider; | |
| 27 | 35 | use Dudlewebs\WPMCS\s3\Aws\Signature\SignatureProvider; |
| 28 | -use Dudlewebs\WPMCS\s3\Aws\Endpoint\EndpointProvider; | |
| 36 | +use Dudlewebs\WPMCS\s3\Aws\Token\Token; | |
| 37 | +use Dudlewebs\WPMCS\s3\Aws\Token\TokenInterface; | |
| 38 | +use Dudlewebs\WPMCS\s3\Aws\Token\BedrockTokenProvider; | |
| 39 | +use Dudlewebs\WPMCS\s3\Aws\Token\TokenProvider; | |
| 29 | 40 | use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise\PromiseInterface; |
| 30 | -use Dudlewebs\WPMCS\s3\Aws\Credentials\CredentialProvider; | |
| 31 | 41 | use InvalidArgumentException as IAE; |
| 32 | 42 | use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface; |
| 33 | 43 | /** |
| 34 | 44 | * @internal Resolves a hash of client arguments to construct a client. |
| @@ -36,11 +46,23 @@ | ||
| 36 | 46 | class ClientResolver |
| 37 | 47 | { |
| 38 | 48 | /** @var array */ |
| 39 | 49 | private $argDefinitions; |
| 50 | + /** | |
| 51 | + * When using this option as default please make sure that, your config | |
| 52 | + * has at least one data type defined in `valid` otherwise it will be | |
| 53 | + * defaulted to `string`. Also, the default value will be the falsy value | |
| 54 | + * based on the resolved data type. For example, the default for `string` | |
| 55 | + * will be `''` and for bool will be `false`. | |
| 56 | + * | |
| 57 | + * @var string | |
| 58 | + */ | |
| 59 | + const DEFAULT_FROM_ENV_INI = [__CLASS__, '_resolve_from_env_ini']; | |
| 40 | 60 | /** @var array Map of types to a corresponding function */ |
| 41 | - private static $typeMap = ['resource' => 'is_resource', 'callable' => 'is_callable', 'int' => 'is_int', 'bool' => 'is_bool', 'string' => 'is_string', 'object' => 'is_object', 'array' => 'is_array']; | |
| 42 | - private static $defaultArgs = ['service' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'Name of the service to utilize. This value will be supplied by default when using one of the SDK clients (e.g., Aws\\S3\\S3Client).', 'required' => \true, 'internal' => \true], 'exception_class' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'Exception class to create when an error occurs.', 'default' => 'Dudlewebs\\WPMCS\\s3\\Aws\\Exception\\AwsException', 'internal' => \true], 'scheme' => ['type' => 'value', 'valid' => ['string'], 'default' => 'https', 'doc' => 'URI scheme to use when connecting connect. The SDK will utilize "https" endpoints (i.e., utilize SSL/TLS connections) by default. You can attempt to connect to a service over an unencrypted "http" endpoint by setting ``scheme`` to "http".'], 'disable_host_prefix_injection' => ['type' => 'value', 'valid' => ['bool'], 'doc' => 'Set to true to disable host prefix injection logic for services that use it. This disables the entire prefix injection, including the portions supplied by user-defined parameters. Setting this flag will have no effect on services that do not use host prefix injection.', 'default' => \false], 'endpoint' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'The full URI of the webservice. This is only required when connecting to a custom endpoint (e.g., a local version of S3).', 'fn' => [__CLASS__, '_apply_endpoint']], 'region' => ['type' => 'value', 'valid' => ['string'], 'required' => [__CLASS__, '_missing_region'], 'doc' => 'Region to connect to. See http://docs.aws.amazon.com/general/latest/gr/rande.html for a list of available regions.'], 'version' => ['type' => 'value', 'valid' => ['string'], 'required' => [__CLASS__, '_missing_version'], 'doc' => 'The version of the webservice to utilize (e.g., 2006-03-01).'], 'signature_provider' => ['type' => 'value', 'valid' => ['callable'], 'doc' => 'A callable that accepts a signature version name (e.g., "v4"), a service name, and region, and returns a SignatureInterface object or null. This provider is used to create signers utilized by the client. See Aws\\Signature\\SignatureProvider for a list of built-in providers', 'default' => [__CLASS__, '_default_signature_provider']], 'api_provider' => ['type' => 'value', 'valid' => ['callable'], 'doc' => 'An optional PHP callable that accepts a type, service, and version argument, and returns an array of corresponding configuration data. The type value can be one of api, waiter, or paginator.', 'fn' => [__CLASS__, '_apply_api_provider'], 'default' => [ApiProvider::class, 'defaultProvider']], 'configuration_mode' => ['type' => 'value', 'valid' => [ConfigModeInterface::class, CacheInterface::class, 'string', 'closure'], 'doc' => "Sets the default configuration mode. Otherwise provide an instance of Aws\\DefaultsMode\\ConfigurationInterface, an instance of Aws\\CacheInterface, or a string containing a valid mode", 'fn' => [__CLASS__, '_apply_defaults'], 'default' => [ConfigModeProvider::class, 'defaultProvider']], 'use_fips_endpoint' => ['type' => 'value', 'valid' => ['bool', UseFipsEndpointConfiguration::class, CacheInterface::class, 'callable'], 'doc' => 'Set to true to enable the use of FIPS pseudo regions', 'fn' => [__CLASS__, '_apply_use_fips_endpoint'], 'default' => [__CLASS__, '_default_use_fips_endpoint']], 'use_dual_stack_endpoint' => ['type' => 'value', 'valid' => ['bool', UseDualStackEndpointConfiguration::class, CacheInterface::class, 'callable'], 'doc' => 'Set to true to enable the use of dual-stack endpoints', 'fn' => [__CLASS__, '_apply_use_dual_stack_endpoint'], 'default' => [__CLASS__, '_default_use_dual_stack_endpoint']], 'endpoint_provider' => ['type' => 'value', 'valid' => ['callable'], 'fn' => [__CLASS__, '_apply_endpoint_provider'], 'doc' => 'An optional PHP callable that accepts a hash of options including a "service" and "region" key and returns NULL or a hash of endpoint data, of which the "endpoint" key is required. See Aws\\Endpoint\\EndpointProvider for a list of built-in providers.', 'default' => [__CLASS__, '_default_endpoint_provider']], 'serializer' => ['default' => [__CLASS__, '_default_serializer'], 'fn' => [__CLASS__, '_apply_serializer'], 'internal' => \true, 'type' => 'value', 'valid' => ['callable']], 'signature_version' => ['type' => 'config', 'valid' => ['string'], 'doc' => 'A string representing a custom signature version to use with a service (e.g., v4). Note that per/operation signature version MAY override this requested signature version.', 'default' => [__CLASS__, '_default_signature_version']], 'signing_name' => ['type' => 'config', 'valid' => ['string'], 'doc' => 'A string representing a custom service name to be used when calculating a request signature.', 'default' => [__CLASS__, '_default_signing_name']], 'signing_region' => ['type' => 'config', 'valid' => ['string'], 'doc' => 'A string representing a custom region name to be used when calculating a request signature.', 'default' => [__CLASS__, '_default_signing_region']], 'profile' => ['type' => 'config', 'valid' => ['string'], 'doc' => 'Allows you to specify which profile to use when credentials are created from the AWS credentials file in your HOME directory. This setting overrides the AWS_PROFILE environment variable. Note: Specifying "profile" will cause the "credentials" and "use_aws_shared_config_files" keys to be ignored.', 'fn' => [__CLASS__, '_apply_profile']], 'credentials' => ['type' => 'value', 'valid' => [CredentialsInterface::class, CacheInterface::class, 'array', 'bool', 'callable'], 'doc' => 'Specifies the credentials used to sign requests. Provide an Aws\\Credentials\\CredentialsInterface object, an associative array of "key", "secret", and an optional "token" key, `false` to use null credentials, or a callable credentials provider used to create credentials or return null. See Aws\\Credentials\\CredentialProvider for a list of built-in credentials providers. If no credentials are provided, the SDK will attempt to load them from the environment.', 'fn' => [__CLASS__, '_apply_credentials'], 'default' => [__CLASS__, '_default_credential_provider']], 'endpoint_discovery' => ['type' => 'value', 'valid' => [ConfigurationInterface::class, CacheInterface::class, 'array', 'callable'], 'doc' => 'Specifies settings for endpoint discovery. Provide an instance of Aws\\EndpointDiscovery\\ConfigurationInterface, an instance Aws\\CacheInterface, a callable that provides a promise for a Configuration object, or an associative array with the following keys: enabled: (bool) Set to true to enable endpoint discovery, false to explicitly disable it. Defaults to false; cache_limit: (int) The maximum number of keys in the endpoints cache. Defaults to 1000.', 'fn' => [__CLASS__, '_apply_endpoint_discovery'], 'default' => [__CLASS__, '_default_endpoint_discovery_provider']], 'stats' => ['type' => 'value', 'valid' => ['bool', 'array'], 'default' => \false, 'doc' => 'Set to true to gather transfer statistics on requests sent. Alternatively, you can provide an associative array with the following keys: retries: (bool) Set to false to disable reporting on retries attempted; http: (bool) Set to true to enable collecting statistics from lower level HTTP adapters (e.g., values returned in GuzzleHttp\\TransferStats). HTTP handlers must support an http_stats_receiver option for this to have an effect; timer: (bool) Set to true to enable a command timer that reports the total wall clock time spent on an operation in seconds.', 'fn' => [__CLASS__, '_apply_stats']], 'retries' => ['type' => 'value', 'valid' => ['int', RetryConfigInterface::class, CacheInterface::class, 'callable', 'array'], 'doc' => "Configures the retry mode and maximum number of allowed retries for a client (pass 0 to disable retries). Provide an integer for 'legacy' mode with the specified number of retries. Otherwise provide an instance of Aws\\Retry\\ConfigurationInterface, an instance of Aws\\CacheInterface, a callable function, or an array with the following keys: mode: (string) Set to 'legacy', 'standard' (uses retry quota management), or 'adapative' (an experimental mode that adds client-side rate limiting to standard mode); max_attempts: (int) The maximum number of attempts for a given request. ", 'fn' => [__CLASS__, '_apply_retries'], 'default' => [RetryConfigProvider::class, 'defaultProvider']], 'validate' => ['type' => 'value', 'valid' => ['bool', 'array'], 'default' => \true, 'doc' => 'Set to false to disable client-side parameter validation. Set to true to utilize default validation constraints. Set to an associative array of validation options to enable specific validation constraints.', 'fn' => [__CLASS__, '_apply_validate']], 'debug' => ['type' => 'value', 'valid' => ['bool', 'array'], 'doc' => 'Set to true to display debug information when sending requests. Alternatively, you can provide an associative array with the following keys: logfn: (callable) Function that is invoked with log messages; stream_size: (int) When the size of a stream is greater than this number, the stream data will not be logged (set to "0" to not log any stream data); scrub_auth: (bool) Set to false to disable the scrubbing of auth data from the logged messages; http: (bool) Set to false to disable the "debug" feature of lower level HTTP adapters (e.g., verbose curl output).', 'fn' => [__CLASS__, '_apply_debug']], 'csm' => ['type' => 'value', 'valid' => [\Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationInterface::class, 'callable', 'array', 'bool'], 'doc' => 'CSM options for the client. Provides a callable wrapping a promise, a boolean "false", an instance of ConfigurationInterface, or an associative array of "enabled", "host", "port", and "client_id".', 'fn' => [__CLASS__, '_apply_csm'], 'default' => [\Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationProvider::class, 'defaultProvider']], 'http' => ['type' => 'value', 'valid' => ['array'], 'default' => [], 'doc' => 'Set to an array of SDK request options to apply to each request (e.g., proxy, verify, etc.).'], 'http_handler' => ['type' => 'value', 'valid' => ['callable'], 'doc' => 'An HTTP handler is a function that accepts a PSR-7 request object and returns a promise that is fulfilled with a PSR-7 response object or rejected with an array of exception data. NOTE: This option supersedes any provided "handler" option.', 'fn' => [__CLASS__, '_apply_http_handler']], 'handler' => ['type' => 'value', 'valid' => ['callable'], 'doc' => 'A handler that accepts a command object, request object and returns a promise that is fulfilled with an Aws\\ResultInterface object or rejected with an Aws\\Exception\\AwsException. A handler does not accept a next handler as it is terminal and expected to fulfill a command. If no handler is provided, a default Guzzle handler will be utilized.', 'fn' => [__CLASS__, '_apply_handler'], 'default' => [__CLASS__, '_default_handler']], 'ua_append' => ['type' => 'value', 'valid' => ['string', 'array'], 'doc' => 'Provide a string or array of strings to send in the User-Agent header.', 'fn' => [__CLASS__, '_apply_user_agent'], 'default' => []], 'idempotency_auto_fill' => ['type' => 'value', 'valid' => ['bool', 'callable'], 'doc' => 'Set to false to disable SDK to populate parameters that enabled \'idempotencyToken\' trait with a random UUID v4 value on your behalf. Using default value \'true\' still allows parameter value to be overwritten when provided. Note: auto-fill only works when cryptographically secure random bytes generator functions(random_bytes, openssl_random_pseudo_bytes or mcrypt_create_iv) can be found. You may also provide a callable source of random bytes.', 'default' => \true, 'fn' => [__CLASS__, '_apply_idempotency_auto_fill']], 'use_aws_shared_config_files' => ['type' => 'value', 'valid' => ['bool'], 'doc' => 'Set to false to disable checking for shared aws config files usually located in \'~/.aws/config\' and \'~/.aws/credentials\'. This will be ignored if you set the \'profile\' setting.', 'default' => \true]]; | |
| 61 | + private static $typeMap = ['resource' => 'is_resource', 'callable' => 'is_callable', 'int' => 'is_int', 'bool' => 'is_bool', 'boolean' => 'is_bool', 'string' => 'is_string', 'object' => 'is_object', 'array' => 'is_array']; | |
| 62 | + private static $defaultArgs = ['service' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'Name of the service to utilize. This value will be supplied by default when using one of the SDK clients (e.g., Aws\\S3\\S3Client).', 'required' => \true, 'internal' => \true], 'exception_class' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'Exception class to create when an error occurs.', 'default' => AwsException::class, 'internal' => \true], 'scheme' => ['type' => 'value', 'valid' => ['string'], 'default' => 'https', 'doc' => 'URI scheme to use when connecting connect. The SDK will utilize "https" endpoints (i.e., utilize SSL/TLS connections) by default. You can attempt to connect to a service over an unencrypted "http" endpoint by setting ``scheme`` to "http".'], 'disable_host_prefix_injection' => ['type' => 'value', 'valid' => ['bool'], 'doc' => 'Set to true to disable host prefix injection logic for services that use it. This disables the entire prefix injection, including the portions supplied by user-defined parameters. Setting this flag will have no effect on services that do not use host prefix injection.', 'default' => \false], 'ignore_configured_endpoint_urls' => ['type' => 'value', 'valid' => ['bool'], 'doc' => 'Set to true to disable endpoint urls configured using `AWS_ENDPOINT_URL` and `endpoint_url` shared config option.', 'fn' => [__CLASS__, '_apply_ignore_configured_endpoint_urls'], 'default' => self::DEFAULT_FROM_ENV_INI], 'endpoint' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'The full URI of the webservice. This is only required when connecting to a custom endpoint (e.g., a local version of S3).', 'fn' => [__CLASS__, '_apply_endpoint'], 'default' => [__CLASS__, '_default_endpoint']], 'region' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'Region to connect to. See http://docs.aws.amazon.com/general/latest/gr/rande.html for a list of available regions.', 'fn' => [__CLASS__, '_apply_region'], 'default' => self::DEFAULT_FROM_ENV_INI], 'version' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'The version of the webservice to utilize (e.g., 2006-03-01).', 'default' => 'latest'], 'signature_provider' => ['type' => 'value', 'valid' => ['callable'], 'doc' => 'A callable that accepts a signature version name (e.g., "v4"), a service name, and region, and returns a SignatureInterface object or null. This provider is used to create signers utilized by the client. See Aws\\Signature\\SignatureProvider for a list of built-in providers', 'default' => [__CLASS__, '_default_signature_provider']], 'api_provider' => ['type' => 'value', 'valid' => ['callable'], 'doc' => 'An optional PHP callable that accepts a type, service, and version argument, and returns an array of corresponding configuration data. The type value can be one of api, waiter, or paginator.', 'fn' => [__CLASS__, '_apply_api_provider'], 'default' => [ApiProvider::class, 'defaultProvider']], 'configuration_mode' => ['type' => 'value', 'valid' => [ConfigModeInterface::class, CacheInterface::class, 'string', 'closure'], 'doc' => "Sets the default configuration mode. Otherwise provide an instance of Aws\\DefaultsMode\\ConfigurationInterface, an instance of Aws\\CacheInterface, or a string containing a valid mode", 'fn' => [__CLASS__, '_apply_defaults'], 'default' => [ConfigModeProvider::class, 'defaultProvider']], 'use_fips_endpoint' => ['type' => 'value', 'valid' => ['bool', UseFipsEndpointConfiguration::class, CacheInterface::class, 'callable'], 'doc' => 'Set to true to enable the use of FIPS pseudo regions', 'fn' => [__CLASS__, '_apply_use_fips_endpoint'], 'default' => [__CLASS__, '_default_use_fips_endpoint']], 'use_dual_stack_endpoint' => ['type' => 'value', 'valid' => ['bool', UseDualStackEndpointConfiguration::class, CacheInterface::class, 'callable'], 'doc' => 'Set to true to enable the use of dual-stack endpoints', 'fn' => [__CLASS__, '_apply_use_dual_stack_endpoint'], 'default' => [__CLASS__, '_default_use_dual_stack_endpoint']], 'endpoint_provider' => ['type' => 'value', 'valid' => ['callable', EndpointV2\EndpointProviderV2::class], 'fn' => [__CLASS__, '_apply_endpoint_provider'], 'doc' => 'An optional PHP callable that accepts a hash of options including a "service" and "region" key and returns NULL or a hash of endpoint data, of which the "endpoint" key is required. See Aws\\Endpoint\\EndpointProvider for a list of built-in providers.', 'default' => [__CLASS__, '_default_endpoint_provider']], 'serializer' => ['default' => [__CLASS__, '_default_serializer'], 'fn' => [__CLASS__, '_apply_serializer'], 'internal' => \true, 'type' => 'value', 'valid' => ['callable']], 'signature_version' => ['type' => 'config', 'valid' => ['string'], 'doc' => 'A string representing a custom signature version to use with a service (e.g., v4). Note that per/operation signature version MAY override this requested signature version.', 'default' => [__CLASS__, '_default_signature_version']], 'signing_name' => ['type' => 'config', 'valid' => ['string'], 'doc' => 'A string representing a custom service name to be used when calculating a request signature.', 'default' => [__CLASS__, '_default_signing_name']], 'signing_region' => ['type' => 'config', 'valid' => ['string'], 'doc' => 'A string representing a custom region name to be used when calculating a request signature.', 'default' => [__CLASS__, '_default_signing_region']], 'profile' => ['type' => 'config', 'valid' => ['string'], 'doc' => 'Allows you to specify which profile to use when credentials are created from the AWS credentials file in your HOME directory. This setting overrides the AWS_PROFILE environment variable. Note: Specifying "profile" will cause the "credentials" and "use_aws_shared_config_files" keys to be ignored.', 'fn' => [__CLASS__, '_apply_profile']], 'credentials' => ['type' => 'value', 'valid' => [CredentialsInterface::class, CacheInterface::class, 'array', 'bool', 'callable'], 'doc' => 'Specifies the credentials used to sign requests. Provide an Aws\\Credentials\\CredentialsInterface object, an associative array of "key", "secret", and an optional "token" key, `false` to use null credentials, or a callable credentials provider used to create credentials or return null. See Aws\\Credentials\\CredentialProvider for a list of built-in credentials providers. If no credentials are provided, the SDK will attempt to load them from the environment.', 'fn' => [__CLASS__, '_apply_credentials'], 'default' => [__CLASS__, '_default_credential_provider']], 'auth_scheme_preference' => ['type' => 'value', 'valid' => ['string', 'array'], 'doc' => 'Comma-separated list of authentication scheme preferences in priority order. Configure via environment variable `AWS_AUTH_SCHEME_PREFERENCE`, INI config file `auth_scheme_preference`, or client constructor parameter `auth_scheme_preference` (string or array).\\nExample: `AWS_AUTH_SCHEME_PREFERENCE=aws.auth#sigv4a,aws.auth#sigv4,smithy.api#httpBearerAuth`', 'default' => self::DEFAULT_FROM_ENV_INI, 'fn' => [__CLASS__, '_apply_auth_scheme_preference']], 'token' => ['type' => 'value', 'valid' => [TokenInterface::class, CacheInterface::class, 'array', 'bool', 'callable'], 'doc' => 'Specifies the token used to authorize requests. Provide an Aws\\Token\\TokenInterface object, an associative array of "token", and an optional "expiration" key, `false` to use a null token, or a callable token provider used to fetch a token or return null. See Aws\\Token\\TokenProvider for a list of built-in credentials providers. If no token is provided, the SDK will attempt to load one from the environment.', 'fn' => [__CLASS__, '_apply_token'], 'default' => [__CLASS__, '_default_token_provider']], 'auth_scheme_resolver' => ['type' => 'value', 'valid' => [AuthSchemeResolverInterface::class], 'doc' => 'An instance of Aws\\Auth\\AuthSchemeResolverInterface which selects a modeled auth scheme and returns a signature version', 'default' => [__CLASS__, '_default_auth_scheme_resolver']], 'endpoint_discovery' => ['type' => 'value', 'valid' => [ConfigurationInterface::class, CacheInterface::class, 'array', 'callable'], 'doc' => 'Specifies settings for endpoint discovery. Provide an instance of Aws\\EndpointDiscovery\\ConfigurationInterface, an instance Aws\\CacheInterface, a callable that provides a promise for a Configuration object, or an associative array with the following keys: enabled: (bool) Set to true to enable endpoint discovery, false to explicitly disable it. Defaults to false; cache_limit: (int) The maximum number of keys in the endpoints cache. Defaults to 1000.', 'fn' => [__CLASS__, '_apply_endpoint_discovery'], 'default' => [__CLASS__, '_default_endpoint_discovery_provider']], 'stats' => ['type' => 'value', 'valid' => ['bool', 'array'], 'default' => \false, 'doc' => 'Set to true to gather transfer statistics on requests sent. Alternatively, you can provide an associative array with the following keys: retries: (bool) Set to false to disable reporting on retries attempted; http: (bool) Set to true to enable collecting statistics from lower level HTTP adapters (e.g., values returned in GuzzleHttp\\TransferStats). HTTP handlers must support an http_stats_receiver option for this to have an effect; timer: (bool) Set to true to enable a command timer that reports the total wall clock time spent on an operation in seconds.', 'fn' => [__CLASS__, '_apply_stats']], 'retries' => ['type' => 'value', 'valid' => ['int', RetryConfigInterface::class, CacheInterface::class, 'callable', 'array'], 'doc' => "Configures the retry mode and maximum number of allowed retries for a client (pass 0 to disable retries). Provide an integer for 'legacy' mode with the specified number of retries. Otherwise provide an instance of Aws\\Retry\\ConfigurationInterface, an instance of Aws\\CacheInterface, a callable function, or an array with the following keys: mode: (string) Set to 'legacy', 'standard' (uses retry quota management), or 'adapative' (an experimental mode that adds client-side rate limiting to standard mode); max_attempts: (int) The maximum number of attempts for a given request. ", 'fn' => [__CLASS__, '_apply_retries'], 'default' => [RetryConfigProvider::class, 'defaultProvider']], 'validate' => ['type' => 'value', 'valid' => ['bool', 'array'], 'default' => \true, 'doc' => 'Set to false to disable client-side parameter validation. Set to true to utilize default validation constraints. Set to an associative array of validation options to enable specific validation constraints.', 'fn' => [__CLASS__, '_apply_validate']], 'debug' => ['type' => 'value', 'valid' => ['bool', 'array'], 'doc' => 'Set to true to display debug information when sending requests. Alternatively, you can provide an associative array with the following keys: logfn: (callable) Function that is invoked with log messages; stream_size: (int) When the size of a stream is greater than this number, the stream data will not be logged (set to "0" to not log any stream data); scrub_auth: (bool) Set to false to disable the scrubbing of auth data from the logged messages; http: (bool) Set to false to disable the "debug" feature of lower level HTTP adapters (e.g., verbose curl output).', 'fn' => [__CLASS__, '_apply_debug']], 'disable_request_compression' => ['type' => 'value', 'valid' => ['bool', 'callable'], 'doc' => 'Set to true to disable request compression for supported operations', 'fn' => [__CLASS__, '_apply_disable_request_compression'], 'default' => self::DEFAULT_FROM_ENV_INI], 'request_min_compression_size_bytes' => ['type' => 'value', 'valid' => ['int', 'callable'], 'doc' => 'Set to a value between between 0 and 10485760 bytes, inclusive. This value will be ignored if `disable_request_compression` is set to `true`', 'fn' => [__CLASS__, '_apply_min_compression_size'], 'default' => [__CLASS__, '_default_min_compression_size']], 'csm' => ['type' => 'value', 'valid' => [\Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationInterface::class, 'callable', 'array', 'bool'], 'doc' => 'CSM options for the client. Provides a callable wrapping a promise, a boolean "false", an instance of ConfigurationInterface, or an associative array of "enabled", "host", "port", and "client_id".', 'fn' => [__CLASS__, '_apply_csm'], 'default' => [\Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationProvider::class, 'defaultProvider']], 'http' => ['type' => 'value', 'valid' => ['array'], 'default' => [], 'doc' => 'Set to an array of SDK request options to apply to each request (e.g., proxy, verify, etc.).'], 'http_handler' => ['type' => 'value', 'valid' => ['callable'], 'doc' => 'An HTTP handler is a function that accepts a PSR-7 request object and returns a promise that is fulfilled with a PSR-7 response object or rejected with an array of exception data. NOTE: This option supersedes any provided "handler" option.', 'fn' => [__CLASS__, '_apply_http_handler']], 'handler' => ['type' => 'value', 'valid' => ['callable'], 'doc' => 'A handler that accepts a command object, request object and returns a promise that is fulfilled with an Aws\\ResultInterface object or rejected with an Aws\\Exception\\AwsException. A handler does not accept a next handler as it is terminal and expected to fulfill a command. If no handler is provided, a default Guzzle handler will be utilized.', 'fn' => [__CLASS__, '_apply_handler'], 'default' => [__CLASS__, '_default_handler']], 'app_id' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'app_id(AppId) is an optional application specific identifier that can be set. | |
| 63 | + When set it will be appended to the User-Agent header of every request in the form of App/{AppId}. | |
| 64 | + This value is also sourced from environment variable AWS_SDK_UA_APP_ID or the shared config profile attribute sdk_ua_app_id.', 'fn' => [__CLASS__, '_apply_app_id'], 'default' => [__CLASS__, '_default_app_id']], 'ua_append' => ['type' => 'value', 'valid' => ['string', 'array'], 'doc' => 'Provide a string or array of strings to send in the User-Agent header.', 'fn' => [__CLASS__, '_apply_user_agent'], 'default' => []], 'idempotency_auto_fill' => ['type' => 'value', 'valid' => ['bool', 'callable'], 'doc' => 'Set to false to disable SDK to populate parameters that enabled \'idempotencyToken\' trait with a random UUID v4 value on your behalf. Using default value \'true\' still allows parameter value to be overwritten when provided. Note: auto-fill only works when cryptographically secure random bytes generator functions(random_bytes, openssl_random_pseudo_bytes or mcrypt_create_iv) can be found. You may also provide a callable source of random bytes.', 'default' => \true, 'fn' => [__CLASS__, '_apply_idempotency_auto_fill']], 'use_aws_shared_config_files' => ['type' => 'value', 'valid' => ['bool'], 'doc' => 'Set to false to disable checking for shared aws config files usually located in \'~/.aws/config\' and \'~/.aws/credentials\'. This will be ignored if you set the \'profile\' setting.', 'default' => \true], 'suppress_php_deprecation_warning' => ['type' => 'value', 'valid' => ['bool'], 'doc' => 'Set to true to suppress PHP runtime deprecation warnings. The current deprecation campaign is PHP versions 8.0.x and below, taking effect on 1/13/2025.', 'default' => \false, 'fn' => [__CLASS__, '_apply_suppress_php_deprecation_warning']], 'account_id_endpoint_mode' => ['type' => 'value', 'valid' => ['string'], 'doc' => 'Decides whether account_id must a be a required resolved credentials property. If this configuration is set to disabled, then account_id is not required. If set to preferred a warning will be logged when account_id is not resolved, and when set to required an exception will be thrown if account_id is not resolved.', 'default' => [__CLASS__, '_default_account_id_endpoint_mode'], 'fn' => [__CLASS__, '_apply_account_id_endpoint_mode']], 'sigv4a_signing_region_set' => ['type' => 'value', 'valid' => ['string', 'array'], 'doc' => 'A comma-delimited list of supported regions sent in sigv4a requests.', 'fn' => [__CLASS__, '_apply_sigv4a_signing_region_set'], 'default' => self::DEFAULT_FROM_ENV_INI]]; | |
| 43 | 65 | /** |
| 44 | 66 | * Gets an array of default client arguments, each argument containing a |
| 45 | 67 | * hash of the following: |
| 46 | 68 | * |
| @@ -98,9 +120,13 @@ | ||
| 98 | 120 | if (!isset($args[$key])) { |
| 99 | 121 | if (isset($a['default'])) { |
| 100 | 122 | // Merge defaults in when not present. |
| 101 | 123 | if (\is_callable($a['default']) && (\is_array($a['default']) || $a['default'] instanceof \Closure)) { |
| 102 | - $args[$key] = $a['default']($args); | |
| 124 | + if ($a['default'] === self::DEFAULT_FROM_ENV_INI) { | |
| 125 | + $args[$key] = $a['default']($key, $a['valid'][0] ?? 'string', $args); | |
| 126 | + } else { | |
| 127 | + $args[$key] = $a['default']($args); | |
| 128 | + } | |
| 103 | 129 | } else { |
| 104 | 130 | $args[$key] = $a['default']; |
| 105 | 131 | } |
| 106 | 132 | } elseif (empty($a['required'])) { |
| @@ -129,8 +155,9 @@ | ||
| 129 | 155 | if ($a['type'] === 'config') { |
| 130 | 156 | $args['config'][$key] = $args[$key]; |
| 131 | 157 | } |
| 132 | 158 | } |
| 159 | + $this->_apply_client_context_params($args); | |
| 133 | 160 | return $args; |
| 134 | 161 | } |
| 135 | 162 | /** |
| 136 | 163 | * Creates a verbose error message for an invalid argument. |
| @@ -233,8 +260,32 @@ | ||
| 233 | 260 | $args['http']['timeout'] = $config->getHttpRequestTimeoutInMillis() / 1000; |
| 234 | 261 | } |
| 235 | 262 | } |
| 236 | 263 | } |
| 264 | + public static function _apply_disable_request_compression($value, array &$args) | |
| 265 | + { | |
| 266 | + if (\is_callable($value)) { | |
| 267 | + $value = $value(); | |
| 268 | + } | |
| 269 | + if (!\is_bool($value)) { | |
| 270 | + throw new IAE("Invalid configuration value provided for 'disable_request_compression'." . " value must be a bool."); | |
| 271 | + } | |
| 272 | + $args['config']['disable_request_compression'] = $value; | |
| 273 | + } | |
| 274 | + public static function _apply_min_compression_size($value, array &$args) | |
| 275 | + { | |
| 276 | + if (\is_callable($value)) { | |
| 277 | + $value = $value(); | |
| 278 | + } | |
| 279 | + if (!\is_int($value) || \is_int($value) && ($value < 0 || $value > 10485760)) { | |
| 280 | + throw new IAE(" Invalid configuration value provided for 'min_compression_size_bytes'." . " value must be an integer between 0 and 10485760, inclusive."); | |
| 281 | + } | |
| 282 | + $args['config']['request_min_compression_size_bytes'] = $value; | |
| 283 | + } | |
| 284 | + public static function _default_min_compression_size(array &$args) | |
| 285 | + { | |
| 286 | + return ConfigurationResolver::resolve('request_min_compression_size_bytes', 10240, 'int', $args); | |
| 287 | + } | |
| 237 | 288 | public static function _apply_credentials($value, array &$args) |
| 238 | 289 | { |
| 239 | 290 | if (\is_callable($value)) { |
| 240 | 291 | return; |
| @@ -241,16 +292,17 @@ | ||
| 241 | 292 | } |
| 242 | 293 | if ($value instanceof CredentialsInterface) { |
| 243 | 294 | $args['credentials'] = CredentialProvider::fromCredentials($value); |
| 244 | 295 | } elseif (\is_array($value) && isset($value['key']) && isset($value['secret'])) { |
| 245 | - $args['credentials'] = CredentialProvider::fromCredentials(new Credentials($value['key'], $value['secret'], isset($value['token']) ? $value['token'] : null, isset($value['expires']) ? $value['expires'] : null)); | |
| 296 | + $args['credentials'] = CredentialProvider::fromCredentials(new Credentials($value['key'], $value['secret'], $value['token'] ?? null, $value['expires'] ?? null, $value['accountId'] ?? null)); | |
| 246 | 297 | } elseif ($value === \false) { |
| 247 | 298 | $args['credentials'] = CredentialProvider::fromCredentials(new Credentials('', '')); |
| 248 | 299 | $args['config']['signature_version'] = 'anonymous'; |
| 300 | + $args['config']['configured_signature_version'] = \true; | |
| 249 | 301 | } elseif ($value instanceof CacheInterface) { |
| 250 | 302 | $args['credentials'] = CredentialProvider::defaultProvider($args); |
| 251 | 303 | } else { |
| 252 | - throw new IAE('Credentials must be an instance of ' . 'Dudlewebs\\WPMCS\\s3\\Aws\\Credentials\\CredentialsInterface, an associative ' . 'array that contains "key", "secret", and an optional "token" ' . 'key-value pairs, a credentials provider function, or false.'); | |
| 304 | + throw new IAE('Credentials must be an instance of ' . "'" . CredentialsInterface::class . ', an associative ' . 'array that contains "key", "secret", and an optional "token" ' . 'key-value pairs, a credentials provider function, or false.'); | |
| 253 | 305 | } |
| 254 | 306 | } |
| 255 | 307 | public static function _default_credential_provider(array $args) |
| 256 | 308 | { |
| @@ -255,8 +307,35 @@ | ||
| 255 | 307 | public static function _default_credential_provider(array $args) |
| 256 | 308 | { |
| 257 | 309 | return CredentialProvider::defaultProvider($args); |
| 258 | 310 | } |
| 311 | + public static function _apply_token($value, array &$args) | |
| 312 | + { | |
| 313 | + if (\is_callable($value)) { | |
| 314 | + return; | |
| 315 | + } | |
| 316 | + if ($value instanceof Token) { | |
| 317 | + $args['token'] = TokenProvider::fromToken($value); | |
| 318 | + } elseif (\is_array($value) && isset($value['token'])) { | |
| 319 | + $args['token'] = TokenProvider::fromToken(new Token($value['token'], $value['expires'] ?? null)); | |
| 320 | + } elseif ($value instanceof CacheInterface) { | |
| 321 | + $args['token'] = TokenProvider::defaultProvider($args); | |
| 322 | + } else { | |
| 323 | + throw new IAE('Token must be an instance of ' . TokenInterface::class . ', an associative ' . 'array that contains "token" and an optional "expires" ' . 'key-value pairs, a token provider function, or false.'); | |
| 324 | + } | |
| 325 | + } | |
| 326 | + public static function _default_token_provider(array &$args) | |
| 327 | + { | |
| 328 | + if (($args['config']['signing_name'] ?? '') === 'bedrock') { | |
| 329 | + // Checks for env value, if present, sets auth_scheme_preference | |
| 330 | + // to bearer auth and returns a provider | |
| 331 | + $provider = BedrockTokenProvider::createIfAvailable($args); | |
| 332 | + if (!\is_null($provider)) { | |
| 333 | + return $provider; | |
| 334 | + } | |
| 335 | + } | |
| 336 | + return TokenProvider::defaultProvider($args); | |
| 337 | + } | |
| 259 | 338 | public static function _apply_csm($value, array &$args, HandlerList $list) |
| 260 | 339 | { |
| 261 | 340 | if ($value === \false) { |
| 262 | 341 | $value = new Configuration(\false, \Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationProvider::DEFAULT_HOST, \Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationProvider::DEFAULT_PORT, \Dudlewebs\WPMCS\s3\Aws\ClientSideMonitoring\ConfigurationProvider::DEFAULT_CLIENT_ID); |
| @@ -274,12 +353,16 @@ | ||
| 274 | 353 | $args['api'] = $api; |
| 275 | 354 | $args['parser'] = Service::createParser($api); |
| 276 | 355 | $args['error_parser'] = Service::createErrorParser($api->getProtocol(), $api); |
| 277 | 356 | } |
| 278 | - public static function _apply_endpoint_provider(callable $value, array &$args) | |
| 357 | + public static function _apply_endpoint_provider($value, array &$args) | |
| 279 | 358 | { |
| 280 | 359 | if (!isset($args['endpoint'])) { |
| 281 | - $endpointPrefix = isset($args['api']['metadata']['endpointPrefix']) ? $args['api']['metadata']['endpointPrefix'] : $args['service']; | |
| 360 | + if ($value instanceof \Dudlewebs\WPMCS\s3\Aws\EndpointV2\EndpointProviderV2) { | |
| 361 | + $options = self::getEndpointProviderOptions($args); | |
| 362 | + $value = PartitionEndpointProvider::defaultProvider($options)->getPartition($args['region'], $args['service']); | |
| 363 | + } | |
| 364 | + $endpointPrefix = $args['api']['metadata']['endpointPrefix'] ?? $args['service']; | |
| 282 | 365 | // Check region is a valid host label when it is being used to |
| 283 | 366 | // generate an endpoint |
| 284 | 367 | if (!self::isValidRegion($args['region'])) { |
| 285 | 368 | throw new InvalidRegionException('Region must be a valid RFC' . ' host label.'); |
| @@ -291,10 +374,14 @@ | ||
| 291 | 374 | $args['region'] = \Dudlewebs\WPMCS\s3\Aws\strip_fips_pseudo_regions($args['region']); |
| 292 | 375 | // Invoke the endpoint provider and throw if it does not resolve. |
| 293 | 376 | $result = EndpointProvider::resolve($value, ['service' => $endpointPrefix, 'region' => $args['region'], 'scheme' => $args['scheme'], 'options' => self::getEndpointProviderOptions($args)]); |
| 294 | 377 | $args['endpoint'] = $result['endpoint']; |
| 295 | - if (empty($args['config']['signature_version']) && isset($result['signatureVersion'])) { | |
| 296 | - $args['config']['signature_version'] = $result['signatureVersion']; | |
| 378 | + if (empty($args['config']['signature_version'])) { | |
| 379 | + if (isset($args['api']) && $args['api']->getSignatureVersion() == 'bearer') { | |
| 380 | + $args['config']['signature_version'] = 'bearer'; | |
| 381 | + } elseif (isset($result['signatureVersion'])) { | |
| 382 | + $args['config']['signature_version'] = $result['signatureVersion']; | |
| 383 | + } | |
| 297 | 384 | } |
| 298 | 385 | if (empty($args['config']['signing_region']) && isset($result['signingRegion'])) { |
| 299 | 386 | $args['config']['signing_region'] = $result['signingRegion']; |
| 300 | 387 | } |
| @@ -399,31 +486,26 @@ | ||
| 399 | 486 | public static function _apply_http_handler($value, array &$args, HandlerList $list) |
| 400 | 487 | { |
| 401 | 488 | $args['handler'] = new WrappedHttpHandler($value, $args['parser'], $args['error_parser'], $args['exception_class'], $args['stats']['http']); |
| 402 | 489 | } |
| 403 | - public static function _apply_user_agent($inputUserAgent, array &$args, HandlerList $list) | |
| 490 | + public static function _apply_app_id($value, array &$args) | |
| 404 | 491 | { |
| 405 | - //Add SDK version | |
| 406 | - $userAgent = ['aws-sdk-php/' . Sdk::VERSION]; | |
| 407 | - //If on HHVM add the HHVM version | |
| 408 | - if (\defined('Dudlewebs\\WPMCS\\s3\\HHVM_VERSION')) { | |
| 409 | - $userAgent[] = 'HHVM/' . HHVM_VERSION; | |
| 492 | + // AppId should not be longer than 50 chars | |
| 493 | + static $MAX_APP_ID_LENGTH = 50; | |
| 494 | + if (\strlen($value) > $MAX_APP_ID_LENGTH) { | |
| 495 | + \trigger_error("The provided or configured value for `AppId`, " . "which is an user agent parameter, exceeds the maximum length of " . "{$MAX_APP_ID_LENGTH} characters.", \E_USER_WARNING); | |
| 410 | 496 | } |
| 411 | - //Add OS version | |
| 412 | - $disabledFunctions = \explode(',', \ini_get('disable_functions')); | |
| 413 | - if (\function_exists('php_uname') && !\in_array('php_uname', $disabledFunctions, \true)) { | |
| 414 | - $osName = "OS/" . \php_uname('s') . '/' . \php_uname('r'); | |
| 415 | - if (!empty($osName)) { | |
| 416 | - $userAgent[] = $osName; | |
| 417 | - } | |
| 418 | - } | |
| 419 | - //Add the language version | |
| 420 | - $userAgent[] = 'lang/php/' . \phpversion(); | |
| 421 | - //Add exec environment if present | |
| 422 | - if ($executionEnvironment = \getenv('AWS_EXECUTION_ENV')) { | |
| 423 | - $userAgent[] = $executionEnvironment; | |
| 424 | - } | |
| 425 | - //Add the input to the end | |
| 497 | + $args['app_id'] = $value; | |
| 498 | + } | |
| 499 | + public static function _default_app_id(array $args) | |
| 500 | + { | |
| 501 | + return ConfigurationResolver::resolve('sdk_ua_app_id', '', 'string', $args); | |
| 502 | + } | |
| 503 | + public static function _apply_user_agent($inputUserAgent, array &$args, HandlerList $list) : void | |
| 504 | + { | |
| 505 | + // Add endpoint discovery if set | |
| 506 | + $userAgent = []; | |
| 507 | + // Add the input to the end | |
| 426 | 508 | if ($inputUserAgent) { |
| 427 | 509 | if (!\is_array($inputUserAgent)) { |
| 428 | 510 | $inputUserAgent = [$inputUserAgent]; |
| 429 | 511 | } |
| @@ -430,16 +512,19 @@ | ||
| 430 | 512 | $inputUserAgent = \array_map('strval', $inputUserAgent); |
| 431 | 513 | $userAgent = \array_merge($userAgent, $inputUserAgent); |
| 432 | 514 | } |
| 433 | 515 | $args['ua_append'] = $userAgent; |
| 434 | - $list->appendBuild(static function (callable $handler) use($userAgent) { | |
| 435 | - return function (CommandInterface $command, RequestInterface $request) use($handler, $userAgent) { | |
| 436 | - return $handler($command, $request->withHeader('X-Amz-User-Agent', \implode(' ', \array_merge($userAgent, $request->getHeader('X-Amz-User-Agent'))))->withHeader('User-Agent', \implode(' ', \array_merge($userAgent, $request->getHeader('User-Agent'))))); | |
| 437 | - }; | |
| 438 | - }); | |
| 516 | + $list->appendBuild(Middleware::mapRequest(function (RequestInterface $request) use($userAgent) { | |
| 517 | + return $request->withHeader('X-Amz-User-Agent', \implode(' ', \array_merge($userAgent, $request->getHeader('X-Amz-User-Agent')))); | |
| 518 | + })); | |
| 439 | 519 | } |
| 440 | 520 | public static function _apply_endpoint($value, array &$args, HandlerList $list) |
| 441 | 521 | { |
| 522 | + if (empty($value)) { | |
| 523 | + unset($args['endpoint']); | |
| 524 | + return; | |
| 525 | + } | |
| 526 | + $args['endpoint_override'] = \true; | |
| 442 | 527 | $args['endpoint'] = $value; |
| 443 | 528 | } |
| 444 | 529 | public static function _apply_idempotency_auto_fill($value, array &$args, HandlerList $list) |
| 445 | 530 | { |
| @@ -454,10 +539,29 @@ | ||
| 454 | 539 | if ($enabled) { |
| 455 | 540 | $list->prependInit(IdempotencyTokenMiddleware::wrap($args['api'], $generator), 'idempotency_auto_fill'); |
| 456 | 541 | } |
| 457 | 542 | } |
| 543 | + public static function _default_account_id_endpoint_mode($args) | |
| 544 | + { | |
| 545 | + return ConfigurationResolver::resolve('account_id_endpoint_mode', 'preferred', 'string', $args); | |
| 546 | + } | |
| 547 | + public static function _apply_account_id_endpoint_mode($value, array &$args) | |
| 548 | + { | |
| 549 | + static $accountIdEndpointModes = ['disabled', 'required', 'preferred']; | |
| 550 | + if (!\in_array($value, $accountIdEndpointModes)) { | |
| 551 | + throw new IAE("The value provided for the config account_id_endpoint_mode is invalid." . "Valid values are: " . \implode(", ", $accountIdEndpointModes)); | |
| 552 | + } | |
| 553 | + $args['account_id_endpoint_mode'] = $value; | |
| 554 | + } | |
| 458 | 555 | public static function _default_endpoint_provider(array $args) |
| 459 | 556 | { |
| 557 | + $service = $args['api'] ?? null; | |
| 558 | + $serviceName = isset($service) ? $service->getServiceName() : null; | |
| 559 | + $apiVersion = isset($service) ? $service->getApiVersion() : null; | |
| 560 | + if (self::isValidService($serviceName) && self::isValidApiVersion($serviceName, $apiVersion)) { | |
| 561 | + $ruleset = EndpointDefinitionProvider::getEndpointRuleset($service->getServiceName(), $service->getApiVersion()); | |
| 562 | + return new \Dudlewebs\WPMCS\s3\Aws\EndpointV2\EndpointProviderV2($ruleset, EndpointDefinitionProvider::getPartitions()); | |
| 563 | + } | |
| 460 | 564 | $options = self::getEndpointProviderOptions($args); |
| 461 | 565 | return PartitionEndpointProvider::defaultProvider($options)->getPartition($args['region'], $args['service']); |
| 462 | 566 | } |
| 463 | 567 | public static function _default_serializer(array $args) |
| @@ -467,8 +571,31 @@ | ||
| 467 | 571 | public static function _default_signature_provider() |
| 468 | 572 | { |
| 469 | 573 | return SignatureProvider::defaultProvider(); |
| 470 | 574 | } |
| 575 | + public static function _default_auth_scheme_resolver(array $args) | |
| 576 | + { | |
| 577 | + return new AuthSchemeResolver($args['credentials'], $args['token']); | |
| 578 | + } | |
| 579 | + public static function _apply_auth_scheme_preference(string|array|null &$value, array &$args) : void | |
| 580 | + { | |
| 581 | + // Not provided user's preference auth scheme list | |
| 582 | + if (empty($value)) { | |
| 583 | + $value = null; | |
| 584 | + $args['config']['auth_scheme_preference'] = $value; | |
| 585 | + return; | |
| 586 | + } | |
| 587 | + // Normalize it as an array | |
| 588 | + if (\is_string($value)) { | |
| 589 | + $value = \explode(',', $value); | |
| 590 | + } | |
| 591 | + // Let`s trim each value to remove break lines, spaces and/or tabs | |
| 592 | + foreach ($value as &$val) { | |
| 593 | + $val = \trim($val); | |
| 594 | + } | |
| 595 | + // Assign user's preferred auth scheme list | |
| 596 | + $args['auth_scheme_preference'] = $value; | |
| 597 | + } | |
| 471 | 598 | public static function _default_signature_version(array &$args) |
| 472 | 599 | { |
| 473 | 600 | if (isset($args['config']['signature_version'])) { |
| 474 | 601 | return $args['config']['signature_version']; |
| @@ -495,45 +622,90 @@ | ||
| 495 | 622 | if (isset($args['config']['signing_region'])) { |
| 496 | 623 | return $args['config']['signing_region']; |
| 497 | 624 | } |
| 498 | 625 | $args['__partition_result'] = isset($args['__partition_result']) ? isset($args['__partition_result']) : \call_user_func(PartitionEndpointProvider::defaultProvider(), ['service' => $args['service'], 'region' => $args['region']]); |
| 499 | - return isset($args['__partition_result']['signingRegion']) ? $args['__partition_result']['signingRegion'] : $args['region']; | |
| 626 | + return $args['__partition_result']['signingRegion'] ?? $args['region']; | |
| 500 | 627 | } |
| 501 | - public static function _missing_version(array $args) | |
| 628 | + public static function _apply_ignore_configured_endpoint_urls($value, array &$args) | |
| 502 | 629 | { |
| 503 | - $service = isset($args['service']) ? $args['service'] : ''; | |
| 504 | - $versions = ApiProvider::defaultProvider()->getVersions($service); | |
| 505 | - $versions = \implode("\n", \array_map(function ($v) { | |
| 506 | - return "* \"{$v}\""; | |
| 507 | - }, $versions)) ?: '* (none found)'; | |
| 508 | - return <<<EOT | |
| 509 | -A "version" configuration value is required. Specifying a version constraint | |
| 510 | -ensures that your code will not be affected by a breaking change made to the | |
| 511 | -service. For example, when using Amazon S3, you can lock your API version to | |
| 512 | -"2006-03-01". | |
| 513 | - | |
| 514 | -Your build of the SDK has the following version(s) of "{$service}": {$versions} | |
| 515 | - | |
| 516 | -You may provide "latest" to the "version" configuration value to utilize the | |
| 517 | -most recent available API version that your client's API provider can find. | |
| 518 | -Note: Using 'latest' in a production application is not recommended. | |
| 519 | - | |
| 520 | -A list of available API versions can be found on each client's API documentation | |
| 521 | -page: http://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html. If you are | |
| 522 | -unable to load a specific API version, then you may need to update your copy of | |
| 523 | -the SDK. | |
| 524 | -EOT; | |
| 630 | + $args['config']['ignore_configured_endpoint_urls'] = $value; | |
| 525 | 631 | } |
| 632 | + public static function _apply_suppress_php_deprecation_warning($value, &$args) | |
| 633 | + { | |
| 634 | + if ($value) { | |
| 635 | + $args['suppress_php_deprecation_warning'] = \true; | |
| 636 | + } elseif (!empty(\getenv("AWS_SUPPRESS_PHP_DEPRECATION_WARNING"))) { | |
| 637 | + $args['suppress_php_deprecation_warning'] = \Dudlewebs\WPMCS\s3\Aws\boolean_value(\getenv("AWS_SUPPRESS_PHP_DEPRECATION_WARNING")); | |
| 638 | + } elseif (!empty($_SERVER["AWS_SUPPRESS_PHP_DEPRECATION_WARNING"])) { | |
| 639 | + $args['suppress_php_deprecation_warning'] = \Dudlewebs\WPMCS\s3\Aws\boolean_value($_SERVER["AWS_SUPPRESS_PHP_DEPRECATION_WARNING"]); | |
| 640 | + } elseif (!empty($_ENV["AWS_SUPPRESS_PHP_DEPRECATION_WARNING"])) { | |
| 641 | + $args['suppress_php_deprecation_warning'] = \Dudlewebs\WPMCS\s3\Aws\boolean_value($_ENV["AWS_SUPPRESS_PHP_DEPRECATION_WARNING"]); | |
| 642 | + } | |
| 643 | + if ($args['suppress_php_deprecation_warning'] === \false && \PHP_VERSION_ID < 80100) { | |
| 644 | + self::emitDeprecationWarning(); | |
| 645 | + } | |
| 646 | + } | |
| 647 | + public static function _default_endpoint(array &$args) | |
| 648 | + { | |
| 649 | + if ($args['config']['ignore_configured_endpoint_urls'] || !self::isValidService($args['service'])) { | |
| 650 | + return ''; | |
| 651 | + } | |
| 652 | + $serviceIdentifier = \Dudlewebs\WPMCS\s3\Aws\manifest($args['service'])['serviceIdentifier']; | |
| 653 | + $value = ConfigurationResolver::resolve('endpoint_url_' . $serviceIdentifier, '', 'string', $args + ['ini_resolver_options' => ['section' => 'services', 'subsection' => $serviceIdentifier, 'key' => 'endpoint_url']]); | |
| 654 | + if (empty($value)) { | |
| 655 | + $value = ConfigurationResolver::resolve('endpoint_url', '', 'string', $args); | |
| 656 | + } | |
| 657 | + if (!empty($value)) { | |
| 658 | + $args['config']['configured_endpoint_url'] = \true; | |
| 659 | + } | |
| 660 | + return $value; | |
| 661 | + } | |
| 662 | + public static function _apply_sigv4a_signing_region_set($value, array &$args) | |
| 663 | + { | |
| 664 | + if (empty($value)) { | |
| 665 | + $args['sigv4a_signing_region_set'] = null; | |
| 666 | + } elseif (\is_array($value)) { | |
| 667 | + $args['sigv4a_signing_region_set'] = \implode(', ', $value); | |
| 668 | + } else { | |
| 669 | + $args['sigv4a_signing_region_set'] = $value; | |
| 670 | + } | |
| 671 | + } | |
| 672 | + public static function _apply_region($value, array &$args) | |
| 673 | + { | |
| 674 | + if (empty($value)) { | |
| 675 | + self::_missing_region($args); | |
| 676 | + } | |
| 677 | + $args['region'] = $value; | |
| 678 | + } | |
| 526 | 679 | public static function _missing_region(array $args) |
| 527 | 680 | { |
| 528 | - $service = isset($args['service']) ? $args['service'] : ''; | |
| 529 | - return <<<EOT | |
| 681 | + $service = $args['service'] ?? ''; | |
| 682 | + $msg = <<<EOT | |
| 683 | +Missing required client configuration options: | |
| 684 | + | |
| 685 | +region: (string) | |
| 686 | + | |
| 530 | 687 | A "region" configuration value is required for the "{$service}" service |
| 531 | 688 | (e.g., "us-west-2"). A list of available public regions and endpoints can be |
| 532 | 689 | found at http://docs.aws.amazon.com/general/latest/gr/rande.html. |
| 533 | 690 | EOT; |
| 691 | + throw new IAE($msg); | |
| 534 | 692 | } |
| 535 | 693 | /** |
| 694 | + * Resolves a value from env or config. | |
| 695 | + * | |
| 696 | + * @param $key | |
| 697 | + * @param $expectedType | |
| 698 | + * @param $args | |
| 699 | + * | |
| 700 | + * @return mixed|string | |
| 701 | + */ | |
| 702 | + private static function _resolve_from_env_ini(string $key, string $expectedType, array $args) | |
| 703 | + { | |
| 704 | + static $typeDefaultMap = ['int' => 0, 'bool' => \false, 'boolean' => \false, 'string' => '']; | |
| 705 | + return ConfigurationResolver::resolve($key, $typeDefaultMap[$expectedType] ?? '', $expectedType, $args); | |
| 706 | + } | |
| 707 | + /** | |
| 536 | 708 | * Extracts client options for the endpoint provider to its own array |
| 537 | 709 | * |
| 538 | 710 | * @param array $args |
| 539 | 711 | * @return array |
| @@ -563,6 +735,42 @@ | ||
| 563 | 735 | */ |
| 564 | 736 | private static function isValidRegion($region) |
| 565 | 737 | { |
| 566 | 738 | return is_valid_hostlabel($region); |
| 739 | + } | |
| 740 | + private function _apply_client_context_params(array $args) | |
| 741 | + { | |
| 742 | + if (isset($args['api']) && !empty($args['api']->getClientContextParams())) { | |
| 743 | + $clientContextParams = $args['api']->getClientContextParams(); | |
| 744 | + foreach ($clientContextParams as $paramName => $paramDefinition) { | |
| 745 | + $definition = ['type' => 'value', 'valid' => [$paramDefinition['type']], 'doc' => $paramDefinition['documentation'] ?? null]; | |
| 746 | + $this->argDefinitions[$paramName] = $definition; | |
| 747 | + if (isset($args[$paramName])) { | |
| 748 | + $fn = self::$typeMap[$paramDefinition['type']]; | |
| 749 | + if (!$fn($args[$paramName])) { | |
| 750 | + $this->invalidType($paramName, $args[$paramName]); | |
| 751 | + } | |
| 752 | + } | |
| 753 | + } | |
| 754 | + } | |
| 755 | + } | |
| 756 | + private static function isValidService($service) | |
| 757 | + { | |
| 758 | + if (\is_null($service)) { | |
| 759 | + return \false; | |
| 760 | + } | |
| 761 | + $services = \Dudlewebs\WPMCS\s3\Aws\manifest(); | |
| 762 | + return isset($services[$service]); | |
| 763 | + } | |
| 764 | + private static function isValidApiVersion($service, $apiVersion) | |
| 765 | + { | |
| 766 | + if (\is_null($apiVersion)) { | |
| 767 | + return \false; | |
| 768 | + } | |
| 769 | + return \is_dir(__DIR__ . "/data/{$service}/{$apiVersion}"); | |
| 770 | + } | |
| 771 | + private static function emitDeprecationWarning() | |
| 772 | + { | |
| 773 | + $phpVersionString = \phpversion(); | |
| 774 | + \trigger_error("This installation of the SDK is using PHP version" . " {$phpVersionString}, which will be deprecated on January" . " 13th, 2025.\nPlease upgrade your PHP version to a minimum of" . " 8.1.x to continue receiving updates for the AWS" . " SDK for PHP.\nTo disable this warning, set" . " suppress_php_deprecation_warning to true on the client constructor" . " or set the environment variable AWS_SUPPRESS_PHP_DEPRECATION_WARNING" . " to true.\nMore information can be found at: " . "https://aws.amazon.com/blogs/developer/announcing-the-end-of-support-for-php-runtimes-8-0-x-and-below-in-the-aws-sdk-for-php/\n", \E_USER_DEPRECATED); | |
| 567 | 775 | } |
| 568 | 776 | } |