Version Description
- Fix: Authenticated Persistent XSS & XFS in CDN admin page
- Update: AWS library version 3.183.0
- Update: Minify: Include theme template files using page_* filenames
Download this release
Release Info
Developer | joemoto |
Plugin | W3 Total Cache |
Version | 2.1.3 |
Comparing to | |
See all releases |
Code changes from version 2.1.2 to 2.1.3
- CdnEngine_CloudFront.php +1 -1
- CdnEngine_Mirror_CloudFront.php +1 -1
- CdnEngine_S3.php +3 -2
- Cdnfsd_CloudFront_Engine.php +1 -1
- Cdnfsd_CloudFront_Popup.php +1 -1
- Enterprise_SnsBase.php +1 -1
- Generic_AdminActions_Default.php +1 -1
- Util_Theme.php +6 -6
- composer.json +18 -0
- composer.lock +605 -0
- inc/options/cdn/s3.php +1 -1
- inc/options/cdn/s3_compatible.php +1 -1
- lib/Aws/Aws/Api/ApiProvider.php +0 -244
- lib/Aws/Aws/Api/DateTimeResult.php +0 -41
- lib/Aws/Aws/Api/DocModel.php +0 -128
- lib/Aws/Aws/Api/ErrorParser/JsonParserTrait.php +0 -26
- lib/Aws/Aws/Api/ErrorParser/JsonRpcErrorParser.php +0 -31
- lib/Aws/Aws/Api/ErrorParser/RestJsonErrorParser.php +0 -35
- lib/Aws/Aws/Api/ErrorParser/XmlErrorParser.php +0 -82
- lib/Aws/Aws/Api/Parser/AbstractRestParser.php +0 -173
- lib/Aws/Aws/Api/Parser/Crc32ValidatingParser.php +0 -54
- lib/Aws/Aws/Api/Parser/DecodingEventStreamIterator.php +0 -335
- lib/Aws/Aws/Api/Parser/Exception/ParserException.php +0 -31
- lib/Aws/Aws/Api/Parser/JsonParser.php +0 -62
- lib/Aws/Aws/Api/Parser/PayloadParserTrait.php +0 -61
- lib/Aws/Aws/Api/Parser/XmlParser.php +0 -138
- lib/Aws/Aws/Api/Serializer/RestSerializer.php +0 -219
- lib/Aws/Aws/Api/Serializer/RestXmlSerializer.php +0 -34
- lib/Aws/Aws/Api/Serializer/XmlBody.php +0 -220
- lib/Aws/Aws/Api/Service.php +0 -448
- lib/Aws/Aws/Api/ShapeMap.php +0 -66
- lib/Aws/Aws/AwsClient.php +0 -402
- lib/Aws/Aws/AwsClientTrait.php +0 -92
- lib/Aws/Aws/ClientResolver.php +0 -768
- lib/Aws/Aws/ClientSideMonitoring/AbstractMonitoringMiddleware.php +0 -275
- lib/Aws/Aws/ClientSideMonitoring/Configuration.php +0 -65
- lib/Aws/Aws/ClientSideMonitoring/ConfigurationInterface.php +0 -37
- lib/Aws/Aws/ClientSideMonitoring/ConfigurationProvider.php +0 -342
- lib/Aws/Aws/CloudFront/CloudFrontClient.php +0 -190
- lib/Aws/Aws/CloudFront/Signer.php +0 -117
- lib/Aws/Aws/CloudFront/UrlSigner.php +0 -119
- lib/Aws/Aws/Command.php +0 -62
- lib/Aws/Aws/Credentials/CredentialProvider.php +0 -488
- lib/Aws/Aws/Credentials/EcsCredentialProvider.php +0 -88
- lib/Aws/Aws/Credentials/InstanceProfileProvider.php +0 -118
- lib/Aws/Aws/Endpoint/Partition.php +0 -183
- lib/Aws/Aws/Endpoint/PartitionEndpointProvider.php +0 -108
- lib/Aws/Aws/EndpointDiscovery/ConfigurationProvider.php +0 -333
- lib/Aws/Aws/EndpointDiscovery/EndpointDiscoveryMiddleware.php +0 -414
- lib/Aws/Aws/EndpointParameterMiddleware.php +0 -84
- lib/Aws/Aws/Exception/AwsException.php +0 -237
- lib/Aws/Aws/Handler/GuzzleV5/GuzzleHandler.php +0 -210
- lib/Aws/Aws/Handler/GuzzleV6/GuzzleHandler.php +0 -85
- lib/Aws/Aws/Middleware.php +0 -372
- lib/Aws/Aws/MockHandler.php +0 -145
- lib/Aws/Aws/MultiRegionClient.php +0 -236
- lib/Aws/Aws/PresignUrlMiddleware.php +0 -99
- lib/Aws/Aws/ResponseContainerInterface.php +0 -13
- lib/Aws/Aws/RetryMiddleware.php +0 -315
- lib/Aws/Aws/S3/AmbiguousSuccessParser.php +0 -68
- lib/Aws/Aws/S3/ApplyChecksumMiddleware.php +0 -78
- lib/Aws/Aws/S3/Crypto/HeadersMetadataStrategy.php +0 -52
- lib/Aws/Aws/S3/Crypto/S3EncryptionClient.php +0 -317
- lib/Aws/Aws/S3/Crypto/S3EncryptionMultipartUploader.php +0 -157
- lib/Aws/Aws/S3/MultipartCopy.php +0 -183
- lib/Aws/Aws/S3/MultipartUploader.php +0 -168
- lib/Aws/Aws/S3/ObjectCopier.php +0 -150
- lib/Aws/Aws/S3/ObjectUploader.php +0 -140
- lib/Aws/Aws/S3/PostObjectV4.php +0 -195
- lib/Aws/Aws/S3/PutObjectUrlMiddleware.php +0 -57
- lib/Aws/Aws/S3/S3Client.php +0 -633
- lib/Aws/Aws/S3/S3ClientInterface.php +0 -322
- lib/Aws/Aws/S3/S3EndpointMiddleware.php +0 -234
- lib/Aws/Aws/S3/S3MultiRegionClient.php +0 -339
- lib/Aws/Aws/S3/S3UriParser.php +0 -133
- lib/Aws/Aws/S3/StreamWrapper.php +0 -958
- lib/Aws/Aws/S3/Transfer.php +0 -428
- lib/Aws/Aws/Sdk.php +0 -466
- lib/Aws/Aws/Signature/AnonymousSignature.php +0 -26
- lib/Aws/Aws/Signature/S3SignatureV4.php +0 -68
- lib/Aws/Aws/Signature/SignatureInterface.php +0 -44
- lib/Aws/Aws/Signature/SignatureProvider.php +0 -131
- lib/Aws/Aws/Signature/SignatureV4.php +0 -412
- lib/Aws/Aws/Sns/Exception/InvalidSnsMessageException.php +0 -9
- lib/Aws/Aws/Sns/Message.php +0 -156
- lib/Aws/Aws/Sns/MessageValidator.php +0 -190
- lib/Aws/Aws/TraceMiddleware.php +0 -314
- lib/Aws/Aws/WrappedHttpHandler.php +0 -203
- lib/Aws/Aws/data/endpoints.json.php +0 -3
- lib/Aws/Aws/data/endpoints_prefix_history.json.php +0 -3
- lib/Aws/Aws/data/manifest.json.php +0 -3
- lib/Aws/Aws/data/s3/2006-03-01/api-2.json.php +0 -3
- lib/Aws/Aws/data/sns/2010-03-31/api-2.json.php +0 -3
- lib/Aws/Aws/functions.php +0 -411
- lib/Aws/Aws/signer/signerClient.php +0 -27
- lib/Aws/GuzzleHttp/Client.php +0 -422
- lib/Aws/GuzzleHttp/ClientInterface.php +0 -84
- lib/Aws/GuzzleHttp/Cookie/CookieJar.php +0 -314
- lib/Aws/GuzzleHttp/Cookie/CookieJarInterface.php +0 -84
- lib/Aws/GuzzleHttp/Cookie/FileCookieJar.php +0 -90
- lib/Aws/GuzzleHttp/Cookie/SessionCookieJar.php +0 -71
- lib/Aws/GuzzleHttp/Cookie/SetCookie.php +0 -403
- lib/Aws/GuzzleHttp/Exception/ClientException.php +0 -7
- lib/Aws/GuzzleHttp/Exception/GuzzleException.php +0 -13
- lib/Aws/GuzzleHttp/Exception/RequestException.php +0 -217
- lib/Aws/GuzzleHttp/Exception/ServerException.php +0 -7
- lib/Aws/GuzzleHttp/Exception/TooManyRedirectsException.php +0 -4
- lib/Aws/GuzzleHttp/Exception/TransferException.php +0 -4
- lib/Aws/GuzzleHttp/Handler/CurlFactory.php +0 -565
- lib/Aws/GuzzleHttp/Handler/CurlMultiHandler.php +0 -199
- lib/Aws/GuzzleHttp/Handler/MockHandler.php +0 -189
- lib/Aws/GuzzleHttp/Handler/StreamHandler.php +0 -532
- lib/Aws/GuzzleHttp/HandlerStack.php +0 -273
- lib/Aws/GuzzleHttp/MessageFormatter.php +0 -180
- lib/Aws/GuzzleHttp/Middleware.php +0 -255
- lib/Aws/GuzzleHttp/Pool.php +0 -123
- lib/Aws/GuzzleHttp/PrepareBodyMiddleware.php +0 -106
- lib/Aws/GuzzleHttp/Promise/AggregateException.php +0 -16
- lib/Aws/GuzzleHttp/Promise/CancellationException.php +0 -9
- lib/Aws/GuzzleHttp/Promise/Coroutine.php +0 -151
- lib/Aws/GuzzleHttp/Promise/EachPromise.php +0 -229
- lib/Aws/GuzzleHttp/Promise/FulfilledPromise.php +0 -82
- lib/Aws/GuzzleHttp/Promise/Promise.php +0 -98
CdnEngine_CloudFront.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
-
require_once
|
6 |
}
|
7 |
|
8 |
/**
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_DIR . '/vendor/autoload.php';
|
6 |
}
|
7 |
|
8 |
/**
|
CdnEngine_Mirror_CloudFront.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
-
require_once
|
6 |
}
|
7 |
|
8 |
/**
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_DIR . '/vendor/autoload.php';
|
6 |
}
|
7 |
|
8 |
/**
|
CdnEngine_S3.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
-
require_once
|
6 |
}
|
7 |
|
8 |
/**
|
@@ -107,7 +107,8 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
107 |
$this->api = new \Aws\S3\S3Client( array(
|
108 |
'credentials' => $credentials,
|
109 |
'region' => $this->_config['bucket_location'],
|
110 |
-
'version' => '2006-03-01'
|
|
|
111 |
)
|
112 |
);
|
113 |
}
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_DIR . '/vendor/autoload.php';
|
6 |
}
|
7 |
|
8 |
/**
|
107 |
$this->api = new \Aws\S3\S3Client( array(
|
108 |
'credentials' => $credentials,
|
109 |
'region' => $this->_config['bucket_location'],
|
110 |
+
'version' => '2006-03-01',
|
111 |
+
'use_arn_region' => true,
|
112 |
)
|
113 |
);
|
114 |
}
|
Cdnfsd_CloudFront_Engine.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
-
require_once
|
6 |
}
|
7 |
|
8 |
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_DIR . '/vendor/autoload.php';
|
6 |
}
|
7 |
|
8 |
|
Cdnfsd_CloudFront_Popup.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
-
require_once
|
6 |
}
|
7 |
|
8 |
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_DIR . '/vendor/autoload.php';
|
6 |
}
|
7 |
|
8 |
|
Enterprise_SnsBase.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
-
require_once
|
6 |
}
|
7 |
|
8 |
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_DIR . '/vendor/autoload.php';
|
6 |
}
|
7 |
|
8 |
|
Generic_AdminActions_Default.php
CHANGED
@@ -367,7 +367,7 @@ class Generic_AdminActions_Default {
|
|
367 |
$cdn_domains = array();
|
368 |
|
369 |
foreach ( $cdn_cnames as $cdn_cname ) {
|
370 |
-
$cdn_cname =
|
371 |
|
372 |
/**
|
373 |
* Auto expand wildcard domain to 10 subdomains
|
367 |
$cdn_domains = array();
|
368 |
|
369 |
foreach ( $cdn_cnames as $cdn_cname ) {
|
370 |
+
$cdn_cname = preg_replace( '~[^0-9a-zA-Z.:\-]~', '', strip_tags( $cdn_cname ) );
|
371 |
|
372 |
/**
|
373 |
* Auto expand wildcard domain to 10 subdomains
|
Util_Theme.php
CHANGED
@@ -102,17 +102,17 @@ class Util_Theme {
|
|
102 |
$patterns = array(
|
103 |
'404',
|
104 |
'search',
|
105 |
-
'taxonomy(
|
106 |
'front-page',
|
107 |
'home',
|
108 |
'index',
|
109 |
'(image|video|text|audio|application).*',
|
110 |
'attachment',
|
111 |
-
'single(
|
112 |
-
'page(
|
113 |
-
'category(
|
114 |
-
'tag(
|
115 |
-
'author(
|
116 |
'date',
|
117 |
'archive',
|
118 |
'comments-popup',
|
102 |
$patterns = array(
|
103 |
'404',
|
104 |
'search',
|
105 |
+
'taxonomy((-|_).*)?',
|
106 |
'front-page',
|
107 |
'home',
|
108 |
'index',
|
109 |
'(image|video|text|audio|application).*',
|
110 |
'attachment',
|
111 |
+
'single((-|_).*)?',
|
112 |
+
'page((-|_).*)?',
|
113 |
+
'category((-|_).*)?',
|
114 |
+
'tag((-|_).*)?',
|
115 |
+
'author((-|_).*)?',
|
116 |
'date',
|
117 |
'archive',
|
118 |
'comments-popup',
|
composer.json
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"require": {
|
3 |
+
"aws/aws-sdk-php": "^3.180",
|
4 |
+
"guzzlehttp/guzzle": "6.*",
|
5 |
+
"symfony/polyfill-intl-idn" : "1.20.*",
|
6 |
+
"symfony/polyfill-intl-normalizer" : "1.20.*",
|
7 |
+
"symfony/polyfill-mbstring" : "1.20.*"
|
8 |
+
},
|
9 |
+
"replace": {
|
10 |
+
"symfony/polyfill-php56": "*",
|
11 |
+
"symfony/polyfill-php70": "*",
|
12 |
+
"symfony/polyfill-php71": "*",
|
13 |
+
"symfony/polyfill-php72": "*",
|
14 |
+
"symfony/polyfill-php73": "*",
|
15 |
+
"symfony/polyfill-php74": "*",
|
16 |
+
"symfony/polyfill-mbstring": "*"
|
17 |
+
}
|
18 |
+
}
|
composer.lock
ADDED
@@ -0,0 +1,605 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_readme": [
|
3 |
+
"This file locks the dependencies of your project to a known state",
|
4 |
+
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
+
"This file is @generated automatically"
|
6 |
+
],
|
7 |
+
"content-hash": "d855034b6d59c71406bb056a1a3b487c",
|
8 |
+
"packages": [
|
9 |
+
{
|
10 |
+
"name": "aws/aws-sdk-php",
|
11 |
+
"version": "3.183.8",
|
12 |
+
"source": {
|
13 |
+
"type": "git",
|
14 |
+
"url": "https://github.com/aws/aws-sdk-php.git",
|
15 |
+
"reference": "3b52c4a99faa539c5bdc0a84cf88ee6ea385fd1c"
|
16 |
+
},
|
17 |
+
"dist": {
|
18 |
+
"type": "zip",
|
19 |
+
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3b52c4a99faa539c5bdc0a84cf88ee6ea385fd1c",
|
20 |
+
"reference": "3b52c4a99faa539c5bdc0a84cf88ee6ea385fd1c",
|
21 |
+
"shasum": ""
|
22 |
+
},
|
23 |
+
"require": {
|
24 |
+
"ext-json": "*",
|
25 |
+
"ext-pcre": "*",
|
26 |
+
"ext-simplexml": "*",
|
27 |
+
"guzzlehttp/guzzle": "^5.3.3|^6.2.1|^7.0",
|
28 |
+
"guzzlehttp/promises": "^1.4.0",
|
29 |
+
"guzzlehttp/psr7": "^1.7.0",
|
30 |
+
"mtdowling/jmespath.php": "^2.6",
|
31 |
+
"php": ">=5.5"
|
32 |
+
},
|
33 |
+
"require-dev": {
|
34 |
+
"andrewsville/php-token-reflection": "^1.4",
|
35 |
+
"aws/aws-php-sns-message-validator": "~1.0",
|
36 |
+
"behat/behat": "~3.0",
|
37 |
+
"doctrine/cache": "~1.4",
|
38 |
+
"ext-dom": "*",
|
39 |
+
"ext-openssl": "*",
|
40 |
+
"ext-pcntl": "*",
|
41 |
+
"ext-sockets": "*",
|
42 |
+
"nette/neon": "^2.3",
|
43 |
+
"paragonie/random_compat": ">= 2",
|
44 |
+
"phpunit/phpunit": "^4.8.35|^5.4.3",
|
45 |
+
"psr/cache": "^1.0",
|
46 |
+
"psr/simple-cache": "^1.0",
|
47 |
+
"sebastian/comparator": "^1.2.3"
|
48 |
+
},
|
49 |
+
"suggest": {
|
50 |
+
"aws/aws-php-sns-message-validator": "To validate incoming SNS notifications",
|
51 |
+
"doctrine/cache": "To use the DoctrineCacheAdapter",
|
52 |
+
"ext-curl": "To send requests using cURL",
|
53 |
+
"ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages",
|
54 |
+
"ext-sockets": "To use client-side monitoring"
|
55 |
+
},
|
56 |
+
"type": "library",
|
57 |
+
"extra": {
|
58 |
+
"branch-alias": {
|
59 |
+
"dev-master": "3.0-dev"
|
60 |
+
}
|
61 |
+
},
|
62 |
+
"autoload": {
|
63 |
+
"psr-4": {
|
64 |
+
"Aws\\": "src/"
|
65 |
+
},
|
66 |
+
"files": [
|
67 |
+
"src/functions.php"
|
68 |
+
]
|
69 |
+
},
|
70 |
+
"notification-url": "https://packagist.org/downloads/",
|
71 |
+
"license": [
|
72 |
+
"Apache-2.0"
|
73 |
+
],
|
74 |
+
"authors": [
|
75 |
+
{
|
76 |
+
"name": "Amazon Web Services",
|
77 |
+
"homepage": "http://aws.amazon.com"
|
78 |
+
}
|
79 |
+
],
|
80 |
+
"description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
|
81 |
+
"homepage": "http://aws.amazon.com/sdkforphp",
|
82 |
+
"keywords": [
|
83 |
+
"amazon",
|
84 |
+
"aws",
|
85 |
+
"cloud",
|
86 |
+
"dynamodb",
|
87 |
+
"ec2",
|
88 |
+
"glacier",
|
89 |
+
"s3",
|
90 |
+
"sdk"
|
91 |
+
],
|
92 |
+
"time": "2021-05-27T18:13:28+00:00"
|
93 |
+
},
|
94 |
+
{
|
95 |
+
"name": "guzzlehttp/guzzle",
|
96 |
+
"version": "6.5.5",
|
97 |
+
"source": {
|
98 |
+
"type": "git",
|
99 |
+
"url": "https://github.com/guzzle/guzzle.git",
|
100 |
+
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e"
|
101 |
+
},
|
102 |
+
"dist": {
|
103 |
+
"type": "zip",
|
104 |
+
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e",
|
105 |
+
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e",
|
106 |
+
"shasum": ""
|
107 |
+
},
|
108 |
+
"require": {
|
109 |
+
"ext-json": "*",
|
110 |
+
"guzzlehttp/promises": "^1.0",
|
111 |
+
"guzzlehttp/psr7": "^1.6.1",
|
112 |
+
"php": ">=5.5",
|
113 |
+
"symfony/polyfill-intl-idn": "^1.17.0"
|
114 |
+
},
|
115 |
+
"require-dev": {
|
116 |
+
"ext-curl": "*",
|
117 |
+
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
|
118 |
+
"psr/log": "^1.1"
|
119 |
+
},
|
120 |
+
"suggest": {
|
121 |
+
"psr/log": "Required for using the Log middleware"
|
122 |
+
},
|
123 |
+
"type": "library",
|
124 |
+
"extra": {
|
125 |
+
"branch-alias": {
|
126 |
+
"dev-master": "6.5-dev"
|
127 |
+
}
|
128 |
+
},
|
129 |
+
"autoload": {
|
130 |
+
"psr-4": {
|
131 |
+
"GuzzleHttp\\": "src/"
|
132 |
+
},
|
133 |
+
"files": [
|
134 |
+
"src/functions_include.php"
|
135 |
+
]
|
136 |
+
},
|
137 |
+
"notification-url": "https://packagist.org/downloads/",
|
138 |
+
"license": [
|
139 |
+
"MIT"
|
140 |
+
],
|
141 |
+
"authors": [
|
142 |
+
{
|
143 |
+
"name": "Michael Dowling",
|
144 |
+
"email": "mtdowling@gmail.com",
|
145 |
+
"homepage": "https://github.com/mtdowling"
|
146 |
+
}
|
147 |
+
],
|
148 |
+
"description": "Guzzle is a PHP HTTP client library",
|
149 |
+
"homepage": "http://guzzlephp.org/",
|
150 |
+
"keywords": [
|
151 |
+
"client",
|
152 |
+
"curl",
|
153 |
+
"framework",
|
154 |
+
"http",
|
155 |
+
"http client",
|
156 |
+
"rest",
|
157 |
+
"web service"
|
158 |
+
],
|
159 |
+
"time": "2020-06-16T21:01:06+00:00"
|
160 |
+
},
|
161 |
+
{
|
162 |
+
"name": "guzzlehttp/promises",
|
163 |
+
"version": "1.4.1",
|
164 |
+
"source": {
|
165 |
+
"type": "git",
|
166 |
+
"url": "https://github.com/guzzle/promises.git",
|
167 |
+
"reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d"
|
168 |
+
},
|
169 |
+
"dist": {
|
170 |
+
"type": "zip",
|
171 |
+
"url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d",
|
172 |
+
"reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d",
|
173 |
+
"shasum": ""
|
174 |
+
},
|
175 |
+
"require": {
|
176 |
+
"php": ">=5.5"
|
177 |
+
},
|
178 |
+
"require-dev": {
|
179 |
+
"symfony/phpunit-bridge": "^4.4 || ^5.1"
|
180 |
+
},
|
181 |
+
"type": "library",
|
182 |
+
"extra": {
|
183 |
+
"branch-alias": {
|
184 |
+
"dev-master": "1.4-dev"
|
185 |
+
}
|
186 |
+
},
|
187 |
+
"autoload": {
|
188 |
+
"psr-4": {
|
189 |
+
"GuzzleHttp\\Promise\\": "src/"
|
190 |
+
},
|
191 |
+
"files": [
|
192 |
+
"src/functions_include.php"
|
193 |
+
]
|
194 |
+
},
|
195 |
+
"notification-url": "https://packagist.org/downloads/",
|
196 |
+
"license": [
|
197 |
+
"MIT"
|
198 |
+
],
|
199 |
+
"authors": [
|
200 |
+
{
|
201 |
+
"name": "Michael Dowling",
|
202 |
+
"email": "mtdowling@gmail.com",
|
203 |
+
"homepage": "https://github.com/mtdowling"
|
204 |
+
}
|
205 |
+
],
|
206 |
+
"description": "Guzzle promises library",
|
207 |
+
"keywords": [
|
208 |
+
"promise"
|
209 |
+
],
|
210 |
+
"time": "2021-03-07T09:25:29+00:00"
|
211 |
+
},
|
212 |
+
{
|
213 |
+
"name": "guzzlehttp/psr7",
|
214 |
+
"version": "1.8.2",
|
215 |
+
"source": {
|
216 |
+
"type": "git",
|
217 |
+
"url": "https://github.com/guzzle/psr7.git",
|
218 |
+
"reference": "dc960a912984efb74d0a90222870c72c87f10c91"
|
219 |
+
},
|
220 |
+
"dist": {
|
221 |
+
"type": "zip",
|
222 |
+
"url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91",
|
223 |
+
"reference": "dc960a912984efb74d0a90222870c72c87f10c91",
|
224 |
+
"shasum": ""
|
225 |
+
},
|
226 |
+
"require": {
|
227 |
+
"php": ">=5.4.0",
|
228 |
+
"psr/http-message": "~1.0",
|
229 |
+
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
|
230 |
+
},
|
231 |
+
"provide": {
|
232 |
+
"psr/http-message-implementation": "1.0"
|
233 |
+
},
|
234 |
+
"require-dev": {
|
235 |
+
"ext-zlib": "*",
|
236 |
+
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
|
237 |
+
},
|
238 |
+
"suggest": {
|
239 |
+
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
240 |
+
},
|
241 |
+
"type": "library",
|
242 |
+
"extra": {
|
243 |
+
"branch-alias": {
|
244 |
+
"dev-master": "1.7-dev"
|
245 |
+
}
|
246 |
+
},
|
247 |
+
"autoload": {
|
248 |
+
"psr-4": {
|
249 |
+
"GuzzleHttp\\Psr7\\": "src/"
|
250 |
+
},
|
251 |
+
"files": [
|
252 |
+
"src/functions_include.php"
|
253 |
+
]
|
254 |
+
},
|
255 |
+
"notification-url": "https://packagist.org/downloads/",
|
256 |
+
"license": [
|
257 |
+
"MIT"
|
258 |
+
],
|
259 |
+
"authors": [
|
260 |
+
{
|
261 |
+
"name": "Michael Dowling",
|
262 |
+
"email": "mtdowling@gmail.com",
|
263 |
+
"homepage": "https://github.com/mtdowling"
|
264 |
+
},
|
265 |
+
{
|
266 |
+
"name": "Tobias Schultze",
|
267 |
+
"homepage": "https://github.com/Tobion"
|
268 |
+
}
|
269 |
+
],
|
270 |
+
"description": "PSR-7 message implementation that also provides common utility methods",
|
271 |
+
"keywords": [
|
272 |
+
"http",
|
273 |
+
"message",
|
274 |
+
"psr-7",
|
275 |
+
"request",
|
276 |
+
"response",
|
277 |
+
"stream",
|
278 |
+
"uri",
|
279 |
+
"url"
|
280 |
+
],
|
281 |
+
"time": "2021-04-26T09:17:50+00:00"
|
282 |
+
},
|
283 |
+
{
|
284 |
+
"name": "mtdowling/jmespath.php",
|
285 |
+
"version": "2.6.0",
|
286 |
+
"source": {
|
287 |
+
"type": "git",
|
288 |
+
"url": "https://github.com/jmespath/jmespath.php.git",
|
289 |
+
"reference": "42dae2cbd13154083ca6d70099692fef8ca84bfb"
|
290 |
+
},
|
291 |
+
"dist": {
|
292 |
+
"type": "zip",
|
293 |
+
"url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/42dae2cbd13154083ca6d70099692fef8ca84bfb",
|
294 |
+
"reference": "42dae2cbd13154083ca6d70099692fef8ca84bfb",
|
295 |
+
"shasum": ""
|
296 |
+
},
|
297 |
+
"require": {
|
298 |
+
"php": "^5.4 || ^7.0 || ^8.0",
|
299 |
+
"symfony/polyfill-mbstring": "^1.17"
|
300 |
+
},
|
301 |
+
"require-dev": {
|
302 |
+
"composer/xdebug-handler": "^1.4",
|
303 |
+
"phpunit/phpunit": "^4.8.36 || ^7.5.15"
|
304 |
+
},
|
305 |
+
"bin": [
|
306 |
+
"bin/jp.php"
|
307 |
+
],
|
308 |
+
"type": "library",
|
309 |
+
"extra": {
|
310 |
+
"branch-alias": {
|
311 |
+
"dev-master": "2.6-dev"
|
312 |
+
}
|
313 |
+
},
|
314 |
+
"autoload": {
|
315 |
+
"psr-4": {
|
316 |
+
"JmesPath\\": "src/"
|
317 |
+
},
|
318 |
+
"files": [
|
319 |
+
"src/JmesPath.php"
|
320 |
+
]
|
321 |
+
},
|
322 |
+
"notification-url": "https://packagist.org/downloads/",
|
323 |
+
"license": [
|
324 |
+
"MIT"
|
325 |
+
],
|
326 |
+
"authors": [
|
327 |
+
{
|
328 |
+
"name": "Michael Dowling",
|
329 |
+
"email": "mtdowling@gmail.com",
|
330 |
+
"homepage": "https://github.com/mtdowling"
|
331 |
+
}
|
332 |
+
],
|
333 |
+
"description": "Declaratively specify how to extract elements from a JSON document",
|
334 |
+
"keywords": [
|
335 |
+
"json",
|
336 |
+
"jsonpath"
|
337 |
+
],
|
338 |
+
"time": "2020-07-31T21:01:56+00:00"
|
339 |
+
},
|
340 |
+
{
|
341 |
+
"name": "psr/http-message",
|
342 |
+
"version": "1.0.1",
|
343 |
+
"source": {
|
344 |
+
"type": "git",
|
345 |
+
"url": "https://github.com/php-fig/http-message.git",
|
346 |
+
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
347 |
+
},
|
348 |
+
"dist": {
|
349 |
+
"type": "zip",
|
350 |
+
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
351 |
+
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
352 |
+
"shasum": ""
|
353 |
+
},
|
354 |
+
"require": {
|
355 |
+
"php": ">=5.3.0"
|
356 |
+
},
|
357 |
+
"type": "library",
|
358 |
+
"extra": {
|
359 |
+
"branch-alias": {
|
360 |
+
"dev-master": "1.0.x-dev"
|
361 |
+
}
|
362 |
+
},
|
363 |
+
"autoload": {
|
364 |
+
"psr-4": {
|
365 |
+
"Psr\\Http\\Message\\": "src/"
|
366 |
+
}
|
367 |
+
},
|
368 |
+
"notification-url": "https://packagist.org/downloads/",
|
369 |
+
"license": [
|
370 |
+
"MIT"
|
371 |
+
],
|
372 |
+
"authors": [
|
373 |
+
{
|
374 |
+
"name": "PHP-FIG",
|
375 |
+
"homepage": "http://www.php-fig.org/"
|
376 |
+
}
|
377 |
+
],
|
378 |
+
"description": "Common interface for HTTP messages",
|
379 |
+
"homepage": "https://github.com/php-fig/http-message",
|
380 |
+
"keywords": [
|
381 |
+
"http",
|
382 |
+
"http-message",
|
383 |
+
"psr",
|
384 |
+
"psr-7",
|
385 |
+
"request",
|
386 |
+
"response"
|
387 |
+
],
|
388 |
+
"time": "2016-08-06T14:39:51+00:00"
|
389 |
+
},
|
390 |
+
{
|
391 |
+
"name": "ralouphie/getallheaders",
|
392 |
+
"version": "3.0.3",
|
393 |
+
"source": {
|
394 |
+
"type": "git",
|
395 |
+
"url": "https://github.com/ralouphie/getallheaders.git",
|
396 |
+
"reference": "120b605dfeb996808c31b6477290a714d356e822"
|
397 |
+
},
|
398 |
+
"dist": {
|
399 |
+
"type": "zip",
|
400 |
+
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
|
401 |
+
"reference": "120b605dfeb996808c31b6477290a714d356e822",
|
402 |
+
"shasum": ""
|
403 |
+
},
|
404 |
+
"require": {
|
405 |
+
"php": ">=5.6"
|
406 |
+
},
|
407 |
+
"require-dev": {
|
408 |
+
"php-coveralls/php-coveralls": "^2.1",
|
409 |
+
"phpunit/phpunit": "^5 || ^6.5"
|
410 |
+
},
|
411 |
+
"type": "library",
|
412 |
+
"autoload": {
|
413 |
+
"files": [
|
414 |
+
"src/getallheaders.php"
|
415 |
+
]
|
416 |
+
},
|
417 |
+
"notification-url": "https://packagist.org/downloads/",
|
418 |
+
"license": [
|
419 |
+
"MIT"
|
420 |
+
],
|
421 |
+
"authors": [
|
422 |
+
{
|
423 |
+
"name": "Ralph Khattar",
|
424 |
+
"email": "ralph.khattar@gmail.com"
|
425 |
+
}
|
426 |
+
],
|
427 |
+
"description": "A polyfill for getallheaders.",
|
428 |
+
"time": "2019-03-08T08:55:37+00:00"
|
429 |
+
},
|
430 |
+
{
|
431 |
+
"name": "symfony/polyfill-intl-idn",
|
432 |
+
"version": "v1.20.0",
|
433 |
+
"source": {
|
434 |
+
"type": "git",
|
435 |
+
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
436 |
+
"reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117"
|
437 |
+
},
|
438 |
+
"dist": {
|
439 |
+
"type": "zip",
|
440 |
+
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3b75acd829741c768bc8b1f84eb33265e7cc5117",
|
441 |
+
"reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117",
|
442 |
+
"shasum": ""
|
443 |
+
},
|
444 |
+
"require": {
|
445 |
+
"php": ">=7.1",
|
446 |
+
"symfony/polyfill-intl-normalizer": "^1.10",
|
447 |
+
"symfony/polyfill-php72": "^1.10"
|
448 |
+
},
|
449 |
+
"suggest": {
|
450 |
+
"ext-intl": "For best performance"
|
451 |
+
},
|
452 |
+
"type": "library",
|
453 |
+
"extra": {
|
454 |
+
"branch-alias": {
|
455 |
+
"dev-main": "1.20-dev"
|
456 |
+
},
|
457 |
+
"thanks": {
|
458 |
+
"name": "symfony/polyfill",
|
459 |
+
"url": "https://github.com/symfony/polyfill"
|
460 |
+
}
|
461 |
+
},
|
462 |
+
"autoload": {
|
463 |
+
"psr-4": {
|
464 |
+
"Symfony\\Polyfill\\Intl\\Idn\\": ""
|
465 |
+
},
|
466 |
+
"files": [
|
467 |
+
"bootstrap.php"
|
468 |
+
]
|
469 |
+
},
|
470 |
+
"notification-url": "https://packagist.org/downloads/",
|
471 |
+
"license": [
|
472 |
+
"MIT"
|
473 |
+
],
|
474 |
+
"authors": [
|
475 |
+
{
|
476 |
+
"name": "Laurent Bassin",
|
477 |
+
"email": "laurent@bassin.info"
|
478 |
+
},
|
479 |
+
{
|
480 |
+
"name": "Trevor Rowbotham",
|
481 |
+
"email": "trevor.rowbotham@pm.me"
|
482 |
+
},
|
483 |
+
{
|
484 |
+
"name": "Symfony Community",
|
485 |
+
"homepage": "https://symfony.com/contributors"
|
486 |
+
}
|
487 |
+
],
|
488 |
+
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
|
489 |
+
"homepage": "https://symfony.com",
|
490 |
+
"keywords": [
|
491 |
+
"compatibility",
|
492 |
+
"idn",
|
493 |
+
"intl",
|
494 |
+
"polyfill",
|
495 |
+
"portable",
|
496 |
+
"shim"
|
497 |
+
],
|
498 |
+
"funding": [
|
499 |
+
{
|
500 |
+
"url": "https://symfony.com/sponsor",
|
501 |
+
"type": "custom"
|
502 |
+
},
|
503 |
+
{
|
504 |
+
"url": "https://github.com/fabpot",
|
505 |
+
"type": "github"
|
506 |
+
},
|
507 |
+
{
|
508 |
+
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
509 |
+
"type": "tidelift"
|
510 |
+
}
|
511 |
+
],
|
512 |
+
"time": "2020-10-23T14:02:19+00:00"
|
513 |
+
},
|
514 |
+
{
|
515 |
+
"name": "symfony/polyfill-intl-normalizer",
|
516 |
+
"version": "v1.20.0",
|
517 |
+
"source": {
|
518 |
+
"type": "git",
|
519 |
+
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
520 |
+
"reference": "727d1096295d807c309fb01a851577302394c897"
|
521 |
+
},
|
522 |
+
"dist": {
|
523 |
+
"type": "zip",
|
524 |
+
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897",
|
525 |
+
"reference": "727d1096295d807c309fb01a851577302394c897",
|
526 |
+
"shasum": ""
|
527 |
+
},
|
528 |
+
"require": {
|
529 |
+
"php": ">=7.1"
|
530 |
+
},
|
531 |
+
"suggest": {
|
532 |
+
"ext-intl": "For best performance"
|
533 |
+
},
|
534 |
+
"type": "library",
|
535 |
+
"extra": {
|
536 |
+
"branch-alias": {
|
537 |
+
"dev-main": "1.20-dev"
|
538 |
+
},
|
539 |
+
"thanks": {
|
540 |
+
"name": "symfony/polyfill",
|
541 |
+
"url": "https://github.com/symfony/polyfill"
|
542 |
+
}
|
543 |
+
},
|
544 |
+
"autoload": {
|
545 |
+
"psr-4": {
|
546 |
+
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
|
547 |
+
},
|
548 |
+
"files": [
|
549 |
+
"bootstrap.php"
|
550 |
+
],
|
551 |
+
"classmap": [
|
552 |
+
"Resources/stubs"
|
553 |
+
]
|
554 |
+
},
|
555 |
+
"notification-url": "https://packagist.org/downloads/",
|
556 |
+
"license": [
|
557 |
+
"MIT"
|
558 |
+
],
|
559 |
+
"authors": [
|
560 |
+
{
|
561 |
+
"name": "Nicolas Grekas",
|
562 |
+
"email": "p@tchwork.com"
|
563 |
+
},
|
564 |
+
{
|
565 |
+
"name": "Symfony Community",
|
566 |
+
"homepage": "https://symfony.com/contributors"
|
567 |
+
}
|
568 |
+
],
|
569 |
+
"description": "Symfony polyfill for intl's Normalizer class and related functions",
|
570 |
+
"homepage": "https://symfony.com",
|
571 |
+
"keywords": [
|
572 |
+
"compatibility",
|
573 |
+
"intl",
|
574 |
+
"normalizer",
|
575 |
+
"polyfill",
|
576 |
+
"portable",
|
577 |
+
"shim"
|
578 |
+
],
|
579 |
+
"funding": [
|
580 |
+
{
|
581 |
+
"url": "https://symfony.com/sponsor",
|
582 |
+
"type": "custom"
|
583 |
+
},
|
584 |
+
{
|
585 |
+
"url": "https://github.com/fabpot",
|
586 |
+
"type": "github"
|
587 |
+
},
|
588 |
+
{
|
589 |
+
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
590 |
+
"type": "tidelift"
|
591 |
+
}
|
592 |
+
],
|
593 |
+
"time": "2020-10-23T14:02:19+00:00"
|
594 |
+
}
|
595 |
+
],
|
596 |
+
"packages-dev": [],
|
597 |
+
"aliases": [],
|
598 |
+
"minimum-stability": "stable",
|
599 |
+
"stability-flags": [],
|
600 |
+
"prefer-stable": false,
|
601 |
+
"prefer-lowest": false,
|
602 |
+
"platform": [],
|
603 |
+
"platform-dev": [],
|
604 |
+
"plugin-api-version": "1.1.0"
|
605 |
+
}
|
inc/options/cdn/s3.php
CHANGED
@@ -62,7 +62,7 @@ if ( !defined( 'W3TC' ) )
|
|
62 |
<bucket>.s3.amazonaws.com
|
63 |
<?php endif; ?> <?php _e( 'or CNAME:', 'w3-total-cache' ); ?>
|
64 |
<?php $cnames = $this->_config->get_array( 'cdn.s3.cname' ); include W3TC_INC_DIR . '/options/cdn/common/cnames.php'; ?>
|
65 |
-
<p class="description"><?php _e( 'If you have already added a <a href="
|
66 |
</td>
|
67 |
</tr>
|
68 |
<tr>
|
62 |
<bucket>.s3.amazonaws.com
|
63 |
<?php endif; ?> <?php _e( 'or CNAME:', 'w3-total-cache' ); ?>
|
64 |
<?php $cnames = $this->_config->get_array( 'cdn.s3.cname' ); include W3TC_INC_DIR . '/options/cdn/common/cnames.php'; ?>
|
65 |
+
<p class="description"><?php _e( 'If you have already added a <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#VirtualHostingCustomURLs" target="_blank">CNAME</a> to your <acronym title="Domain Name System">DNS</acronym> Zone, enter it here.', 'w3-total-cache' ); ?></p>
|
66 |
</td>
|
67 |
</tr>
|
68 |
<tr>
|
inc/options/cdn/s3_compatible.php
CHANGED
@@ -49,7 +49,7 @@ Util_Ui::config_item( array(
|
|
49 |
<th><?php _e( 'Replace site\'s hostname with:', 'w3-total-cache' ); ?></th>
|
50 |
<td>
|
51 |
<?php $cnames = $this->_config->get_array( 'cdn.s3.cname' ); include W3TC_INC_DIR . '/options/cdn/common/cnames.php'; ?>
|
52 |
-
<p class="description"><?php _e( 'If you have already added a <a href="
|
53 |
</td>
|
54 |
</tr>
|
55 |
<tr>
|
49 |
<th><?php _e( 'Replace site\'s hostname with:', 'w3-total-cache' ); ?></th>
|
50 |
<td>
|
51 |
<?php $cnames = $this->_config->get_array( 'cdn.s3.cname' ); include W3TC_INC_DIR . '/options/cdn/common/cnames.php'; ?>
|
52 |
+
<p class="description"><?php _e( 'If you have already added a <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#VirtualHostingCustomURLs" target="_blank">CNAME</a> to your <acronym title="Domain Name System">DNS</acronym> Zone, enter it here.', 'w3-total-cache' ); ?></p>
|
53 |
</td>
|
54 |
</tr>
|
55 |
<tr>
|
lib/Aws/Aws/Api/ApiProvider.php
DELETED
@@ -1,244 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api;
|
3 |
-
|
4 |
-
use Aws\Exception\UnresolvedApiException;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* API providers.
|
8 |
-
*
|
9 |
-
* An API provider is a function that accepts a type, service, and version and
|
10 |
-
* returns an array of API data on success or NULL if no API data can be created
|
11 |
-
* for the provided arguments.
|
12 |
-
*
|
13 |
-
* You can wrap your calls to an API provider with the
|
14 |
-
* {@see ApiProvider::resolve} method to ensure that API data is created. If the
|
15 |
-
* API data is not created, then the resolve() method will throw a
|
16 |
-
* {@see Aws\Exception\UnresolvedApiException}.
|
17 |
-
*
|
18 |
-
* use Aws\Api\ApiProvider;
|
19 |
-
* $provider = ApiProvider::defaultProvider();
|
20 |
-
* // Returns an array or NULL.
|
21 |
-
* $data = $provider('api', 's3', '2006-03-01');
|
22 |
-
* // Returns an array or throws.
|
23 |
-
* $data = ApiProvider::resolve($provider, 'api', 'elasticfood', '2020-01-01');
|
24 |
-
*
|
25 |
-
* You can compose multiple providers into a single provider using
|
26 |
-
* {@see Aws\or_chain}. This method accepts providers as arguments and
|
27 |
-
* returns a new function that will invoke each provider until a non-null value
|
28 |
-
* is returned.
|
29 |
-
*
|
30 |
-
* $a = ApiProvider::filesystem(sys_get_temp_dir() . '/aws-beta-models');
|
31 |
-
* $b = ApiProvider::manifest();
|
32 |
-
*
|
33 |
-
* $c = \Aws\or_chain($a, $b);
|
34 |
-
* $data = $c('api', 'betaservice', '2015-08-08'); // $a handles this.
|
35 |
-
* $data = $c('api', 's3', '2006-03-01'); // $b handles this.
|
36 |
-
* $data = $c('api', 'invalid', '2014-12-15'); // Neither handles this.
|
37 |
-
*/
|
38 |
-
class ApiProvider
|
39 |
-
{
|
40 |
-
/** @var array A map of public API type names to their file suffix. */
|
41 |
-
private static $typeMap = [
|
42 |
-
'api' => 'api-2',
|
43 |
-
'paginator' => 'paginators-1',
|
44 |
-
'waiter' => 'waiters-2',
|
45 |
-
'docs' => 'docs-2',
|
46 |
-
];
|
47 |
-
|
48 |
-
/** @var array API manifest */
|
49 |
-
private $manifest;
|
50 |
-
|
51 |
-
/** @var string The directory containing service models. */
|
52 |
-
private $modelsDir;
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Resolves an API provider and ensures a non-null return value.
|
56 |
-
*
|
57 |
-
* @param callable $provider Provider function to invoke.
|
58 |
-
* @param string $type Type of data ('api', 'waiter', 'paginator').
|
59 |
-
* @param string $service Service name.
|
60 |
-
* @param string $version API version.
|
61 |
-
*
|
62 |
-
* @return array
|
63 |
-
* @throws UnresolvedApiException
|
64 |
-
*/
|
65 |
-
public static function resolve(callable $provider, $type, $service, $version)
|
66 |
-
{
|
67 |
-
// Execute the provider and return the result, if there is one.
|
68 |
-
$result = $provider($type, $service, $version);
|
69 |
-
if (is_array($result)) {
|
70 |
-
if (!isset($result['metadata']['serviceIdentifier'])) {
|
71 |
-
$result['metadata']['serviceIdentifier'] = $service;
|
72 |
-
}
|
73 |
-
return $result;
|
74 |
-
}
|
75 |
-
|
76 |
-
// Throw an exception with a message depending on the inputs.
|
77 |
-
if (!isset(self::$typeMap[$type])) {
|
78 |
-
$msg = "The type must be one of: " . implode(', ', self::$typeMap);
|
79 |
-
} elseif ($service) {
|
80 |
-
$msg = "The {$service} service does not have version: {$version}.";
|
81 |
-
} else {
|
82 |
-
$msg = "You must specify a service name to retrieve its API data.";
|
83 |
-
}
|
84 |
-
|
85 |
-
throw new UnresolvedApiException($msg);
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Default SDK API provider.
|
90 |
-
*
|
91 |
-
* This provider loads pre-built manifest data from the `data` directory.
|
92 |
-
*
|
93 |
-
* @return self
|
94 |
-
*/
|
95 |
-
public static function defaultProvider()
|
96 |
-
{
|
97 |
-
return new self(__DIR__ . '/../data', \Aws\manifest());
|
98 |
-
}
|
99 |
-
|
100 |
-
/**
|
101 |
-
* Loads API data after resolving the version to the latest, compatible,
|
102 |
-
* available version based on the provided manifest data.
|
103 |
-
*
|
104 |
-
* Manifest data is essentially an associative array of service names to
|
105 |
-
* associative arrays of API version aliases.
|
106 |
-
*
|
107 |
-
* [
|
108 |
-
* ...
|
109 |
-
* 'ec2' => [
|
110 |
-
* 'latest' => '2014-10-01',
|
111 |
-
* '2014-10-01' => '2014-10-01',
|
112 |
-
* '2014-09-01' => '2014-10-01',
|
113 |
-
* '2014-06-15' => '2014-10-01',
|
114 |
-
* ...
|
115 |
-
* ],
|
116 |
-
* 'ecs' => [...],
|
117 |
-
* 'elasticache' => [...],
|
118 |
-
* ...
|
119 |
-
* ]
|
120 |
-
*
|
121 |
-
* @param string $dir Directory containing service models.
|
122 |
-
* @param array $manifest The API version manifest data.
|
123 |
-
*
|
124 |
-
* @return self
|
125 |
-
*/
|
126 |
-
public static function manifest($dir, array $manifest)
|
127 |
-
{
|
128 |
-
return new self($dir, $manifest);
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Loads API data from the specified directory.
|
133 |
-
*
|
134 |
-
* If "latest" is specified as the version, this provider must glob the
|
135 |
-
* directory to find which is the latest available version.
|
136 |
-
*
|
137 |
-
* @param string $dir Directory containing service models.
|
138 |
-
*
|
139 |
-
* @return self
|
140 |
-
* @throws \InvalidArgumentException if the provided `$dir` is invalid.
|
141 |
-
*/
|
142 |
-
public static function filesystem($dir)
|
143 |
-
{
|
144 |
-
return new self($dir);
|
145 |
-
}
|
146 |
-
|
147 |
-
/**
|
148 |
-
* Retrieves a list of valid versions for the specified service.
|
149 |
-
*
|
150 |
-
* @param string $service Service name
|
151 |
-
*
|
152 |
-
* @return array
|
153 |
-
*/
|
154 |
-
public function getVersions($service)
|
155 |
-
{
|
156 |
-
if (!isset($this->manifest)) {
|
157 |
-
$this->buildVersionsList($service);
|
158 |
-
}
|
159 |
-
|
160 |
-
if (!isset($this->manifest[$service]['versions'])) {
|
161 |
-
return [];
|
162 |
-
}
|
163 |
-
|
164 |
-
return array_values(array_unique($this->manifest[$service]['versions']));
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Execute the the provider.
|
169 |
-
*
|
170 |
-
* @param string $type Type of data ('api', 'waiter', 'paginator').
|
171 |
-
* @param string $service Service name.
|
172 |
-
* @param string $version API version.
|
173 |
-
*
|
174 |
-
* @return array|null
|
175 |
-
*/
|
176 |
-
public function __invoke($type, $service, $version)
|
177 |
-
{
|
178 |
-
// Resolve the type or return null.
|
179 |
-
if (isset(self::$typeMap[$type])) {
|
180 |
-
$type = self::$typeMap[$type];
|
181 |
-
} else {
|
182 |
-
return null;
|
183 |
-
}
|
184 |
-
|
185 |
-
// Resolve the version or return null.
|
186 |
-
if (!isset($this->manifest)) {
|
187 |
-
$this->buildVersionsList($service);
|
188 |
-
}
|
189 |
-
|
190 |
-
if (!isset($this->manifest[$service]['versions'][$version])) {
|
191 |
-
return null;
|
192 |
-
}
|
193 |
-
|
194 |
-
$version = $this->manifest[$service]['versions'][$version];
|
195 |
-
$path = "{$this->modelsDir}/{$service}/{$version}/{$type}.json";
|
196 |
-
|
197 |
-
try {
|
198 |
-
return \Aws\load_compiled_json($path);
|
199 |
-
} catch (\InvalidArgumentException $e) {
|
200 |
-
return null;
|
201 |
-
}
|
202 |
-
}
|
203 |
-
|
204 |
-
/**
|
205 |
-
* @param string $modelsDir Directory containing service models.
|
206 |
-
* @param array $manifest The API version manifest data.
|
207 |
-
*/
|
208 |
-
private function __construct($modelsDir, array $manifest = null)
|
209 |
-
{
|
210 |
-
$this->manifest = $manifest;
|
211 |
-
$this->modelsDir = rtrim($modelsDir, '/');
|
212 |
-
if (!is_dir($this->modelsDir)) {
|
213 |
-
throw new \InvalidArgumentException(
|
214 |
-
"The specified models directory, {$modelsDir}, was not found."
|
215 |
-
);
|
216 |
-
}
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Build the versions list for the specified service by globbing the dir.
|
221 |
-
*/
|
222 |
-
private function buildVersionsList($service)
|
223 |
-
{
|
224 |
-
$dir = "{$this->modelsDir}/{$service}/";
|
225 |
-
|
226 |
-
if (!is_dir($dir)) {
|
227 |
-
return;
|
228 |
-
}
|
229 |
-
|
230 |
-
// Get versions, remove . and .., and sort in descending order.
|
231 |
-
$results = array_diff(scandir($dir, SCANDIR_SORT_DESCENDING), ['..', '.']);
|
232 |
-
|
233 |
-
if (!$results) {
|
234 |
-
$this->manifest[$service] = ['versions' => []];
|
235 |
-
} else {
|
236 |
-
$this->manifest[$service] = [
|
237 |
-
'versions' => [
|
238 |
-
'latest' => $results[0]
|
239 |
-
]
|
240 |
-
];
|
241 |
-
$this->manifest[$service]['versions'] += array_combine($results, $results);
|
242 |
-
}
|
243 |
-
}
|
244 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/DateTimeResult.php
DELETED
@@ -1,41 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* DateTime overrides that make DateTime work more seamlessly as a string,
|
6 |
-
* with JSON documents, and with JMESPath.
|
7 |
-
*/
|
8 |
-
class DateTimeResult extends \DateTime implements \JsonSerializable
|
9 |
-
{
|
10 |
-
/**
|
11 |
-
* Create a new DateTimeResult from a unix timestamp.
|
12 |
-
*
|
13 |
-
* @param $unixTimestamp
|
14 |
-
*
|
15 |
-
* @return DateTimeResult
|
16 |
-
*/
|
17 |
-
public static function fromEpoch($unixTimestamp)
|
18 |
-
{
|
19 |
-
return new self(gmdate('c', $unixTimestamp));
|
20 |
-
}
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Serialize the DateTimeResult as an ISO 8601 date string.
|
24 |
-
*
|
25 |
-
* @return string
|
26 |
-
*/
|
27 |
-
public function __toString()
|
28 |
-
{
|
29 |
-
return $this->format('c');
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Serialize the date as an ISO 8601 date when serializing as JSON.
|
34 |
-
*
|
35 |
-
* @return mixed|string
|
36 |
-
*/
|
37 |
-
public function jsonSerialize()
|
38 |
-
{
|
39 |
-
return (string) $this;
|
40 |
-
}
|
41 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/DocModel.php
DELETED
@@ -1,128 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Encapsulates the documentation strings for a given service-version and
|
6 |
-
* provides methods for extracting the desired parts related to a service,
|
7 |
-
* operation, error, or shape (i.e., parameter).
|
8 |
-
*/
|
9 |
-
class DocModel
|
10 |
-
{
|
11 |
-
/** @var array */
|
12 |
-
private $docs;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @param array $docs
|
16 |
-
*
|
17 |
-
* @throws \RuntimeException
|
18 |
-
*/
|
19 |
-
public function __construct(array $docs)
|
20 |
-
{
|
21 |
-
if (!extension_loaded('tidy')) {
|
22 |
-
throw new \RuntimeException('The "tidy" PHP extension is required.');
|
23 |
-
}
|
24 |
-
|
25 |
-
$this->docs = $docs;
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Convert the doc model to an array.
|
30 |
-
*
|
31 |
-
* @return array
|
32 |
-
*/
|
33 |
-
public function toArray()
|
34 |
-
{
|
35 |
-
return $this->docs;
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Retrieves documentation about the service.
|
40 |
-
*
|
41 |
-
* @return null|string
|
42 |
-
*/
|
43 |
-
public function getServiceDocs()
|
44 |
-
{
|
45 |
-
return isset($this->docs['service']) ? $this->docs['service'] : null;
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Retrieves documentation about an operation.
|
50 |
-
*
|
51 |
-
* @param string $operation Name of the operation
|
52 |
-
*
|
53 |
-
* @return null|string
|
54 |
-
*/
|
55 |
-
public function getOperationDocs($operation)
|
56 |
-
{
|
57 |
-
return isset($this->docs['operations'][$operation])
|
58 |
-
? $this->docs['operations'][$operation]
|
59 |
-
: null;
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Retrieves documentation about an error.
|
64 |
-
*
|
65 |
-
* @param string $error Name of the error
|
66 |
-
*
|
67 |
-
* @return null|string
|
68 |
-
*/
|
69 |
-
public function getErrorDocs($error)
|
70 |
-
{
|
71 |
-
return isset($this->docs['shapes'][$error]['base'])
|
72 |
-
? $this->docs['shapes'][$error]['base']
|
73 |
-
: null;
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Retrieves documentation about a shape, specific to the context.
|
78 |
-
*
|
79 |
-
* @param string $shapeName Name of the shape.
|
80 |
-
* @param string $parentName Name of the parent/context shape.
|
81 |
-
* @param string $ref Name used by the context to reference the shape.
|
82 |
-
*
|
83 |
-
* @return null|string
|
84 |
-
*/
|
85 |
-
public function getShapeDocs($shapeName, $parentName, $ref)
|
86 |
-
{
|
87 |
-
if (!isset($this->docs['shapes'][$shapeName])) {
|
88 |
-
return '';
|
89 |
-
}
|
90 |
-
|
91 |
-
$result = '';
|
92 |
-
$d = $this->docs['shapes'][$shapeName];
|
93 |
-
if (isset($d['refs']["{$parentName}\$${ref}"])) {
|
94 |
-
$result = $d['refs']["{$parentName}\$${ref}"];
|
95 |
-
} elseif (isset($d['base'])) {
|
96 |
-
$result = $d['base'];
|
97 |
-
}
|
98 |
-
|
99 |
-
if (isset($d['append'])) {
|
100 |
-
$result .= $d['append'];
|
101 |
-
}
|
102 |
-
|
103 |
-
return $this->clean($result);
|
104 |
-
}
|
105 |
-
|
106 |
-
private function clean($content)
|
107 |
-
{
|
108 |
-
if (!$content) {
|
109 |
-
return '';
|
110 |
-
}
|
111 |
-
|
112 |
-
$tidy = new \Tidy();
|
113 |
-
$tidy->parseString($content, [
|
114 |
-
'indent' => true,
|
115 |
-
'doctype' => 'omit',
|
116 |
-
'output-html' => true,
|
117 |
-
'show-body-only' => true,
|
118 |
-
'drop-empty-paras' => true,
|
119 |
-
'drop-font-tags' => true,
|
120 |
-
'drop-proprietary-attributes' => true,
|
121 |
-
'hide-comments' => true,
|
122 |
-
'logical-emphasis' => true
|
123 |
-
]);
|
124 |
-
$tidy->cleanRepair();
|
125 |
-
|
126 |
-
return (string) $content;
|
127 |
-
}
|
128 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/ErrorParser/JsonParserTrait.php
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\ErrorParser;
|
3 |
-
|
4 |
-
use Aws\Api\Parser\PayloadParserTrait;
|
5 |
-
use Psr\Http\Message\ResponseInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Provides basic JSON error parsing functionality.
|
9 |
-
*/
|
10 |
-
trait JsonParserTrait
|
11 |
-
{
|
12 |
-
use PayloadParserTrait;
|
13 |
-
|
14 |
-
private function genericHandler(ResponseInterface $response)
|
15 |
-
{
|
16 |
-
$code = (string) $response->getStatusCode();
|
17 |
-
|
18 |
-
return [
|
19 |
-
'request_id' => (string) $response->getHeaderLine('x-amzn-requestid'),
|
20 |
-
'code' => null,
|
21 |
-
'message' => null,
|
22 |
-
'type' => $code[0] == '4' ? 'client' : 'server',
|
23 |
-
'parsed' => $this->parseJson($response->getBody(), $response)
|
24 |
-
];
|
25 |
-
}
|
26 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/ErrorParser/JsonRpcErrorParser.php
DELETED
@@ -1,31 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\ErrorParser;
|
3 |
-
|
4 |
-
use Psr\Http\Message\ResponseInterface;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Parsers JSON-RPC errors.
|
8 |
-
*/
|
9 |
-
class JsonRpcErrorParser
|
10 |
-
{
|
11 |
-
use JsonParserTrait;
|
12 |
-
|
13 |
-
public function __invoke(ResponseInterface $response)
|
14 |
-
{
|
15 |
-
$data = $this->genericHandler($response);
|
16 |
-
// Make the casing consistent across services.
|
17 |
-
if ($data['parsed']) {
|
18 |
-
$data['parsed'] = array_change_key_case($data['parsed']);
|
19 |
-
}
|
20 |
-
|
21 |
-
if (isset($data['parsed']['__type'])) {
|
22 |
-
$parts = explode('#', $data['parsed']['__type']);
|
23 |
-
$data['code'] = isset($parts[1]) ? $parts[1] : $parts[0];
|
24 |
-
$data['message'] = isset($data['parsed']['message'])
|
25 |
-
? $data['parsed']['message']
|
26 |
-
: null;
|
27 |
-
}
|
28 |
-
|
29 |
-
return $data;
|
30 |
-
}
|
31 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/ErrorParser/RestJsonErrorParser.php
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\ErrorParser;
|
3 |
-
|
4 |
-
use Psr\Http\Message\ResponseInterface;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Parses JSON-REST errors.
|
8 |
-
*/
|
9 |
-
class RestJsonErrorParser
|
10 |
-
{
|
11 |
-
use JsonParserTrait;
|
12 |
-
|
13 |
-
public function __invoke(ResponseInterface $response)
|
14 |
-
{
|
15 |
-
$data = $this->genericHandler($response);
|
16 |
-
|
17 |
-
// Merge in error data from the JSON body
|
18 |
-
if ($json = $data['parsed']) {
|
19 |
-
$data = array_replace($data, $json);
|
20 |
-
}
|
21 |
-
|
22 |
-
// Correct error type from services like Amazon Glacier
|
23 |
-
if (!empty($data['type'])) {
|
24 |
-
$data['type'] = strtolower($data['type']);
|
25 |
-
}
|
26 |
-
|
27 |
-
// Retrieve the error code from services like Amazon Elastic Transcoder
|
28 |
-
if ($code = $response->getHeaderLine('x-amzn-errortype')) {
|
29 |
-
$colon = strpos($code, ':');
|
30 |
-
$data['code'] = $colon ? substr($code, 0, $colon) : $code;
|
31 |
-
}
|
32 |
-
|
33 |
-
return $data;
|
34 |
-
}
|
35 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/ErrorParser/XmlErrorParser.php
DELETED
@@ -1,82 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\ErrorParser;
|
3 |
-
|
4 |
-
use Aws\Api\Parser\PayloadParserTrait;
|
5 |
-
use Psr\Http\Message\ResponseInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Parses XML errors.
|
9 |
-
*/
|
10 |
-
class XmlErrorParser
|
11 |
-
{
|
12 |
-
use PayloadParserTrait;
|
13 |
-
|
14 |
-
public function __invoke(ResponseInterface $response)
|
15 |
-
{
|
16 |
-
$code = (string) $response->getStatusCode();
|
17 |
-
|
18 |
-
$data = [
|
19 |
-
'type' => $code[0] == '4' ? 'client' : 'server',
|
20 |
-
'request_id' => null,
|
21 |
-
'code' => null,
|
22 |
-
'message' => null,
|
23 |
-
'parsed' => null
|
24 |
-
];
|
25 |
-
|
26 |
-
$body = $response->getBody();
|
27 |
-
if ($body->getSize() > 0) {
|
28 |
-
$this->parseBody($this->parseXml($body, $response), $data);
|
29 |
-
} else {
|
30 |
-
$this->parseHeaders($response, $data);
|
31 |
-
}
|
32 |
-
|
33 |
-
return $data;
|
34 |
-
}
|
35 |
-
|
36 |
-
private function parseHeaders(ResponseInterface $response, array &$data)
|
37 |
-
{
|
38 |
-
if ($response->getStatusCode() == '404') {
|
39 |
-
$data['code'] = 'NotFound';
|
40 |
-
}
|
41 |
-
|
42 |
-
$data['message'] = $response->getStatusCode() . ' '
|
43 |
-
. $response->getReasonPhrase();
|
44 |
-
|
45 |
-
if ($requestId = $response->getHeaderLine('x-amz-request-id')) {
|
46 |
-
$data['request_id'] = $requestId;
|
47 |
-
$data['message'] .= " (Request-ID: $requestId)";
|
48 |
-
}
|
49 |
-
}
|
50 |
-
|
51 |
-
private function parseBody(\SimpleXMLElement $body, array &$data)
|
52 |
-
{
|
53 |
-
$data['parsed'] = $body;
|
54 |
-
|
55 |
-
$namespaces = $body->getDocNamespaces();
|
56 |
-
if (!isset($namespaces[''])) {
|
57 |
-
$prefix = '';
|
58 |
-
} else {
|
59 |
-
// Account for the default namespace being defined and PHP not
|
60 |
-
// being able to handle it :(.
|
61 |
-
$body->registerXPathNamespace('ns', $namespaces['']);
|
62 |
-
$prefix = 'ns:';
|
63 |
-
}
|
64 |
-
|
65 |
-
if ($tempXml = $body->xpath("//{$prefix}Code[1]")) {
|
66 |
-
$data['code'] = (string) $tempXml[0];
|
67 |
-
}
|
68 |
-
|
69 |
-
if ($tempXml = $body->xpath("//{$prefix}Message[1]")) {
|
70 |
-
$data['message'] = (string) $tempXml[0];
|
71 |
-
}
|
72 |
-
|
73 |
-
$tempXml = $body->xpath("//{$prefix}RequestId[1]");
|
74 |
-
if (empty($tempXml)) {
|
75 |
-
$tempXml = $body->xpath("//{$prefix}RequestID[1]");
|
76 |
-
}
|
77 |
-
|
78 |
-
if (isset($tempXml[0])) {
|
79 |
-
$data['request_id'] = (string) $tempXml[0];
|
80 |
-
}
|
81 |
-
}
|
82 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Parser/AbstractRestParser.php
DELETED
@@ -1,173 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Parser;
|
3 |
-
|
4 |
-
use Aws\Api\DateTimeResult;
|
5 |
-
use Aws\Api\Shape;
|
6 |
-
use Aws\Api\StructureShape;
|
7 |
-
use Aws\Result;
|
8 |
-
use Aws\CommandInterface;
|
9 |
-
use Psr\Http\Message\ResponseInterface;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @internal
|
13 |
-
*/
|
14 |
-
abstract class AbstractRestParser extends AbstractParser
|
15 |
-
{
|
16 |
-
use PayloadParserTrait;
|
17 |
-
/**
|
18 |
-
* Parses a payload from a response.
|
19 |
-
*
|
20 |
-
* @param ResponseInterface $response Response to parse.
|
21 |
-
* @param StructureShape $member Member to parse
|
22 |
-
* @param array $result Result value
|
23 |
-
*
|
24 |
-
* @return mixed
|
25 |
-
*/
|
26 |
-
abstract protected function payload(
|
27 |
-
ResponseInterface $response,
|
28 |
-
StructureShape $member,
|
29 |
-
array &$result
|
30 |
-
);
|
31 |
-
|
32 |
-
public function __invoke(
|
33 |
-
CommandInterface $command,
|
34 |
-
ResponseInterface $response
|
35 |
-
) {
|
36 |
-
$output = $this->api->getOperation($command->getName())->getOutput();
|
37 |
-
$result = [];
|
38 |
-
|
39 |
-
if ($payload = $output['payload']) {
|
40 |
-
$this->extractPayload($payload, $output, $response, $result);
|
41 |
-
}
|
42 |
-
|
43 |
-
foreach ($output->getMembers() as $name => $member) {
|
44 |
-
switch ($member['location']) {
|
45 |
-
case 'header':
|
46 |
-
$this->extractHeader($name, $member, $response, $result);
|
47 |
-
break;
|
48 |
-
case 'headers':
|
49 |
-
$this->extractHeaders($name, $member, $response, $result);
|
50 |
-
break;
|
51 |
-
case 'statusCode':
|
52 |
-
$this->extractStatus($name, $response, $result);
|
53 |
-
break;
|
54 |
-
}
|
55 |
-
}
|
56 |
-
|
57 |
-
if (!$payload
|
58 |
-
&& $response->getBody()->getSize() > 0
|
59 |
-
&& count($output->getMembers()) > 0
|
60 |
-
) {
|
61 |
-
// if no payload was found, then parse the contents of the body
|
62 |
-
$this->payload($response, $output, $result);
|
63 |
-
}
|
64 |
-
|
65 |
-
return new Result($result);
|
66 |
-
}
|
67 |
-
|
68 |
-
private function extractPayload(
|
69 |
-
$payload,
|
70 |
-
StructureShape $output,
|
71 |
-
ResponseInterface $response,
|
72 |
-
array &$result
|
73 |
-
) {
|
74 |
-
$member = $output->getMember($payload);
|
75 |
-
|
76 |
-
if (!empty($member['eventstream'])) {
|
77 |
-
$result[$payload] = new EventParsingIterator(
|
78 |
-
$response->getBody(),
|
79 |
-
$member,
|
80 |
-
$this
|
81 |
-
);
|
82 |
-
} else if ($member instanceof StructureShape) {
|
83 |
-
// Structure members parse top-level data into a specific key.
|
84 |
-
$result[$payload] = [];
|
85 |
-
$this->payload($response, $member, $result[$payload]);
|
86 |
-
} else {
|
87 |
-
// Streaming data is just the stream from the response body.
|
88 |
-
$result[$payload] = $response->getBody();
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Extract a single header from the response into the result.
|
94 |
-
*/
|
95 |
-
private function extractHeader(
|
96 |
-
$name,
|
97 |
-
Shape $shape,
|
98 |
-
ResponseInterface $response,
|
99 |
-
&$result
|
100 |
-
) {
|
101 |
-
$value = $response->getHeaderLine($shape['locationName'] ?: $name);
|
102 |
-
|
103 |
-
switch ($shape->getType()) {
|
104 |
-
case 'float':
|
105 |
-
case 'double':
|
106 |
-
$value = (float) $value;
|
107 |
-
break;
|
108 |
-
case 'long':
|
109 |
-
$value = (int) $value;
|
110 |
-
break;
|
111 |
-
case 'boolean':
|
112 |
-
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
|
113 |
-
break;
|
114 |
-
case 'blob':
|
115 |
-
$value = base64_decode($value);
|
116 |
-
break;
|
117 |
-
case 'timestamp':
|
118 |
-
try {
|
119 |
-
if (!empty($shape['timestampFormat'])
|
120 |
-
&& $shape['timestampFormat'] === 'unixTimestamp') {
|
121 |
-
$value = DateTimeResult::fromEpoch($value);
|
122 |
-
}
|
123 |
-
$value = new DateTimeResult($value);
|
124 |
-
break;
|
125 |
-
} catch (\Exception $e) {
|
126 |
-
// If the value cannot be parsed, then do not add it to the
|
127 |
-
// output structure.
|
128 |
-
return;
|
129 |
-
}
|
130 |
-
case 'string':
|
131 |
-
if ($shape['jsonvalue']) {
|
132 |
-
$value = $this->parseJson(base64_decode($value), $response);
|
133 |
-
}
|
134 |
-
break;
|
135 |
-
}
|
136 |
-
|
137 |
-
$result[$name] = $value;
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Extract a map of headers with an optional prefix from the response.
|
142 |
-
*/
|
143 |
-
private function extractHeaders(
|
144 |
-
$name,
|
145 |
-
Shape $shape,
|
146 |
-
ResponseInterface $response,
|
147 |
-
&$result
|
148 |
-
) {
|
149 |
-
// Check if the headers are prefixed by a location name
|
150 |
-
$result[$name] = [];
|
151 |
-
$prefix = $shape['locationName'];
|
152 |
-
$prefixLen = strlen($prefix);
|
153 |
-
|
154 |
-
foreach ($response->getHeaders() as $k => $values) {
|
155 |
-
if (!$prefixLen) {
|
156 |
-
$result[$name][$k] = implode(', ', $values);
|
157 |
-
} elseif (stripos($k, $prefix) === 0) {
|
158 |
-
$result[$name][substr($k, $prefixLen)] = implode(', ', $values);
|
159 |
-
}
|
160 |
-
}
|
161 |
-
}
|
162 |
-
|
163 |
-
/**
|
164 |
-
* Places the status code of the response into the result array.
|
165 |
-
*/
|
166 |
-
private function extractStatus(
|
167 |
-
$name,
|
168 |
-
ResponseInterface $response,
|
169 |
-
array &$result
|
170 |
-
) {
|
171 |
-
$result[$name] = (int) $response->getStatusCode();
|
172 |
-
}
|
173 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Parser/Crc32ValidatingParser.php
DELETED
@@ -1,54 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Parser;
|
3 |
-
|
4 |
-
use Aws\Api\StructureShape;
|
5 |
-
use Aws\CommandInterface;
|
6 |
-
use Aws\Exception\AwsException;
|
7 |
-
use Psr\Http\Message\ResponseInterface;
|
8 |
-
use Psr\Http\Message\StreamInterface;
|
9 |
-
use GuzzleHttp\Psr7;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @internal Decorates a parser and validates the x-amz-crc32 header.
|
13 |
-
*/
|
14 |
-
class Crc32ValidatingParser extends AbstractParser
|
15 |
-
{
|
16 |
-
/**
|
17 |
-
* @param callable $parser Parser to wrap.
|
18 |
-
*/
|
19 |
-
public function __construct(callable $parser)
|
20 |
-
{
|
21 |
-
$this->parser = $parser;
|
22 |
-
}
|
23 |
-
|
24 |
-
public function __invoke(
|
25 |
-
CommandInterface $command,
|
26 |
-
ResponseInterface $response
|
27 |
-
) {
|
28 |
-
if ($expected = $response->getHeaderLine('x-amz-crc32')) {
|
29 |
-
$hash = hexdec(Psr7\hash($response->getBody(), 'crc32b'));
|
30 |
-
if ($expected != $hash) {
|
31 |
-
throw new AwsException(
|
32 |
-
"crc32 mismatch. Expected {$expected}, found {$hash}.",
|
33 |
-
$command,
|
34 |
-
[
|
35 |
-
'code' => 'ClientChecksumMismatch',
|
36 |
-
'connection_error' => true,
|
37 |
-
'response' => $response
|
38 |
-
]
|
39 |
-
);
|
40 |
-
}
|
41 |
-
}
|
42 |
-
|
43 |
-
$fn = $this->parser;
|
44 |
-
return $fn($command, $response);
|
45 |
-
}
|
46 |
-
|
47 |
-
public function parseMemberFromStream(
|
48 |
-
StreamInterface $stream,
|
49 |
-
StructureShape $member,
|
50 |
-
$response
|
51 |
-
) {
|
52 |
-
return $this->parser->parseMemberFromStream($stream, $member, $response);
|
53 |
-
}
|
54 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Parser/DecodingEventStreamIterator.php
DELETED
@@ -1,335 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Aws\Api\Parser;
|
4 |
-
|
5 |
-
use \Iterator;
|
6 |
-
use Aws\Api\DateTimeResult;
|
7 |
-
use GuzzleHttp\Psr7;
|
8 |
-
use Psr\Http\Message\StreamInterface;
|
9 |
-
use Aws\Api\Parser\Exception\ParserException;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @internal Implements a decoder for a binary encoded event stream that will
|
13 |
-
* decode, validate, and provide individual events from the stream.
|
14 |
-
*/
|
15 |
-
class DecodingEventStreamIterator implements Iterator
|
16 |
-
{
|
17 |
-
const HEADERS = 'headers';
|
18 |
-
const PAYLOAD = 'payload';
|
19 |
-
|
20 |
-
const LENGTH_TOTAL = 'total_length';
|
21 |
-
const LENGTH_HEADERS = 'headers_length';
|
22 |
-
|
23 |
-
const CRC_PRELUDE = 'prelude_crc';
|
24 |
-
|
25 |
-
const BYTES_PRELUDE = 12;
|
26 |
-
const BYTES_TRAILING = 4;
|
27 |
-
|
28 |
-
private static $preludeFormat = [
|
29 |
-
self::LENGTH_TOTAL => 'decodeUint32',
|
30 |
-
self::LENGTH_HEADERS => 'decodeUint32',
|
31 |
-
self::CRC_PRELUDE => 'decodeUint32',
|
32 |
-
];
|
33 |
-
|
34 |
-
private static $lengthFormatMap = [
|
35 |
-
1 => 'decodeUint8',
|
36 |
-
2 => 'decodeUint16',
|
37 |
-
4 => 'decodeUint32',
|
38 |
-
8 => 'decodeUint64',
|
39 |
-
];
|
40 |
-
|
41 |
-
private static $headerTypeMap = [
|
42 |
-
0 => 'decodeBooleanTrue',
|
43 |
-
1 => 'decodeBooleanFalse',
|
44 |
-
2 => 'decodeInt8',
|
45 |
-
3 => 'decodeInt16',
|
46 |
-
4 => 'decodeInt32',
|
47 |
-
5 => 'decodeInt64',
|
48 |
-
6 => 'decodeBytes',
|
49 |
-
7 => 'decodeString',
|
50 |
-
8 => 'decodeTimestamp',
|
51 |
-
9 => 'decodeUuid',
|
52 |
-
];
|
53 |
-
|
54 |
-
/** @var StreamInterface Stream of eventstream shape to parse. */
|
55 |
-
private $stream;
|
56 |
-
|
57 |
-
/** @var array Currently parsed event. */
|
58 |
-
private $currentEvent;
|
59 |
-
|
60 |
-
/** @var int Current in-order event key. */
|
61 |
-
private $key;
|
62 |
-
|
63 |
-
/** @var resource|HashContext CRC32 hash context for event validation */
|
64 |
-
private $hashContext;
|
65 |
-
|
66 |
-
/** @var int $currentPosition */
|
67 |
-
private $currentPosition;
|
68 |
-
|
69 |
-
/**
|
70 |
-
* DecodingEventStreamIterator constructor.
|
71 |
-
*
|
72 |
-
* @param StreamInterface $stream
|
73 |
-
*/
|
74 |
-
public function __construct(StreamInterface $stream)
|
75 |
-
{
|
76 |
-
$this->stream = $stream;
|
77 |
-
$this->rewind();
|
78 |
-
}
|
79 |
-
|
80 |
-
private function parseHeaders($headerBytes)
|
81 |
-
{
|
82 |
-
$headers = [];
|
83 |
-
$bytesRead = 0;
|
84 |
-
|
85 |
-
while ($bytesRead < $headerBytes) {
|
86 |
-
list($key, $numBytes) = $this->decodeString(1);
|
87 |
-
$bytesRead += $numBytes;
|
88 |
-
|
89 |
-
list($type, $numBytes) = $this->decodeUint8();
|
90 |
-
$bytesRead += $numBytes;
|
91 |
-
|
92 |
-
$f = self::$headerTypeMap[$type];
|
93 |
-
list($value, $numBytes) = $this->{$f}();
|
94 |
-
$bytesRead += $numBytes;
|
95 |
-
|
96 |
-
if (isset($headers[$key])) {
|
97 |
-
throw new ParserException('Duplicate key in event headers.');
|
98 |
-
}
|
99 |
-
$headers[$key] = $value;
|
100 |
-
}
|
101 |
-
|
102 |
-
return [$headers, $bytesRead];
|
103 |
-
}
|
104 |
-
|
105 |
-
private function parsePrelude()
|
106 |
-
{
|
107 |
-
$prelude = [];
|
108 |
-
$bytesRead = 0;
|
109 |
-
|
110 |
-
$calculatedCrc = null;
|
111 |
-
foreach (self::$preludeFormat as $key => $decodeFunction) {
|
112 |
-
if ($key === self::CRC_PRELUDE) {
|
113 |
-
$hashCopy = hash_copy($this->hashContext);
|
114 |
-
$calculatedCrc = hash_final($this->hashContext, true);
|
115 |
-
$this->hashContext = $hashCopy;
|
116 |
-
}
|
117 |
-
list($value, $numBytes) = $this->{$decodeFunction}();
|
118 |
-
$bytesRead += $numBytes;
|
119 |
-
|
120 |
-
$prelude[$key] = $value;
|
121 |
-
}
|
122 |
-
|
123 |
-
if (unpack('N', $calculatedCrc)[1] !== $prelude[self::CRC_PRELUDE]) {
|
124 |
-
throw new ParserException('Prelude checksum mismatch.');
|
125 |
-
}
|
126 |
-
|
127 |
-
return [$prelude, $bytesRead];
|
128 |
-
}
|
129 |
-
|
130 |
-
private function parseEvent()
|
131 |
-
{
|
132 |
-
$event = [];
|
133 |
-
|
134 |
-
if ($this->stream->tell() < $this->stream->getSize()) {
|
135 |
-
$this->hashContext = hash_init('crc32b');
|
136 |
-
|
137 |
-
$bytesLeft = $this->stream->getSize() - $this->stream->tell();
|
138 |
-
list($prelude, $numBytes) = $this->parsePrelude();
|
139 |
-
if ($prelude[self::LENGTH_TOTAL] > $bytesLeft) {
|
140 |
-
throw new ParserException('Message length too long.');
|
141 |
-
}
|
142 |
-
$bytesLeft -= $numBytes;
|
143 |
-
|
144 |
-
if ($prelude[self::LENGTH_HEADERS] > $bytesLeft) {
|
145 |
-
throw new ParserException('Headers length too long.');
|
146 |
-
}
|
147 |
-
|
148 |
-
list(
|
149 |
-
$event[self::HEADERS],
|
150 |
-
$numBytes
|
151 |
-
) = $this->parseHeaders($prelude[self::LENGTH_HEADERS]);
|
152 |
-
|
153 |
-
$event[self::PAYLOAD] = Psr7\stream_for(
|
154 |
-
$this->readAndHashBytes(
|
155 |
-
$prelude[self::LENGTH_TOTAL] - self::BYTES_PRELUDE
|
156 |
-
- $numBytes - self::BYTES_TRAILING
|
157 |
-
)
|
158 |
-
);
|
159 |
-
|
160 |
-
$calculatedCrc = hash_final($this->hashContext, true);
|
161 |
-
$messageCrc = $this->stream->read(4);
|
162 |
-
if ($calculatedCrc !== $messageCrc) {
|
163 |
-
throw new ParserException('Message checksum mismatch.');
|
164 |
-
}
|
165 |
-
}
|
166 |
-
|
167 |
-
return $event;
|
168 |
-
}
|
169 |
-
|
170 |
-
// Iterator Functionality
|
171 |
-
|
172 |
-
/**
|
173 |
-
* @return array
|
174 |
-
*/
|
175 |
-
public function current()
|
176 |
-
{
|
177 |
-
return $this->currentEvent;
|
178 |
-
}
|
179 |
-
|
180 |
-
/**
|
181 |
-
* @return int
|
182 |
-
*/
|
183 |
-
public function key()
|
184 |
-
{
|
185 |
-
return $this->key;
|
186 |
-
}
|
187 |
-
|
188 |
-
public function next()
|
189 |
-
{
|
190 |
-
$this->currentPosition = $this->stream->tell();
|
191 |
-
if ($this->valid()) {
|
192 |
-
$this->key++;
|
193 |
-
$this->currentEvent = $this->parseEvent();
|
194 |
-
}
|
195 |
-
}
|
196 |
-
|
197 |
-
public function rewind()
|
198 |
-
{
|
199 |
-
$this->stream->rewind();
|
200 |
-
$this->key = 0;
|
201 |
-
$this->currentPosition = 0;
|
202 |
-
$this->currentEvent = $this->parseEvent();
|
203 |
-
}
|
204 |
-
|
205 |
-
/**
|
206 |
-
* @return bool
|
207 |
-
*/
|
208 |
-
public function valid()
|
209 |
-
{
|
210 |
-
return $this->currentPosition < $this->stream->getSize();
|
211 |
-
}
|
212 |
-
|
213 |
-
// Decoding Utilities
|
214 |
-
|
215 |
-
private function readAndHashBytes($num)
|
216 |
-
{
|
217 |
-
$bytes = $this->stream->read($num);
|
218 |
-
hash_update($this->hashContext, $bytes);
|
219 |
-
return $bytes;
|
220 |
-
}
|
221 |
-
|
222 |
-
private function decodeBooleanTrue()
|
223 |
-
{
|
224 |
-
return [true, 0];
|
225 |
-
}
|
226 |
-
|
227 |
-
private function decodeBooleanFalse()
|
228 |
-
{
|
229 |
-
return [false, 0];
|
230 |
-
}
|
231 |
-
|
232 |
-
private function uintToInt($val, $size)
|
233 |
-
{
|
234 |
-
$signedCap = pow(2, $size - 1);
|
235 |
-
if ($val > $signedCap) {
|
236 |
-
$val -= (2 * $signedCap);
|
237 |
-
}
|
238 |
-
return $val;
|
239 |
-
}
|
240 |
-
|
241 |
-
private function decodeInt8()
|
242 |
-
{
|
243 |
-
$val = (int)unpack('C', $this->readAndHashBytes(1))[1];
|
244 |
-
return [$this->uintToInt($val, 8), 1];
|
245 |
-
}
|
246 |
-
|
247 |
-
private function decodeUint8()
|
248 |
-
{
|
249 |
-
return [unpack('C', $this->readAndHashBytes(1))[1], 1];
|
250 |
-
}
|
251 |
-
|
252 |
-
private function decodeInt16()
|
253 |
-
{
|
254 |
-
$val = (int)unpack('n', $this->readAndHashBytes(2))[1];
|
255 |
-
return [$this->uintToInt($val, 16), 2];
|
256 |
-
}
|
257 |
-
|
258 |
-
private function decodeUint16()
|
259 |
-
{
|
260 |
-
return [unpack('n', $this->readAndHashBytes(2))[1], 2];
|
261 |
-
}
|
262 |
-
|
263 |
-
private function decodeInt32()
|
264 |
-
{
|
265 |
-
$val = (int)unpack('N', $this->readAndHashBytes(4))[1];
|
266 |
-
return [$this->uintToInt($val, 32), 4];
|
267 |
-
}
|
268 |
-
|
269 |
-
private function decodeUint32()
|
270 |
-
{
|
271 |
-
return [unpack('N', $this->readAndHashBytes(4))[1], 4];
|
272 |
-
}
|
273 |
-
|
274 |
-
private function decodeInt64()
|
275 |
-
{
|
276 |
-
$val = $this->unpackInt64($this->readAndHashBytes(8))[1];
|
277 |
-
return [$this->uintToInt($val, 64), 8];
|
278 |
-
}
|
279 |
-
|
280 |
-
private function decodeUint64()
|
281 |
-
{
|
282 |
-
return [$this->unpackInt64($this->readAndHashBytes(8))[1], 8];
|
283 |
-
}
|
284 |
-
|
285 |
-
private function unpackInt64($bytes)
|
286 |
-
{
|
287 |
-
if (version_compare(PHP_VERSION, '5.6.3', '<')) {
|
288 |
-
$d = unpack('N2', $bytes);
|
289 |
-
return [1 => $d[1] << 32 | $d[2]];
|
290 |
-
}
|
291 |
-
return unpack('J', $bytes);
|
292 |
-
}
|
293 |
-
|
294 |
-
private function decodeBytes($lengthBytes=2)
|
295 |
-
{
|
296 |
-
if (!isset(self::$lengthFormatMap[$lengthBytes])) {
|
297 |
-
throw new ParserException('Undefined variable length format.');
|
298 |
-
}
|
299 |
-
$f = self::$lengthFormatMap[$lengthBytes];
|
300 |
-
list($len, $bytes) = $this->{$f}();
|
301 |
-
return [$this->readAndHashBytes($len), $len + $bytes];
|
302 |
-
}
|
303 |
-
|
304 |
-
private function decodeString($lengthBytes=2)
|
305 |
-
{
|
306 |
-
if (!isset(self::$lengthFormatMap[$lengthBytes])) {
|
307 |
-
throw new ParserException('Undefined variable length format.');
|
308 |
-
}
|
309 |
-
$f = self::$lengthFormatMap[$lengthBytes];
|
310 |
-
list($len, $bytes) = $this->{$f}();
|
311 |
-
return [$this->readAndHashBytes($len), $len + $bytes];
|
312 |
-
}
|
313 |
-
|
314 |
-
private function decodeTimestamp()
|
315 |
-
{
|
316 |
-
list($val, $bytes) = $this->decodeInt64();
|
317 |
-
return [
|
318 |
-
DateTimeResult::createFromFormat('U.u', $val / 1000),
|
319 |
-
$bytes
|
320 |
-
];
|
321 |
-
}
|
322 |
-
|
323 |
-
private function decodeUuid()
|
324 |
-
{
|
325 |
-
$val = unpack('H32', $this->readAndHashBytes(16))[1];
|
326 |
-
return [
|
327 |
-
substr($val, 0, 8) . '-'
|
328 |
-
. substr($val, 8, 4) . '-'
|
329 |
-
. substr($val, 12, 4) . '-'
|
330 |
-
. substr($val, 16, 4) . '-'
|
331 |
-
. substr($val, 20, 12),
|
332 |
-
16
|
333 |
-
];
|
334 |
-
}
|
335 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Parser/Exception/ParserException.php
DELETED
@@ -1,31 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Parser\Exception;
|
3 |
-
|
4 |
-
use Aws\HasMonitoringEventsTrait;
|
5 |
-
use Aws\MonitoringEventsInterface;
|
6 |
-
use Aws\ResponseContainerInterface;
|
7 |
-
|
8 |
-
class ParserException extends \RuntimeException implements
|
9 |
-
MonitoringEventsInterface,
|
10 |
-
ResponseContainerInterface
|
11 |
-
{
|
12 |
-
use HasMonitoringEventsTrait;
|
13 |
-
|
14 |
-
private $response;
|
15 |
-
|
16 |
-
public function __construct($message = '', $code = 0, $previous = null, array $context = [])
|
17 |
-
{
|
18 |
-
$this->response = isset($context['response']) ? $context['response'] : null;
|
19 |
-
parent::__construct($message, $code, $previous);
|
20 |
-
}
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Get the received HTTP response if any.
|
24 |
-
*
|
25 |
-
* @return ResponseInterface|null
|
26 |
-
*/
|
27 |
-
public function getResponse()
|
28 |
-
{
|
29 |
-
return $this->response;
|
30 |
-
}
|
31 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Parser/JsonParser.php
DELETED
@@ -1,62 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Parser;
|
3 |
-
|
4 |
-
use Aws\Api\DateTimeResult;
|
5 |
-
use Aws\Api\Shape;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @internal Implements standard JSON parsing.
|
9 |
-
*/
|
10 |
-
class JsonParser
|
11 |
-
{
|
12 |
-
public function parse(Shape $shape, $value)
|
13 |
-
{
|
14 |
-
if ($value === null) {
|
15 |
-
return $value;
|
16 |
-
}
|
17 |
-
|
18 |
-
switch ($shape['type']) {
|
19 |
-
case 'structure':
|
20 |
-
$target = [];
|
21 |
-
foreach ($shape->getMembers() as $name => $member) {
|
22 |
-
$locationName = $member['locationName'] ?: $name;
|
23 |
-
if (isset($value[$locationName])) {
|
24 |
-
$target[$name] = $this->parse($member, $value[$locationName]);
|
25 |
-
}
|
26 |
-
}
|
27 |
-
return $target;
|
28 |
-
|
29 |
-
case 'list':
|
30 |
-
$member = $shape->getMember();
|
31 |
-
$target = [];
|
32 |
-
foreach ($value as $v) {
|
33 |
-
$target[] = $this->parse($member, $v);
|
34 |
-
}
|
35 |
-
return $target;
|
36 |
-
|
37 |
-
case 'map':
|
38 |
-
$values = $shape->getValue();
|
39 |
-
$target = [];
|
40 |
-
foreach ($value as $k => $v) {
|
41 |
-
$target[$k] = $this->parse($values, $v);
|
42 |
-
}
|
43 |
-
return $target;
|
44 |
-
|
45 |
-
case 'timestamp':
|
46 |
-
if (!empty($shape['timestampFormat'])
|
47 |
-
&& $shape['timestampFormat'] !== 'unixTimestamp') {
|
48 |
-
return new DateTimeResult($value);
|
49 |
-
}
|
50 |
-
// The Unix epoch (or Unix time or POSIX time or Unix
|
51 |
-
// timestamp) is the number of seconds that have elapsed since
|
52 |
-
// January 1, 1970 (midnight UTC/GMT).
|
53 |
-
return DateTimeResult::fromEpoch($value);
|
54 |
-
|
55 |
-
case 'blob':
|
56 |
-
return base64_decode($value);
|
57 |
-
|
58 |
-
default:
|
59 |
-
return $value;
|
60 |
-
}
|
61 |
-
}
|
62 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Parser/PayloadParserTrait.php
DELETED
@@ -1,61 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Parser;
|
3 |
-
|
4 |
-
use Aws\Api\Parser\Exception\ParserException;
|
5 |
-
use Psr\Http\Message\ResponseInterface;
|
6 |
-
|
7 |
-
trait PayloadParserTrait
|
8 |
-
{
|
9 |
-
/**
|
10 |
-
* @param string $json
|
11 |
-
*
|
12 |
-
* @throws ParserException
|
13 |
-
*
|
14 |
-
* @return array
|
15 |
-
*/
|
16 |
-
private function parseJson($json, $response)
|
17 |
-
{
|
18 |
-
$jsonPayload = json_decode($json, true);
|
19 |
-
|
20 |
-
if (JSON_ERROR_NONE !== json_last_error()) {
|
21 |
-
throw new ParserException(
|
22 |
-
'Error parsing JSON: ' . json_last_error_msg(),
|
23 |
-
0,
|
24 |
-
null,
|
25 |
-
['response' => $response]
|
26 |
-
);
|
27 |
-
}
|
28 |
-
|
29 |
-
return $jsonPayload;
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @param string $xml
|
34 |
-
*
|
35 |
-
* @throws ParserException
|
36 |
-
*
|
37 |
-
* @return \SimpleXMLElement
|
38 |
-
*/
|
39 |
-
private function parseXml($xml, $response)
|
40 |
-
{
|
41 |
-
$priorSetting = libxml_use_internal_errors(true);
|
42 |
-
try {
|
43 |
-
libxml_clear_errors();
|
44 |
-
$xmlPayload = new \SimpleXMLElement($xml);
|
45 |
-
if ($error = libxml_get_last_error()) {
|
46 |
-
throw new \RuntimeException($error->message);
|
47 |
-
}
|
48 |
-
} catch (\Exception $e) {
|
49 |
-
throw new ParserException(
|
50 |
-
"Error parsing XML: {$e->getMessage()}",
|
51 |
-
0,
|
52 |
-
$e,
|
53 |
-
['response' => $response]
|
54 |
-
);
|
55 |
-
} finally {
|
56 |
-
libxml_use_internal_errors($priorSetting);
|
57 |
-
}
|
58 |
-
|
59 |
-
return $xmlPayload;
|
60 |
-
}
|
61 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Parser/XmlParser.php
DELETED
@@ -1,138 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Parser;
|
3 |
-
|
4 |
-
use Aws\Api\DateTimeResult;
|
5 |
-
use Aws\Api\ListShape;
|
6 |
-
use Aws\Api\MapShape;
|
7 |
-
use Aws\Api\Shape;
|
8 |
-
use Aws\Api\StructureShape;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @internal Implements standard XML parsing for REST-XML and Query protocols.
|
12 |
-
*/
|
13 |
-
class XmlParser
|
14 |
-
{
|
15 |
-
public function parse(StructureShape $shape, \SimpleXMLElement $value)
|
16 |
-
{
|
17 |
-
return $this->dispatch($shape, $value);
|
18 |
-
}
|
19 |
-
|
20 |
-
private function dispatch($shape, \SimpleXMLElement $value)
|
21 |
-
{
|
22 |
-
static $methods = [
|
23 |
-
'structure' => 'parse_structure',
|
24 |
-
'list' => 'parse_list',
|
25 |
-
'map' => 'parse_map',
|
26 |
-
'blob' => 'parse_blob',
|
27 |
-
'boolean' => 'parse_boolean',
|
28 |
-
'integer' => 'parse_integer',
|
29 |
-
'float' => 'parse_float',
|
30 |
-
'double' => 'parse_float',
|
31 |
-
'timestamp' => 'parse_timestamp',
|
32 |
-
];
|
33 |
-
|
34 |
-
$type = $shape['type'];
|
35 |
-
if (isset($methods[$type])) {
|
36 |
-
return $this->{$methods[$type]}($shape, $value);
|
37 |
-
}
|
38 |
-
|
39 |
-
return (string) $value;
|
40 |
-
}
|
41 |
-
|
42 |
-
private function parse_structure(
|
43 |
-
StructureShape $shape,
|
44 |
-
\SimpleXMLElement $value
|
45 |
-
) {
|
46 |
-
$target = [];
|
47 |
-
|
48 |
-
foreach ($shape->getMembers() as $name => $member) {
|
49 |
-
// Extract the name of the XML node
|
50 |
-
$node = $this->memberKey($member, $name);
|
51 |
-
if (isset($value->{$node})) {
|
52 |
-
$target[$name] = $this->dispatch($member, $value->{$node});
|
53 |
-
}
|
54 |
-
}
|
55 |
-
|
56 |
-
return $target;
|
57 |
-
}
|
58 |
-
|
59 |
-
private function memberKey(Shape $shape, $name)
|
60 |
-
{
|
61 |
-
if (null !== $shape['locationName']) {
|
62 |
-
return $shape['locationName'];
|
63 |
-
}
|
64 |
-
|
65 |
-
if ($shape instanceof ListShape && $shape['flattened']) {
|
66 |
-
return $shape->getMember()['locationName'] ?: $name;
|
67 |
-
}
|
68 |
-
|
69 |
-
return $name;
|
70 |
-
}
|
71 |
-
|
72 |
-
private function parse_list(ListShape $shape, \SimpleXMLElement $value)
|
73 |
-
{
|
74 |
-
$target = [];
|
75 |
-
$member = $shape->getMember();
|
76 |
-
|
77 |
-
if (!$shape['flattened']) {
|
78 |
-
$value = $value->{$member['locationName'] ?: 'member'};
|
79 |
-
}
|
80 |
-
|
81 |
-
foreach ($value as $v) {
|
82 |
-
$target[] = $this->dispatch($member, $v);
|
83 |
-
}
|
84 |
-
|
85 |
-
return $target;
|
86 |
-
}
|
87 |
-
|
88 |
-
private function parse_map(MapShape $shape, \SimpleXMLElement $value)
|
89 |
-
{
|
90 |
-
$target = [];
|
91 |
-
|
92 |
-
if (!$shape['flattened']) {
|
93 |
-
$value = $value->entry;
|
94 |
-
}
|
95 |
-
|
96 |
-
$mapKey = $shape->getKey();
|
97 |
-
$mapValue = $shape->getValue();
|
98 |
-
$keyName = $shape->getKey()['locationName'] ?: 'key';
|
99 |
-
$valueName = $shape->getValue()['locationName'] ?: 'value';
|
100 |
-
|
101 |
-
foreach ($value as $node) {
|
102 |
-
$key = $this->dispatch($mapKey, $node->{$keyName});
|
103 |
-
$value = $this->dispatch($mapValue, $node->{$valueName});
|
104 |
-
$target[$key] = $value;
|
105 |
-
}
|
106 |
-
|
107 |
-
return $target;
|
108 |
-
}
|
109 |
-
|
110 |
-
private function parse_blob(Shape $shape, $value)
|
111 |
-
{
|
112 |
-
return base64_decode((string) $value);
|
113 |
-
}
|
114 |
-
|
115 |
-
private function parse_float(Shape $shape, $value)
|
116 |
-
{
|
117 |
-
return (float) (string) $value;
|
118 |
-
}
|
119 |
-
|
120 |
-
private function parse_integer(Shape $shape, $value)
|
121 |
-
{
|
122 |
-
return (int) (string) $value;
|
123 |
-
}
|
124 |
-
|
125 |
-
private function parse_boolean(Shape $shape, $value)
|
126 |
-
{
|
127 |
-
return $value == 'true';
|
128 |
-
}
|
129 |
-
|
130 |
-
private function parse_timestamp(Shape $shape, $value)
|
131 |
-
{
|
132 |
-
if (!empty($shape['timestampFormat'])
|
133 |
-
&& $shape['timestampFormat'] === 'unixTimestamp') {
|
134 |
-
return DateTimeResult::fromEpoch((string) $value);
|
135 |
-
}
|
136 |
-
return new DateTimeResult($value);
|
137 |
-
}
|
138 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Serializer/RestSerializer.php
DELETED
@@ -1,219 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Serializer;
|
3 |
-
|
4 |
-
use Aws\Api\MapShape;
|
5 |
-
use Aws\Api\Service;
|
6 |
-
use Aws\Api\Operation;
|
7 |
-
use Aws\Api\Shape;
|
8 |
-
use Aws\Api\StructureShape;
|
9 |
-
use Aws\Api\TimestampShape;
|
10 |
-
use Aws\CommandInterface;
|
11 |
-
use GuzzleHttp\Psr7;
|
12 |
-
use GuzzleHttp\Psr7\Uri;
|
13 |
-
use GuzzleHttp\Psr7\UriResolver;
|
14 |
-
use Psr\Http\Message\RequestInterface;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Serializes HTTP locations like header, uri, payload, etc...
|
18 |
-
* @internal
|
19 |
-
*/
|
20 |
-
abstract class RestSerializer
|
21 |
-
{
|
22 |
-
/** @var Service */
|
23 |
-
private $api;
|
24 |
-
|
25 |
-
/** @var Psr7\Uri */
|
26 |
-
private $endpoint;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @param Service $api Service API description
|
30 |
-
* @param string $endpoint Endpoint to connect to
|
31 |
-
*/
|
32 |
-
public function __construct(Service $api, $endpoint)
|
33 |
-
{
|
34 |
-
$this->api = $api;
|
35 |
-
$this->endpoint = Psr7\uri_for($endpoint);
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @param CommandInterface $command Command to serialized
|
40 |
-
*
|
41 |
-
* @return RequestInterface
|
42 |
-
*/
|
43 |
-
public function __invoke(CommandInterface $command)
|
44 |
-
{
|
45 |
-
$operation = $this->api->getOperation($command->getName());
|
46 |
-
$args = $command->toArray();
|
47 |
-
$opts = $this->serialize($operation, $args);
|
48 |
-
$uri = $this->buildEndpoint($operation, $args, $opts);
|
49 |
-
|
50 |
-
return new Psr7\Request(
|
51 |
-
$operation['http']['method'],
|
52 |
-
$uri,
|
53 |
-
isset($opts['headers']) ? $opts['headers'] : [],
|
54 |
-
isset($opts['body']) ? $opts['body'] : null
|
55 |
-
);
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Modifies a hash of request options for a payload body.
|
60 |
-
*
|
61 |
-
* @param StructureShape $member Member to serialize
|
62 |
-
* @param array $value Value to serialize
|
63 |
-
* @param array $opts Request options to modify.
|
64 |
-
*/
|
65 |
-
abstract protected function payload(
|
66 |
-
StructureShape $member,
|
67 |
-
array $value,
|
68 |
-
array &$opts
|
69 |
-
);
|
70 |
-
|
71 |
-
private function serialize(Operation $operation, array $args)
|
72 |
-
{
|
73 |
-
$opts = [];
|
74 |
-
$input = $operation->getInput();
|
75 |
-
|
76 |
-
// Apply the payload trait if present
|
77 |
-
if ($payload = $input['payload']) {
|
78 |
-
$this->applyPayload($input, $payload, $args, $opts);
|
79 |
-
}
|
80 |
-
|
81 |
-
foreach ($args as $name => $value) {
|
82 |
-
if ($input->hasMember($name)) {
|
83 |
-
$member = $input->getMember($name);
|
84 |
-
$location = $member['location'];
|
85 |
-
if (!$payload && !$location) {
|
86 |
-
$bodyMembers[$name] = $value;
|
87 |
-
} elseif ($location == 'header') {
|
88 |
-
$this->applyHeader($name, $member, $value, $opts);
|
89 |
-
} elseif ($location == 'querystring') {
|
90 |
-
$this->applyQuery($name, $member, $value, $opts);
|
91 |
-
} elseif ($location == 'headers') {
|
92 |
-
$this->applyHeaderMap($name, $member, $value, $opts);
|
93 |
-
}
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
if (isset($bodyMembers)) {
|
98 |
-
$this->payload($operation->getInput(), $bodyMembers, $opts);
|
99 |
-
}
|
100 |
-
|
101 |
-
return $opts;
|
102 |
-
}
|
103 |
-
|
104 |
-
private function applyPayload(StructureShape $input, $name, array $args, array &$opts)
|
105 |
-
{
|
106 |
-
if (!isset($args[$name])) {
|
107 |
-
return;
|
108 |
-
}
|
109 |
-
|
110 |
-
$m = $input->getMember($name);
|
111 |
-
|
112 |
-
if ($m['streaming'] ||
|
113 |
-
($m['type'] == 'string' || $m['type'] == 'blob')
|
114 |
-
) {
|
115 |
-
// Streaming bodies or payloads that are strings are
|
116 |
-
// always just a stream of data.
|
117 |
-
$opts['body'] = Psr7\stream_for($args[$name]);
|
118 |
-
return;
|
119 |
-
}
|
120 |
-
|
121 |
-
$this->payload($m, $args[$name], $opts);
|
122 |
-
}
|
123 |
-
|
124 |
-
private function applyHeader($name, Shape $member, $value, array &$opts)
|
125 |
-
{
|
126 |
-
if ($member->getType() === 'timestamp') {
|
127 |
-
$timestampFormat = !empty($member['timestampFormat'])
|
128 |
-
? $member['timestampFormat']
|
129 |
-
: 'rfc822';
|
130 |
-
$value = TimestampShape::format($value, $timestampFormat);
|
131 |
-
}
|
132 |
-
if ($member['jsonvalue']) {
|
133 |
-
$value = json_encode($value);
|
134 |
-
if (empty($value) && JSON_ERROR_NONE !== json_last_error()) {
|
135 |
-
throw new \InvalidArgumentException('Unable to encode the provided value'
|
136 |
-
. ' with \'json_encode\'. ' . json_last_error_msg());
|
137 |
-
}
|
138 |
-
|
139 |
-
$value = base64_encode($value);
|
140 |
-
}
|
141 |
-
|
142 |
-
$opts['headers'][$member['locationName'] ?: $name] = $value;
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
-
* Note: This is currently only present in the Amazon S3 model.
|
147 |
-
*/
|
148 |
-
private function applyHeaderMap($name, Shape $member, array $value, array &$opts)
|
149 |
-
{
|
150 |
-
$prefix = $member['locationName'];
|
151 |
-
foreach ($value as $k => $v) {
|
152 |
-
$opts['headers'][$prefix . $k] = $v;
|
153 |
-
}
|
154 |
-
}
|
155 |
-
|
156 |
-
private function applyQuery($name, Shape $member, $value, array &$opts)
|
157 |
-
{
|
158 |
-
if ($member instanceof MapShape) {
|
159 |
-
$opts['query'] = isset($opts['query']) && is_array($opts['query'])
|
160 |
-
? $opts['query'] + $value
|
161 |
-
: $value;
|
162 |
-
} elseif ($value !== null) {
|
163 |
-
$type = $member->getType();
|
164 |
-
if ($type === 'boolean') {
|
165 |
-
$value = $value ? 'true' : 'false';
|
166 |
-
} elseif ($type === 'timestamp') {
|
167 |
-
$timestampFormat = !empty($member['timestampFormat'])
|
168 |
-
? $member['timestampFormat']
|
169 |
-
: 'iso8601';
|
170 |
-
$value = TimestampShape::format($value, $timestampFormat);
|
171 |
-
}
|
172 |
-
|
173 |
-
$opts['query'][$member['locationName'] ?: $name] = $value;
|
174 |
-
}
|
175 |
-
}
|
176 |
-
|
177 |
-
private function buildEndpoint(Operation $operation, array $args, array $opts)
|
178 |
-
{
|
179 |
-
$varspecs = [];
|
180 |
-
|
181 |
-
// Create an associative array of varspecs used in expansions
|
182 |
-
foreach ($operation->getInput()->getMembers() as $name => $member) {
|
183 |
-
if ($member['location'] == 'uri') {
|
184 |
-
$varspecs[$member['locationName'] ?: $name] =
|
185 |
-
isset($args[$name])
|
186 |
-
? $args[$name]
|
187 |
-
: null;
|
188 |
-
}
|
189 |
-
}
|
190 |
-
|
191 |
-
$relative = preg_replace_callback(
|
192 |
-
'/\{([^\}]+)\}/',
|
193 |
-
function (array $matches) use ($varspecs) {
|
194 |
-
$isGreedy = substr($matches[1], -1, 1) == '+';
|
195 |
-
$k = $isGreedy ? substr($matches[1], 0, -1) : $matches[1];
|
196 |
-
if (!isset($varspecs[$k])) {
|
197 |
-
return '';
|
198 |
-
}
|
199 |
-
|
200 |
-
if ($isGreedy) {
|
201 |
-
return str_replace('%2F', '/', rawurlencode($varspecs[$k]));
|
202 |
-
}
|
203 |
-
|
204 |
-
return rawurlencode($varspecs[$k]);
|
205 |
-
},
|
206 |
-
$operation['http']['requestUri']
|
207 |
-
);
|
208 |
-
|
209 |
-
// Add the query string variables or appending to one if needed.
|
210 |
-
if (!empty($opts['query'])) {
|
211 |
-
$append = Psr7\build_query($opts['query']);
|
212 |
-
$relative .= strpos($relative, '?') ? "&{$append}" : "?$append";
|
213 |
-
}
|
214 |
-
|
215 |
-
// Expand path place holders using Amazon's slightly different URI
|
216 |
-
// template syntax.
|
217 |
-
return UriResolver::resolve($this->endpoint, new Uri($relative));
|
218 |
-
}
|
219 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Serializer/RestXmlSerializer.php
DELETED
@@ -1,34 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Serializer;
|
3 |
-
|
4 |
-
use Aws\Api\StructureShape;
|
5 |
-
use Aws\Api\Service;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @internal
|
9 |
-
*/
|
10 |
-
class RestXmlSerializer extends RestSerializer
|
11 |
-
{
|
12 |
-
/** @var XmlBody */
|
13 |
-
private $xmlBody;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @param Service $api Service API description
|
17 |
-
* @param string $endpoint Endpoint to connect to
|
18 |
-
* @param XmlBody $xmlBody Optional XML formatter to use
|
19 |
-
*/
|
20 |
-
public function __construct(
|
21 |
-
Service $api,
|
22 |
-
$endpoint,
|
23 |
-
XmlBody $xmlBody = null
|
24 |
-
) {
|
25 |
-
parent::__construct($api, $endpoint);
|
26 |
-
$this->xmlBody = $xmlBody ?: new XmlBody($api);
|
27 |
-
}
|
28 |
-
|
29 |
-
protected function payload(StructureShape $member, array $value, array &$opts)
|
30 |
-
{
|
31 |
-
$opts['headers']['Content-Type'] = 'application/xml';
|
32 |
-
$opts['body'] = (string) $this->xmlBody->build($member, $value);
|
33 |
-
}
|
34 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Serializer/XmlBody.php
DELETED
@@ -1,220 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api\Serializer;
|
3 |
-
|
4 |
-
use Aws\Api\MapShape;
|
5 |
-
use Aws\Api\Service;
|
6 |
-
use Aws\Api\Shape;
|
7 |
-
use Aws\Api\StructureShape;
|
8 |
-
use Aws\Api\ListShape;
|
9 |
-
use Aws\Api\TimestampShape;
|
10 |
-
use XMLWriter;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @internal Formats the XML body of a REST-XML services.
|
14 |
-
*/
|
15 |
-
class XmlBody
|
16 |
-
{
|
17 |
-
/** @var \Aws\Api\Service */
|
18 |
-
private $api;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @param Service $api API being used to create the XML body.
|
22 |
-
*/
|
23 |
-
public function __construct(Service $api)
|
24 |
-
{
|
25 |
-
$this->api = $api;
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Builds the XML body based on an array of arguments.
|
30 |
-
*
|
31 |
-
* @param Shape $shape Operation being constructed
|
32 |
-
* @param array $args Associative array of arguments
|
33 |
-
*
|
34 |
-
* @return string
|
35 |
-
*/
|
36 |
-
public function build(Shape $shape, array $args)
|
37 |
-
{
|
38 |
-
$xml = new XMLWriter();
|
39 |
-
$xml->openMemory();
|
40 |
-
$xml->startDocument('1.0', 'UTF-8');
|
41 |
-
$this->format($shape, $shape['locationName'] ?: $shape['name'], $args, $xml);
|
42 |
-
$xml->endDocument();
|
43 |
-
|
44 |
-
return $xml->outputMemory();
|
45 |
-
}
|
46 |
-
|
47 |
-
private function startElement(Shape $shape, $name, XMLWriter $xml)
|
48 |
-
{
|
49 |
-
$xml->startElement($name);
|
50 |
-
|
51 |
-
if ($ns = $shape['xmlNamespace']) {
|
52 |
-
$xml->writeAttribute(
|
53 |
-
isset($ns['prefix']) ? "xmlns:{$ns['prefix']}" : 'xmlns',
|
54 |
-
$shape['xmlNamespace']['uri']
|
55 |
-
);
|
56 |
-
}
|
57 |
-
}
|
58 |
-
|
59 |
-
private function format(Shape $shape, $name, $value, XMLWriter $xml)
|
60 |
-
{
|
61 |
-
// Any method mentioned here has a custom serialization handler.
|
62 |
-
static $methods = [
|
63 |
-
'add_structure' => true,
|
64 |
-
'add_list' => true,
|
65 |
-
'add_blob' => true,
|
66 |
-
'add_timestamp' => true,
|
67 |
-
'add_boolean' => true,
|
68 |
-
'add_map' => true,
|
69 |
-
'add_string' => true
|
70 |
-
];
|
71 |
-
|
72 |
-
$type = 'add_' . $shape['type'];
|
73 |
-
if (isset($methods[$type])) {
|
74 |
-
$this->{$type}($shape, $name, $value, $xml);
|
75 |
-
} else {
|
76 |
-
$this->defaultShape($shape, $name, $value, $xml);
|
77 |
-
}
|
78 |
-
}
|
79 |
-
|
80 |
-
private function defaultShape(Shape $shape, $name, $value, XMLWriter $xml)
|
81 |
-
{
|
82 |
-
$this->startElement($shape, $name, $xml);
|
83 |
-
$xml->writeRaw($value);
|
84 |
-
$xml->endElement();
|
85 |
-
}
|
86 |
-
|
87 |
-
private function add_structure(
|
88 |
-
StructureShape $shape,
|
89 |
-
$name,
|
90 |
-
array $value,
|
91 |
-
\XMLWriter $xml
|
92 |
-
) {
|
93 |
-
$this->startElement($shape, $name, $xml);
|
94 |
-
|
95 |
-
foreach ($this->getStructureMembers($shape, $value) as $k => $definition) {
|
96 |
-
$this->format(
|
97 |
-
$definition['member'],
|
98 |
-
$definition['member']['locationName'] ?: $k,
|
99 |
-
$definition['value'],
|
100 |
-
$xml
|
101 |
-
);
|
102 |
-
}
|
103 |
-
|
104 |
-
$xml->endElement();
|
105 |
-
}
|
106 |
-
|
107 |
-
private function getStructureMembers(StructureShape $shape, array $value)
|
108 |
-
{
|
109 |
-
$members = [];
|
110 |
-
|
111 |
-
foreach ($value as $k => $v) {
|
112 |
-
if ($v !== null && $shape->hasMember($k)) {
|
113 |
-
$definition = [
|
114 |
-
'member' => $shape->getMember($k),
|
115 |
-
'value' => $v,
|
116 |
-
];
|
117 |
-
|
118 |
-
if ($definition['member']['xmlAttribute']) {
|
119 |
-
// array_unshift_associative
|
120 |
-
$members = [$k => $definition] + $members;
|
121 |
-
} else {
|
122 |
-
$members[$k] = $definition;
|
123 |
-
}
|
124 |
-
}
|
125 |
-
}
|
126 |
-
|
127 |
-
return $members;
|
128 |
-
}
|
129 |
-
|
130 |
-
private function add_list(
|
131 |
-
ListShape $shape,
|
132 |
-
$name,
|
133 |
-
array $value,
|
134 |
-
XMLWriter $xml
|
135 |
-
) {
|
136 |
-
$items = $shape->getMember();
|
137 |
-
|
138 |
-
if ($shape['flattened']) {
|
139 |
-
$elementName = $name;
|
140 |
-
} else {
|
141 |
-
$this->startElement($shape, $name, $xml);
|
142 |
-
$elementName = $items['locationName'] ?: 'member';
|
143 |
-
}
|
144 |
-
|
145 |
-
foreach ($value as $v) {
|
146 |
-
$this->format($items, $elementName, $v, $xml);
|
147 |
-
}
|
148 |
-
|
149 |
-
if (!$shape['flattened']) {
|
150 |
-
$xml->endElement();
|
151 |
-
}
|
152 |
-
}
|
153 |
-
|
154 |
-
private function add_map(
|
155 |
-
MapShape $shape,
|
156 |
-
$name,
|
157 |
-
array $value,
|
158 |
-
XMLWriter $xml
|
159 |
-
) {
|
160 |
-
$xmlEntry = $shape['flattened'] ? $shape['locationName'] : 'entry';
|
161 |
-
$xmlKey = $shape->getKey()['locationName'] ?: 'key';
|
162 |
-
$xmlValue = $shape->getValue()['locationName'] ?: 'value';
|
163 |
-
|
164 |
-
$this->startElement($shape, $name, $xml);
|
165 |
-
|
166 |
-
foreach ($value as $key => $v) {
|
167 |
-
$this->startElement($shape, $xmlEntry, $xml);
|
168 |
-
$this->format($shape->getKey(), $xmlKey, $key, $xml);
|
169 |
-
$this->format($shape->getValue(), $xmlValue, $v, $xml);
|
170 |
-
$xml->endElement();
|
171 |
-
}
|
172 |
-
|
173 |
-
$xml->endElement();
|
174 |
-
}
|
175 |
-
|
176 |
-
private function add_blob(Shape $shape, $name, $value, XMLWriter $xml)
|
177 |
-
{
|
178 |
-
$this->startElement($shape, $name, $xml);
|
179 |
-
$xml->writeRaw(base64_encode($value));
|
180 |
-
$xml->endElement();
|
181 |
-
}
|
182 |
-
|
183 |
-
private function add_timestamp(
|
184 |
-
TimestampShape $shape,
|
185 |
-
$name,
|
186 |
-
$value,
|
187 |
-
XMLWriter $xml
|
188 |
-
) {
|
189 |
-
$this->startElement($shape, $name, $xml);
|
190 |
-
$timestampFormat = !empty($shape['timestampFormat'])
|
191 |
-
? $shape['timestampFormat']
|
192 |
-
: 'iso8601';
|
193 |
-
$xml->writeRaw(TimestampShape::format($value, $timestampFormat));
|
194 |
-
$xml->endElement();
|
195 |
-
}
|
196 |
-
|
197 |
-
private function add_boolean(
|
198 |
-
Shape $shape,
|
199 |
-
$name,
|
200 |
-
$value,
|
201 |
-
XMLWriter $xml
|
202 |
-
) {
|
203 |
-
$this->startElement($shape, $name, $xml);
|
204 |
-
$xml->writeRaw($value ? 'true' : 'false');
|
205 |
-
$xml->endElement();
|
206 |
-
}
|
207 |
-
|
208 |
-
private function add_string(
|
209 |
-
Shape $shape,
|
210 |
-
$name,
|
211 |
-
$value,
|
212 |
-
XMLWriter $xml
|
213 |
-
) {
|
214 |
-
if ($shape['xmlAttribute']) {
|
215 |
-
$xml->writeAttribute($shape['locationName'] ?: $name, $value);
|
216 |
-
} else {
|
217 |
-
$this->defaultShape($shape, $name, $value, $xml);
|
218 |
-
}
|
219 |
-
}
|
220 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/Service.php
DELETED
@@ -1,448 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api;
|
3 |
-
|
4 |
-
use Aws\Api\Serializer\QuerySerializer;
|
5 |
-
use Aws\Api\Serializer\Ec2ParamBuilder;
|
6 |
-
use Aws\Api\Parser\QueryParser;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents a web service API model.
|
10 |
-
*/
|
11 |
-
class Service extends AbstractModel
|
12 |
-
{
|
13 |
-
/** @var callable */
|
14 |
-
private $apiProvider;
|
15 |
-
|
16 |
-
/** @var string */
|
17 |
-
private $serviceName;
|
18 |
-
|
19 |
-
/** @var string */
|
20 |
-
private $apiVersion;
|
21 |
-
|
22 |
-
/** @var Operation[] */
|
23 |
-
private $operations = [];
|
24 |
-
|
25 |
-
/** @var array */
|
26 |
-
private $paginators = null;
|
27 |
-
|
28 |
-
/** @var array */
|
29 |
-
private $waiters = null;
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @param array $definition
|
33 |
-
* @param callable $provider
|
34 |
-
*
|
35 |
-
* @internal param array $definition Service description
|
36 |
-
*/
|
37 |
-
public function __construct(array $definition, callable $provider)
|
38 |
-
{
|
39 |
-
static $defaults = [
|
40 |
-
'operations' => [],
|
41 |
-
'shapes' => [],
|
42 |
-
'metadata' => []
|
43 |
-
], $defaultMeta = [
|
44 |
-
'apiVersion' => null,
|
45 |
-
'serviceFullName' => null,
|
46 |
-
'serviceId' => null,
|
47 |
-
'endpointPrefix' => null,
|
48 |
-
'signingName' => null,
|
49 |
-
'signatureVersion' => null,
|
50 |
-
'protocol' => null,
|
51 |
-
'uid' => null
|
52 |
-
];
|
53 |
-
|
54 |
-
$definition += $defaults;
|
55 |
-
$definition['metadata'] += $defaultMeta;
|
56 |
-
$this->definition = $definition;
|
57 |
-
$this->apiProvider = $provider;
|
58 |
-
parent::__construct($definition, new ShapeMap($definition['shapes']));
|
59 |
-
|
60 |
-
if (isset($definition['metadata']['serviceIdentifier'])) {
|
61 |
-
$this->serviceName = $this->getServiceName();
|
62 |
-
} else {
|
63 |
-
$this->serviceName = $this->getEndpointPrefix();
|
64 |
-
}
|
65 |
-
|
66 |
-
$this->apiVersion = $this->getApiVersion();
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Creates a request serializer for the provided API object.
|
71 |
-
*
|
72 |
-
* @param Service $api API that contains a protocol.
|
73 |
-
* @param string $endpoint Endpoint to send requests to.
|
74 |
-
*
|
75 |
-
* @return callable
|
76 |
-
* @throws \UnexpectedValueException
|
77 |
-
*/
|
78 |
-
public static function createSerializer(Service $api, $endpoint)
|
79 |
-
{
|
80 |
-
static $mapping = [
|
81 |
-
'json' => 'Aws\Api\Serializer\JsonRpcSerializer',
|
82 |
-
'query' => 'Aws\Api\Serializer\QuerySerializer',
|
83 |
-
'rest-json' => 'Aws\Api\Serializer\RestJsonSerializer',
|
84 |
-
'rest-xml' => 'Aws\Api\Serializer\RestXmlSerializer'
|
85 |
-
];
|
86 |
-
|
87 |
-
$proto = $api->getProtocol();
|
88 |
-
|
89 |
-
if (isset($mapping[$proto])) {
|
90 |
-
return new $mapping[$proto]($api, $endpoint);
|
91 |
-
}
|
92 |
-
|
93 |
-
if ($proto == 'ec2') {
|
94 |
-
return new QuerySerializer($api, $endpoint, new Ec2ParamBuilder());
|
95 |
-
}
|
96 |
-
|
97 |
-
throw new \UnexpectedValueException(
|
98 |
-
'Unknown protocol: ' . $api->getProtocol()
|
99 |
-
);
|
100 |
-
}
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Creates an error parser for the given protocol.
|
104 |
-
*
|
105 |
-
* @param string $protocol Protocol to parse (e.g., query, json, etc.)
|
106 |
-
*
|
107 |
-
* @return callable
|
108 |
-
* @throws \UnexpectedValueException
|
109 |
-
*/
|
110 |
-
public static function createErrorParser($protocol)
|
111 |
-
{
|
112 |
-
static $mapping = [
|
113 |
-
'json' => 'Aws\Api\ErrorParser\JsonRpcErrorParser',
|
114 |
-
'query' => 'Aws\Api\ErrorParser\XmlErrorParser',
|
115 |
-
'rest-json' => 'Aws\Api\ErrorParser\RestJsonErrorParser',
|
116 |
-
'rest-xml' => 'Aws\Api\ErrorParser\XmlErrorParser',
|
117 |
-
'ec2' => 'Aws\Api\ErrorParser\XmlErrorParser'
|
118 |
-
];
|
119 |
-
|
120 |
-
if (isset($mapping[$protocol])) {
|
121 |
-
return new $mapping[$protocol]();
|
122 |
-
}
|
123 |
-
|
124 |
-
throw new \UnexpectedValueException("Unknown protocol: $protocol");
|
125 |
-
}
|
126 |
-
|
127 |
-
/**
|
128 |
-
* Applies the listeners needed to parse client models.
|
129 |
-
*
|
130 |
-
* @param Service $api API to create a parser for
|
131 |
-
* @return callable
|
132 |
-
* @throws \UnexpectedValueException
|
133 |
-
*/
|
134 |
-
public static function createParser(Service $api)
|
135 |
-
{
|
136 |
-
static $mapping = [
|
137 |
-
'json' => 'Aws\Api\Parser\JsonRpcParser',
|
138 |
-
'query' => 'Aws\Api\Parser\QueryParser',
|
139 |
-
'rest-json' => 'Aws\Api\Parser\RestJsonParser',
|
140 |
-
'rest-xml' => 'Aws\Api\Parser\RestXmlParser'
|
141 |
-
];
|
142 |
-
|
143 |
-
$proto = $api->getProtocol();
|
144 |
-
if (isset($mapping[$proto])) {
|
145 |
-
return new $mapping[$proto]($api);
|
146 |
-
}
|
147 |
-
|
148 |
-
if ($proto == 'ec2') {
|
149 |
-
return new QueryParser($api, null, false);
|
150 |
-
}
|
151 |
-
|
152 |
-
throw new \UnexpectedValueException(
|
153 |
-
'Unknown protocol: ' . $api->getProtocol()
|
154 |
-
);
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Get the full name of the service
|
159 |
-
*
|
160 |
-
* @return string
|
161 |
-
*/
|
162 |
-
public function getServiceFullName()
|
163 |
-
{
|
164 |
-
return $this->definition['metadata']['serviceFullName'];
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Get the service id
|
169 |
-
*
|
170 |
-
* @return string
|
171 |
-
*/
|
172 |
-
public function getServiceId()
|
173 |
-
{
|
174 |
-
return $this->definition['metadata']['serviceId'];
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Get the API version of the service
|
179 |
-
*
|
180 |
-
* @return string
|
181 |
-
*/
|
182 |
-
public function getApiVersion()
|
183 |
-
{
|
184 |
-
return $this->definition['metadata']['apiVersion'];
|
185 |
-
}
|
186 |
-
|
187 |
-
/**
|
188 |
-
* Get the API version of the service
|
189 |
-
*
|
190 |
-
* @return string
|
191 |
-
*/
|
192 |
-
public function getEndpointPrefix()
|
193 |
-
{
|
194 |
-
return $this->definition['metadata']['endpointPrefix'];
|
195 |
-
}
|
196 |
-
|
197 |
-
/**
|
198 |
-
* Get the signing name used by the service.
|
199 |
-
*
|
200 |
-
* @return string
|
201 |
-
*/
|
202 |
-
public function getSigningName()
|
203 |
-
{
|
204 |
-
return $this->definition['metadata']['signingName']
|
205 |
-
?: $this->definition['metadata']['endpointPrefix'];
|
206 |
-
}
|
207 |
-
|
208 |
-
/**
|
209 |
-
* Get the service name.
|
210 |
-
*
|
211 |
-
* @return string
|
212 |
-
*/
|
213 |
-
public function getServiceName()
|
214 |
-
{
|
215 |
-
return $this->definition['metadata']['serviceIdentifier'];
|
216 |
-
}
|
217 |
-
|
218 |
-
/**
|
219 |
-
* Get the default signature version of the service.
|
220 |
-
*
|
221 |
-
* Note: this method assumes "v4" when not specified in the model.
|
222 |
-
*
|
223 |
-
* @return string
|
224 |
-
*/
|
225 |
-
public function getSignatureVersion()
|
226 |
-
{
|
227 |
-
return $this->definition['metadata']['signatureVersion'] ?: 'v4';
|
228 |
-
}
|
229 |
-
|
230 |
-
/**
|
231 |
-
* Get the protocol used by the service.
|
232 |
-
*
|
233 |
-
* @return string
|
234 |
-
*/
|
235 |
-
public function getProtocol()
|
236 |
-
{
|
237 |
-
return $this->definition['metadata']['protocol'];
|
238 |
-
}
|
239 |
-
|
240 |
-
/**
|
241 |
-
* Get the uid string used by the service
|
242 |
-
*
|
243 |
-
* @return string
|
244 |
-
*/
|
245 |
-
public function getUid()
|
246 |
-
{
|
247 |
-
return $this->definition['metadata']['uid'];
|
248 |
-
}
|
249 |
-
|
250 |
-
/**
|
251 |
-
* Check if the description has a specific operation by name.
|
252 |
-
*
|
253 |
-
* @param string $name Operation to check by name
|
254 |
-
*
|
255 |
-
* @return bool
|
256 |
-
*/
|
257 |
-
public function hasOperation($name)
|
258 |
-
{
|
259 |
-
return isset($this['operations'][$name]);
|
260 |
-
}
|
261 |
-
|
262 |
-
/**
|
263 |
-
* Get an operation by name.
|
264 |
-
*
|
265 |
-
* @param string $name Operation to retrieve by name
|
266 |
-
*
|
267 |
-
* @return Operation
|
268 |
-
* @throws \InvalidArgumentException If the operation is not found
|
269 |
-
*/
|
270 |
-
public function getOperation($name)
|
271 |
-
{
|
272 |
-
if (!isset($this->operations[$name])) {
|
273 |
-
if (!isset($this->definition['operations'][$name])) {
|
274 |
-
throw new \InvalidArgumentException("Unknown operation: $name");
|
275 |
-
}
|
276 |
-
$this->operations[$name] = new Operation(
|
277 |
-
$this->definition['operations'][$name],
|
278 |
-
$this->shapeMap
|
279 |
-
);
|
280 |
-
}
|
281 |
-
|
282 |
-
return $this->operations[$name];
|
283 |
-
}
|
284 |
-
|
285 |
-
/**
|
286 |
-
* Get all of the operations of the description.
|
287 |
-
*
|
288 |
-
* @return Operation[]
|
289 |
-
*/
|
290 |
-
public function getOperations()
|
291 |
-
{
|
292 |
-
$result = [];
|
293 |
-
foreach ($this->definition['operations'] as $name => $definition) {
|
294 |
-
$result[$name] = $this->getOperation($name);
|
295 |
-
}
|
296 |
-
|
297 |
-
return $result;
|
298 |
-
}
|
299 |
-
|
300 |
-
/**
|
301 |
-
* Get all of the service metadata or a specific metadata key value.
|
302 |
-
*
|
303 |
-
* @param string|null $key Key to retrieve or null to retrieve all metadata
|
304 |
-
*
|
305 |
-
* @return mixed Returns the result or null if the key is not found
|
306 |
-
*/
|
307 |
-
public function getMetadata($key = null)
|
308 |
-
{
|
309 |
-
if (!$key) {
|
310 |
-
return $this['metadata'];
|
311 |
-
}
|
312 |
-
|
313 |
-
if (isset($this->definition['metadata'][$key])) {
|
314 |
-
return $this->definition['metadata'][$key];
|
315 |
-
}
|
316 |
-
|
317 |
-
return null;
|
318 |
-
}
|
319 |
-
|
320 |
-
/**
|
321 |
-
* Gets an associative array of available paginator configurations where
|
322 |
-
* the key is the name of the paginator, and the value is the paginator
|
323 |
-
* configuration.
|
324 |
-
*
|
325 |
-
* @return array
|
326 |
-
* @unstable The configuration format of paginators may change in the future
|
327 |
-
*/
|
328 |
-
public function getPaginators()
|
329 |
-
{
|
330 |
-
if (!isset($this->paginators)) {
|
331 |
-
$res = call_user_func(
|
332 |
-
$this->apiProvider,
|
333 |
-
'paginator',
|
334 |
-
$this->serviceName,
|
335 |
-
$this->apiVersion
|
336 |
-
);
|
337 |
-
$this->paginators = isset($res['pagination'])
|
338 |
-
? $res['pagination']
|
339 |
-
: [];
|
340 |
-
}
|
341 |
-
|
342 |
-
return $this->paginators;
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Determines if the service has a paginator by name.
|
347 |
-
*
|
348 |
-
* @param string $name Name of the paginator.
|
349 |
-
*
|
350 |
-
* @return bool
|
351 |
-
*/
|
352 |
-
public function hasPaginator($name)
|
353 |
-
{
|
354 |
-
return isset($this->getPaginators()[$name]);
|
355 |
-
}
|
356 |
-
|
357 |
-
/**
|
358 |
-
* Retrieve a paginator by name.
|
359 |
-
*
|
360 |
-
* @param string $name Paginator to retrieve by name. This argument is
|
361 |
-
* typically the operation name.
|
362 |
-
* @return array
|
363 |
-
* @throws \UnexpectedValueException if the paginator does not exist.
|
364 |
-
* @unstable The configuration format of paginators may change in the future
|
365 |
-
*/
|
366 |
-
public function getPaginatorConfig($name)
|
367 |
-
{
|
368 |
-
static $defaults = [
|
369 |
-
'input_token' => null,
|
370 |
-
'output_token' => null,
|
371 |
-
'limit_key' => null,
|
372 |
-
'result_key' => null,
|
373 |
-
'more_results' => null,
|
374 |
-
];
|
375 |
-
|
376 |
-
if ($this->hasPaginator($name)) {
|
377 |
-
return $this->paginators[$name] + $defaults;
|
378 |
-
}
|
379 |
-
|
380 |
-
throw new \UnexpectedValueException("There is no {$name} "
|
381 |
-
. "paginator defined for the {$this->serviceName} service.");
|
382 |
-
}
|
383 |
-
|
384 |
-
/**
|
385 |
-
* Gets an associative array of available waiter configurations where the
|
386 |
-
* key is the name of the waiter, and the value is the waiter
|
387 |
-
* configuration.
|
388 |
-
*
|
389 |
-
* @return array
|
390 |
-
*/
|
391 |
-
public function getWaiters()
|
392 |
-
{
|
393 |
-
if (!isset($this->waiters)) {
|
394 |
-
$res = call_user_func(
|
395 |
-
$this->apiProvider,
|
396 |
-
'waiter',
|
397 |
-
$this->serviceName,
|
398 |
-
$this->apiVersion
|
399 |
-
);
|
400 |
-
$this->waiters = isset($res['waiters'])
|
401 |
-
? $res['waiters']
|
402 |
-
: [];
|
403 |
-
}
|
404 |
-
|
405 |
-
return $this->waiters;
|
406 |
-
}
|
407 |
-
|
408 |
-
/**
|
409 |
-
* Determines if the service has a waiter by name.
|
410 |
-
*
|
411 |
-
* @param string $name Name of the waiter.
|
412 |
-
*
|
413 |
-
* @return bool
|
414 |
-
*/
|
415 |
-
public function hasWaiter($name)
|
416 |
-
{
|
417 |
-
return isset($this->getWaiters()[$name]);
|
418 |
-
}
|
419 |
-
|
420 |
-
/**
|
421 |
-
* Get a waiter configuration by name.
|
422 |
-
*
|
423 |
-
* @param string $name Name of the waiter by name.
|
424 |
-
*
|
425 |
-
* @return array
|
426 |
-
* @throws \UnexpectedValueException if the waiter does not exist.
|
427 |
-
*/
|
428 |
-
public function getWaiterConfig($name)
|
429 |
-
{
|
430 |
-
// Error if the waiter is not defined
|
431 |
-
if ($this->hasWaiter($name)) {
|
432 |
-
return $this->waiters[$name];
|
433 |
-
}
|
434 |
-
|
435 |
-
throw new \UnexpectedValueException("There is no {$name} waiter "
|
436 |
-
. "defined for the {$this->serviceName} service.");
|
437 |
-
}
|
438 |
-
|
439 |
-
/**
|
440 |
-
* Get the shape map used by the API.
|
441 |
-
*
|
442 |
-
* @return ShapeMap
|
443 |
-
*/
|
444 |
-
public function getShapeMap()
|
445 |
-
{
|
446 |
-
return $this->shapeMap;
|
447 |
-
}
|
448 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Api/ShapeMap.php
DELETED
@@ -1,66 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Api;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Builds shape based on shape references.
|
6 |
-
*/
|
7 |
-
class ShapeMap
|
8 |
-
{
|
9 |
-
/** @var array */
|
10 |
-
private $definitions;
|
11 |
-
|
12 |
-
/** @var Shape[] */
|
13 |
-
private $simple;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @param array $shapeModels Associative array of shape definitions.
|
17 |
-
*/
|
18 |
-
public function __construct(array $shapeModels)
|
19 |
-
{
|
20 |
-
$this->definitions = $shapeModels;
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Get an array of shape names.
|
25 |
-
*
|
26 |
-
* @return array
|
27 |
-
*/
|
28 |
-
public function getShapeNames()
|
29 |
-
{
|
30 |
-
return array_keys($this->definitions);
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Resolve a shape reference
|
35 |
-
*
|
36 |
-
* @param array $shapeRef Shape reference shape
|
37 |
-
*
|
38 |
-
* @return Shape
|
39 |
-
* @throws \InvalidArgumentException
|
40 |
-
*/
|
41 |
-
public function resolve(array $shapeRef)
|
42 |
-
{
|
43 |
-
$shape = $shapeRef['shape'];
|
44 |
-
|
45 |
-
if (!isset($this->definitions[$shape])) {
|
46 |
-
throw new \InvalidArgumentException('Shape not found: ' . $shape);
|
47 |
-
}
|
48 |
-
|
49 |
-
$isSimple = count($shapeRef) == 1;
|
50 |
-
if ($isSimple && isset($this->simple[$shape])) {
|
51 |
-
return $this->simple[$shape];
|
52 |
-
}
|
53 |
-
|
54 |
-
$definition = $shapeRef + $this->definitions[$shape];
|
55 |
-
$definition['name'] = $definition['shape'];
|
56 |
-
unset($definition['shape']);
|
57 |
-
|
58 |
-
$result = Shape::create($definition, $this);
|
59 |
-
|
60 |
-
if ($isSimple) {
|
61 |
-
$this->simple[$shape] = $result;
|
62 |
-
}
|
63 |
-
|
64 |
-
return $result;
|
65 |
-
}
|
66 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/AwsClient.php
DELETED
@@ -1,402 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Api\ApiProvider;
|
5 |
-
use Aws\Api\DocModel;
|
6 |
-
use Aws\Api\Service;
|
7 |
-
use Aws\ClientSideMonitoring\ApiCallAttemptMonitoringMiddleware;
|
8 |
-
use Aws\ClientSideMonitoring\ApiCallMonitoringMiddleware;
|
9 |
-
use Aws\ClientSideMonitoring\ConfigurationProvider;
|
10 |
-
use Aws\EndpointDiscovery\EndpointDiscoveryMiddleware;
|
11 |
-
use Aws\Signature\SignatureProvider;
|
12 |
-
use GuzzleHttp\Psr7\Uri;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Default AWS client implementation
|
16 |
-
*/
|
17 |
-
class AwsClient implements AwsClientInterface
|
18 |
-
{
|
19 |
-
use AwsClientTrait;
|
20 |
-
|
21 |
-
/** @var array */
|
22 |
-
private $config;
|
23 |
-
|
24 |
-
/** @var string */
|
25 |
-
private $region;
|
26 |
-
|
27 |
-
/** @var string */
|
28 |
-
private $endpoint;
|
29 |
-
|
30 |
-
/** @var Service */
|
31 |
-
private $api;
|
32 |
-
|
33 |
-
/** @var callable */
|
34 |
-
private $signatureProvider;
|
35 |
-
|
36 |
-
/** @var callable */
|
37 |
-
private $credentialProvider;
|
38 |
-
|
39 |
-
/** @var HandlerList */
|
40 |
-
private $handlerList;
|
41 |
-
|
42 |
-
/** @var array*/
|
43 |
-
private $defaultRequestOptions;
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Get an array of client constructor arguments used by the client.
|
47 |
-
*
|
48 |
-
* @return array
|
49 |
-
*/
|
50 |
-
public static function getArguments()
|
51 |
-
{
|
52 |
-
return ClientResolver::getDefaultArguments();
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* The client constructor accepts the following options:
|
57 |
-
*
|
58 |
-
* - api_provider: (callable) An optional PHP callable that accepts a
|
59 |
-
* type, service, and version argument, and returns an array of
|
60 |
-
* corresponding configuration data. The type value can be one of api,
|
61 |
-
* waiter, or paginator.
|
62 |
-
* - credentials:
|
63 |
-
* (Aws\Credentials\CredentialsInterface|array|bool|callable) Specifies
|
64 |
-
* the credentials used to sign requests. Provide an
|
65 |
-
* Aws\Credentials\CredentialsInterface object, an associative array of
|
66 |
-
* "key", "secret", and an optional "token" key, `false` to use null
|
67 |
-
* credentials, or a callable credentials provider used to create
|
68 |
-
* credentials or return null. See Aws\Credentials\CredentialProvider for
|
69 |
-
* a list of built-in credentials providers. If no credentials are
|
70 |
-
* provided, the SDK will attempt to load them from the environment.
|
71 |
-
* - debug: (bool|array) Set to true to display debug information when
|
72 |
-
* sending requests. Alternatively, you can provide an associative array
|
73 |
-
* with the following keys: logfn: (callable) Function that is invoked
|
74 |
-
* with log messages; stream_size: (int) When the size of a stream is
|
75 |
-
* greater than this number, the stream data will not be logged (set to
|
76 |
-
* "0" to not log any stream data); scrub_auth: (bool) Set to false to
|
77 |
-
* disable the scrubbing of auth data from the logged messages; http:
|
78 |
-
* (bool) Set to false to disable the "debug" feature of lower level HTTP
|
79 |
-
* adapters (e.g., verbose curl output).
|
80 |
-
* - stats: (bool|array) Set to true to gather transfer statistics on
|
81 |
-
* requests sent. Alternatively, you can provide an associative array with
|
82 |
-
* the following keys: retries: (bool) Set to false to disable reporting
|
83 |
-
* on retries attempted; http: (bool) Set to true to enable collecting
|
84 |
-
* statistics from lower level HTTP adapters (e.g., values returned in
|
85 |
-
* GuzzleHttp\TransferStats). HTTP handlers must support an
|
86 |
-
* `http_stats_receiver` option for this to have an effect; timer: (bool)
|
87 |
-
* Set to true to enable a command timer that reports the total wall clock
|
88 |
-
* time spent on an operation in seconds.
|
89 |
-
* - disable_host_prefix_injection: (bool) Set to true to disable host prefix
|
90 |
-
* injection logic for services that use it. This disables the entire
|
91 |
-
* prefix injection, including the portions supplied by user-defined
|
92 |
-
* parameters. Setting this flag will have no effect on services that do
|
93 |
-
* not use host prefix injection.
|
94 |
-
* - endpoint: (string) The full URI of the webservice. This is only
|
95 |
-
* required when connecting to a custom endpoint (e.g., a local version
|
96 |
-
* of S3).
|
97 |
-
* - endpoint_discovery: (Aws\EndpointDiscovery\ConfigurationInterface,
|
98 |
-
* Aws\CacheInterface, array, callable) Settings for endpoint discovery.
|
99 |
-
* Provide an instance of Aws\EndpointDiscovery\ConfigurationInterface,
|
100 |
-
* an instance Aws\CacheInterface, a callable that provides a promise for
|
101 |
-
* a Configuration object, or an associative array with the following
|
102 |
-
* keys: enabled: (bool) Set to true to enable endpoint discovery,
|
103 |
-
* defaults to false; cache_limit: (int) The maximum number of keys in the
|
104 |
-
* endpoints cache, defaults to 1000.
|
105 |
-
* - endpoint_provider: (callable) An optional PHP callable that
|
106 |
-
* accepts a hash of options including a "service" and "region" key and
|
107 |
-
* returns NULL or a hash of endpoint data, of which the "endpoint" key
|
108 |
-
* is required. See Aws\Endpoint\EndpointProvider for a list of built-in
|
109 |
-
* providers.
|
110 |
-
* - handler: (callable) A handler that accepts a command object,
|
111 |
-
* request object and returns a promise that is fulfilled with an
|
112 |
-
* Aws\ResultInterface object or rejected with an
|
113 |
-
* Aws\Exception\AwsException. A handler does not accept a next handler
|
114 |
-
* as it is terminal and expected to fulfill a command. If no handler is
|
115 |
-
* provided, a default Guzzle handler will be utilized.
|
116 |
-
* - http: (array, default=array(0)) Set to an array of SDK request
|
117 |
-
* options to apply to each request (e.g., proxy, verify, etc.).
|
118 |
-
* - http_handler: (callable) An HTTP handler is a function that
|
119 |
-
* accepts a PSR-7 request object and returns a promise that is fulfilled
|
120 |
-
* with a PSR-7 response object or rejected with an array of exception
|
121 |
-
* data. NOTE: This option supersedes any provided "handler" option.
|
122 |
-
* - idempotency_auto_fill: (bool|callable) Set to false to disable SDK to
|
123 |
-
* populate parameters that enabled 'idempotencyToken' trait with a random
|
124 |
-
* UUID v4 value on your behalf. Using default value 'true' still allows
|
125 |
-
* parameter value to be overwritten when provided. Note: auto-fill only
|
126 |
-
* works when cryptographically secure random bytes generator functions
|
127 |
-
* (random_bytes, openssl_random_pseudo_bytes or mcrypt_create_iv) can be
|
128 |
-
* found. You may also provide a callable source of random bytes.
|
129 |
-
* - profile: (string) Allows you to specify which profile to use when
|
130 |
-
* credentials are created from the AWS credentials file in your HOME
|
131 |
-
* directory. This setting overrides the AWS_PROFILE environment
|
132 |
-
* variable. Note: Specifying "profile" will cause the "credentials" key
|
133 |
-
* to be ignored.
|
134 |
-
* - region: (string, required) Region to connect to. See
|
135 |
-
* http://docs.aws.amazon.com/general/latest/gr/rande.html for a list of
|
136 |
-
* available regions.
|
137 |
-
* - retries: (int, default=int(3)) Configures the maximum number of
|
138 |
-
* allowed retries for a client (pass 0 to disable retries).
|
139 |
-
* - scheme: (string, default=string(5) "https") URI scheme to use when
|
140 |
-
* connecting connect. The SDK will utilize "https" endpoints (i.e.,
|
141 |
-
* utilize SSL/TLS connections) by default. You can attempt to connect to
|
142 |
-
* a service over an unencrypted "http" endpoint by setting ``scheme`` to
|
143 |
-
* "http".
|
144 |
-
* - signature_provider: (callable) A callable that accepts a signature
|
145 |
-
* version name (e.g., "v4"), a service name, and region, and
|
146 |
-
* returns a SignatureInterface object or null. This provider is used to
|
147 |
-
* create signers utilized by the client. See
|
148 |
-
* Aws\Signature\SignatureProvider for a list of built-in providers
|
149 |
-
* - signature_version: (string) A string representing a custom
|
150 |
-
* signature version to use with a service (e.g., v4). Note that
|
151 |
-
* per/operation signature version MAY override this requested signature
|
152 |
-
* version.
|
153 |
-
* - validate: (bool, default=bool(true)) Set to false to disable
|
154 |
-
* client-side parameter validation.
|
155 |
-
* - version: (string, required) The version of the webservice to
|
156 |
-
* utilize (e.g., 2006-03-01).
|
157 |
-
*
|
158 |
-
* @param array $args Client configuration arguments.
|
159 |
-
*
|
160 |
-
* @throws \InvalidArgumentException if any required options are missing or
|
161 |
-
* the service is not supported.
|
162 |
-
*/
|
163 |
-
public function __construct(array $args)
|
164 |
-
{
|
165 |
-
list($service, $exceptionClass) = $this->parseClass();
|
166 |
-
if (!isset($args['service'])) {
|
167 |
-
$args['service'] = manifest($service)['endpoint'];
|
168 |
-
}
|
169 |
-
if (!isset($args['exception_class'])) {
|
170 |
-
$args['exception_class'] = $exceptionClass;
|
171 |
-
}
|
172 |
-
$this->handlerList = new HandlerList();
|
173 |
-
$resolver = new ClientResolver(static::getArguments());
|
174 |
-
$config = $resolver->resolve($args, $this->handlerList);
|
175 |
-
$this->api = $config['api'];
|
176 |
-
$this->signatureProvider = $config['signature_provider'];
|
177 |
-
$this->endpoint = new Uri($config['endpoint']);
|
178 |
-
$this->credentialProvider = $config['credentials'];
|
179 |
-
$this->region = isset($config['region']) ? $config['region'] : null;
|
180 |
-
$this->config = $config['config'];
|
181 |
-
$this->defaultRequestOptions = $config['http'];
|
182 |
-
$this->addSignatureMiddleware();
|
183 |
-
$this->addInvocationId();
|
184 |
-
$this->addClientSideMonitoring($args);
|
185 |
-
$this->addEndpointParameterMiddleware($args);
|
186 |
-
$this->addEndpointDiscoveryMiddleware($config, $args);
|
187 |
-
|
188 |
-
if (isset($args['with_resolved'])) {
|
189 |
-
$args['with_resolved']($config);
|
190 |
-
}
|
191 |
-
}
|
192 |
-
|
193 |
-
public function getHandlerList()
|
194 |
-
{
|
195 |
-
return $this->handlerList;
|
196 |
-
}
|
197 |
-
|
198 |
-
public function getConfig($option = null)
|
199 |
-
{
|
200 |
-
return $option === null
|
201 |
-
? $this->config
|
202 |
-
: (isset($this->config[$option])
|
203 |
-
? $this->config[$option]
|
204 |
-
: null);
|
205 |
-
}
|
206 |
-
|
207 |
-
public function getCredentials()
|
208 |
-
{
|
209 |
-
$fn = $this->credentialProvider;
|
210 |
-
return $fn();
|
211 |
-
}
|
212 |
-
|
213 |
-
public function getEndpoint()
|
214 |
-
{
|
215 |
-
return $this->endpoint;
|
216 |
-
}
|
217 |
-
|
218 |
-
public function getRegion()
|
219 |
-
{
|
220 |
-
return $this->region;
|
221 |
-
}
|
222 |
-
|
223 |
-
public function getApi()
|
224 |
-
{
|
225 |
-
return $this->api;
|
226 |
-
}
|
227 |
-
|
228 |
-
public function getCommand($name, array $args = [])
|
229 |
-
{
|
230 |
-
// Fail fast if the command cannot be found in the description.
|
231 |
-
if (!isset($this->getApi()['operations'][$name])) {
|
232 |
-
$name = ucfirst($name);
|
233 |
-
if (!isset($this->getApi()['operations'][$name])) {
|
234 |
-
throw new \InvalidArgumentException("Operation not found: $name");
|
235 |
-
}
|
236 |
-
}
|
237 |
-
|
238 |
-
if (!isset($args['@http'])) {
|
239 |
-
$args['@http'] = $this->defaultRequestOptions;
|
240 |
-
} else {
|
241 |
-
$args['@http'] += $this->defaultRequestOptions;
|
242 |
-
}
|
243 |
-
|
244 |
-
return new Command($name, $args, clone $this->getHandlerList());
|
245 |
-
}
|
246 |
-
|
247 |
-
public function __sleep()
|
248 |
-
{
|
249 |
-
throw new \RuntimeException('Instances of ' . static::class
|
250 |
-
. ' cannot be serialized');
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* Get the signature_provider function of the client.
|
255 |
-
*
|
256 |
-
* @return callable
|
257 |
-
*/
|
258 |
-
final protected function getSignatureProvider()
|
259 |
-
{
|
260 |
-
return $this->signatureProvider;
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* Parse the class name and setup the custom exception class of the client
|
265 |
-
* and return the "service" name of the client and "exception_class".
|
266 |
-
*
|
267 |
-
* @return array
|
268 |
-
*/
|
269 |
-
private function parseClass()
|
270 |
-
{
|
271 |
-
$klass = get_class($this);
|
272 |
-
|
273 |
-
if ($klass === __CLASS__) {
|
274 |
-
return ['', 'Aws\Exception\AwsException'];
|
275 |
-
}
|
276 |
-
|
277 |
-
$service = substr($klass, strrpos($klass, '\\') + 1, -6);
|
278 |
-
|
279 |
-
return [
|
280 |
-
strtolower($service),
|
281 |
-
"Aws\\{$service}\\Exception\\{$service}Exception"
|
282 |
-
];
|
283 |
-
}
|
284 |
-
|
285 |
-
private function addEndpointParameterMiddleware($args)
|
286 |
-
{
|
287 |
-
if (empty($args['disable_host_prefix_injection'])) {
|
288 |
-
$list = $this->getHandlerList();
|
289 |
-
$list->appendBuild(
|
290 |
-
EndpointParameterMiddleware::wrap(
|
291 |
-
$this->api
|
292 |
-
),
|
293 |
-
'endpoint_parameter'
|
294 |
-
);
|
295 |
-
}
|
296 |
-
}
|
297 |
-
|
298 |
-
private function addEndpointDiscoveryMiddleware($config, $args)
|
299 |
-
{
|
300 |
-
$list = $this->getHandlerList();
|
301 |
-
|
302 |
-
if (!isset($args['endpoint'])) {
|
303 |
-
$list->appendBuild(
|
304 |
-
EndpointDiscoveryMiddleware::wrap(
|
305 |
-
$this,
|
306 |
-
$args,
|
307 |
-
$config['endpoint_discovery']
|
308 |
-
),
|
309 |
-
'EndpointDiscoveryMiddleware'
|
310 |
-
);
|
311 |
-
}
|
312 |
-
}
|
313 |
-
|
314 |
-
private function addSignatureMiddleware()
|
315 |
-
{
|
316 |
-
$api = $this->getApi();
|
317 |
-
$provider = $this->signatureProvider;
|
318 |
-
$version = $this->config['signature_version'];
|
319 |
-
$name = $this->config['signing_name'];
|
320 |
-
$region = $this->config['signing_region'];
|
321 |
-
|
322 |
-
$resolver = static function (
|
323 |
-
CommandInterface $c
|
324 |
-
) use ($api, $provider, $name, $region, $version) {
|
325 |
-
$authType = $api->getOperation($c->getName())['authtype'];
|
326 |
-
switch ($authType){
|
327 |
-
case 'none':
|
328 |
-
$version = 'anonymous';
|
329 |
-
break;
|
330 |
-
case 'v4-unsigned-body':
|
331 |
-
$version = 'v4-unsigned-body';
|
332 |
-
break;
|
333 |
-
}
|
334 |
-
return SignatureProvider::resolve($provider, $version, $name, $region);
|
335 |
-
};
|
336 |
-
$this->handlerList->appendSign(
|
337 |
-
Middleware::signer($this->credentialProvider, $resolver),
|
338 |
-
'signer'
|
339 |
-
);
|
340 |
-
}
|
341 |
-
|
342 |
-
private function addInvocationId()
|
343 |
-
{
|
344 |
-
// Add invocation id to each request
|
345 |
-
$this->handlerList->prependSign(Middleware::invocationId(), 'invocation-id');
|
346 |
-
}
|
347 |
-
|
348 |
-
private function addClientSideMonitoring($args)
|
349 |
-
{
|
350 |
-
$options = ConfigurationProvider::defaultProvider($args);
|
351 |
-
|
352 |
-
$this->handlerList->appendBuild(
|
353 |
-
ApiCallMonitoringMiddleware::wrap(
|
354 |
-
$this->credentialProvider,
|
355 |
-
$options,
|
356 |
-
$this->region,
|
357 |
-
$this->getApi()->getServiceId()
|
358 |
-
),
|
359 |
-
'ApiCallMonitoringMiddleware'
|
360 |
-
);
|
361 |
-
|
362 |
-
$callAttemptMiddleware = ApiCallAttemptMonitoringMiddleware::wrap(
|
363 |
-
$this->credentialProvider,
|
364 |
-
$options,
|
365 |
-
$this->region,
|
366 |
-
$this->getApi()->getServiceId()
|
367 |
-
);
|
368 |
-
$this->handlerList->appendAttempt (
|
369 |
-
$callAttemptMiddleware,
|
370 |
-
'ApiCallAttemptMonitoringMiddleware'
|
371 |
-
);
|
372 |
-
}
|
373 |
-
|
374 |
-
/**
|
375 |
-
* Returns a service model and doc model with any necessary changes
|
376 |
-
* applied.
|
377 |
-
*
|
378 |
-
* @param array $api Array of service data being documented.
|
379 |
-
* @param array $docs Array of doc model data.
|
380 |
-
*
|
381 |
-
* @return array Tuple containing a [Service, DocModel]
|
382 |
-
*
|
383 |
-
* @internal This should only used to document the service API.
|
384 |
-
* @codeCoverageIgnore
|
385 |
-
*/
|
386 |
-
public static function applyDocFilters(array $api, array $docs)
|
387 |
-
{
|
388 |
-
return [
|
389 |
-
new Service($api, ApiProvider::defaultProvider()),
|
390 |
-
new DocModel($docs)
|
391 |
-
];
|
392 |
-
}
|
393 |
-
|
394 |
-
/**
|
395 |
-
* @deprecated
|
396 |
-
* @return static
|
397 |
-
*/
|
398 |
-
public static function factory(array $config = [])
|
399 |
-
{
|
400 |
-
return new static($config);
|
401 |
-
}
|
402 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/AwsClientTrait.php
DELETED
@@ -1,92 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Api\Service;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* A trait providing generic functionality for interacting with Amazon Web
|
8 |
-
* Services. This is meant to be used in classes implementing
|
9 |
-
* \Aws\AwsClientInterface
|
10 |
-
*/
|
11 |
-
trait AwsClientTrait
|
12 |
-
{
|
13 |
-
public function getPaginator($name, array $args = [])
|
14 |
-
{
|
15 |
-
$config = $this->getApi()->getPaginatorConfig($name);
|
16 |
-
|
17 |
-
return new ResultPaginator($this, $name, $args, $config);
|
18 |
-
}
|
19 |
-
|
20 |
-
public function getIterator($name, array $args = [])
|
21 |
-
{
|
22 |
-
$config = $this->getApi()->getPaginatorConfig($name);
|
23 |
-
if (!$config['result_key']) {
|
24 |
-
throw new \UnexpectedValueException(sprintf(
|
25 |
-
'There are no resources to iterate for the %s operation of %s',
|
26 |
-
$name, $this->getApi()['serviceFullName']
|
27 |
-
));
|
28 |
-
}
|
29 |
-
|
30 |
-
$key = is_array($config['result_key'])
|
31 |
-
? $config['result_key'][0]
|
32 |
-
: $config['result_key'];
|
33 |
-
|
34 |
-
if ($config['output_token'] && $config['input_token']) {
|
35 |
-
return $this->getPaginator($name, $args)->search($key);
|
36 |
-
}
|
37 |
-
|
38 |
-
$result = $this->execute($this->getCommand($name, $args))->search($key);
|
39 |
-
|
40 |
-
return new \ArrayIterator((array) $result);
|
41 |
-
}
|
42 |
-
|
43 |
-
public function waitUntil($name, array $args = [])
|
44 |
-
{
|
45 |
-
return $this->getWaiter($name, $args)->promise()->wait();
|
46 |
-
}
|
47 |
-
|
48 |
-
public function getWaiter($name, array $args = [])
|
49 |
-
{
|
50 |
-
$config = isset($args['@waiter']) ? $args['@waiter'] : [];
|
51 |
-
$config += $this->getApi()->getWaiterConfig($name);
|
52 |
-
|
53 |
-
return new Waiter($this, $name, $args, $config);
|
54 |
-
}
|
55 |
-
|
56 |
-
public function execute(CommandInterface $command)
|
57 |
-
{
|
58 |
-
return $this->executeAsync($command)->wait();
|
59 |
-
}
|
60 |
-
|
61 |
-
public function executeAsync(CommandInterface $command)
|
62 |
-
{
|
63 |
-
$handler = $command->getHandlerList()->resolve();
|
64 |
-
return $handler($command);
|
65 |
-
}
|
66 |
-
|
67 |
-
public function __call($name, array $args)
|
68 |
-
{
|
69 |
-
$params = isset($args[0]) ? $args[0] : [];
|
70 |
-
|
71 |
-
if (substr($name, -5) === 'Async') {
|
72 |
-
return $this->executeAsync(
|
73 |
-
$this->getCommand(substr($name, 0, -5), $params)
|
74 |
-
);
|
75 |
-
}
|
76 |
-
|
77 |
-
return $this->execute($this->getCommand($name, $params));
|
78 |
-
}
|
79 |
-
|
80 |
-
/**
|
81 |
-
* @param string $name
|
82 |
-
* @param array $args
|
83 |
-
*
|
84 |
-
* @return CommandInterface
|
85 |
-
*/
|
86 |
-
abstract public function getCommand($name, array $args = []);
|
87 |
-
|
88 |
-
/**
|
89 |
-
* @return Service
|
90 |
-
*/
|
91 |
-
abstract public function getApi();
|
92 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/ClientResolver.php
DELETED
@@ -1,768 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Api\Validator;
|
5 |
-
use Aws\Api\ApiProvider;
|
6 |
-
use Aws\Api\Service;
|
7 |
-
use Aws\Credentials\Credentials;
|
8 |
-
use Aws\Credentials\CredentialsInterface;
|
9 |
-
use Aws\Endpoint\PartitionEndpointProvider;
|
10 |
-
use Aws\EndpointDiscovery\ConfigurationInterface;
|
11 |
-
use Aws\EndpointDiscovery\ConfigurationProvider;
|
12 |
-
use Aws\EndpointDiscovery\EndpointDiscoveryMiddleware;
|
13 |
-
use Aws\Signature\SignatureProvider;
|
14 |
-
use Aws\Endpoint\EndpointProvider;
|
15 |
-
use Aws\Credentials\CredentialProvider;
|
16 |
-
use InvalidArgumentException as IAE;
|
17 |
-
use Psr\Http\Message\RequestInterface;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @internal Resolves a hash of client arguments to construct a client.
|
21 |
-
*/
|
22 |
-
class ClientResolver
|
23 |
-
{
|
24 |
-
/** @var array */
|
25 |
-
private $argDefinitions;
|
26 |
-
|
27 |
-
/** @var array Map of types to a corresponding function */
|
28 |
-
private static $typeMap = [
|
29 |
-
'resource' => 'is_resource',
|
30 |
-
'callable' => 'is_callable',
|
31 |
-
'int' => 'is_int',
|
32 |
-
'bool' => 'is_bool',
|
33 |
-
'string' => 'is_string',
|
34 |
-
'object' => 'is_object',
|
35 |
-
'array' => 'is_array',
|
36 |
-
];
|
37 |
-
|
38 |
-
private static $defaultArgs = [
|
39 |
-
'service' => [
|
40 |
-
'type' => 'value',
|
41 |
-
'valid' => ['string'],
|
42 |
-
'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).',
|
43 |
-
'required' => true,
|
44 |
-
'internal' => true
|
45 |
-
],
|
46 |
-
'exception_class' => [
|
47 |
-
'type' => 'value',
|
48 |
-
'valid' => ['string'],
|
49 |
-
'doc' => 'Exception class to create when an error occurs.',
|
50 |
-
'default' => 'Aws\Exception\AwsException',
|
51 |
-
'internal' => true
|
52 |
-
],
|
53 |
-
'scheme' => [
|
54 |
-
'type' => 'value',
|
55 |
-
'valid' => ['string'],
|
56 |
-
'default' => 'https',
|
57 |
-
'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".',
|
58 |
-
],
|
59 |
-
'disable_host_prefix_injection' => [
|
60 |
-
'type' => 'value',
|
61 |
-
'valid' => ['bool'],
|
62 |
-
'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.',
|
63 |
-
'default' => false,
|
64 |
-
],
|
65 |
-
'endpoint' => [
|
66 |
-
'type' => 'value',
|
67 |
-
'valid' => ['string'],
|
68 |
-
'doc' => 'The full URI of the webservice. This is only required when connecting to a custom endpoint (e.g., a local version of S3).',
|
69 |
-
'fn' => [__CLASS__, '_apply_endpoint'],
|
70 |
-
],
|
71 |
-
'region' => [
|
72 |
-
'type' => 'value',
|
73 |
-
'valid' => ['string'],
|
74 |
-
'required' => [__CLASS__, '_missing_region'],
|
75 |
-
'doc' => 'Region to connect to. See http://docs.aws.amazon.com/general/latest/gr/rande.html for a list of available regions.',
|
76 |
-
],
|
77 |
-
'version' => [
|
78 |
-
'type' => 'value',
|
79 |
-
'valid' => ['string'],
|
80 |
-
'required' => [__CLASS__, '_missing_version'],
|
81 |
-
'doc' => 'The version of the webservice to utilize (e.g., 2006-03-01).',
|
82 |
-
],
|
83 |
-
'signature_provider' => [
|
84 |
-
'type' => 'value',
|
85 |
-
'valid' => ['callable'],
|
86 |
-
'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',
|
87 |
-
'default' => [__CLASS__, '_default_signature_provider'],
|
88 |
-
],
|
89 |
-
'api_provider' => [
|
90 |
-
'type' => 'value',
|
91 |
-
'valid' => ['callable'],
|
92 |
-
'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.',
|
93 |
-
'fn' => [__CLASS__, '_apply_api_provider'],
|
94 |
-
'default' => [ApiProvider::class, 'defaultProvider'],
|
95 |
-
],
|
96 |
-
'endpoint_provider' => [
|
97 |
-
'type' => 'value',
|
98 |
-
'valid' => ['callable'],
|
99 |
-
'fn' => [__CLASS__, '_apply_endpoint_provider'],
|
100 |
-
'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.',
|
101 |
-
'default' => [__CLASS__, '_default_endpoint_provider'],
|
102 |
-
],
|
103 |
-
'serializer' => [
|
104 |
-
'default' => [__CLASS__, '_default_serializer'],
|
105 |
-
'fn' => [__CLASS__, '_apply_serializer'],
|
106 |
-
'internal' => true,
|
107 |
-
'type' => 'value',
|
108 |
-
'valid' => ['callable'],
|
109 |
-
],
|
110 |
-
'signature_version' => [
|
111 |
-
'type' => 'config',
|
112 |
-
'valid' => ['string'],
|
113 |
-
'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.',
|
114 |
-
'default' => [__CLASS__, '_default_signature_version'],
|
115 |
-
],
|
116 |
-
'signing_name' => [
|
117 |
-
'type' => 'config',
|
118 |
-
'valid' => ['string'],
|
119 |
-
'doc' => 'A string representing a custom service name to be used when calculating a request signature.',
|
120 |
-
'default' => [__CLASS__, '_default_signing_name'],
|
121 |
-
],
|
122 |
-
'signing_region' => [
|
123 |
-
'type' => 'config',
|
124 |
-
'valid' => ['string'],
|
125 |
-
'doc' => 'A string representing a custom region name to be used when calculating a request signature.',
|
126 |
-
'default' => [__CLASS__, '_default_signing_region'],
|
127 |
-
],
|
128 |
-
'profile' => [
|
129 |
-
'type' => 'config',
|
130 |
-
'valid' => ['string'],
|
131 |
-
'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" key to be ignored.',
|
132 |
-
'fn' => [__CLASS__, '_apply_profile'],
|
133 |
-
],
|
134 |
-
'credentials' => [
|
135 |
-
'type' => 'value',
|
136 |
-
'valid' => [CredentialsInterface::class, CacheInterface::class, 'array', 'bool', 'callable'],
|
137 |
-
'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.',
|
138 |
-
'fn' => [__CLASS__, '_apply_credentials'],
|
139 |
-
'default' => [CredentialProvider::class, 'defaultProvider'],
|
140 |
-
],
|
141 |
-
'endpoint_discovery' => [
|
142 |
-
'type' => 'value',
|
143 |
-
'valid' => [ConfigurationInterface::class, CacheInterface::class, 'array', 'callable'],
|
144 |
-
'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. Defaults to false; cache_limit: (int) The maximum number of keys in the endpoints cache. Defaults to 1000.',
|
145 |
-
'fn' => [__CLASS__, '_apply_endpoint_discovery'],
|
146 |
-
'default' => [__CLASS__, '_default_endpoint_discovery_provider']
|
147 |
-
],
|
148 |
-
'stats' => [
|
149 |
-
'type' => 'value',
|
150 |
-
'valid' => ['bool', 'array'],
|
151 |
-
'default' => false,
|
152 |
-
'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.',
|
153 |
-
'fn' => [__CLASS__, '_apply_stats'],
|
154 |
-
],
|
155 |
-
'retries' => [
|
156 |
-
'type' => 'value',
|
157 |
-
'valid' => ['int'],
|
158 |
-
'doc' => 'Configures the maximum number of allowed retries for a client (pass 0 to disable retries). ',
|
159 |
-
'fn' => [__CLASS__, '_apply_retries'],
|
160 |
-
'default' => 3,
|
161 |
-
],
|
162 |
-
'validate' => [
|
163 |
-
'type' => 'value',
|
164 |
-
'valid' => ['bool', 'array'],
|
165 |
-
'default' => true,
|
166 |
-
'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.',
|
167 |
-
'fn' => [__CLASS__, '_apply_validate'],
|
168 |
-
],
|
169 |
-
'debug' => [
|
170 |
-
'type' => 'value',
|
171 |
-
'valid' => ['bool', 'array'],
|
172 |
-
'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).',
|
173 |
-
'fn' => [__CLASS__, '_apply_debug'],
|
174 |
-
],
|
175 |
-
'http' => [
|
176 |
-
'type' => 'value',
|
177 |
-
'valid' => ['array'],
|
178 |
-
'default' => [],
|
179 |
-
'doc' => 'Set to an array of SDK request options to apply to each request (e.g., proxy, verify, etc.).',
|
180 |
-
],
|
181 |
-
'http_handler' => [
|
182 |
-
'type' => 'value',
|
183 |
-
'valid' => ['callable'],
|
184 |
-
'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.',
|
185 |
-
'fn' => [__CLASS__, '_apply_http_handler']
|
186 |
-
],
|
187 |
-
'handler' => [
|
188 |
-
'type' => 'value',
|
189 |
-
'valid' => ['callable'],
|
190 |
-
'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.',
|
191 |
-
'fn' => [__CLASS__, '_apply_handler'],
|
192 |
-
'default' => [__CLASS__, '_default_handler']
|
193 |
-
],
|
194 |
-
'ua_append' => [
|
195 |
-
'type' => 'value',
|
196 |
-
'valid' => ['string', 'array'],
|
197 |
-
'doc' => 'Provide a string or array of strings to send in the User-Agent header.',
|
198 |
-
'fn' => [__CLASS__, '_apply_user_agent'],
|
199 |
-
'default' => [],
|
200 |
-
],
|
201 |
-
'idempotency_auto_fill' => [
|
202 |
-
'type' => 'value',
|
203 |
-
'valid' => ['bool', 'callable'],
|
204 |
-
'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.',
|
205 |
-
'default' => true,
|
206 |
-
'fn' => [__CLASS__, '_apply_idempotency_auto_fill']
|
207 |
-
],
|
208 |
-
];
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Gets an array of default client arguments, each argument containing a
|
212 |
-
* hash of the following:
|
213 |
-
*
|
214 |
-
* - type: (string, required) option type described as follows:
|
215 |
-
* - value: The default option type.
|
216 |
-
* - config: The provided value is made available in the client's
|
217 |
-
* getConfig() method.
|
218 |
-
* - valid: (array, required) Valid PHP types or class names. Note: null
|
219 |
-
* is not an allowed type.
|
220 |
-
* - required: (bool, callable) Whether or not the argument is required.
|
221 |
-
* Provide a function that accepts an array of arguments and returns a
|
222 |
-
* string to provide a custom error message.
|
223 |
-
* - default: (mixed) The default value of the argument if not provided. If
|
224 |
-
* a function is provided, then it will be invoked to provide a default
|
225 |
-
* value. The function is provided the array of options and is expected
|
226 |
-
* to return the default value of the option. The default value can be a
|
227 |
-
* closure and can not be a callable string that is not part of the
|
228 |
-
* defaultArgs array.
|
229 |
-
* - doc: (string) The argument documentation string.
|
230 |
-
* - fn: (callable) Function used to apply the argument. The function
|
231 |
-
* accepts the provided value, array of arguments by reference, and an
|
232 |
-
* event emitter.
|
233 |
-
*
|
234 |
-
* Note: Order is honored and important when applying arguments.
|
235 |
-
*
|
236 |
-
* @return array
|
237 |
-
*/
|
238 |
-
public static function getDefaultArguments()
|
239 |
-
{
|
240 |
-
return self::$defaultArgs;
|
241 |
-
}
|
242 |
-
|
243 |
-
/**
|
244 |
-
* @param array $argDefinitions Client arguments.
|
245 |
-
*/
|
246 |
-
public function __construct(array $argDefinitions)
|
247 |
-
{
|
248 |
-
$this->argDefinitions = $argDefinitions;
|
249 |
-
}
|
250 |
-
|
251 |
-
/**
|
252 |
-
* Resolves client configuration options and attached event listeners.
|
253 |
-
* Check for missing keys in passed arguments
|
254 |
-
*
|
255 |
-
* @param array $args Provided constructor arguments.
|
256 |
-
* @param HandlerList $list Handler list to augment.
|
257 |
-
*
|
258 |
-
* @return array Returns the array of provided options.
|
259 |
-
* @throws \InvalidArgumentException
|
260 |
-
* @see Aws\AwsClient::__construct for a list of available options.
|
261 |
-
*/
|
262 |
-
public function resolve(array $args, HandlerList $list)
|
263 |
-
{
|
264 |
-
$args['config'] = [];
|
265 |
-
foreach ($this->argDefinitions as $key => $a) {
|
266 |
-
// Add defaults, validate required values, and skip if not set.
|
267 |
-
if (!isset($args[$key])) {
|
268 |
-
if (isset($a['default'])) {
|
269 |
-
// Merge defaults in when not present.
|
270 |
-
if (is_callable($a['default'])
|
271 |
-
&& (
|
272 |
-
is_array($a['default'])
|
273 |
-
|| $a['default'] instanceof \Closure
|
274 |
-
)
|
275 |
-
) {
|
276 |
-
$args[$key] = $a['default']($args);
|
277 |
-
} else {
|
278 |
-
$args[$key] = $a['default'];
|
279 |
-
}
|
280 |
-
} elseif (empty($a['required'])) {
|
281 |
-
continue;
|
282 |
-
} else {
|
283 |
-
$this->throwRequired($args);
|
284 |
-
}
|
285 |
-
}
|
286 |
-
|
287 |
-
// Validate the types against the provided value.
|
288 |
-
foreach ($a['valid'] as $check) {
|
289 |
-
if (isset(self::$typeMap[$check])) {
|
290 |
-
$fn = self::$typeMap[$check];
|
291 |
-
if ($fn($args[$key])) {
|
292 |
-
goto is_valid;
|
293 |
-
}
|
294 |
-
} elseif ($args[$key] instanceof $check) {
|
295 |
-
goto is_valid;
|
296 |
-
}
|
297 |
-
}
|
298 |
-
|
299 |
-
$this->invalidType($key, $args[$key]);
|
300 |
-
|
301 |
-
// Apply the value
|
302 |
-
is_valid:
|
303 |
-
if (isset($a['fn'])) {
|
304 |
-
$a['fn']($args[$key], $args, $list);
|
305 |
-
}
|
306 |
-
|
307 |
-
if ($a['type'] === 'config') {
|
308 |
-
$args['config'][$key] = $args[$key];
|
309 |
-
}
|
310 |
-
}
|
311 |
-
|
312 |
-
return $args;
|
313 |
-
}
|
314 |
-
|
315 |
-
/**
|
316 |
-
* Creates a verbose error message for an invalid argument.
|
317 |
-
*
|
318 |
-
* @param string $name Name of the argument that is missing.
|
319 |
-
* @param array $args Provided arguments
|
320 |
-
* @param bool $useRequired Set to true to show the required fn text if
|
321 |
-
* available instead of the documentation.
|
322 |
-
* @return string
|
323 |
-
*/
|
324 |
-
private function getArgMessage($name, $args = [], $useRequired = false)
|
325 |
-
{
|
326 |
-
$arg = $this->argDefinitions[$name];
|
327 |
-
$msg = '';
|
328 |
-
$modifiers = [];
|
329 |
-
if (isset($arg['valid'])) {
|
330 |
-
$modifiers[] = implode('|', $arg['valid']);
|
331 |
-
}
|
332 |
-
if (isset($arg['choice'])) {
|
333 |
-
$modifiers[] = 'One of ' . implode(', ', $arg['choice']);
|
334 |
-
}
|
335 |
-
if ($modifiers) {
|
336 |
-
$msg .= '(' . implode('; ', $modifiers) . ')';
|
337 |
-
}
|
338 |
-
$msg = wordwrap("{$name}: {$msg}", 75, "\n ");
|
339 |
-
|
340 |
-
if ($useRequired && is_callable($arg['required'])) {
|
341 |
-
$msg .= "\n\n ";
|
342 |
-
$msg .= str_replace("\n", "\n ", call_user_func($arg['required'], $args));
|
343 |
-
} elseif (isset($arg['doc'])) {
|
344 |
-
$msg .= wordwrap("\n\n {$arg['doc']}", 75, "\n ");
|
345 |
-
}
|
346 |
-
|
347 |
-
return $msg;
|
348 |
-
}
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Throw when an invalid type is encountered.
|
352 |
-
*
|
353 |
-
* @param string $name Name of the value being validated.
|
354 |
-
* @param mixed $provided The provided value.
|
355 |
-
* @throws \InvalidArgumentException
|
356 |
-
*/
|
357 |
-
private function invalidType($name, $provided)
|
358 |
-
{
|
359 |
-
$expected = implode('|', $this->argDefinitions[$name]['valid']);
|
360 |
-
$msg = "Invalid configuration value "
|
361 |
-
. "provided for \"{$name}\". Expected {$expected}, but got "
|
362 |
-
. describe_type($provided) . "\n\n"
|
363 |
-
. $this->getArgMessage($name);
|
364 |
-
throw new IAE($msg);
|
365 |
-
}
|
366 |
-
|
367 |
-
/**
|
368 |
-
* Throws an exception for missing required arguments.
|
369 |
-
*
|
370 |
-
* @param array $args Passed in arguments.
|
371 |
-
* @throws \InvalidArgumentException
|
372 |
-
*/
|
373 |
-
private function throwRequired(array $args)
|
374 |
-
{
|
375 |
-
$missing = [];
|
376 |
-
foreach ($this->argDefinitions as $k => $a) {
|
377 |
-
if (empty($a['required'])
|
378 |
-
|| isset($a['default'])
|
379 |
-
|| isset($args[$k])
|
380 |
-
) {
|
381 |
-
continue;
|
382 |
-
}
|
383 |
-
$missing[] = $this->getArgMessage($k, $args, true);
|
384 |
-
}
|
385 |
-
$msg = "Missing required client configuration options: \n\n";
|
386 |
-
$msg .= implode("\n\n", $missing);
|
387 |
-
throw new IAE($msg);
|
388 |
-
}
|
389 |
-
|
390 |
-
public static function _apply_retries($value, array &$args, HandlerList $list)
|
391 |
-
{
|
392 |
-
if ($value) {
|
393 |
-
$decider = RetryMiddleware::createDefaultDecider($value);
|
394 |
-
$list->appendSign(
|
395 |
-
Middleware::retry($decider, null, $args['stats']['retries']),
|
396 |
-
'retry'
|
397 |
-
);
|
398 |
-
}
|
399 |
-
}
|
400 |
-
|
401 |
-
public static function _apply_credentials($value, array &$args)
|
402 |
-
{
|
403 |
-
if (is_callable($value)) {
|
404 |
-
return;
|
405 |
-
}
|
406 |
-
|
407 |
-
if ($value instanceof CredentialsInterface) {
|
408 |
-
$args['credentials'] = CredentialProvider::fromCredentials($value);
|
409 |
-
} elseif (is_array($value)
|
410 |
-
&& isset($value['key'])
|
411 |
-
&& isset($value['secret'])
|
412 |
-
) {
|
413 |
-
$args['credentials'] = CredentialProvider::fromCredentials(
|
414 |
-
new Credentials(
|
415 |
-
$value['key'],
|
416 |
-
$value['secret'],
|
417 |
-
isset($value['token']) ? $value['token'] : null,
|
418 |
-
isset($value['expires']) ? $value['expires'] : null
|
419 |
-
)
|
420 |
-
);
|
421 |
-
} elseif ($value === false) {
|
422 |
-
$args['credentials'] = CredentialProvider::fromCredentials(
|
423 |
-
new Credentials('', '')
|
424 |
-
);
|
425 |
-
$args['config']['signature_version'] = 'anonymous';
|
426 |
-
} elseif ($value instanceof CacheInterface) {
|
427 |
-
$args['credentials'] = CredentialProvider::defaultProvider($args);
|
428 |
-
} else {
|
429 |
-
throw new IAE('Credentials must be an instance of '
|
430 |
-
. 'Aws\Credentials\CredentialsInterface, an associative '
|
431 |
-
. 'array that contains "key", "secret", and an optional "token" '
|
432 |
-
. 'key-value pairs, a credentials provider function, or false.');
|
433 |
-
}
|
434 |
-
}
|
435 |
-
|
436 |
-
public static function _apply_api_provider(callable $value, array &$args)
|
437 |
-
{
|
438 |
-
$api = new Service(
|
439 |
-
ApiProvider::resolve(
|
440 |
-
$value,
|
441 |
-
'api',
|
442 |
-
$args['service'],
|
443 |
-
$args['version']
|
444 |
-
),
|
445 |
-
$value
|
446 |
-
);
|
447 |
-
|
448 |
-
if (
|
449 |
-
empty($args['config']['signing_name'])
|
450 |
-
&& isset($api['metadata']['signingName'])
|
451 |
-
) {
|
452 |
-
$args['config']['signing_name'] = $api['metadata']['signingName'];
|
453 |
-
}
|
454 |
-
|
455 |
-
$args['api'] = $api;
|
456 |
-
$args['parser'] = Service::createParser($api);
|
457 |
-
$args['error_parser'] = Service::createErrorParser($api->getProtocol());
|
458 |
-
}
|
459 |
-
|
460 |
-
public static function _apply_endpoint_provider(callable $value, array &$args)
|
461 |
-
{
|
462 |
-
if (!isset($args['endpoint'])) {
|
463 |
-
$endpointPrefix = isset($args['api']['metadata']['endpointPrefix'])
|
464 |
-
? $args['api']['metadata']['endpointPrefix']
|
465 |
-
: $args['service'];
|
466 |
-
|
467 |
-
// Invoke the endpoint provider and throw if it does not resolve.
|
468 |
-
$result = EndpointProvider::resolve($value, [
|
469 |
-
'service' => $endpointPrefix,
|
470 |
-
'region' => $args['region'],
|
471 |
-
'scheme' => $args['scheme']
|
472 |
-
]);
|
473 |
-
|
474 |
-
$args['endpoint'] = $result['endpoint'];
|
475 |
-
|
476 |
-
if (
|
477 |
-
empty($args['config']['signature_version'])
|
478 |
-
&& isset($result['signatureVersion'])
|
479 |
-
) {
|
480 |
-
$args['config']['signature_version']
|
481 |
-
= $result['signatureVersion'];
|
482 |
-
}
|
483 |
-
|
484 |
-
if (
|
485 |
-
empty($args['config']['signing_region'])
|
486 |
-
&& isset($result['signingRegion'])
|
487 |
-
) {
|
488 |
-
$args['config']['signing_region'] = $result['signingRegion'];
|
489 |
-
}
|
490 |
-
|
491 |
-
if (
|
492 |
-
empty($args['config']['signing_name'])
|
493 |
-
&& isset($result['signingName'])
|
494 |
-
) {
|
495 |
-
$args['config']['signing_name'] = $result['signingName'];
|
496 |
-
}
|
497 |
-
}
|
498 |
-
}
|
499 |
-
|
500 |
-
public static function _apply_endpoint_discovery($value, array &$args) {
|
501 |
-
$args['endpoint_discovery'] = $value;
|
502 |
-
}
|
503 |
-
|
504 |
-
public static function _default_endpoint_discovery_provider(array $args)
|
505 |
-
{
|
506 |
-
return ConfigurationProvider::defaultProvider($args);
|
507 |
-
}
|
508 |
-
|
509 |
-
public static function _apply_serializer($value, array &$args, HandlerList $list)
|
510 |
-
{
|
511 |
-
$list->prependBuild(Middleware::requestBuilder($value), 'builder');
|
512 |
-
}
|
513 |
-
|
514 |
-
public static function _apply_debug($value, array &$args, HandlerList $list)
|
515 |
-
{
|
516 |
-
if ($value !== false) {
|
517 |
-
$list->interpose(new TraceMiddleware($value === true ? [] : $value));
|
518 |
-
}
|
519 |
-
}
|
520 |
-
|
521 |
-
public static function _apply_stats($value, array &$args, HandlerList $list)
|
522 |
-
{
|
523 |
-
// Create an array of stat collectors that are disabled (set to false)
|
524 |
-
// by default. If the user has passed in true, enable all stat
|
525 |
-
// collectors.
|
526 |
-
$defaults = array_fill_keys(
|
527 |
-
['http', 'retries', 'timer'],
|
528 |
-
$value === true
|
529 |
-
);
|
530 |
-
$args['stats'] = is_array($value)
|
531 |
-
? array_replace($defaults, $value)
|
532 |
-
: $defaults;
|
533 |
-
|
534 |
-
if ($args['stats']['timer']) {
|
535 |
-
$list->prependInit(Middleware::timer(), 'timer');
|
536 |
-
}
|
537 |
-
}
|
538 |
-
|
539 |
-
public static function _apply_profile($_, array &$args)
|
540 |
-
{
|
541 |
-
$args['credentials'] = CredentialProvider::ini($args['profile']);
|
542 |
-
}
|
543 |
-
|
544 |
-
public static function _apply_validate($value, array &$args, HandlerList $list)
|
545 |
-
{
|
546 |
-
if ($value === false) {
|
547 |
-
return;
|
548 |
-
}
|
549 |
-
|
550 |
-
$validator = $value === true
|
551 |
-
? new Validator()
|
552 |
-
: new Validator($value);
|
553 |
-
$list->appendValidate(
|
554 |
-
Middleware::validation($args['api'], $validator),
|
555 |
-
'validation'
|
556 |
-
);
|
557 |
-
}
|
558 |
-
|
559 |
-
public static function _apply_handler($value, array &$args, HandlerList $list)
|
560 |
-
{
|
561 |
-
$list->setHandler($value);
|
562 |
-
}
|
563 |
-
|
564 |
-
public static function _default_handler(array &$args)
|
565 |
-
{
|
566 |
-
return new WrappedHttpHandler(
|
567 |
-
default_http_handler(),
|
568 |
-
$args['parser'],
|
569 |
-
$args['error_parser'],
|
570 |
-
$args['exception_class'],
|
571 |
-
$args['stats']['http']
|
572 |
-
);
|
573 |
-
}
|
574 |
-
|
575 |
-
public static function _apply_http_handler($value, array &$args, HandlerList $list)
|
576 |
-
{
|
577 |
-
$args['handler'] = new WrappedHttpHandler(
|
578 |
-
$value,
|
579 |
-
$args['parser'],
|
580 |
-
$args['error_parser'],
|
581 |
-
$args['exception_class'],
|
582 |
-
$args['stats']['http']
|
583 |
-
);
|
584 |
-
}
|
585 |
-
|
586 |
-
public static function _apply_user_agent($value, array &$args, HandlerList $list)
|
587 |
-
{
|
588 |
-
if (!is_array($value)) {
|
589 |
-
$value = [$value];
|
590 |
-
}
|
591 |
-
|
592 |
-
$value = array_map('strval', $value);
|
593 |
-
|
594 |
-
if (defined('HHVM_VERSION')) {
|
595 |
-
array_unshift($value, 'HHVM/' . HHVM_VERSION);
|
596 |
-
}
|
597 |
-
array_unshift($value, 'aws-sdk-php/' . Sdk::VERSION);
|
598 |
-
$args['ua_append'] = $value;
|
599 |
-
|
600 |
-
$list->appendBuild(static function (callable $handler) use ($value) {
|
601 |
-
return function (
|
602 |
-
CommandInterface $command,
|
603 |
-
RequestInterface $request
|
604 |
-
) use ($handler, $value) {
|
605 |
-
return $handler($command, $request->withHeader(
|
606 |
-
'User-Agent',
|
607 |
-
implode(' ', array_merge(
|
608 |
-
$value,
|
609 |
-
$request->getHeader('User-Agent')
|
610 |
-
))
|
611 |
-
));
|
612 |
-
};
|
613 |
-
});
|
614 |
-
}
|
615 |
-
|
616 |
-
public static function _apply_endpoint($value, array &$args, HandlerList $list)
|
617 |
-
{
|
618 |
-
$parts = parse_url($value);
|
619 |
-
if (empty($parts['scheme']) || empty($parts['host'])) {
|
620 |
-
throw new IAE(
|
621 |
-
'Endpoints must be full URIs and include a scheme and host'
|
622 |
-
);
|
623 |
-
}
|
624 |
-
|
625 |
-
$args['endpoint'] = $value;
|
626 |
-
}
|
627 |
-
|
628 |
-
public static function _apply_idempotency_auto_fill(
|
629 |
-
$value,
|
630 |
-
array &$args,
|
631 |
-
HandlerList $list
|
632 |
-
) {
|
633 |
-
$enabled = false;
|
634 |
-
$generator = null;
|
635 |
-
|
636 |
-
|
637 |
-
if (is_bool($value)) {
|
638 |
-
$enabled = $value;
|
639 |
-
} elseif (is_callable($value)) {
|
640 |
-
$enabled = true;
|
641 |
-
$generator = $value;
|
642 |
-
}
|
643 |
-
|
644 |
-
if ($enabled) {
|
645 |
-
$list->prependInit(
|
646 |
-
IdempotencyTokenMiddleware::wrap($args['api'], $generator),
|
647 |
-
'idempotency_auto_fill'
|
648 |
-
);
|
649 |
-
}
|
650 |
-
}
|
651 |
-
|
652 |
-
public static function _default_endpoint_provider(array $args)
|
653 |
-
{
|
654 |
-
return PartitionEndpointProvider::defaultProvider()
|
655 |
-
->getPartition($args['region'], $args['service']);
|
656 |
-
}
|
657 |
-
|
658 |
-
public static function _default_serializer(array $args)
|
659 |
-
{
|
660 |
-
return Service::createSerializer(
|
661 |
-
$args['api'],
|
662 |
-
$args['endpoint']
|
663 |
-
);
|
664 |
-
}
|
665 |
-
|
666 |
-
public static function _default_signature_provider()
|
667 |
-
{
|
668 |
-
return SignatureProvider::defaultProvider();
|
669 |
-
}
|
670 |
-
|
671 |
-
public static function _default_signature_version(array &$args)
|
672 |
-
{
|
673 |
-
if (isset($args['config']['signature_version'])) {
|
674 |
-
return $args['config']['signature_version'];
|
675 |
-
}
|
676 |
-
|
677 |
-
$args['__partition_result'] = isset($args['__partition_result'])
|
678 |
-
? isset($args['__partition_result'])
|
679 |
-
: call_user_func(PartitionEndpointProvider::defaultProvider(), [
|
680 |
-
'service' => $args['service'],
|
681 |
-
'region' => $args['region'],
|
682 |
-
]);
|
683 |
-
|
684 |
-
return isset($args['__partition_result']['signatureVersion'])
|
685 |
-
? $args['__partition_result']['signatureVersion']
|
686 |
-
: $args['api']->getSignatureVersion();
|
687 |
-
}
|
688 |
-
|
689 |
-
public static function _default_signing_name(array &$args)
|
690 |
-
{
|
691 |
-
if (isset($args['config']['signing_name'])) {
|
692 |
-
return $args['config']['signing_name'];
|
693 |
-
}
|
694 |
-
|
695 |
-
$args['__partition_result'] = isset($args['__partition_result'])
|
696 |
-
? isset($args['__partition_result'])
|
697 |
-
: call_user_func(PartitionEndpointProvider::defaultProvider(), [
|
698 |
-
'service' => $args['service'],
|
699 |
-
'region' => $args['region'],
|
700 |
-
]);
|
701 |
-
|
702 |
-
if (isset($args['__partition_result']['signingName'])) {
|
703 |
-
return $args['__partition_result']['signingName'];
|
704 |
-
}
|
705 |
-
|
706 |
-
if ($signingName = $args['api']->getSigningName()) {
|
707 |
-
return $signingName;
|
708 |
-
}
|
709 |
-
|
710 |
-
return $args['service'];
|
711 |
-
}
|
712 |
-
|
713 |
-
public static function _default_signing_region(array &$args)
|
714 |
-
{
|
715 |
-
if (isset($args['config']['signing_region'])) {
|
716 |
-
return $args['config']['signing_region'];
|
717 |
-
}
|
718 |
-
|
719 |
-
$args['__partition_result'] = isset($args['__partition_result'])
|
720 |
-
? isset($args['__partition_result'])
|
721 |
-
: call_user_func(PartitionEndpointProvider::defaultProvider(), [
|
722 |
-
'service' => $args['service'],
|
723 |
-
'region' => $args['region'],
|
724 |
-
]);
|
725 |
-
|
726 |
-
return isset($args['__partition_result']['signingRegion'])
|
727 |
-
? $args['__partition_result']['signingRegion']
|
728 |
-
: $args['region'];
|
729 |
-
}
|
730 |
-
|
731 |
-
public static function _missing_version(array $args)
|
732 |
-
{
|
733 |
-
$service = isset($args['service']) ? $args['service'] : '';
|
734 |
-
$versions = ApiProvider::defaultProvider()->getVersions($service);
|
735 |
-
$versions = implode("\n", array_map(function ($v) {
|
736 |
-
return "* \"$v\"";
|
737 |
-
}, $versions)) ?: '* (none found)';
|
738 |
-
|
739 |
-
return <<<EOT
|
740 |
-
A "version" configuration value is required. Specifying a version constraint
|
741 |
-
ensures that your code will not be affected by a breaking change made to the
|
742 |
-
service. For example, when using Amazon S3, you can lock your API version to
|
743 |
-
"2006-03-01".
|
744 |
-
|
745 |
-
Your build of the SDK has the following version(s) of "{$service}": {$versions}
|
746 |
-
|
747 |
-
You may provide "latest" to the "version" configuration value to utilize the
|
748 |
-
most recent available API version that your client's API provider can find.
|
749 |
-
Note: Using 'latest' in a production application is not recommended.
|
750 |
-
|
751 |
-
A list of available API versions can be found on each client's API documentation
|
752 |
-
page: http://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html. If you are
|
753 |
-
unable to load a specific API version, then you may need to update your copy of
|
754 |
-
the SDK.
|
755 |
-
EOT;
|
756 |
-
}
|
757 |
-
|
758 |
-
public static function _missing_region(array $args)
|
759 |
-
{
|
760 |
-
$service = isset($args['service']) ? $args['service'] : '';
|
761 |
-
|
762 |
-
return <<<EOT
|
763 |
-
A "region" configuration value is required for the "{$service}" service
|
764 |
-
(e.g., "us-west-2"). A list of available public regions and endpoints can be
|
765 |
-
found at http://docs.aws.amazon.com/general/latest/gr/rande.html.
|
766 |
-
EOT;
|
767 |
-
}
|
768 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/ClientSideMonitoring/AbstractMonitoringMiddleware.php
DELETED
@@ -1,275 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Aws\ClientSideMonitoring;
|
4 |
-
|
5 |
-
use Aws\CommandInterface;
|
6 |
-
use Aws\Exception\AwsException;
|
7 |
-
use Aws\MonitoringEventsInterface;
|
8 |
-
use Aws\ResponseContainerInterface;
|
9 |
-
use Aws\ResultInterface;
|
10 |
-
use GuzzleHttp\Promise;
|
11 |
-
use Psr\Http\Message\RequestInterface;
|
12 |
-
use Psr\Http\Message\ResponseInterface;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @internal
|
16 |
-
*/
|
17 |
-
abstract class AbstractMonitoringMiddleware
|
18 |
-
implements MonitoringMiddlewareInterface
|
19 |
-
{
|
20 |
-
private static $socket;
|
21 |
-
|
22 |
-
private $nextHandler;
|
23 |
-
private $options;
|
24 |
-
protected $credentialProvider;
|
25 |
-
protected $region;
|
26 |
-
protected $service;
|
27 |
-
|
28 |
-
protected static function getAwsExceptionHeader(AwsException $e, $headerName)
|
29 |
-
{
|
30 |
-
$response = $e->getResponse();
|
31 |
-
if ($response !== null) {
|
32 |
-
$header = $response->getHeader($headerName);
|
33 |
-
if (!empty($header[0])) {
|
34 |
-
return $header[0];
|
35 |
-
}
|
36 |
-
}
|
37 |
-
return null;
|
38 |
-
}
|
39 |
-
|
40 |
-
protected static function getResultHeader(ResultInterface $result, $headerName)
|
41 |
-
{
|
42 |
-
if (isset($result['@metadata']['headers'][$headerName])) {
|
43 |
-
return $result['@metadata']['headers'][$headerName];
|
44 |
-
}
|
45 |
-
return null;
|
46 |
-
}
|
47 |
-
|
48 |
-
protected static function getExceptionHeader(\Exception $e, $headerName)
|
49 |
-
{
|
50 |
-
if ($e instanceof ResponseContainerInterface) {
|
51 |
-
$response = $e->getResponse();
|
52 |
-
if ($response instanceof ResponseInterface) {
|
53 |
-
$header = $response->getHeader($headerName);
|
54 |
-
if (!empty($header[0])) {
|
55 |
-
return $header[0];
|
56 |
-
}
|
57 |
-
}
|
58 |
-
}
|
59 |
-
return null;
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Constructor stores the passed in handler and options.
|
64 |
-
*
|
65 |
-
* @param callable $handler
|
66 |
-
* @param callable $credentialProvider
|
67 |
-
* @param array $options
|
68 |
-
* @param $region
|
69 |
-
* @param $service
|
70 |
-
*/
|
71 |
-
public function __construct(
|
72 |
-
callable $handler,
|
73 |
-
callable $credentialProvider,
|
74 |
-
$options,
|
75 |
-
$region,
|
76 |
-
$service
|
77 |
-
) {
|
78 |
-
$this->nextHandler = $handler;
|
79 |
-
$this->credentialProvider = $credentialProvider;
|
80 |
-
$this->options = $options;
|
81 |
-
$this->region = $region;
|
82 |
-
$this->service = $service;
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Standard invoke pattern for middleware execution to be implemented by
|
87 |
-
* child classes.
|
88 |
-
*
|
89 |
-
* @param CommandInterface $cmd
|
90 |
-
* @param RequestInterface $request
|
91 |
-
* @return Promise\PromiseInterface
|
92 |
-
*/
|
93 |
-
public function __invoke(CommandInterface $cmd, RequestInterface $request)
|
94 |
-
{
|
95 |
-
$handler = $this->nextHandler;
|
96 |
-
$eventData = null;
|
97 |
-
$enabled = $this->isEnabled();
|
98 |
-
|
99 |
-
if ($enabled) {
|
100 |
-
$cmd['@http']['collect_stats'] = true;
|
101 |
-
$eventData = $this->populateRequestEventData(
|
102 |
-
$cmd,
|
103 |
-
$request,
|
104 |
-
$this->getNewEvent($cmd, $request)
|
105 |
-
);
|
106 |
-
}
|
107 |
-
|
108 |
-
$g = function ($value) use ($eventData, $enabled) {
|
109 |
-
if ($enabled) {
|
110 |
-
$eventData = $this->populateResultEventData(
|
111 |
-
$value,
|
112 |
-
$eventData
|
113 |
-
);
|
114 |
-
$this->sendEventData($eventData);
|
115 |
-
|
116 |
-
if ($value instanceof MonitoringEventsInterface) {
|
117 |
-
$value->appendMonitoringEvent($eventData);
|
118 |
-
}
|
119 |
-
}
|
120 |
-
if ($value instanceof \Exception || $value instanceof \Throwable) {
|
121 |
-
return Promise\rejection_for($value);
|
122 |
-
}
|
123 |
-
return $value;
|
124 |
-
};
|
125 |
-
|
126 |
-
return Promise\promise_for($handler($cmd, $request))->then($g, $g);
|
127 |
-
}
|
128 |
-
|
129 |
-
private function getClientId()
|
130 |
-
{
|
131 |
-
return $this->unwrappedOptions()->getClientId();
|
132 |
-
}
|
133 |
-
|
134 |
-
private function getNewEvent(
|
135 |
-
CommandInterface $cmd,
|
136 |
-
RequestInterface $request
|
137 |
-
) {
|
138 |
-
$event = [
|
139 |
-
'Api' => $cmd->getName(),
|
140 |
-
'ClientId' => $this->getClientId(),
|
141 |
-
'Region' => $this->getRegion(),
|
142 |
-
'Service' => $this->getService(),
|
143 |
-
'Timestamp' => (int) floor(microtime(true) * 1000),
|
144 |
-
'UserAgent' => substr(
|
145 |
-
$request->getHeaderLine('User-Agent') . ' ' . \Aws\default_user_agent(),
|
146 |
-
0,
|
147 |
-
256
|
148 |
-
),
|
149 |
-
'Version' => 1
|
150 |
-
];
|
151 |
-
return $event;
|
152 |
-
}
|
153 |
-
|
154 |
-
private function getPort()
|
155 |
-
{
|
156 |
-
return $this->unwrappedOptions()->getPort();
|
157 |
-
}
|
158 |
-
|
159 |
-
private function getRegion()
|
160 |
-
{
|
161 |
-
return $this->region;
|
162 |
-
}
|
163 |
-
|
164 |
-
private function getService()
|
165 |
-
{
|
166 |
-
return $this->service;
|
167 |
-
}
|
168 |
-
|
169 |
-
/**
|
170 |
-
* Returns enabled flag from options, unwrapping options if necessary.
|
171 |
-
*
|
172 |
-
* @return bool
|
173 |
-
*/
|
174 |
-
private function isEnabled()
|
175 |
-
{
|
176 |
-
return $this->unwrappedOptions()->isEnabled();
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* Returns $eventData array with information from the request and command.
|
181 |
-
*
|
182 |
-
* @param CommandInterface $cmd
|
183 |
-
* @param RequestInterface $request
|
184 |
-
* @param array $event
|
185 |
-
* @return array
|
186 |
-
*/
|
187 |
-
protected function populateRequestEventData(
|
188 |
-
CommandInterface $cmd,
|
189 |
-
RequestInterface $request,
|
190 |
-
array $event
|
191 |
-
) {
|
192 |
-
$dataFormat = static::getRequestData($request);
|
193 |
-
foreach ($dataFormat as $eventKey => $value) {
|
194 |
-
if ($value !== null) {
|
195 |
-
$event[$eventKey] = $value;
|
196 |
-
}
|
197 |
-
}
|
198 |
-
return $event;
|
199 |
-
}
|
200 |
-
|
201 |
-
/**
|
202 |
-
* Returns $eventData array with information from the response, including
|
203 |
-
* the calculation for attempt latency.
|
204 |
-
*
|
205 |
-
* @param ResultInterface|\Exception $result
|
206 |
-
* @param array $event
|
207 |
-
* @return array
|
208 |
-
*/
|
209 |
-
protected function populateResultEventData(
|
210 |
-
$result,
|
211 |
-
array $event
|
212 |
-
) {
|
213 |
-
$dataFormat = static::getResponseData($result);
|
214 |
-
foreach ($dataFormat as $eventKey => $value) {
|
215 |
-
if ($value !== null) {
|
216 |
-
$event[$eventKey] = $value;
|
217 |
-
}
|
218 |
-
}
|
219 |
-
return $event;
|
220 |
-
}
|
221 |
-
|
222 |
-
/**
|
223 |
-
* Creates a UDP socket resource and stores it with the class, or retrieves
|
224 |
-
* it if already instantiated and connected. Handles error-checking and
|
225 |
-
* re-connecting if necessary. If $forceNewConnection is set to true, a new
|
226 |
-
* socket will be created.
|
227 |
-
*
|
228 |
-
* @param bool $forceNewConnection
|
229 |
-
* @return Resource
|
230 |
-
*/
|
231 |
-
private function prepareSocket($forceNewConnection = false)
|
232 |
-
{
|
233 |
-
if (!is_resource(self::$socket)
|
234 |
-
|| $forceNewConnection
|
235 |
-
|| socket_last_error(self::$socket)
|
236 |
-
) {
|
237 |
-
self::$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
|
238 |
-
socket_clear_error(self::$socket);
|
239 |
-
socket_connect(self::$socket, '127.0.0.1', $this->getPort());
|
240 |
-
}
|
241 |
-
|
242 |
-
return self::$socket;
|
243 |
-
}
|
244 |
-
|
245 |
-
/**
|
246 |
-
* Sends formatted monitoring event data via the UDP socket connection to
|
247 |
-
* the CSM agent endpoint.
|
248 |
-
*
|
249 |
-
* @param array $eventData
|
250 |
-
* @return int
|
251 |
-
*/
|
252 |
-
private function sendEventData(array $eventData)
|
253 |
-
{
|
254 |
-
$socket = $this->prepareSocket();
|
255 |
-
$datagram = json_encode($eventData);
|
256 |
-
$result = socket_write($socket, $datagram, strlen($datagram));
|
257 |
-
if ($result === false) {
|
258 |
-
$this->prepareSocket(true);
|
259 |
-
}
|
260 |
-
return $result;
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* Unwraps options, if needed, and returns them.
|
265 |
-
*
|
266 |
-
* @return ConfigurationInterface
|
267 |
-
*/
|
268 |
-
private function unwrappedOptions()
|
269 |
-
{
|
270 |
-
if (!($this->options instanceof ConfigurationInterface)) {
|
271 |
-
$this->options = ConfigurationProvider::unwrap($this->options);
|
272 |
-
}
|
273 |
-
return $this->options;
|
274 |
-
}
|
275 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/ClientSideMonitoring/Configuration.php
DELETED
@@ -1,65 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\ClientSideMonitoring;
|
3 |
-
|
4 |
-
class Configuration implements ConfigurationInterface
|
5 |
-
{
|
6 |
-
private $clientId;
|
7 |
-
private $enabled;
|
8 |
-
private $port;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Constructs a new Configuration object with the specified CSM options set.
|
12 |
-
*
|
13 |
-
* @param mixed $enabled
|
14 |
-
* @param string|int $port
|
15 |
-
* @param string $clientId
|
16 |
-
*/
|
17 |
-
public function __construct($enabled, $port, $clientId = '')
|
18 |
-
{
|
19 |
-
$this->port = filter_var($port, FILTER_VALIDATE_INT);
|
20 |
-
if ($this->port === false) {
|
21 |
-
throw new \InvalidArgumentException(
|
22 |
-
"CSM 'port' value must be an integer!");
|
23 |
-
}
|
24 |
-
|
25 |
-
// Unparsable $enabled flag errors on the side of disabling CSM
|
26 |
-
$this->enabled = filter_var($enabled, FILTER_VALIDATE_BOOLEAN);
|
27 |
-
$this->clientId = trim($clientId);
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* {@inheritdoc}
|
32 |
-
*/
|
33 |
-
public function isEnabled()
|
34 |
-
{
|
35 |
-
return $this->enabled;
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* {@inheritdoc}
|
40 |
-
*/
|
41 |
-
public function getClientId()
|
42 |
-
{
|
43 |
-
return $this->clientId;
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* {@inheritdoc}
|
48 |
-
*/
|
49 |
-
public function getPort()
|
50 |
-
{
|
51 |
-
return $this->port;
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* {@inheritdoc}
|
56 |
-
*/
|
57 |
-
public function toArray()
|
58 |
-
{
|
59 |
-
return [
|
60 |
-
'client_id' => $this->getClientId(),
|
61 |
-
'enabled' => $this->isEnabled(),
|
62 |
-
'port' => $this->getPort()
|
63 |
-
];
|
64 |
-
}
|
65 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/ClientSideMonitoring/ConfigurationInterface.php
DELETED
@@ -1,37 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\ClientSideMonitoring;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Provides access to client-side monitoring configuration options:
|
6 |
-
* 'client_id', 'enabled', 'port'
|
7 |
-
*/
|
8 |
-
interface ConfigurationInterface
|
9 |
-
{
|
10 |
-
/**
|
11 |
-
* Checks whether or not client-side monitoring is enabled.
|
12 |
-
*
|
13 |
-
* @return bool
|
14 |
-
*/
|
15 |
-
public function isEnabled();
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Returns the Client ID, if available.
|
19 |
-
*
|
20 |
-
* @return string|null
|
21 |
-
*/
|
22 |
-
public function getClientId();
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Returns the configured port.
|
26 |
-
*
|
27 |
-
* @return int|null
|
28 |
-
*/
|
29 |
-
public function getPort();
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Returns the configuration as an associative array.
|
33 |
-
*
|
34 |
-
* @return array
|
35 |
-
*/
|
36 |
-
public function toArray();
|
37 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/ClientSideMonitoring/ConfigurationProvider.php
DELETED
@@ -1,342 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\ClientSideMonitoring;
|
3 |
-
|
4 |
-
use Aws\CacheInterface;
|
5 |
-
use Aws\ClientSideMonitoring\Exception\ConfigurationException;
|
6 |
-
use GuzzleHttp\Promise;
|
7 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* A configuration provider is a function that accepts no arguments and returns
|
11 |
-
* a promise that is fulfilled with a {@see \Aws\ClientSideMonitoring\ConfigurationInterface}
|
12 |
-
* or rejected with an {@see \Aws\ClientSideMonitoring\Exception\ConfigurationException}.
|
13 |
-
*
|
14 |
-
* <code>
|
15 |
-
* use Aws\ClientSideMonitoring\ConfigurationProvider;
|
16 |
-
* $provider = ConfigurationProvider::defaultProvider();
|
17 |
-
* // Returns a ConfigurationInterface or throws.
|
18 |
-
* $config = $provider()->wait();
|
19 |
-
* </code>
|
20 |
-
*
|
21 |
-
* Configuration providers can be composed to create configuration using
|
22 |
-
* conditional logic that can create different configurations in different
|
23 |
-
* environments. You can compose multiple providers into a single provider using
|
24 |
-
* {@see Aws\ClientSideMonitoring\ConfigurationProvider::chain}. This function
|
25 |
-
* accepts providers as variadic arguments and returns a new function that will
|
26 |
-
* invoke each provider until a successful configuration is returned.
|
27 |
-
*
|
28 |
-
* <code>
|
29 |
-
* // First try an INI file at this location.
|
30 |
-
* $a = ConfigurationProvider::ini(null, '/path/to/file.ini');
|
31 |
-
* // Then try an INI file at this location.
|
32 |
-
* $b = ConfigurationProvider::ini(null, '/path/to/other-file.ini');
|
33 |
-
* // Then try loading from environment variables.
|
34 |
-
* $c = ConfigurationProvider::env();
|
35 |
-
* // Combine the three providers together.
|
36 |
-
* $composed = ConfigurationProvider::chain($a, $b, $c);
|
37 |
-
* // Returns a promise that is fulfilled with a configuration or throws.
|
38 |
-
* $promise = $composed();
|
39 |
-
* // Wait on the configuration to resolve.
|
40 |
-
* $config = $promise->wait();
|
41 |
-
* </code>
|
42 |
-
*/
|
43 |
-
class ConfigurationProvider
|
44 |
-
{
|
45 |
-
|
46 |
-
const CACHE_KEY = 'aws_cached_csm_config';
|
47 |
-
const DEFAULT_CLIENT_ID = '';
|
48 |
-
const DEFAULT_ENABLED = false;
|
49 |
-
const DEFAULT_PORT = 31000;
|
50 |
-
const ENV_CLIENT_ID = 'AWS_CSM_CLIENT_ID';
|
51 |
-
const ENV_ENABLED = 'AWS_CSM_ENABLED';
|
52 |
-
const ENV_PORT = 'AWS_CSM_PORT';
|
53 |
-
const ENV_PROFILE = 'AWS_PROFILE';
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Wraps a credential provider and saves provided credentials in an
|
57 |
-
* instance of Aws\CacheInterface. Forwards calls when no credentials found
|
58 |
-
* in cache and updates cache with the results.
|
59 |
-
*
|
60 |
-
* @param callable $provider Credentials provider function to wrap
|
61 |
-
* @param CacheInterface $cache Cache to store credentials
|
62 |
-
* @param string|null $cacheKey (optional) Cache key to use
|
63 |
-
*
|
64 |
-
* @return callable
|
65 |
-
*/
|
66 |
-
public static function cache(
|
67 |
-
callable $provider,
|
68 |
-
CacheInterface $cache,
|
69 |
-
$cacheKey = null
|
70 |
-
) {
|
71 |
-
$cacheKey = $cacheKey ?: self::CACHE_KEY;
|
72 |
-
|
73 |
-
return function () use ($provider, $cache, $cacheKey) {
|
74 |
-
$found = $cache->get($cacheKey);
|
75 |
-
if ($found instanceof ConfigurationInterface) {
|
76 |
-
return Promise\promise_for($found);
|
77 |
-
}
|
78 |
-
|
79 |
-
return $provider()
|
80 |
-
->then(function (ConfigurationInterface $config) use (
|
81 |
-
$cache,
|
82 |
-
$cacheKey
|
83 |
-
) {
|
84 |
-
$cache->set(
|
85 |
-
$cacheKey,
|
86 |
-
$config
|
87 |
-
);
|
88 |
-
|
89 |
-
return $config;
|
90 |
-
});
|
91 |
-
};
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Creates an aggregate credentials provider that invokes the provided
|
96 |
-
* variadic providers one after the other until a provider returns
|
97 |
-
* credentials.
|
98 |
-
*
|
99 |
-
* @return callable
|
100 |
-
*/
|
101 |
-
public static function chain()
|
102 |
-
{
|
103 |
-
$links = func_get_args();
|
104 |
-
if (empty($links)) {
|
105 |
-
throw new \InvalidArgumentException('No providers in chain');
|
106 |
-
}
|
107 |
-
|
108 |
-
return function () use ($links) {
|
109 |
-
/** @var callable $parent */
|
110 |
-
$parent = array_shift($links);
|
111 |
-
$promise = $parent();
|
112 |
-
while ($next = array_shift($links)) {
|
113 |
-
$promise = $promise->otherwise($next);
|
114 |
-
}
|
115 |
-
return $promise;
|
116 |
-
};
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Create a default CSM config provider that first checks for environment
|
121 |
-
* variables, then checks for a specified profile in ~/.aws/config, then
|
122 |
-
* checks for the "aws_csm" profile in ~/.aws/config, and failing those uses
|
123 |
-
* a default fallback set of configuration options.
|
124 |
-
*
|
125 |
-
* This provider is automatically wrapped in a memoize function that caches
|
126 |
-
* previously provided config options.
|
127 |
-
*
|
128 |
-
* @param array $config Optional array of ecs/instance profile credentials
|
129 |
-
* provider options.
|
130 |
-
*
|
131 |
-
* @return callable
|
132 |
-
*/
|
133 |
-
public static function defaultProvider(array $config = [])
|
134 |
-
{
|
135 |
-
$configProviders = [
|
136 |
-
self::env(),
|
137 |
-
self::ini(),
|
138 |
-
self::fallback()
|
139 |
-
];
|
140 |
-
|
141 |
-
$memo = self::memoize(
|
142 |
-
call_user_func_array('self::chain', $configProviders)
|
143 |
-
);
|
144 |
-
|
145 |
-
if (isset($config['csm']) && $config['csm'] instanceof CacheInterface) {
|
146 |
-
return self::cache($memo, $config['csm'], self::CACHE_KEY);
|
147 |
-
}
|
148 |
-
|
149 |
-
return $memo;
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Provider that creates CSM config from environment variables.
|
154 |
-
*
|
155 |
-
* @return callable
|
156 |
-
*/
|
157 |
-
public static function env()
|
158 |
-
{
|
159 |
-
return function () {
|
160 |
-
// Use credentials from environment variables, if available
|
161 |
-
$enabled = getenv(self::ENV_ENABLED);
|
162 |
-
if ($enabled !== false) {
|
163 |
-
return Promise\promise_for(
|
164 |
-
new Configuration(
|
165 |
-
$enabled,
|
166 |
-
getenv(self::ENV_PORT) ?: self::DEFAULT_PORT,
|
167 |
-
getenv(self:: ENV_CLIENT_ID) ?: self::DEFAULT_CLIENT_ID
|
168 |
-
)
|
169 |
-
);
|
170 |
-
}
|
171 |
-
|
172 |
-
return self::reject('Could not find environment variable CSM config'
|
173 |
-
. ' in ' . self::ENV_ENABLED. '/' . self::ENV_PORT . '/'
|
174 |
-
. self::ENV_CLIENT_ID);
|
175 |
-
};
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* Fallback config options when other sources are not set.
|
180 |
-
*
|
181 |
-
* @return callable
|
182 |
-
*/
|
183 |
-
public static function fallback()
|
184 |
-
{
|
185 |
-
return function() {
|
186 |
-
return Promise\promise_for(
|
187 |
-
new Configuration(
|
188 |
-
self::DEFAULT_ENABLED,
|
189 |
-
self::DEFAULT_PORT,
|
190 |
-
self::DEFAULT_CLIENT_ID
|
191 |
-
)
|
192 |
-
);
|
193 |
-
};
|
194 |
-
}
|
195 |
-
|
196 |
-
/**
|
197 |
-
* Gets the environment's HOME directory if available.
|
198 |
-
*
|
199 |
-
* @return null|string
|
200 |
-
*/
|
201 |
-
private static function getHomeDir()
|
202 |
-
{
|
203 |
-
// On Linux/Unix-like systems, use the HOME environment variable
|
204 |
-
if ($homeDir = getenv('HOME')) {
|
205 |
-
return $homeDir;
|
206 |
-
}
|
207 |
-
|
208 |
-
// Get the HOMEDRIVE and HOMEPATH values for Windows hosts
|
209 |
-
$homeDrive = getenv('HOMEDRIVE');
|
210 |
-
$homePath = getenv('HOMEPATH');
|
211 |
-
|
212 |
-
return ($homeDrive && $homePath) ? $homeDrive . $homePath : null;
|
213 |
-
}
|
214 |
-
|
215 |
-
/**
|
216 |
-
* CSM config provider that creates CSM config using an ini file stored
|
217 |
-
* in the current user's home directory.
|
218 |
-
*
|
219 |
-
* @param string|null $profile Profile to use. If not specified will use
|
220 |
-
* the "aws_csm" profile in "~/.aws/config".
|
221 |
-
* @param string|null $filename If provided, uses a custom filename rather
|
222 |
-
* than looking in the home directory.
|
223 |
-
*
|
224 |
-
* @return callable
|
225 |
-
*/
|
226 |
-
public static function ini($profile = null, $filename = null)
|
227 |
-
{
|
228 |
-
$filename = $filename ?: (self::getHomeDir() . '/.aws/config');
|
229 |
-
$profile = $profile ?: (getenv(self::ENV_PROFILE) ?: 'aws_csm');
|
230 |
-
|
231 |
-
return function () use ($profile, $filename) {
|
232 |
-
if (!is_readable($filename)) {
|
233 |
-
return self::reject("Cannot read CSM config from $filename");
|
234 |
-
}
|
235 |
-
$data = \Aws\parse_ini_file($filename, true);
|
236 |
-
if ($data === false) {
|
237 |
-
return self::reject("Invalid config file: $filename");
|
238 |
-
}
|
239 |
-
if (!isset($data[$profile])) {
|
240 |
-
return self::reject("'$profile' not found in config file");
|
241 |
-
}
|
242 |
-
if (!isset($data[$profile]['csm_enabled'])) {
|
243 |
-
return self::reject("Required CSM config values not present in
|
244 |
-
INI profile '{$profile}' ({$filename})");
|
245 |
-
}
|
246 |
-
|
247 |
-
// port is optional
|
248 |
-
if (empty($data[$profile]['csm_port'])) {
|
249 |
-
$data[$profile]['csm_port'] = self::DEFAULT_PORT;
|
250 |
-
}
|
251 |
-
|
252 |
-
// client_id is optional
|
253 |
-
if (empty($data[$profile]['csm_client_id'])) {
|
254 |
-
$data[$profile]['csm_client_id'] = self::DEFAULT_CLIENT_ID;
|
255 |
-
}
|
256 |
-
|
257 |
-
return Promise\promise_for(
|
258 |
-
new Configuration(
|
259 |
-
$data[$profile]['csm_enabled'],
|
260 |
-
$data[$profile]['csm_port'],
|
261 |
-
$data[$profile]['csm_client_id']
|
262 |
-
)
|
263 |
-
);
|
264 |
-
};
|
265 |
-
}
|
266 |
-
|
267 |
-
/**
|
268 |
-
* Wraps a CSM config provider and caches previously provided configuration.
|
269 |
-
*
|
270 |
-
* Ensures that cached configuration is refreshed when it expires.
|
271 |
-
*
|
272 |
-
* @param callable $provider CSM config provider function to wrap.
|
273 |
-
*
|
274 |
-
* @return callable
|
275 |
-
*/
|
276 |
-
public static function memoize(callable $provider)
|
277 |
-
{
|
278 |
-
return function () use ($provider) {
|
279 |
-
static $result;
|
280 |
-
static $isConstant;
|
281 |
-
|
282 |
-
// Constant config will be returned constantly.
|
283 |
-
if ($isConstant) {
|
284 |
-
return $result;
|
285 |
-
}
|
286 |
-
|
287 |
-
// Create the initial promise that will be used as the cached value
|
288 |
-
// until it expires.
|
289 |
-
if (null === $result) {
|
290 |
-
$result = $provider();
|
291 |
-
}
|
292 |
-
|
293 |
-
// Return config and set flag that provider is already set
|
294 |
-
return $result
|
295 |
-
->then(function (ConfigurationInterface $config) use (&$isConstant) {
|
296 |
-
$isConstant = true;
|
297 |
-
return $config;
|
298 |
-
});
|
299 |
-
};
|
300 |
-
}
|
301 |
-
|
302 |
-
/**
|
303 |
-
* Reject promise with standardized exception.
|
304 |
-
*
|
305 |
-
* @param $msg
|
306 |
-
* @return Promise\RejectedPromise
|
307 |
-
*/
|
308 |
-
private static function reject($msg)
|
309 |
-
{
|
310 |
-
return new Promise\RejectedPromise(new ConfigurationException($msg));
|
311 |
-
}
|
312 |
-
|
313 |
-
/**
|
314 |
-
* Unwraps a configuration object in whatever valid form it is in,
|
315 |
-
* always returning a ConfigurationInterface object.
|
316 |
-
*
|
317 |
-
* @param mixed $config
|
318 |
-
* @return ConfigurationInterface
|
319 |
-
* @throws \InvalidArgumentException
|
320 |
-
*/
|
321 |
-
public static function unwrap($config)
|
322 |
-
{
|
323 |
-
if (is_callable($config)) {
|
324 |
-
$config = $config();
|
325 |
-
}
|
326 |
-
if ($config instanceof PromiseInterface) {
|
327 |
-
$config = $config->wait();
|
328 |
-
}
|
329 |
-
if ($config instanceof ConfigurationInterface) {
|
330 |
-
return $config;
|
331 |
-
} elseif (is_array($config) && isset($config['enabled'])) {
|
332 |
-
$client_id = isset($config['client_id']) ? $config['client_id']
|
333 |
-
: self::DEFAULT_CLIENT_ID;
|
334 |
-
$port = isset($config['port']) ? $config['port']
|
335 |
-
: self::DEFAULT_PORT;
|
336 |
-
return new Configuration($config['enabled'], $port, $client_id);
|
337 |
-
}
|
338 |
-
|
339 |
-
throw new \InvalidArgumentException('Not a valid CSM configuration '
|
340 |
-
. 'argument.');
|
341 |
-
}
|
342 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/CloudFront/CloudFrontClient.php
DELETED
@@ -1,190 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\CloudFront;
|
3 |
-
|
4 |
-
use Aws\AwsClient;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* This client is used to interact with the **Amazon CloudFront** service.
|
8 |
-
*
|
9 |
-
* @method \Aws\Result createCloudFrontOriginAccessIdentity(array $args = [])
|
10 |
-
* @method \GuzzleHttp\Promise\Promise createCloudFrontOriginAccessIdentityAsync(array $args = [])
|
11 |
-
* @method \Aws\Result createDistribution(array $args = [])
|
12 |
-
* @method \GuzzleHttp\Promise\Promise createDistributionAsync(array $args = [])
|
13 |
-
* @method \Aws\Result createInvalidation(array $args = [])
|
14 |
-
* @method \GuzzleHttp\Promise\Promise createInvalidationAsync(array $args = [])
|
15 |
-
* @method \Aws\Result createStreamingDistribution(array $args = [])
|
16 |
-
* @method \GuzzleHttp\Promise\Promise createStreamingDistributionAsync(array $args = [])
|
17 |
-
* @method \Aws\Result deleteCloudFrontOriginAccessIdentity(array $args = [])
|
18 |
-
* @method \GuzzleHttp\Promise\Promise deleteCloudFrontOriginAccessIdentityAsync(array $args = [])
|
19 |
-
* @method \Aws\Result deleteDistribution(array $args = [])
|
20 |
-
* @method \GuzzleHttp\Promise\Promise deleteDistributionAsync(array $args = [])
|
21 |
-
* @method \Aws\Result deleteStreamingDistribution(array $args = [])
|
22 |
-
* @method \GuzzleHttp\Promise\Promise deleteStreamingDistributionAsync(array $args = [])
|
23 |
-
* @method \Aws\Result getCloudFrontOriginAccessIdentity(array $args = [])
|
24 |
-
* @method \GuzzleHttp\Promise\Promise getCloudFrontOriginAccessIdentityAsync(array $args = [])
|
25 |
-
* @method \Aws\Result getCloudFrontOriginAccessIdentityConfig(array $args = [])
|
26 |
-
* @method \GuzzleHttp\Promise\Promise getCloudFrontOriginAccessIdentityConfigAsync(array $args = [])
|
27 |
-
* @method \Aws\Result getDistribution(array $args = [])
|
28 |
-
* @method \GuzzleHttp\Promise\Promise getDistributionAsync(array $args = [])
|
29 |
-
* @method \Aws\Result getDistributionConfig(array $args = [])
|
30 |
-
* @method \GuzzleHttp\Promise\Promise getDistributionConfigAsync(array $args = [])
|
31 |
-
* @method \Aws\Result getInvalidation(array $args = [])
|
32 |
-
* @method \GuzzleHttp\Promise\Promise getInvalidationAsync(array $args = [])
|
33 |
-
* @method \Aws\Result getStreamingDistribution(array $args = [])
|
34 |
-
* @method \GuzzleHttp\Promise\Promise getStreamingDistributionAsync(array $args = [])
|
35 |
-
* @method \Aws\Result getStreamingDistributionConfig(array $args = [])
|
36 |
-
* @method \GuzzleHttp\Promise\Promise getStreamingDistributionConfigAsync(array $args = [])
|
37 |
-
* @method \Aws\Result listCloudFrontOriginAccessIdentities(array $args = [])
|
38 |
-
* @method \GuzzleHttp\Promise\Promise listCloudFrontOriginAccessIdentitiesAsync(array $args = [])
|
39 |
-
* @method \Aws\Result listDistributions(array $args = [])
|
40 |
-
* @method \GuzzleHttp\Promise\Promise listDistributionsAsync(array $args = [])
|
41 |
-
* @method \Aws\Result listDistributionsByWebACLId(array $args = [])
|
42 |
-
* @method \GuzzleHttp\Promise\Promise listDistributionsByWebACLIdAsync(array $args = [])
|
43 |
-
* @method \Aws\Result listInvalidations(array $args = [])
|
44 |
-
* @method \GuzzleHttp\Promise\Promise listInvalidationsAsync(array $args = [])
|
45 |
-
* @method \Aws\Result listStreamingDistributions(array $args = [])
|
46 |
-
* @method \GuzzleHttp\Promise\Promise listStreamingDistributionsAsync(array $args = [])
|
47 |
-
* @method \Aws\Result updateCloudFrontOriginAccessIdentity(array $args = [])
|
48 |
-
* @method \GuzzleHttp\Promise\Promise updateCloudFrontOriginAccessIdentityAsync(array $args = [])
|
49 |
-
* @method \Aws\Result updateDistribution(array $args = [])
|
50 |
-
* @method \GuzzleHttp\Promise\Promise updateDistributionAsync(array $args = [])
|
51 |
-
* @method \Aws\Result updateStreamingDistribution(array $args = [])
|
52 |
-
* @method \GuzzleHttp\Promise\Promise updateStreamingDistributionAsync(array $args = [])
|
53 |
-
* @method \Aws\Result createDistributionWithTags(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
54 |
-
* @method \GuzzleHttp\Promise\Promise createDistributionWithTagsAsync(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
55 |
-
* @method \Aws\Result createStreamingDistributionWithTags(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
56 |
-
* @method \GuzzleHttp\Promise\Promise createStreamingDistributionWithTagsAsync(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
57 |
-
* @method \Aws\Result listTagsForResource(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
58 |
-
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
59 |
-
* @method \Aws\Result tagResource(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
60 |
-
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
61 |
-
* @method \Aws\Result untagResource(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
62 |
-
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = []) (supported in versions 2016-08-01, 2016-08-20, 2016-09-07, 2016-09-29, 2016-11-25, 2017-03-25, 2017-10-30, 2018-06-18, 2018-11-05)
|
63 |
-
* @method \Aws\Result deleteServiceLinkedRole(array $args = []) (supported in versions 2017-03-25)
|
64 |
-
* @method \GuzzleHttp\Promise\Promise deleteServiceLinkedRoleAsync(array $args = []) (supported in versions 2017-03-25)
|
65 |
-
* @method \Aws\Result createFieldLevelEncryptionConfig(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
66 |
-
* @method \GuzzleHttp\Promise\Promise createFieldLevelEncryptionConfigAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
67 |
-
* @method \Aws\Result createFieldLevelEncryptionProfile(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
68 |
-
* @method \GuzzleHttp\Promise\Promise createFieldLevelEncryptionProfileAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
69 |
-
* @method \Aws\Result createPublicKey(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
70 |
-
* @method \GuzzleHttp\Promise\Promise createPublicKeyAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
71 |
-
* @method \Aws\Result deleteFieldLevelEncryptionConfig(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
72 |
-
* @method \GuzzleHttp\Promise\Promise deleteFieldLevelEncryptionConfigAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
73 |
-
* @method \Aws\Result deleteFieldLevelEncryptionProfile(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
74 |
-
* @method \GuzzleHttp\Promise\Promise deleteFieldLevelEncryptionProfileAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
75 |
-
* @method \Aws\Result deletePublicKey(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
76 |
-
* @method \GuzzleHttp\Promise\Promise deletePublicKeyAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
77 |
-
* @method \Aws\Result getFieldLevelEncryption(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
78 |
-
* @method \GuzzleHttp\Promise\Promise getFieldLevelEncryptionAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
79 |
-
* @method \Aws\Result getFieldLevelEncryptionConfig(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
80 |
-
* @method \GuzzleHttp\Promise\Promise getFieldLevelEncryptionConfigAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
81 |
-
* @method \Aws\Result getFieldLevelEncryptionProfile(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
82 |
-
* @method \GuzzleHttp\Promise\Promise getFieldLevelEncryptionProfileAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
83 |
-
* @method \Aws\Result getFieldLevelEncryptionProfileConfig(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
84 |
-
* @method \GuzzleHttp\Promise\Promise getFieldLevelEncryptionProfileConfigAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
85 |
-
* @method \Aws\Result getPublicKey(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
86 |
-
* @method \GuzzleHttp\Promise\Promise getPublicKeyAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
87 |
-
* @method \Aws\Result getPublicKeyConfig(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
88 |
-
* @method \GuzzleHttp\Promise\Promise getPublicKeyConfigAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
89 |
-
* @method \Aws\Result listFieldLevelEncryptionConfigs(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
90 |
-
* @method \GuzzleHttp\Promise\Promise listFieldLevelEncryptionConfigsAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
91 |
-
* @method \Aws\Result listFieldLevelEncryptionProfiles(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
92 |
-
* @method \GuzzleHttp\Promise\Promise listFieldLevelEncryptionProfilesAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
93 |
-
* @method \Aws\Result listPublicKeys(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
94 |
-
* @method \GuzzleHttp\Promise\Promise listPublicKeysAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
95 |
-
* @method \Aws\Result updateFieldLevelEncryptionConfig(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
96 |
-
* @method \GuzzleHttp\Promise\Promise updateFieldLevelEncryptionConfigAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
97 |
-
* @method \Aws\Result updateFieldLevelEncryptionProfile(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
98 |
-
* @method \GuzzleHttp\Promise\Promise updateFieldLevelEncryptionProfileAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
99 |
-
* @method \Aws\Result updatePublicKey(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
100 |
-
* @method \GuzzleHttp\Promise\Promise updatePublicKeyAsync(array $args = []) (supported in versions 2017-10-30, 2018-06-18, 2018-11-05)
|
101 |
-
*/
|
102 |
-
class CloudFrontClient extends AwsClient
|
103 |
-
{
|
104 |
-
/**
|
105 |
-
* Create a signed Amazon CloudFront URL.
|
106 |
-
*
|
107 |
-
* This method accepts an array of configuration options:
|
108 |
-
*
|
109 |
-
* - url: (string) URL of the resource being signed (can include query
|
110 |
-
* string and wildcards). For example: rtmp://s5c39gqb8ow64r.cloudfront.net/videos/mp3_name.mp3
|
111 |
-
* http://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes
|
112 |
-
* - policy: (string) JSON policy. Use this option when creating a signed
|
113 |
-
* URL for a custom policy.
|
114 |
-
* - expires: (int) UTC Unix timestamp used when signing with a canned
|
115 |
-
* policy. Not required when passing a custom 'policy' option.
|
116 |
-
* - key_pair_id: (string) The ID of the key pair used to sign CloudFront
|
117 |
-
* URLs for private distributions.
|
118 |
-
* - private_key: (string) The filepath ot the private key used to sign
|
119 |
-
* CloudFront URLs for private distributions.
|
120 |
-
*
|
121 |
-
* @param array $options Array of configuration options used when signing
|
122 |
-
*
|
123 |
-
* @return string Signed URL with authentication parameters
|
124 |
-
* @throws \InvalidArgumentException if url, key_pair_id, or private_key
|
125 |
-
* were not specified.
|
126 |
-
* @link http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/WorkingWithStreamingDistributions.html
|
127 |
-
*/
|
128 |
-
public function getSignedUrl(array $options)
|
129 |
-
{
|
130 |
-
foreach (['url', 'key_pair_id', 'private_key'] as $required) {
|
131 |
-
if (!isset($options[$required])) {
|
132 |
-
throw new \InvalidArgumentException("$required is required");
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
$urlSigner = new UrlSigner(
|
137 |
-
$options['key_pair_id'],
|
138 |
-
$options['private_key']
|
139 |
-
);
|
140 |
-
|
141 |
-
return $urlSigner->getSignedUrl(
|
142 |
-
$options['url'],
|
143 |
-
isset($options['expires']) ? $options['expires'] : null,
|
144 |
-
isset($options['policy']) ? $options['policy'] : null
|
145 |
-
);
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* Create a signed Amazon CloudFront cookie.
|
150 |
-
*
|
151 |
-
* This method accepts an array of configuration options:
|
152 |
-
*
|
153 |
-
* - url: (string) URL of the resource being signed (can include query
|
154 |
-
* string and wildcards). For example: http://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes
|
155 |
-
* - policy: (string) JSON policy. Use this option when creating a signed
|
156 |
-
* URL for a custom policy.
|
157 |
-
* - expires: (int) UTC Unix timestamp used when signing with a canned
|
158 |
-
* policy. Not required when passing a custom 'policy' option.
|
159 |
-
* - key_pair_id: (string) The ID of the key pair used to sign CloudFront
|
160 |
-
* URLs for private distributions.
|
161 |
-
* - private_key: (string) The filepath ot the private key used to sign
|
162 |
-
* CloudFront URLs for private distributions.
|
163 |
-
*
|
164 |
-
* @param array $options Array of configuration options used when signing
|
165 |
-
*
|
166 |
-
* @return array Key => value pairs of signed cookies to set
|
167 |
-
* @throws \InvalidArgumentException if url, key_pair_id, or private_key
|
168 |
-
* were not specified.
|
169 |
-
* @link http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/WorkingWithStreamingDistributions.html
|
170 |
-
*/
|
171 |
-
public function getSignedCookie(array $options)
|
172 |
-
{
|
173 |
-
foreach (['key_pair_id', 'private_key'] as $required) {
|
174 |
-
if (!isset($options[$required])) {
|
175 |
-
throw new \InvalidArgumentException("$required is required");
|
176 |
-
}
|
177 |
-
}
|
178 |
-
|
179 |
-
$cookieSigner = new CookieSigner(
|
180 |
-
$options['key_pair_id'],
|
181 |
-
$options['private_key']
|
182 |
-
);
|
183 |
-
|
184 |
-
return $cookieSigner->getSignedCookie(
|
185 |
-
isset($options['url']) ? $options['url'] : null,
|
186 |
-
isset($options['expires']) ? $options['expires'] : null,
|
187 |
-
isset($options['policy']) ? $options['policy'] : null
|
188 |
-
);
|
189 |
-
}
|
190 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/CloudFront/Signer.php
DELETED
@@ -1,117 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\CloudFront;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* @internal
|
6 |
-
*/
|
7 |
-
class Signer
|
8 |
-
{
|
9 |
-
private $keyPairId;
|
10 |
-
private $pkHandle;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* A signer for creating the signature values used in CloudFront signed URLs
|
14 |
-
* and signed cookies.
|
15 |
-
*
|
16 |
-
* @param $keyPairId string ID of the key pair
|
17 |
-
* @param $privateKey string Path to the private key used for signing
|
18 |
-
*
|
19 |
-
* @throws \RuntimeException if the openssl extension is missing
|
20 |
-
* @throws \InvalidArgumentException if the private key cannot be found.
|
21 |
-
*/
|
22 |
-
public function __construct($keyPairId, $privateKey)
|
23 |
-
{
|
24 |
-
if (!extension_loaded('openssl')) {
|
25 |
-
//@codeCoverageIgnoreStart
|
26 |
-
throw new \RuntimeException('The openssl extension is required to '
|
27 |
-
. 'sign CloudFront urls.');
|
28 |
-
//@codeCoverageIgnoreEnd
|
29 |
-
}
|
30 |
-
|
31 |
-
$this->keyPairId = $keyPairId;
|
32 |
-
|
33 |
-
if (!file_exists($privateKey)) {
|
34 |
-
throw new \InvalidArgumentException("PK file not found: $privateKey");
|
35 |
-
}
|
36 |
-
|
37 |
-
$this->pkHandle = openssl_pkey_get_private("file://$privateKey");
|
38 |
-
|
39 |
-
if (!$this->pkHandle) {
|
40 |
-
throw new \InvalidArgumentException(openssl_error_string());
|
41 |
-
}
|
42 |
-
}
|
43 |
-
|
44 |
-
public function __destruct()
|
45 |
-
{
|
46 |
-
$this->pkHandle && openssl_pkey_free($this->pkHandle);
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Create the values used to construct signed URLs and cookies.
|
51 |
-
*
|
52 |
-
* @param string $resource The CloudFront resource to which
|
53 |
-
* this signature will grant access.
|
54 |
-
* Not used when a custom policy is
|
55 |
-
* provided.
|
56 |
-
* @param string|integer|null $expires UTC Unix timestamp used when
|
57 |
-
* signing with a canned policy.
|
58 |
-
* Not required when passing a
|
59 |
-
* custom $policy.
|
60 |
-
* @param string $policy JSON policy. Use this option when
|
61 |
-
* creating a signature for a custom
|
62 |
-
* policy.
|
63 |
-
*
|
64 |
-
* @return array The values needed to construct a signed URL or cookie
|
65 |
-
* @throws \InvalidArgumentException when not provided either a policy or a
|
66 |
-
* resource and a expires
|
67 |
-
*
|
68 |
-
* @link http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html
|
69 |
-
*/
|
70 |
-
public function getSignature($resource = null, $expires = null, $policy = null)
|
71 |
-
{
|
72 |
-
$signatureHash = [];
|
73 |
-
if ($policy) {
|
74 |
-
$policy = preg_replace('/\s/s', '', $policy);
|
75 |
-
$signatureHash['Policy'] = $this->encode($policy);
|
76 |
-
} elseif ($resource && $expires) {
|
77 |
-
$expires = (int) $expires; // Handle epoch passed as string
|
78 |
-
$policy = $this->createCannedPolicy($resource, $expires);
|
79 |
-
$signatureHash['Expires'] = $expires;
|
80 |
-
} else {
|
81 |
-
throw new \InvalidArgumentException('Either a policy or a resource'
|
82 |
-
. ' and an expiration time must be provided.');
|
83 |
-
}
|
84 |
-
|
85 |
-
$signatureHash['Signature'] = $this->encode($this->sign($policy));
|
86 |
-
$signatureHash['Key-Pair-Id'] = $this->keyPairId;
|
87 |
-
|
88 |
-
return $signatureHash;
|
89 |
-
}
|
90 |
-
|
91 |
-
private function createCannedPolicy($resource, $expiration)
|
92 |
-
{
|
93 |
-
return json_encode([
|
94 |
-
'Statement' => [
|
95 |
-
[
|
96 |
-
'Resource' => $resource,
|
97 |
-
'Condition' => [
|
98 |
-
'DateLessThan' => ['AWS:EpochTime' => $expiration],
|
99 |
-
],
|
100 |
-
],
|
101 |
-
],
|
102 |
-
], JSON_UNESCAPED_SLASHES);
|
103 |
-
}
|
104 |
-
|
105 |
-
private function sign($policy)
|
106 |
-
{
|
107 |
-
$signature = '';
|
108 |
-
openssl_sign($policy, $signature, $this->pkHandle);
|
109 |
-
|
110 |
-
return $signature;
|
111 |
-
}
|
112 |
-
|
113 |
-
private function encode($policy)
|
114 |
-
{
|
115 |
-
return strtr(base64_encode($policy), '+=/', '-_~');
|
116 |
-
}
|
117 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/CloudFront/UrlSigner.php
DELETED
@@ -1,119 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\CloudFront;
|
3 |
-
|
4 |
-
use GuzzleHttp\Psr7;
|
5 |
-
use GuzzleHttp\Psr7\Uri;
|
6 |
-
use Psr\Http\Message\UriInterface;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Creates signed URLs for Amazon CloudFront resources.
|
10 |
-
*/
|
11 |
-
class UrlSigner
|
12 |
-
{
|
13 |
-
private $signer;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @param $keyPairId string ID of the key pair
|
17 |
-
* @param $privateKey string Path to the private key used for signing
|
18 |
-
*
|
19 |
-
* @throws \RuntimeException if the openssl extension is missing
|
20 |
-
* @throws \InvalidArgumentException if the private key cannot be found.
|
21 |
-
*/
|
22 |
-
public function __construct($keyPairId, $privateKey)
|
23 |
-
{
|
24 |
-
$this->signer = new Signer($keyPairId, $privateKey);
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Create a signed Amazon CloudFront URL.
|
29 |
-
*
|
30 |
-
* Keep in mind that URLs meant for use in media/flash players may have
|
31 |
-
* different requirements for URL formats (e.g. some require that the
|
32 |
-
* extension be removed, some require the file name to be prefixed
|
33 |
-
* - mp4:<path>, some require you to add "/cfx/st" into your URL).
|
34 |
-
*
|
35 |
-
* @param string $url URL to sign (can include query
|
36 |
-
* string string and wildcards)
|
37 |
-
* @param string|integer|null $expires UTC Unix timestamp used when signing
|
38 |
-
* with a canned policy. Not required
|
39 |
-
* when passing a custom $policy.
|
40 |
-
* @param string $policy JSON policy. Use this option when
|
41 |
-
* creating a signed URL for a custom
|
42 |
-
* policy.
|
43 |
-
*
|
44 |
-
* @return string The file URL with authentication parameters
|
45 |
-
* @throws \InvalidArgumentException if the URL provided is invalid
|
46 |
-
* @link http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/WorkingWithStreamingDistributions.html
|
47 |
-
*/
|
48 |
-
public function getSignedUrl($url, $expires = null, $policy = null)
|
49 |
-
{
|
50 |
-
// Determine the scheme of the url
|
51 |
-
$urlSections = explode('://', $url);
|
52 |
-
|
53 |
-
if (count($urlSections) < 2) {
|
54 |
-
throw new \InvalidArgumentException("Invalid URL: {$url}");
|
55 |
-
}
|
56 |
-
|
57 |
-
// Get the real scheme by removing wildcards from the scheme
|
58 |
-
$scheme = str_replace('*', '', $urlSections[0]);
|
59 |
-
$uri = new Uri($scheme . '://' . $urlSections[1]);
|
60 |
-
$query = Psr7\parse_query($uri->getQuery(), PHP_QUERY_RFC3986);
|
61 |
-
$signature = $this->signer->getSignature(
|
62 |
-
$this->createResource($scheme, (string) $uri),
|
63 |
-
$expires,
|
64 |
-
$policy
|
65 |
-
);
|
66 |
-
$uri = $uri->withQuery(
|
67 |
-
http_build_query($query + $signature, null, '&', PHP_QUERY_RFC3986)
|
68 |
-
);
|
69 |
-
|
70 |
-
return $scheme === 'rtmp'
|
71 |
-
? $this->createRtmpUrl($uri)
|
72 |
-
: (string) $uri;
|
73 |
-
}
|
74 |
-
|
75 |
-
private function createRtmpUrl(UriInterface $uri)
|
76 |
-
{
|
77 |
-
// Use a relative URL when creating Flash player URLs
|
78 |
-
$result = ltrim($uri->getPath(), '/');
|
79 |
-
|
80 |
-
if ($query = $uri->getQuery()) {
|
81 |
-
$result .= '?' . $query;
|
82 |
-
}
|
83 |
-
|
84 |
-
return $result;
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* @param $scheme
|
89 |
-
* @param $url
|
90 |
-
*
|
91 |
-
* @return string
|
92 |
-
*/
|
93 |
-
private function createResource($scheme, $url)
|
94 |
-
{
|
95 |
-
switch ($scheme) {
|
96 |
-
case 'http':
|
97 |
-
case 'http*':
|
98 |
-
case 'https':
|
99 |
-
return $url;
|
100 |
-
case 'rtmp':
|
101 |
-
$parts = parse_url($url);
|
102 |
-
$pathParts = pathinfo($parts['path']);
|
103 |
-
$resource = ltrim(
|
104 |
-
$pathParts['dirname'] . '/' . $pathParts['basename'],
|
105 |
-
'/'
|
106 |
-
);
|
107 |
-
|
108 |
-
// Add a query string if present.
|
109 |
-
if (isset($parts['query'])) {
|
110 |
-
$resource .= "?{$parts['query']}";
|
111 |
-
}
|
112 |
-
|
113 |
-
return $resource;
|
114 |
-
}
|
115 |
-
|
116 |
-
throw new \InvalidArgumentException("Invalid URI scheme: {$scheme}. "
|
117 |
-
. "Scheme must be one of: http, https, or rtmp");
|
118 |
-
}
|
119 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Command.php
DELETED
@@ -1,62 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* AWS command object.
|
6 |
-
*/
|
7 |
-
class Command implements CommandInterface
|
8 |
-
{
|
9 |
-
use HasDataTrait;
|
10 |
-
|
11 |
-
/** @var string */
|
12 |
-
private $name;
|
13 |
-
|
14 |
-
/** @var HandlerList */
|
15 |
-
private $handlerList;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Accepts an associative array of command options, including:
|
19 |
-
*
|
20 |
-
* - @http: (array) Associative array of transfer options.
|
21 |
-
*
|
22 |
-
* @param string $name Name of the command
|
23 |
-
* @param array $args Arguments to pass to the command
|
24 |
-
* @param HandlerList $list Handler list
|
25 |
-
*/
|
26 |
-
public function __construct($name, array $args = [], HandlerList $list = null)
|
27 |
-
{
|
28 |
-
$this->name = $name;
|
29 |
-
$this->data = $args;
|
30 |
-
$this->handlerList = $list ?: new HandlerList();
|
31 |
-
|
32 |
-
if (!isset($this->data['@http'])) {
|
33 |
-
$this->data['@http'] = [];
|
34 |
-
}
|
35 |
-
}
|
36 |
-
|
37 |
-
public function __clone()
|
38 |
-
{
|
39 |
-
$this->handlerList = clone $this->handlerList;
|
40 |
-
}
|
41 |
-
|
42 |
-
public function getName()
|
43 |
-
{
|
44 |
-
return $this->name;
|
45 |
-
}
|
46 |
-
|
47 |
-
public function hasParam($name)
|
48 |
-
{
|
49 |
-
return array_key_exists($name, $this->data);
|
50 |
-
}
|
51 |
-
|
52 |
-
public function getHandlerList()
|
53 |
-
{
|
54 |
-
return $this->handlerList;
|
55 |
-
}
|
56 |
-
|
57 |
-
/** @deprecated */
|
58 |
-
public function get($name)
|
59 |
-
{
|
60 |
-
return $this[$name];
|
61 |
-
}
|
62 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Credentials/CredentialProvider.php
DELETED
@@ -1,488 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Credentials;
|
3 |
-
|
4 |
-
use Aws;
|
5 |
-
use Aws\Api\DateTimeResult;
|
6 |
-
use Aws\CacheInterface;
|
7 |
-
use Aws\Exception\CredentialsException;
|
8 |
-
use GuzzleHttp\Promise;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Credential providers are functions that accept no arguments and return a
|
12 |
-
* promise that is fulfilled with an {@see \Aws\Credentials\CredentialsInterface}
|
13 |
-
* or rejected with an {@see \Aws\Exception\CredentialsException}.
|
14 |
-
*
|
15 |
-
* <code>
|
16 |
-
* use Aws\Credentials\CredentialProvider;
|
17 |
-
* $provider = CredentialProvider::defaultProvider();
|
18 |
-
* // Returns a CredentialsInterface or throws.
|
19 |
-
* $creds = $provider()->wait();
|
20 |
-
* </code>
|
21 |
-
*
|
22 |
-
* Credential providers can be composed to create credentials using conditional
|
23 |
-
* logic that can create different credentials in different environments. You
|
24 |
-
* can compose multiple providers into a single provider using
|
25 |
-
* {@see Aws\Credentials\CredentialProvider::chain}. This function accepts
|
26 |
-
* providers as variadic arguments and returns a new function that will invoke
|
27 |
-
* each provider until a successful set of credentials is returned.
|
28 |
-
*
|
29 |
-
* <code>
|
30 |
-
* // First try an INI file at this location.
|
31 |
-
* $a = CredentialProvider::ini(null, '/path/to/file.ini');
|
32 |
-
* // Then try an INI file at this location.
|
33 |
-
* $b = CredentialProvider::ini(null, '/path/to/other-file.ini');
|
34 |
-
* // Then try loading from environment variables.
|
35 |
-
* $c = CredentialProvider::env();
|
36 |
-
* // Combine the three providers together.
|
37 |
-
* $composed = CredentialProvider::chain($a, $b, $c);
|
38 |
-
* // Returns a promise that is fulfilled with credentials or throws.
|
39 |
-
* $promise = $composed();
|
40 |
-
* // Wait on the credentials to resolve.
|
41 |
-
* $creds = $promise->wait();
|
42 |
-
* </code>
|
43 |
-
*/
|
44 |
-
class CredentialProvider
|
45 |
-
{
|
46 |
-
const ENV_KEY = 'AWS_ACCESS_KEY_ID';
|
47 |
-
const ENV_SECRET = 'AWS_SECRET_ACCESS_KEY';
|
48 |
-
const ENV_SESSION = 'AWS_SESSION_TOKEN';
|
49 |
-
const ENV_PROFILE = 'AWS_PROFILE';
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Create a default credential provider that first checks for environment
|
53 |
-
* variables, then checks for the "default" profile in ~/.aws/credentials,
|
54 |
-
* then checks for "profile default" profile in ~/.aws/config (which is
|
55 |
-
* the default profile of AWS CLI), then tries to make a GET Request to
|
56 |
-
* fetch credentials if Ecs environment variable is presented, then checks
|
57 |
-
* for credential_process in the "default" profile in ~/.aws/credentials,
|
58 |
-
* then for credential_process in the "default profile" profile in
|
59 |
-
* ~/.aws/config, and finally checks for EC2 instance profile credentials.
|
60 |
-
*
|
61 |
-
* This provider is automatically wrapped in a memoize function that caches
|
62 |
-
* previously provided credentials.
|
63 |
-
*
|
64 |
-
* @param array $config Optional array of ecs/instance profile credentials
|
65 |
-
* provider options.
|
66 |
-
*
|
67 |
-
* @return callable
|
68 |
-
*/
|
69 |
-
public static function defaultProvider(array $config = [])
|
70 |
-
{
|
71 |
-
$localCredentialProviders = self::localCredentialProviders();
|
72 |
-
$remoteCredentialProviders = self::remoteCredentialProviders($config);
|
73 |
-
|
74 |
-
return self::memoize(
|
75 |
-
call_user_func_array(
|
76 |
-
'self::chain',
|
77 |
-
array_merge($localCredentialProviders, $remoteCredentialProviders)
|
78 |
-
)
|
79 |
-
);
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Create a credential provider function from a set of static credentials.
|
84 |
-
*
|
85 |
-
* @param CredentialsInterface $creds
|
86 |
-
*
|
87 |
-
* @return callable
|
88 |
-
*/
|
89 |
-
public static function fromCredentials(CredentialsInterface $creds)
|
90 |
-
{
|
91 |
-
$promise = Promise\promise_for($creds);
|
92 |
-
|
93 |
-
return function () use ($promise) {
|
94 |
-
return $promise;
|
95 |
-
};
|
96 |
-
}
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Creates an aggregate credentials provider that invokes the provided
|
100 |
-
* variadic providers one after the other until a provider returns
|
101 |
-
* credentials.
|
102 |
-
*
|
103 |
-
* @return callable
|
104 |
-
*/
|
105 |
-
public static function chain()
|
106 |
-
{
|
107 |
-
$links = func_get_args();
|
108 |
-
if (empty($links)) {
|
109 |
-
throw new \InvalidArgumentException('No providers in chain');
|
110 |
-
}
|
111 |
-
|
112 |
-
return function () use ($links) {
|
113 |
-
/** @var callable $parent */
|
114 |
-
$parent = array_shift($links);
|
115 |
-
$promise = $parent();
|
116 |
-
while ($next = array_shift($links)) {
|
117 |
-
$promise = $promise->otherwise($next);
|
118 |
-
}
|
119 |
-
return $promise;
|
120 |
-
};
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Wraps a credential provider and caches previously provided credentials.
|
125 |
-
*
|
126 |
-
* Ensures that cached credentials are refreshed when they expire.
|
127 |
-
*
|
128 |
-
* @param callable $provider Credentials provider function to wrap.
|
129 |
-
*
|
130 |
-
* @return callable
|
131 |
-
*/
|
132 |
-
public static function memoize(callable $provider)
|
133 |
-
{
|
134 |
-
return function () use ($provider) {
|
135 |
-
static $result;
|
136 |
-
static $isConstant;
|
137 |
-
|
138 |
-
// Constant credentials will be returned constantly.
|
139 |
-
if ($isConstant) {
|
140 |
-
return $result;
|
141 |
-
}
|
142 |
-
|
143 |
-
// Create the initial promise that will be used as the cached value
|
144 |
-
// until it expires.
|
145 |
-
if (null === $result) {
|
146 |
-
$result = $provider();
|
147 |
-
}
|
148 |
-
|
149 |
-
// Return credentials that could expire and refresh when needed.
|
150 |
-
return $result
|
151 |
-
->then(function (CredentialsInterface $creds) use ($provider, &$isConstant, &$result) {
|
152 |
-
// Determine if these are constant credentials.
|
153 |
-
if (!$creds->getExpiration()) {
|
154 |
-
$isConstant = true;
|
155 |
-
return $creds;
|
156 |
-
}
|
157 |
-
|
158 |
-
// Refresh expired credentials.
|
159 |
-
if (!$creds->isExpired()) {
|
160 |
-
return $creds;
|
161 |
-
}
|
162 |
-
// Refresh the result and forward the promise.
|
163 |
-
return $result = $provider();
|
164 |
-
})
|
165 |
-
->otherwise(function($reason) use (&$result) {
|
166 |
-
// Cleanup rejected promise.
|
167 |
-
$result = null;
|
168 |
-
return new Promise\RejectedPromise($reason);
|
169 |
-
});
|
170 |
-
};
|
171 |
-
}
|
172 |
-
|
173 |
-
/**
|
174 |
-
* Wraps a credential provider and saves provided credentials in an
|
175 |
-
* instance of Aws\CacheInterface. Forwards calls when no credentials found
|
176 |
-
* in cache and updates cache with the results.
|
177 |
-
*
|
178 |
-
* Defaults to using a simple file-based cache when none provided.
|
179 |
-
*
|
180 |
-
* @param callable $provider Credentials provider function to wrap
|
181 |
-
* @param CacheInterface $cache Cache to store credentials
|
182 |
-
* @param string|null $cacheKey (optional) Cache key to use
|
183 |
-
*
|
184 |
-
* @return callable
|
185 |
-
*/
|
186 |
-
public static function cache(
|
187 |
-
callable $provider,
|
188 |
-
CacheInterface $cache,
|
189 |
-
$cacheKey = null
|
190 |
-
) {
|
191 |
-
$cacheKey = $cacheKey ?: 'aws_cached_credentials';
|
192 |
-
|
193 |
-
return function () use ($provider, $cache, $cacheKey) {
|
194 |
-
$found = $cache->get($cacheKey);
|
195 |
-
if ($found instanceof CredentialsInterface && !$found->isExpired()) {
|
196 |
-
return Promise\promise_for($found);
|
197 |
-
}
|
198 |
-
|
199 |
-
return $provider()
|
200 |
-
->then(function (CredentialsInterface $creds) use (
|
201 |
-
$cache,
|
202 |
-
$cacheKey
|
203 |
-
) {
|
204 |
-
$cache->set(
|
205 |
-
$cacheKey,
|
206 |
-
$creds,
|
207 |
-
null === $creds->getExpiration() ?
|
208 |
-
0 : $creds->getExpiration() - time()
|
209 |
-
);
|
210 |
-
|
211 |
-
return $creds;
|
212 |
-
});
|
213 |
-
};
|
214 |
-
}
|
215 |
-
|
216 |
-
/**
|
217 |
-
* Provider that creates credentials from environment variables
|
218 |
-
* AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN.
|
219 |
-
*
|
220 |
-
* @return callable
|
221 |
-
*/
|
222 |
-
public static function env()
|
223 |
-
{
|
224 |
-
return function () {
|
225 |
-
// Use credentials from environment variables, if available
|
226 |
-
$key = getenv(self::ENV_KEY);
|
227 |
-
$secret = getenv(self::ENV_SECRET);
|
228 |
-
if ($key && $secret) {
|
229 |
-
return Promise\promise_for(
|
230 |
-
new Credentials($key, $secret, getenv(self::ENV_SESSION) ?: NULL)
|
231 |
-
);
|
232 |
-
}
|
233 |
-
|
234 |
-
return self::reject('Could not find environment variable '
|
235 |
-
. 'credentials in ' . self::ENV_KEY . '/' . self::ENV_SECRET);
|
236 |
-
};
|
237 |
-
}
|
238 |
-
|
239 |
-
/**
|
240 |
-
* Credential provider that creates credentials using instance profile
|
241 |
-
* credentials.
|
242 |
-
*
|
243 |
-
* @param array $config Array of configuration data.
|
244 |
-
*
|
245 |
-
* @return InstanceProfileProvider
|
246 |
-
* @see Aws\Credentials\InstanceProfileProvider for $config details.
|
247 |
-
*/
|
248 |
-
public static function instanceProfile(array $config = [])
|
249 |
-
{
|
250 |
-
return new InstanceProfileProvider($config);
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* Credential provider that creates credentials using
|
255 |
-
* ecs credentials by a GET request, whose uri is specified
|
256 |
-
* by environment variable
|
257 |
-
*
|
258 |
-
* @param array $config Array of configuration data.
|
259 |
-
*
|
260 |
-
* @return EcsCredentialProvider
|
261 |
-
* @see Aws\Credentials\EcsCredentialProvider for $config details.
|
262 |
-
*/
|
263 |
-
public static function ecsCredentials(array $config = [])
|
264 |
-
{
|
265 |
-
return new EcsCredentialProvider($config);
|
266 |
-
}
|
267 |
-
|
268 |
-
/**
|
269 |
-
* Credential provider that creates credentials using assume role
|
270 |
-
*
|
271 |
-
* @param array $config Array of configuration data
|
272 |
-
* @return callable
|
273 |
-
* @see Aws\Credentials\AssumeRoleCredentialProvider for $config details.
|
274 |
-
*/
|
275 |
-
public static function assumeRole(array $config=[])
|
276 |
-
{
|
277 |
-
return new AssumeRoleCredentialProvider($config);
|
278 |
-
}
|
279 |
-
|
280 |
-
/**
|
281 |
-
* Credentials provider that creates credentials using an ini file stored
|
282 |
-
* in the current user's home directory.
|
283 |
-
*
|
284 |
-
* @param string|null $profile Profile to use. If not specified will use
|
285 |
-
* the "default" profile in "~/.aws/credentials".
|
286 |
-
* @param string|null $filename If provided, uses a custom filename rather
|
287 |
-
* than looking in the home directory.
|
288 |
-
*
|
289 |
-
* @return callable
|
290 |
-
*/
|
291 |
-
public static function ini($profile = null, $filename = null)
|
292 |
-
{
|
293 |
-
$filename = $filename ?: (self::getHomeDir() . '/.aws/credentials');
|
294 |
-
$profile = $profile ?: (getenv(self::ENV_PROFILE) ?: 'default');
|
295 |
-
|
296 |
-
return function () use ($profile, $filename) {
|
297 |
-
if (!is_readable($filename)) {
|
298 |
-
return self::reject("Cannot read credentials from $filename");
|
299 |
-
}
|
300 |
-
$data = \Aws\parse_ini_file($filename, true, INI_SCANNER_RAW);
|
301 |
-
if ($data === false) {
|
302 |
-
return self::reject("Invalid credentials file: $filename");
|
303 |
-
}
|
304 |
-
if (!isset($data[$profile])) {
|
305 |
-
return self::reject("'$profile' not found in credentials file");
|
306 |
-
}
|
307 |
-
if (!isset($data[$profile]['aws_access_key_id'])
|
308 |
-
|| !isset($data[$profile]['aws_secret_access_key'])
|
309 |
-
) {
|
310 |
-
return self::reject("No credentials present in INI profile "
|
311 |
-
. "'$profile' ($filename)");
|
312 |
-
}
|
313 |
-
|
314 |
-
if (empty($data[$profile]['aws_session_token'])) {
|
315 |
-
$data[$profile]['aws_session_token']
|
316 |
-
= isset($data[$profile]['aws_security_token'])
|
317 |
-
? $data[$profile]['aws_security_token']
|
318 |
-
: null;
|
319 |
-
}
|
320 |
-
|
321 |
-
return Promise\promise_for(
|
322 |
-
new Credentials(
|
323 |
-
$data[$profile]['aws_access_key_id'],
|
324 |
-
$data[$profile]['aws_secret_access_key'],
|
325 |
-
$data[$profile]['aws_session_token']
|
326 |
-
)
|
327 |
-
);
|
328 |
-
};
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* Credentials provider that creates credentials using a process configured in
|
333 |
-
* ini file stored in the current user's home directory.
|
334 |
-
*
|
335 |
-
* @param string|null $profile Profile to use. If not specified will use
|
336 |
-
* the "default" profile in "~/.aws/credentials".
|
337 |
-
* @param string|null $filename If provided, uses a custom filename rather
|
338 |
-
* than looking in the home directory.
|
339 |
-
*
|
340 |
-
* @return callable
|
341 |
-
*/
|
342 |
-
public static function process($profile = null, $filename = null)
|
343 |
-
{
|
344 |
-
$filename = $filename ?: (self::getHomeDir() . '/.aws/credentials');
|
345 |
-
$profile = $profile ?: (getenv(self::ENV_PROFILE) ?: 'default');
|
346 |
-
|
347 |
-
return function () use ($profile, $filename) {
|
348 |
-
if (!is_readable($filename)) {
|
349 |
-
return self::reject("Cannot read process credentials from $filename");
|
350 |
-
}
|
351 |
-
$data = \Aws\parse_ini_file($filename, true, INI_SCANNER_RAW);
|
352 |
-
if ($data === false) {
|
353 |
-
return self::reject("Invalid credentials file: $filename");
|
354 |
-
}
|
355 |
-
if (!isset($data[$profile])) {
|
356 |
-
return self::reject("'$profile' not found in credentials file");
|
357 |
-
}
|
358 |
-
if (!isset($data[$profile]['credential_process'])
|
359 |
-
) {
|
360 |
-
return self::reject("No credential_process present in INI profile "
|
361 |
-
. "'$profile' ($filename)");
|
362 |
-
}
|
363 |
-
|
364 |
-
$credentialProcess = $data[$profile]['credential_process'];
|
365 |
-
$json = shell_exec($credentialProcess);
|
366 |
-
|
367 |
-
$processData = json_decode($json, true);
|
368 |
-
|
369 |
-
// Only support version 1
|
370 |
-
if (isset($processData['Version'])) {
|
371 |
-
if ($processData['Version'] !== 1) {
|
372 |
-
return self::reject("credential_process does not return Version == 1");
|
373 |
-
}
|
374 |
-
}
|
375 |
-
|
376 |
-
if (!isset($processData['AccessKeyId']) || !isset($processData['SecretAccessKey'])) {
|
377 |
-
return self::reject("credential_process does not return valid credentials");
|
378 |
-
}
|
379 |
-
|
380 |
-
if (isset($processData['Expiration'])) {
|
381 |
-
try {
|
382 |
-
$expiration = new DateTimeResult($processData['Expiration']);
|
383 |
-
} catch (\Exception $e) {
|
384 |
-
return self::reject("credential_process returned invalid expiration");
|
385 |
-
}
|
386 |
-
$now = new DateTimeResult();
|
387 |
-
if ($expiration < $now) {
|
388 |
-
return self::reject("credential_process returned expired credentials");
|
389 |
-
}
|
390 |
-
} else {
|
391 |
-
$processData['Expiration'] = null;
|
392 |
-
}
|
393 |
-
|
394 |
-
if (empty($processData['SessionToken'])) {
|
395 |
-
$processData['SessionToken'] = null;
|
396 |
-
}
|
397 |
-
|
398 |
-
return Promise\promise_for(
|
399 |
-
new Credentials(
|
400 |
-
$processData['AccessKeyId'],
|
401 |
-
$processData['SecretAccessKey'],
|
402 |
-
$processData['SessionToken'],
|
403 |
-
$processData['Expiration']
|
404 |
-
)
|
405 |
-
);
|
406 |
-
};
|
407 |
-
}
|
408 |
-
|
409 |
-
|
410 |
-
/**
|
411 |
-
* Local credential providers returns a list of local credential providers
|
412 |
-
* in following order:
|
413 |
-
* - credentials from environment variables
|
414 |
-
* - 'default' profile in '.aws/credentials' file
|
415 |
-
* - 'profile default' profile in '.aws/config' file
|
416 |
-
*
|
417 |
-
* @return array
|
418 |
-
*/
|
419 |
-
private static function localCredentialProviders()
|
420 |
-
{
|
421 |
-
return [
|
422 |
-
self::env(),
|
423 |
-
self::ini(),
|
424 |
-
self::ini('profile default', self::getHomeDir() . '/.aws/config')
|
425 |
-
];
|
426 |
-
}
|
427 |
-
|
428 |
-
/**
|
429 |
-
* Remote credential providers returns a list of credentials providers
|
430 |
-
* for the remote endpoints such as EC2 or ECS Roles.
|
431 |
-
*
|
432 |
-
* @param array $config Array of configuration data.
|
433 |
-
*
|
434 |
-
* @return array
|
435 |
-
* @see Aws\Credentials\InstanceProfileProvider for $config details.
|
436 |
-
* @see Aws\Credentials\EcsCredentialProvider for $config details.
|
437 |
-
*/
|
438 |
-
private static function remoteCredentialProviders(array $config = [])
|
439 |
-
{
|
440 |
-
if (!empty(getenv(EcsCredentialProvider::ENV_URI))) {
|
441 |
-
$providers['ecs'] = self::ecsCredentials($config);
|
442 |
-
}
|
443 |
-
$providers['process_credentials'] = self::process();
|
444 |
-
$providers['process_config'] = self::process(
|
445 |
-
'profile default',
|
446 |
-
self::getHomeDir() . '/.aws/config'
|
447 |
-
);
|
448 |
-
$providers['instance'] = self::instanceProfile($config);
|
449 |
-
|
450 |
-
if (isset($config['credentials'])
|
451 |
-
&& $config['credentials'] instanceof CacheInterface
|
452 |
-
) {
|
453 |
-
foreach ($providers as $key => $provider) {
|
454 |
-
$providers[$key] = self::cache(
|
455 |
-
$provider,
|
456 |
-
$config['credentials'],
|
457 |
-
'aws_cached_' . $key . '_credentials'
|
458 |
-
);
|
459 |
-
}
|
460 |
-
}
|
461 |
-
|
462 |
-
return $providers;
|
463 |
-
}
|
464 |
-
|
465 |
-
/**
|
466 |
-
* Gets the environment's HOME directory if available.
|
467 |
-
*
|
468 |
-
* @return null|string
|
469 |
-
*/
|
470 |
-
private static function getHomeDir()
|
471 |
-
{
|
472 |
-
// On Linux/Unix-like systems, use the HOME environment variable
|
473 |
-
if ($homeDir = getenv('HOME')) {
|
474 |
-
return $homeDir;
|
475 |
-
}
|
476 |
-
|
477 |
-
// Get the HOMEDRIVE and HOMEPATH values for Windows hosts
|
478 |
-
$homeDrive = getenv('HOMEDRIVE');
|
479 |
-
$homePath = getenv('HOMEPATH');
|
480 |
-
|
481 |
-
return ($homeDrive && $homePath) ? $homeDrive . $homePath : null;
|
482 |
-
}
|
483 |
-
|
484 |
-
private static function reject($msg)
|
485 |
-
{
|
486 |
-
return new Promise\RejectedPromise(new CredentialsException($msg));
|
487 |
-
}
|
488 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Credentials/EcsCredentialProvider.php
DELETED
@@ -1,88 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Credentials;
|
3 |
-
|
4 |
-
use Aws\Exception\CredentialsException;
|
5 |
-
use GuzzleHttp\Psr7\Request;
|
6 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
7 |
-
use Psr\Http\Message\ResponseInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Credential provider that fetches credentials with GET request.
|
11 |
-
* ECS environment variable is used in constructing request URI.
|
12 |
-
*/
|
13 |
-
class EcsCredentialProvider
|
14 |
-
{
|
15 |
-
const SERVER_URI = 'http://169.254.170.2';
|
16 |
-
const ENV_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
|
17 |
-
|
18 |
-
/** @var callable */
|
19 |
-
private $client;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* The constructor accepts following options:
|
23 |
-
* - timeout: (optional) Connection timeout, in seconds, default 1.0
|
24 |
-
* - client: An EcsClient to make request from
|
25 |
-
*
|
26 |
-
* @param array $config Configuration options
|
27 |
-
*/
|
28 |
-
public function __construct(array $config = [])
|
29 |
-
{
|
30 |
-
$this->timeout = isset($config['timeout']) ? $config['timeout'] : 1.0;
|
31 |
-
$this->client = isset($config['client'])
|
32 |
-
? $config['client']
|
33 |
-
: \Aws\default_http_handler();
|
34 |
-
}
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Load ECS credentials
|
38 |
-
*
|
39 |
-
* @return PromiseInterface
|
40 |
-
*/
|
41 |
-
public function __invoke()
|
42 |
-
{
|
43 |
-
$client = $this->client;
|
44 |
-
$request = new Request('GET', self::getEcsUri());
|
45 |
-
return $client(
|
46 |
-
$request,
|
47 |
-
[
|
48 |
-
'timeout' => $this->timeout,
|
49 |
-
'proxy' => '',
|
50 |
-
]
|
51 |
-
)->then(function (ResponseInterface $response) {
|
52 |
-
$result = $this->decodeResult((string) $response->getBody());
|
53 |
-
return new Credentials(
|
54 |
-
$result['AccessKeyId'],
|
55 |
-
$result['SecretAccessKey'],
|
56 |
-
$result['Token'],
|
57 |
-
strtotime($result['Expiration'])
|
58 |
-
);
|
59 |
-
})->otherwise(function ($reason) {
|
60 |
-
$reason = is_array($reason) ? $reason['exception'] : $reason;
|
61 |
-
$msg = $reason->getMessage();
|
62 |
-
throw new CredentialsException(
|
63 |
-
"Error retrieving credential from ECS ($msg)"
|
64 |
-
);
|
65 |
-
});
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Fetch credential URI from ECS environment variable
|
70 |
-
*
|
71 |
-
* @return string Returns ECS URI
|
72 |
-
*/
|
73 |
-
private function getEcsUri()
|
74 |
-
{
|
75 |
-
$creds_uri = getenv(self::ENV_URI);
|
76 |
-
return self::SERVER_URI . $creds_uri;
|
77 |
-
}
|
78 |
-
|
79 |
-
private function decodeResult($response)
|
80 |
-
{
|
81 |
-
$result = json_decode($response, true);
|
82 |
-
|
83 |
-
if (!isset($result['AccessKeyId'])) {
|
84 |
-
throw new CredentialsException('Unexpected ECS credential value');
|
85 |
-
}
|
86 |
-
return $result;
|
87 |
-
}
|
88 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Credentials/InstanceProfileProvider.php
DELETED
@@ -1,118 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Credentials;
|
3 |
-
|
4 |
-
use Aws\Exception\CredentialsException;
|
5 |
-
use Aws\Sdk;
|
6 |
-
use GuzzleHttp\Promise;
|
7 |
-
use GuzzleHttp\Psr7\Request;
|
8 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
9 |
-
use Psr\Http\Message\ResponseInterface;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Credential provider that provides credentials from the EC2 metadata server.
|
13 |
-
*/
|
14 |
-
class InstanceProfileProvider
|
15 |
-
{
|
16 |
-
const SERVER_URI = 'http://169.254.169.254/latest/';
|
17 |
-
const CRED_PATH = 'meta-data/iam/security-credentials/';
|
18 |
-
|
19 |
-
const ENV_DISABLE = 'AWS_EC2_METADATA_DISABLED';
|
20 |
-
|
21 |
-
/** @var string */
|
22 |
-
private $profile;
|
23 |
-
|
24 |
-
/** @var callable */
|
25 |
-
private $client;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* The constructor accepts the following options:
|
29 |
-
*
|
30 |
-
* - timeout: Connection timeout, in seconds.
|
31 |
-
* - profile: Optional EC2 profile name, if known.
|
32 |
-
*
|
33 |
-
* @param array $config Configuration options.
|
34 |
-
*/
|
35 |
-
public function __construct(array $config = [])
|
36 |
-
{
|
37 |
-
$this->timeout = isset($config['timeout']) ? $config['timeout'] : 1.0;
|
38 |
-
$this->profile = isset($config['profile']) ? $config['profile'] : null;
|
39 |
-
$this->client = isset($config['client'])
|
40 |
-
? $config['client'] // internal use only
|
41 |
-
: \Aws\default_http_handler();
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Loads instance profile credentials.
|
46 |
-
*
|
47 |
-
* @return PromiseInterface
|
48 |
-
*/
|
49 |
-
public function __invoke()
|
50 |
-
{
|
51 |
-
return Promise\coroutine(function () {
|
52 |
-
if (!$this->profile) {
|
53 |
-
$this->profile = (yield $this->request(self::CRED_PATH));
|
54 |
-
}
|
55 |
-
$json = (yield $this->request(self::CRED_PATH . $this->profile));
|
56 |
-
$result = $this->decodeResult($json);
|
57 |
-
yield new Credentials(
|
58 |
-
$result['AccessKeyId'],
|
59 |
-
$result['SecretAccessKey'],
|
60 |
-
$result['Token'],
|
61 |
-
strtotime($result['Expiration'])
|
62 |
-
);
|
63 |
-
});
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* @param string $url
|
68 |
-
* @return PromiseInterface Returns a promise that is fulfilled with the
|
69 |
-
* body of the response as a string.
|
70 |
-
*/
|
71 |
-
private function request($url)
|
72 |
-
{
|
73 |
-
$disabled = getenv(self::ENV_DISABLE) ?: false;
|
74 |
-
if (strcasecmp($disabled, 'true') === 0) {
|
75 |
-
throw new CredentialsException(
|
76 |
-
$this->createErrorMessage('EC2 metadata server access disabled')
|
77 |
-
);
|
78 |
-
}
|
79 |
-
|
80 |
-
$fn = $this->client;
|
81 |
-
$request = new Request('GET', self::SERVER_URI . $url);
|
82 |
-
$userAgent = 'aws-sdk-php/' . Sdk::VERSION;
|
83 |
-
if (defined('HHVM_VERSION')) {
|
84 |
-
$userAgent .= ' HHVM/' . HHVM_VERSION;
|
85 |
-
}
|
86 |
-
$userAgent .= ' ' . \Aws\default_user_agent();
|
87 |
-
$request = $request->withHeader('User-Agent', $userAgent);
|
88 |
-
|
89 |
-
return $fn($request, ['timeout' => $this->timeout])
|
90 |
-
->then(function (ResponseInterface $response) {
|
91 |
-
return (string) $response->getBody();
|
92 |
-
})->otherwise(function (array $reason) {
|
93 |
-
$reason = $reason['exception'];
|
94 |
-
$msg = $reason->getMessage();
|
95 |
-
throw new CredentialsException(
|
96 |
-
$this->createErrorMessage($msg)
|
97 |
-
);
|
98 |
-
});
|
99 |
-
}
|
100 |
-
|
101 |
-
private function createErrorMessage($previous)
|
102 |
-
{
|
103 |
-
return "Error retrieving credentials from the instance profile "
|
104 |
-
. "metadata server. ({$previous})";
|
105 |
-
}
|
106 |
-
|
107 |
-
private function decodeResult($response)
|
108 |
-
{
|
109 |
-
$result = json_decode($response, true);
|
110 |
-
|
111 |
-
if ($result['Code'] !== 'Success') {
|
112 |
-
throw new CredentialsException('Unexpected instance profile '
|
113 |
-
. 'response code: ' . $result['Code']);
|
114 |
-
}
|
115 |
-
|
116 |
-
return $result;
|
117 |
-
}
|
118 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Endpoint/Partition.php
DELETED
@@ -1,183 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Endpoint;
|
3 |
-
|
4 |
-
use ArrayAccess;
|
5 |
-
use Aws\HasDataTrait;
|
6 |
-
use InvalidArgumentException as Iae;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Default implementation of an AWS partition.
|
10 |
-
*/
|
11 |
-
final class Partition implements ArrayAccess, PartitionInterface
|
12 |
-
{
|
13 |
-
use HasDataTrait;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* The partition constructor accepts the following options:
|
17 |
-
*
|
18 |
-
* - `partition`: (string, required) The partition name as specified in an
|
19 |
-
* ARN (e.g., `aws`)
|
20 |
-
* - `partitionName`: (string) The human readable name of the partition
|
21 |
-
* (e.g., "AWS Standard")
|
22 |
-
* - `dnsSuffix`: (string, required) The DNS suffix of the partition. This
|
23 |
-
* value is used to determine how endpoints in the partition are resolved.
|
24 |
-
* - `regionRegex`: (string) A PCRE regular expression that specifies the
|
25 |
-
* pattern that region names in the endpoint adhere to.
|
26 |
-
* - `regions`: (array, required) A map of the regions in the partition.
|
27 |
-
* Each key is the region as present in a hostname (e.g., `us-east-1`),
|
28 |
-
* and each value is a structure containing region information.
|
29 |
-
* - `defaults`: (array) A map of default key value pairs to apply to each
|
30 |
-
* endpoint of the partition. Any value in an `endpoint` definition will
|
31 |
-
* supersede any values specified in `defaults`.
|
32 |
-
* - `services`: (array, required) A map of service endpoint prefix name
|
33 |
-
* (the value found in a hostname) to information about the service.
|
34 |
-
*
|
35 |
-
* @param array $definition
|
36 |
-
*
|
37 |
-
* @throws Iae if any required options are missing
|
38 |
-
*/
|
39 |
-
public function __construct(array $definition)
|
40 |
-
{
|
41 |
-
foreach (['partition', 'regions', 'services', 'dnsSuffix'] as $key) {
|
42 |
-
if (!isset($definition[$key])) {
|
43 |
-
throw new Iae("Partition missing required $key field");
|
44 |
-
}
|
45 |
-
}
|
46 |
-
|
47 |
-
$this->data = $definition;
|
48 |
-
}
|
49 |
-
|
50 |
-
public function getName()
|
51 |
-
{
|
52 |
-
return $this->data['partition'];
|
53 |
-
}
|
54 |
-
|
55 |
-
public function isRegionMatch($region, $service)
|
56 |
-
{
|
57 |
-
if (isset($this->data['regions'][$region])
|
58 |
-
|| isset($this->data['services'][$service]['endpoints'][$region])
|
59 |
-
) {
|
60 |
-
return true;
|
61 |
-
}
|
62 |
-
|
63 |
-
if (isset($this->data['regionRegex'])) {
|
64 |
-
return (bool) preg_match(
|
65 |
-
"@{$this->data['regionRegex']}@",
|
66 |
-
$region
|
67 |
-
);
|
68 |
-
}
|
69 |
-
|
70 |
-
return false;
|
71 |
-
}
|
72 |
-
|
73 |
-
public function getAvailableEndpoints(
|
74 |
-
$service,
|
75 |
-
$allowNonRegionalEndpoints = false
|
76 |
-
) {
|
77 |
-
if ($this->isServicePartitionGlobal($service)) {
|
78 |
-
return [$this->getPartitionEndpoint($service)];
|
79 |
-
}
|
80 |
-
|
81 |
-
if (isset($this->data['services'][$service]['endpoints'])) {
|
82 |
-
$serviceRegions = array_keys(
|
83 |
-
$this->data['services'][$service]['endpoints']
|
84 |
-
);
|
85 |
-
|
86 |
-
return $allowNonRegionalEndpoints
|
87 |
-
? $serviceRegions
|
88 |
-
: array_intersect($serviceRegions, array_keys(
|
89 |
-
$this->data['regions']
|
90 |
-
));
|
91 |
-
}
|
92 |
-
|
93 |
-
return [];
|
94 |
-
}
|
95 |
-
|
96 |
-
public function __invoke(array $args = [])
|
97 |
-
{
|
98 |
-
$service = isset($args['service']) ? $args['service'] : '';
|
99 |
-
$region = isset($args['region']) ? $args['region'] : '';
|
100 |
-
$scheme = isset($args['scheme']) ? $args['scheme'] : 'https';
|
101 |
-
$data = $this->getEndpointData($service, $region);
|
102 |
-
|
103 |
-
return [
|
104 |
-
'endpoint' => "{$scheme}://" . $this->formatEndpoint(
|
105 |
-
isset($data['hostname']) ? $data['hostname'] : '',
|
106 |
-
$service,
|
107 |
-
$region
|
108 |
-
),
|
109 |
-
'signatureVersion' => $this->getSignatureVersion($data),
|
110 |
-
'signingRegion' => isset($data['credentialScope']['region'])
|
111 |
-
? $data['credentialScope']['region']
|
112 |
-
: $region,
|
113 |
-
'signingName' => isset($data['credentialScope']['service'])
|
114 |
-
? $data['credentialScope']['service']
|
115 |
-
: $service,
|
116 |
-
];
|
117 |
-
}
|
118 |
-
|
119 |
-
private function getEndpointData($service, $region)
|
120 |
-
{
|
121 |
-
|
122 |
-
$resolved = $this->resolveRegion($service, $region);
|
123 |
-
$data = isset($this->data['services'][$service]['endpoints'][$resolved])
|
124 |
-
? $this->data['services'][$service]['endpoints'][$resolved]
|
125 |
-
: [];
|
126 |
-
$data += isset($this->data['services'][$service]['defaults'])
|
127 |
-
? $this->data['services'][$service]['defaults']
|
128 |
-
: [];
|
129 |
-
$data += isset($this->data['defaults'])
|
130 |
-
? $this->data['defaults']
|
131 |
-
: [];
|
132 |
-
|
133 |
-
return $data;
|
134 |
-
}
|
135 |
-
|
136 |
-
private function getSignatureVersion(array $data)
|
137 |
-
{
|
138 |
-
static $supportedBySdk = [
|
139 |
-
's3v4',
|
140 |
-
'v4',
|
141 |
-
'anonymous',
|
142 |
-
];
|
143 |
-
|
144 |
-
$possibilities = array_intersect(
|
145 |
-
$supportedBySdk,
|
146 |
-
isset($data['signatureVersions'])
|
147 |
-
? $data['signatureVersions']
|
148 |
-
: ['v4']
|
149 |
-
);
|
150 |
-
|
151 |
-
return array_shift($possibilities);
|
152 |
-
}
|
153 |
-
|
154 |
-
private function resolveRegion($service, $region)
|
155 |
-
{
|
156 |
-
if ($this->isServicePartitionGlobal($service)) {
|
157 |
-
return $this->getPartitionEndpoint($service);
|
158 |
-
}
|
159 |
-
|
160 |
-
return $region;
|
161 |
-
}
|
162 |
-
|
163 |
-
private function isServicePartitionGlobal($service)
|
164 |
-
{
|
165 |
-
return isset($this->data['services'][$service]['isRegionalized'])
|
166 |
-
&& false === $this->data['services'][$service]['isRegionalized']
|
167 |
-
&& isset($this->data['services'][$service]['partitionEndpoint']);
|
168 |
-
}
|
169 |
-
|
170 |
-
private function getPartitionEndpoint($service)
|
171 |
-
{
|
172 |
-
return $this->data['services'][$service]['partitionEndpoint'];
|
173 |
-
}
|
174 |
-
|
175 |
-
private function formatEndpoint($template, $service, $region)
|
176 |
-
{
|
177 |
-
return strtr($template, [
|
178 |
-
'{service}' => $service,
|
179 |
-
'{region}' => $region,
|
180 |
-
'{dnsSuffix}' => $this->data['dnsSuffix'],
|
181 |
-
]);
|
182 |
-
}
|
183 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Endpoint/PartitionEndpointProvider.php
DELETED
@@ -1,108 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Endpoint;
|
3 |
-
|
4 |
-
use JmesPath\Env;
|
5 |
-
|
6 |
-
class PartitionEndpointProvider
|
7 |
-
{
|
8 |
-
/** @var Partition[] */
|
9 |
-
private $partitions;
|
10 |
-
/** @var string */
|
11 |
-
private $defaultPartition;
|
12 |
-
|
13 |
-
public function __construct(array $partitions, $defaultPartition = 'aws')
|
14 |
-
{
|
15 |
-
$this->partitions = array_map(function (array $definition) {
|
16 |
-
return new Partition($definition);
|
17 |
-
}, array_values($partitions));
|
18 |
-
$this->defaultPartition = $defaultPartition;
|
19 |
-
}
|
20 |
-
|
21 |
-
public function __invoke(array $args = [])
|
22 |
-
{
|
23 |
-
$partition = $this->getPartition(
|
24 |
-
isset($args['region']) ? $args['region'] : '',
|
25 |
-
isset($args['service']) ? $args['service'] : ''
|
26 |
-
);
|
27 |
-
|
28 |
-
return $partition($args);
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Returns the partition containing the provided region or the default
|
33 |
-
* partition if no match is found.
|
34 |
-
*
|
35 |
-
* @param string $region
|
36 |
-
* @param string $service
|
37 |
-
*
|
38 |
-
* @return Partition
|
39 |
-
*/
|
40 |
-
public function getPartition($region, $service)
|
41 |
-
{
|
42 |
-
foreach ($this->partitions as $partition) {
|
43 |
-
if ($partition->isRegionMatch($region, $service)) {
|
44 |
-
return $partition;
|
45 |
-
}
|
46 |
-
}
|
47 |
-
|
48 |
-
return $this->getPartitionByName($this->defaultPartition);
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Returns the partition with the provided name or null if no partition with
|
53 |
-
* the provided name can be found.
|
54 |
-
*
|
55 |
-
* @param string $name
|
56 |
-
*
|
57 |
-
* @return Partition|null
|
58 |
-
*/
|
59 |
-
public function getPartitionByName($name)
|
60 |
-
{
|
61 |
-
foreach ($this->partitions as $partition) {
|
62 |
-
if ($name === $partition->getName()) {
|
63 |
-
return $partition;
|
64 |
-
}
|
65 |
-
}
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Creates and returns the default SDK partition provider.
|
70 |
-
*
|
71 |
-
* @return PartitionEndpointProvider
|
72 |
-
*/
|
73 |
-
public static function defaultProvider()
|
74 |
-
{
|
75 |
-
$data = \Aws\load_compiled_json(__DIR__ . '/../data/endpoints.json');
|
76 |
-
$prefixData = \Aws\load_compiled_json(__DIR__ . '/../data/endpoints_prefix_history.json');
|
77 |
-
$mergedData = self::mergePrefixData($data, $prefixData);
|
78 |
-
|
79 |
-
return new self($mergedData['partitions']);
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Copy endpoint data for other prefixes used by a given service
|
84 |
-
*
|
85 |
-
* @param $data
|
86 |
-
* @param $prefixData
|
87 |
-
* @return array
|
88 |
-
*/
|
89 |
-
public static function mergePrefixData($data, $prefixData)
|
90 |
-
{
|
91 |
-
$prefixGroups = $prefixData['prefix-groups'];
|
92 |
-
|
93 |
-
foreach ($data["partitions"] as $index => $partition) {
|
94 |
-
foreach ($prefixGroups as $current => $old) {
|
95 |
-
$serviceData = Env::search("services.{$current}", $partition);
|
96 |
-
if (!empty($serviceData)) {
|
97 |
-
foreach ($old as $prefix) {
|
98 |
-
if (empty(Env::search("services.{$prefix}", $partition))) {
|
99 |
-
$data["partitions"][$index]["services"][$prefix] = $serviceData;
|
100 |
-
}
|
101 |
-
}
|
102 |
-
}
|
103 |
-
}
|
104 |
-
}
|
105 |
-
|
106 |
-
return $data;
|
107 |
-
}
|
108 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/EndpointDiscovery/ConfigurationProvider.php
DELETED
@@ -1,333 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\EndpointDiscovery;
|
3 |
-
|
4 |
-
use Aws\CacheInterface;
|
5 |
-
use Aws\EndpointDiscovery\Exception\ConfigurationException;
|
6 |
-
use GuzzleHttp\Promise;
|
7 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* A configuration provider is a function that returns a promise that is
|
11 |
-
* fulfilled with a {@see \Aws\EndpointDiscovery\ConfigurationInterface}
|
12 |
-
* or rejected with an {@see \Aws\EndpointDiscovery\Exception\ConfigurationException}.
|
13 |
-
*
|
14 |
-
* <code>
|
15 |
-
* use Aws\EndpointDiscovery\ConfigurationProvider;
|
16 |
-
* $provider = ConfigurationProvider::defaultProvider();
|
17 |
-
* // Returns a ConfigurationInterface or throws.
|
18 |
-
* $config = $provider()->wait();
|
19 |
-
* </code>
|
20 |
-
*
|
21 |
-
* Configuration providers can be composed to create configuration using
|
22 |
-
* conditional logic that can create different configurations in different
|
23 |
-
* environments. You can compose multiple providers into a single provider using
|
24 |
-
* {@see Aws\EndpointDiscovery\ConfigurationProvider::chain}. This function
|
25 |
-
* accepts providers as variadic arguments and returns a new function that will
|
26 |
-
* invoke each provider until a successful configuration is returned.
|
27 |
-
*
|
28 |
-
* <code>
|
29 |
-
* // First try an INI file at this location.
|
30 |
-
* $a = ConfigurationProvider::ini(null, '/path/to/file.ini');
|
31 |
-
* // Then try an INI file at this location.
|
32 |
-
* $b = ConfigurationProvider::ini(null, '/path/to/other-file.ini');
|
33 |
-
* // Then try loading from environment variables.
|
34 |
-
* $c = ConfigurationProvider::env();
|
35 |
-
* // Combine the three providers together.
|
36 |
-
* $composed = ConfigurationProvider::chain($a, $b, $c);
|
37 |
-
* // Returns a promise that is fulfilled with a configuration or throws.
|
38 |
-
* $promise = $composed();
|
39 |
-
* // Wait on the configuration to resolve.
|
40 |
-
* $config = $promise->wait();
|
41 |
-
* </code>
|
42 |
-
*/
|
43 |
-
class ConfigurationProvider
|
44 |
-
{
|
45 |
-
const CACHE_KEY = 'aws_cached_endpoint_discovery_config';
|
46 |
-
const DEFAULT_ENABLED = false;
|
47 |
-
const DEFAULT_CACHE_LIMIT = 1000;
|
48 |
-
const ENV_ENABLED = 'AWS_ENDPOINT_DISCOVERY_ENABLED';
|
49 |
-
const ENV_ENABLED_ALT = 'AWS_ENABLE_ENDPOINT_DISCOVERY';
|
50 |
-
const ENV_PROFILE = 'AWS_PROFILE';
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Wraps a config provider and saves provided configuration in an
|
54 |
-
* instance of Aws\CacheInterface. Forwards calls when no config found
|
55 |
-
* in cache and updates cache with the results.
|
56 |
-
*
|
57 |
-
* @param callable $provider Configuration provider function to wrap
|
58 |
-
* @param CacheInterface $cache Cache to store credentials
|
59 |
-
* @param string|null $cacheKey (optional) Cache key to use
|
60 |
-
*
|
61 |
-
* @return callable
|
62 |
-
*/
|
63 |
-
public static function cache(
|
64 |
-
callable $provider,
|
65 |
-
CacheInterface $cache,
|
66 |
-
$cacheKey = null
|
67 |
-
) {
|
68 |
-
$cacheKey = $cacheKey ?: self::CACHE_KEY;
|
69 |
-
|
70 |
-
return function () use ($provider, $cache, $cacheKey) {
|
71 |
-
$found = $cache->get($cacheKey);
|
72 |
-
if ($found instanceof ConfigurationInterface) {
|
73 |
-
return Promise\promise_for($found);
|
74 |
-
}
|
75 |
-
|
76 |
-
return $provider()
|
77 |
-
->then(function (ConfigurationInterface $config) use (
|
78 |
-
$cache,
|
79 |
-
$cacheKey
|
80 |
-
) {
|
81 |
-
$cache->set($cacheKey, $config);
|
82 |
-
return $config;
|
83 |
-
});
|
84 |
-
};
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Creates an aggregate credentials provider that invokes the provided
|
89 |
-
* variadic providers one after the other until a provider returns
|
90 |
-
* credentials.
|
91 |
-
*
|
92 |
-
* @return callable
|
93 |
-
*/
|
94 |
-
public static function chain()
|
95 |
-
{
|
96 |
-
$links = func_get_args();
|
97 |
-
if (empty($links)) {
|
98 |
-
throw new \InvalidArgumentException('No providers in chain');
|
99 |
-
}
|
100 |
-
|
101 |
-
return function () use ($links) {
|
102 |
-
/** @var callable $parent */
|
103 |
-
$parent = array_shift($links);
|
104 |
-
$promise = $parent();
|
105 |
-
while ($next = array_shift($links)) {
|
106 |
-
$promise = $promise->otherwise($next);
|
107 |
-
}
|
108 |
-
return $promise;
|
109 |
-
};
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Create a default config provider that first checks for environment
|
114 |
-
* variables, then checks for a specified profile in ~/.aws/config, then
|
115 |
-
* checks for the "default" profile in ~/.aws/config, and failing those uses
|
116 |
-
* a default fallback set of configuration options.
|
117 |
-
*
|
118 |
-
* This provider is automatically wrapped in a memoize function that caches
|
119 |
-
* previously provided config options.
|
120 |
-
*
|
121 |
-
* @param array $config Optional array of ecs/instance profile credentials
|
122 |
-
* provider options.
|
123 |
-
*
|
124 |
-
* @return callable
|
125 |
-
*/
|
126 |
-
public static function defaultProvider(array $config = [])
|
127 |
-
{
|
128 |
-
$configProviders = [
|
129 |
-
self::env(),
|
130 |
-
self::ini(),
|
131 |
-
self::fallback()
|
132 |
-
];
|
133 |
-
|
134 |
-
$memo = self::memoize(
|
135 |
-
call_user_func_array('self::chain', $configProviders)
|
136 |
-
);
|
137 |
-
|
138 |
-
if (isset($config['endpoint_discovery'])
|
139 |
-
&& $config['endpoint_discovery'] instanceof CacheInterface
|
140 |
-
) {
|
141 |
-
return self::cache($memo, $config['endpoint_discovery'], self::CACHE_KEY);
|
142 |
-
}
|
143 |
-
|
144 |
-
return $memo;
|
145 |
-
}
|
146 |
-
|
147 |
-
/**
|
148 |
-
* Provider that creates config from environment variables.
|
149 |
-
*
|
150 |
-
* @param $cacheLimit
|
151 |
-
* @return callable
|
152 |
-
*/
|
153 |
-
public static function env($cacheLimit = self::DEFAULT_CACHE_LIMIT)
|
154 |
-
{
|
155 |
-
return function () use ($cacheLimit) {
|
156 |
-
// Use config from environment variables, if available
|
157 |
-
$enabled = getenv(self::ENV_ENABLED);
|
158 |
-
if ($enabled === false || $enabled === '') {
|
159 |
-
$enabled = getenv(self::ENV_ENABLED_ALT);
|
160 |
-
}
|
161 |
-
if ($enabled !== false && $enabled !== '') {
|
162 |
-
return Promise\promise_for(
|
163 |
-
new Configuration($enabled, $cacheLimit)
|
164 |
-
);
|
165 |
-
}
|
166 |
-
|
167 |
-
return self::reject('Could not find environment variable config'
|
168 |
-
. ' in ' . self::ENV_ENABLED);
|
169 |
-
};
|
170 |
-
}
|
171 |
-
|
172 |
-
/**
|
173 |
-
* Fallback config options when other sources are not set.
|
174 |
-
*
|
175 |
-
* @return callable
|
176 |
-
*/
|
177 |
-
public static function fallback()
|
178 |
-
{
|
179 |
-
return function () {
|
180 |
-
return Promise\promise_for(
|
181 |
-
new Configuration(
|
182 |
-
self::DEFAULT_ENABLED,
|
183 |
-
self::DEFAULT_CACHE_LIMIT
|
184 |
-
)
|
185 |
-
);
|
186 |
-
};
|
187 |
-
}
|
188 |
-
|
189 |
-
/**
|
190 |
-
* Gets the environment's HOME directory if available.
|
191 |
-
*
|
192 |
-
* @return null|string
|
193 |
-
*/
|
194 |
-
private static function getHomeDir()
|
195 |
-
{
|
196 |
-
// On Linux/Unix-like systems, use the HOME environment variable
|
197 |
-
if ($homeDir = getenv('HOME')) {
|
198 |
-
return $homeDir;
|
199 |
-
}
|
200 |
-
|
201 |
-
// Get the HOMEDRIVE and HOMEPATH values for Windows hosts
|
202 |
-
$homeDrive = getenv('HOMEDRIVE');
|
203 |
-
$homePath = getenv('HOMEPATH');
|
204 |
-
|
205 |
-
return ($homeDrive && $homePath) ? $homeDrive . $homePath : null;
|
206 |
-
}
|
207 |
-
|
208 |
-
/**
|
209 |
-
* Config provider that creates config using an ini file stored
|
210 |
-
* in the current user's home directory.
|
211 |
-
*
|
212 |
-
* @param string|null $profile Profile to use. If not specified will use
|
213 |
-
* the "default" profile in "~/.aws/config".
|
214 |
-
* @param string|null $filename If provided, uses a custom filename rather
|
215 |
-
* than looking in the home directory.
|
216 |
-
* @param int $cacheLimit
|
217 |
-
*
|
218 |
-
* @return callable
|
219 |
-
*/
|
220 |
-
public static function ini(
|
221 |
-
$profile = null,
|
222 |
-
$filename = null,
|
223 |
-
$cacheLimit = self::DEFAULT_CACHE_LIMIT
|
224 |
-
) {
|
225 |
-
$filename = $filename ?: (self::getHomeDir() . '/.aws/config');
|
226 |
-
$profile = $profile ?: (getenv(self::ENV_PROFILE) ?: 'default');
|
227 |
-
|
228 |
-
return function () use ($profile, $filename, $cacheLimit) {
|
229 |
-
if (!is_readable($filename)) {
|
230 |
-
return self::reject("Cannot read configuration from $filename");
|
231 |
-
}
|
232 |
-
$data = \Aws\parse_ini_file($filename, true);
|
233 |
-
if ($data === false) {
|
234 |
-
return self::reject("Invalid config file: $filename");
|
235 |
-
}
|
236 |
-
if (!isset($data[$profile])) {
|
237 |
-
return self::reject("'$profile' not found in config file");
|
238 |
-
}
|
239 |
-
if (!isset($data[$profile]['endpoint_discovery_enabled'])) {
|
240 |
-
return self::reject("Required endpoint discovery config values
|
241 |
-
not present in INI profile '{$profile}' ({$filename})");
|
242 |
-
}
|
243 |
-
|
244 |
-
return Promise\promise_for(
|
245 |
-
new Configuration(
|
246 |
-
$data[$profile]['endpoint_discovery_enabled'],
|
247 |
-
$cacheLimit
|
248 |
-
)
|
249 |
-
);
|
250 |
-
};
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* Wraps a config provider and caches previously provided configuration.
|
255 |
-
*
|
256 |
-
* Ensures that cached configuration is refreshed when it expires.
|
257 |
-
*
|
258 |
-
* @param callable $provider Config provider function to wrap.
|
259 |
-
*
|
260 |
-
* @return callable
|
261 |
-
*/
|
262 |
-
public static function memoize(callable $provider)
|
263 |
-
{
|
264 |
-
return function () use ($provider) {
|
265 |
-
static $result;
|
266 |
-
static $isConstant;
|
267 |
-
|
268 |
-
// Constant config will be returned constantly.
|
269 |
-
if ($isConstant) {
|
270 |
-
return $result;
|
271 |
-
}
|
272 |
-
|
273 |
-
// Create the initial promise that will be used as the cached value
|
274 |
-
// until it expires.
|
275 |
-
if (null === $result) {
|
276 |
-
$result = $provider();
|
277 |
-
}
|
278 |
-
|
279 |
-
// Return config and set flag that provider is already set
|
280 |
-
return $result
|
281 |
-
->then(function (ConfigurationInterface $config) use (&$isConstant) {
|
282 |
-
$isConstant = true;
|
283 |
-
return $config;
|
284 |
-
});
|
285 |
-
};
|
286 |
-
}
|
287 |
-
|
288 |
-
/**
|
289 |
-
* Reject promise with standardized exception.
|
290 |
-
*
|
291 |
-
* @param $msg
|
292 |
-
* @return Promise\RejectedPromise
|
293 |
-
*/
|
294 |
-
private static function reject($msg)
|
295 |
-
{
|
296 |
-
return new Promise\RejectedPromise(new ConfigurationException($msg));
|
297 |
-
}
|
298 |
-
|
299 |
-
/**
|
300 |
-
* Unwraps a configuration object in whatever valid form it is in,
|
301 |
-
* always returning a ConfigurationInterface object.
|
302 |
-
*
|
303 |
-
* @param mixed $config
|
304 |
-
* @return ConfigurationInterface
|
305 |
-
* @throws \InvalidArgumentException
|
306 |
-
*/
|
307 |
-
public static function unwrap($config)
|
308 |
-
{
|
309 |
-
if (is_callable($config)) {
|
310 |
-
$config = $config();
|
311 |
-
}
|
312 |
-
if ($config instanceof PromiseInterface) {
|
313 |
-
$config = $config->wait();
|
314 |
-
}
|
315 |
-
if ($config instanceof ConfigurationInterface) {
|
316 |
-
return $config;
|
317 |
-
} elseif (is_array($config) && isset($config['enabled'])) {
|
318 |
-
if (isset($config['cache_limit'])) {
|
319 |
-
return new Configuration(
|
320 |
-
$config['enabled'],
|
321 |
-
$config['cache_limit']
|
322 |
-
);
|
323 |
-
}
|
324 |
-
return new Configuration(
|
325 |
-
$config['enabled'],
|
326 |
-
self::DEFAULT_CACHE_LIMIT
|
327 |
-
);
|
328 |
-
}
|
329 |
-
|
330 |
-
throw new \InvalidArgumentException('Not a valid endpoint_discovery '
|
331 |
-
. 'configuration argument.');
|
332 |
-
}
|
333 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/EndpointDiscovery/EndpointDiscoveryMiddleware.php
DELETED
@@ -1,414 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\EndpointDiscovery;
|
3 |
-
|
4 |
-
use Aws\AwsClient;
|
5 |
-
use Aws\CacheInterface;
|
6 |
-
use Aws\CommandInterface;
|
7 |
-
use Aws\Credentials\CredentialsInterface;
|
8 |
-
use Aws\Exception\AwsException;
|
9 |
-
use Aws\Exception\UnresolvedEndpointException;
|
10 |
-
use Aws\LruArrayCache;
|
11 |
-
use Aws\Middleware;
|
12 |
-
use Psr\Http\Message\RequestInterface;
|
13 |
-
use Psr\Http\Message\UriInterface;
|
14 |
-
|
15 |
-
class EndpointDiscoveryMiddleware
|
16 |
-
{
|
17 |
-
/**
|
18 |
-
* @var CacheInterface
|
19 |
-
*/
|
20 |
-
private static $cache;
|
21 |
-
private static $discoveryCooldown = 60;
|
22 |
-
|
23 |
-
private $args;
|
24 |
-
private $client;
|
25 |
-
private $config;
|
26 |
-
private $discoveryTimes = [];
|
27 |
-
private $nextHandler;
|
28 |
-
private $service;
|
29 |
-
|
30 |
-
public static function wrap(
|
31 |
-
$client,
|
32 |
-
$args,
|
33 |
-
$config
|
34 |
-
) {
|
35 |
-
return function (callable $handler) use (
|
36 |
-
$client,
|
37 |
-
$args,
|
38 |
-
$config
|
39 |
-
) {
|
40 |
-
return new static(
|
41 |
-
$handler,
|
42 |
-
$client,
|
43 |
-
$args,
|
44 |
-
$config
|
45 |
-
);
|
46 |
-
};
|
47 |
-
}
|
48 |
-
|
49 |
-
public function __construct(
|
50 |
-
callable $handler,
|
51 |
-
AwsClient $client,
|
52 |
-
array $args,
|
53 |
-
$config
|
54 |
-
) {
|
55 |
-
$this->nextHandler = $handler;
|
56 |
-
$this->client = $client;
|
57 |
-
$this->args = $args;
|
58 |
-
$this->service = $client->getApi();
|
59 |
-
$this->config = $config;
|
60 |
-
}
|
61 |
-
|
62 |
-
public function __invoke(CommandInterface $cmd, RequestInterface $request)
|
63 |
-
{
|
64 |
-
$nextHandler = $this->nextHandler;
|
65 |
-
$op = $this->service->getOperation($cmd->getName())->toArray();
|
66 |
-
|
67 |
-
// Continue only if endpointdiscovery trait is set
|
68 |
-
if (isset($op['endpointdiscovery'])) {
|
69 |
-
$config = ConfigurationProvider::unwrap($this->config);
|
70 |
-
$isRequired = !empty($op['endpointdiscovery']['required']);
|
71 |
-
|
72 |
-
// Continue only if required by operation or enabled by config
|
73 |
-
if ($isRequired || $config->isEnabled()) {
|
74 |
-
if (isset($op['endpointoperation'])) {
|
75 |
-
throw new UnresolvedEndpointException('This operation is '
|
76 |
-
. 'contradictorily marked both as using endpoint discovery '
|
77 |
-
. 'and being the endpoint discovery operation. Please '
|
78 |
-
. 'verify the accuracy of your model files.');
|
79 |
-
}
|
80 |
-
|
81 |
-
// Original endpoint may be used if discovery optional
|
82 |
-
$originalUri = $request->getUri();
|
83 |
-
|
84 |
-
$identifiers = $this->getIdentifiers($op);
|
85 |
-
|
86 |
-
$cacheKey = $this->getCacheKey(
|
87 |
-
$this->client->getCredentials()->wait(),
|
88 |
-
$cmd,
|
89 |
-
$identifiers
|
90 |
-
);
|
91 |
-
|
92 |
-
// Check/create cache
|
93 |
-
if (!isset(self::$cache)) {
|
94 |
-
self::$cache = new LruArrayCache($config->getCacheLimit());
|
95 |
-
}
|
96 |
-
|
97 |
-
if (empty($endpointList = self::$cache->get($cacheKey))) {
|
98 |
-
$endpointList = new EndpointList([]);
|
99 |
-
}
|
100 |
-
$endpoint = $endpointList->getActive();
|
101 |
-
|
102 |
-
// Retrieve endpoints if there is no active endpoint
|
103 |
-
if (empty($endpoint)) {
|
104 |
-
try {
|
105 |
-
$endpoint = $this->discoverEndpoint(
|
106 |
-
$cacheKey,
|
107 |
-
$cmd,
|
108 |
-
$identifiers
|
109 |
-
);
|
110 |
-
} catch (\Exception $e) {
|
111 |
-
// Use cached endpoint, expired or active, if any remain
|
112 |
-
$endpoint = $endpointList->getEndpoint();
|
113 |
-
|
114 |
-
if (empty($endpoint)) {
|
115 |
-
return $this->handleDiscoveryException(
|
116 |
-
$isRequired,
|
117 |
-
$originalUri,
|
118 |
-
$e,
|
119 |
-
$cmd,
|
120 |
-
$request
|
121 |
-
);
|
122 |
-
}
|
123 |
-
}
|
124 |
-
}
|
125 |
-
|
126 |
-
$request = $this->modifyRequest($request, $endpoint);
|
127 |
-
|
128 |
-
$g = function ($value) use (
|
129 |
-
$cacheKey,
|
130 |
-
$cmd,
|
131 |
-
$identifiers,
|
132 |
-
$isRequired,
|
133 |
-
$nextHandler,
|
134 |
-
$originalUri,
|
135 |
-
$request,
|
136 |
-
&$endpoint,
|
137 |
-
&$g
|
138 |
-
) {
|
139 |
-
if ($value instanceof AwsException
|
140 |
-
&& (
|
141 |
-
$value->getAwsErrorCode() == 'InvalidEndpointException'
|
142 |
-
|| $value->getStatusCode() == 421
|
143 |
-
)
|
144 |
-
) {
|
145 |
-
return $this->handleInvalidEndpoint(
|
146 |
-
$cacheKey,
|
147 |
-
$cmd,
|
148 |
-
$identifiers,
|
149 |
-
$isRequired,
|
150 |
-
$originalUri,
|
151 |
-
$request,
|
152 |
-
$value,
|
153 |
-
$endpoint,
|
154 |
-
$g
|
155 |
-
);
|
156 |
-
}
|
157 |
-
|
158 |
-
return $value;
|
159 |
-
};
|
160 |
-
|
161 |
-
return $nextHandler($cmd, $request)->otherwise($g);
|
162 |
-
}
|
163 |
-
}
|
164 |
-
|
165 |
-
return $nextHandler($cmd, $request);
|
166 |
-
}
|
167 |
-
|
168 |
-
private function discoverEndpoint(
|
169 |
-
$cacheKey,
|
170 |
-
CommandInterface $cmd,
|
171 |
-
array $identifiers
|
172 |
-
) {
|
173 |
-
$discCmd = $this->getDiscoveryCommand($cmd, $identifiers);
|
174 |
-
$this->discoveryTimes[$cacheKey] = time();
|
175 |
-
$result = $this->client->execute($discCmd);
|
176 |
-
|
177 |
-
if (isset($result['Endpoints'])) {
|
178 |
-
$endpointData = [];
|
179 |
-
foreach ($result['Endpoints'] as $datum) {
|
180 |
-
$endpointData[$datum['Address']] = time()
|
181 |
-
+ ($datum['CachePeriodInMinutes'] * 60);
|
182 |
-
}
|
183 |
-
$endpointList = new EndpointList($endpointData);
|
184 |
-
self::$cache->set($cacheKey, $endpointList);
|
185 |
-
return $endpointList->getEndpoint();
|
186 |
-
}
|
187 |
-
|
188 |
-
throw new UnresolvedEndpointException('The endpoint discovery operation '
|
189 |
-
. 'yielded a response that did not contain properly formatted '
|
190 |
-
. 'endpoint data.');
|
191 |
-
}
|
192 |
-
|
193 |
-
private function getCacheKey(
|
194 |
-
CredentialsInterface $creds,
|
195 |
-
CommandInterface $cmd,
|
196 |
-
array $identifiers
|
197 |
-
) {
|
198 |
-
$key = $this->service->getServiceName() . '_' . $creds->getAccessKeyId();
|
199 |
-
if (!empty($identifiers)) {
|
200 |
-
$key .= '_' . $cmd->getName();
|
201 |
-
foreach ($identifiers as $identifier) {
|
202 |
-
$key .= "_{$cmd[$identifier]}";
|
203 |
-
}
|
204 |
-
}
|
205 |
-
|
206 |
-
return $key;
|
207 |
-
}
|
208 |
-
|
209 |
-
private function getDiscoveryCommand(
|
210 |
-
CommandInterface $cmd,
|
211 |
-
array $identifiers
|
212 |
-
) {
|
213 |
-
foreach ($this->service->getOperations() as $op) {
|
214 |
-
if (isset($op['endpointoperation'])) {
|
215 |
-
$endpointOperation = $op->toArray()['name'];
|
216 |
-
break;
|
217 |
-
}
|
218 |
-
}
|
219 |
-
|
220 |
-
if (!isset($endpointOperation)) {
|
221 |
-
throw new UnresolvedEndpointException('This command is set to use '
|
222 |
-
. 'endpoint discovery, but no endpoint discovery operation was '
|
223 |
-
. 'found. Please verify the accuracy of your model files.');
|
224 |
-
}
|
225 |
-
|
226 |
-
$params = [];
|
227 |
-
if (!empty($identifiers)) {
|
228 |
-
$params['Operation'] = $cmd->getName();
|
229 |
-
$params['Identifiers'] = [];
|
230 |
-
foreach ($identifiers as $identifier) {
|
231 |
-
$params['Identifiers'][$identifier] = $cmd[$identifier];
|
232 |
-
}
|
233 |
-
}
|
234 |
-
$command = $this->client->getCommand($endpointOperation, $params);
|
235 |
-
$command->getHandlerList()->appendBuild(
|
236 |
-
Middleware::mapRequest(function (RequestInterface $r) {
|
237 |
-
return $r->withHeader(
|
238 |
-
'x-amz-api-version',
|
239 |
-
$this->service->getApiVersion()
|
240 |
-
);
|
241 |
-
}),
|
242 |
-
'x-amz-api-version-header'
|
243 |
-
);
|
244 |
-
|
245 |
-
return $command;
|
246 |
-
}
|
247 |
-
|
248 |
-
private function getIdentifiers(array $operation)
|
249 |
-
{
|
250 |
-
$inputShape = $this->service->getShapeMap()
|
251 |
-
->resolve($operation['input'])
|
252 |
-
->toArray();
|
253 |
-
$identifiers = [];
|
254 |
-
foreach ($inputShape['members'] as $key => $member) {
|
255 |
-
if (!empty($member['endpointdiscoveryid'])) {
|
256 |
-
$identifiers[] = $key;
|
257 |
-
}
|
258 |
-
}
|
259 |
-
return $identifiers;
|
260 |
-
}
|
261 |
-
|
262 |
-
private function handleDiscoveryException(
|
263 |
-
$isRequired,
|
264 |
-
$originalUri,
|
265 |
-
\Exception $e,
|
266 |
-
CommandInterface $cmd,
|
267 |
-
RequestInterface $request
|
268 |
-
) {
|
269 |
-
// If no cached endpoints and discovery required,
|
270 |
-
// throw exception
|
271 |
-
if ($isRequired) {
|
272 |
-
$message = 'The endpoint required for this service is currently '
|
273 |
-
. 'unable to be retrieved, and your request can not be fulfilled '
|
274 |
-
. 'unless you manually specify an endpoint.';
|
275 |
-
throw new AwsException(
|
276 |
-
$message,
|
277 |
-
$cmd,
|
278 |
-
[
|
279 |
-
'code' => 'EndpointDiscoveryException',
|
280 |
-
'message' => $message
|
281 |
-
],
|
282 |
-
$e
|
283 |
-
);
|
284 |
-
}
|
285 |
-
|
286 |
-
// If discovery isn't required, use original endpoint
|
287 |
-
return $this->useOriginalUri(
|
288 |
-
$originalUri,
|
289 |
-
$cmd,
|
290 |
-
$request
|
291 |
-
);
|
292 |
-
}
|
293 |
-
|
294 |
-
private function handleInvalidEndpoint(
|
295 |
-
$cacheKey,
|
296 |
-
$cmd,
|
297 |
-
$identifiers,
|
298 |
-
$isRequired,
|
299 |
-
$originalUri,
|
300 |
-
$request,
|
301 |
-
$value,
|
302 |
-
&$endpoint,
|
303 |
-
&$g
|
304 |
-
) {
|
305 |
-
$nextHandler = $this->nextHandler;
|
306 |
-
$endpointList = self::$cache->get($cacheKey);
|
307 |
-
if ($endpointList instanceof EndpointList) {
|
308 |
-
|
309 |
-
// Remove invalid endpoint from cached list
|
310 |
-
$endpointList->remove($endpoint);
|
311 |
-
|
312 |
-
// If possible, get another cached endpoint
|
313 |
-
$newEndpoint = $endpointList->getEndpoint();
|
314 |
-
}
|
315 |
-
if (empty($newEndpoint)) {
|
316 |
-
|
317 |
-
// If no more cached endpoints, make discovery call
|
318 |
-
// if none made within cooldown for given key
|
319 |
-
if (time() - $this->discoveryTimes[$cacheKey]
|
320 |
-
< self::$discoveryCooldown
|
321 |
-
) {
|
322 |
-
|
323 |
-
// If no more cached endpoints and it's required,
|
324 |
-
// fail with original exception
|
325 |
-
if ($isRequired) {
|
326 |
-
return $value;
|
327 |
-
}
|
328 |
-
|
329 |
-
// Use original endpoint if not required
|
330 |
-
return $this->useOriginalUri(
|
331 |
-
$originalUri,
|
332 |
-
$cmd,
|
333 |
-
$request
|
334 |
-
);
|
335 |
-
}
|
336 |
-
|
337 |
-
$newEndpoint = $this->discoverEndpoint(
|
338 |
-
$cacheKey,
|
339 |
-
$cmd,
|
340 |
-
$identifiers
|
341 |
-
);
|
342 |
-
}
|
343 |
-
$endpoint = $newEndpoint;
|
344 |
-
$request = $this->modifyRequest($request, $endpoint);
|
345 |
-
return $nextHandler($cmd, $request)->otherwise($g);
|
346 |
-
}
|
347 |
-
|
348 |
-
private function modifyRequest(RequestInterface $request, $endpoint)
|
349 |
-
{
|
350 |
-
$parsed = $this->parseEndpoint($endpoint);
|
351 |
-
if (!empty($request->getHeader('User-Agent'))) {
|
352 |
-
$userAgent = $request->getHeader('User-Agent')[0];
|
353 |
-
if (strpos($userAgent, 'endpoint-discovery') === false) {
|
354 |
-
$userAgent = $userAgent . ' endpoint-discovery';
|
355 |
-
}
|
356 |
-
} else {
|
357 |
-
$userAgent = 'endpoint-discovery';
|
358 |
-
}
|
359 |
-
|
360 |
-
return $request
|
361 |
-
->withUri(
|
362 |
-
$request->getUri()
|
363 |
-
->withHost($parsed['host'])
|
364 |
-
->withPath($parsed['path'])
|
365 |
-
)
|
366 |
-
->withHeader('User-Agent', $userAgent);
|
367 |
-
}
|
368 |
-
|
369 |
-
/**
|
370 |
-
* Parses an endpoint returned from the discovery API into an array with
|
371 |
-
* 'host' and 'path' keys.
|
372 |
-
*
|
373 |
-
* @param $endpoint
|
374 |
-
* @return array
|
375 |
-
*/
|
376 |
-
private function parseEndpoint($endpoint)
|
377 |
-
{
|
378 |
-
$parsed = parse_url($endpoint);
|
379 |
-
|
380 |
-
// parse_url() will correctly parse full URIs with schemes
|
381 |
-
if (isset($parsed['host'])) {
|
382 |
-
return $parsed;
|
383 |
-
}
|
384 |
-
|
385 |
-
// parse_url() will put host & path in 'path' if scheme is not provided
|
386 |
-
if (isset($parsed['path'])) {
|
387 |
-
$split = explode('/', $parsed['path'], 2);
|
388 |
-
$parsed['host'] = $split[0];
|
389 |
-
if (isset($split[1])) {
|
390 |
-
$parsed['path'] = $split[1];
|
391 |
-
} else {
|
392 |
-
$parsed['path'] = '';
|
393 |
-
}
|
394 |
-
return $parsed;
|
395 |
-
}
|
396 |
-
|
397 |
-
throw new UnresolvedEndpointException("The supplied endpoint '"
|
398 |
-
. "{$endpoint}' is invalid.");
|
399 |
-
}
|
400 |
-
|
401 |
-
private function useOriginalUri(
|
402 |
-
UriInterface $uri,
|
403 |
-
CommandInterface $cmd,
|
404 |
-
RequestInterface $request
|
405 |
-
) {
|
406 |
-
$nextHandler = $this->nextHandler;
|
407 |
-
$endpoint = $uri->getHost() . $uri->getPath();
|
408 |
-
$request = $this->modifyRequest(
|
409 |
-
$request,
|
410 |
-
$endpoint
|
411 |
-
);
|
412 |
-
return $nextHandler($cmd, $request);
|
413 |
-
}
|
414 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/EndpointParameterMiddleware.php
DELETED
@@ -1,84 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Api\Service;
|
5 |
-
use Psr\Http\Message\RequestInterface;
|
6 |
-
use Psr\Log\InvalidArgumentException;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Used to update the host based on a modeled endpoint trait
|
10 |
-
*
|
11 |
-
* IMPORTANT: this middleware must be added after the "build" step.
|
12 |
-
*
|
13 |
-
* @internal
|
14 |
-
*/
|
15 |
-
class EndpointParameterMiddleware
|
16 |
-
{
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Create a middleware wrapper function
|
20 |
-
*
|
21 |
-
* @param Service $service
|
22 |
-
* @param array $args
|
23 |
-
* @return \Closure
|
24 |
-
*/
|
25 |
-
public static function wrap(Service $service)
|
26 |
-
{
|
27 |
-
return function (callable $handler) use ($service) {
|
28 |
-
return new self($handler, $service);
|
29 |
-
};
|
30 |
-
}
|
31 |
-
|
32 |
-
public function __construct(callable $nextHandler, Service $service)
|
33 |
-
{
|
34 |
-
$this->nextHandler = $nextHandler;
|
35 |
-
$this->service = $service;
|
36 |
-
}
|
37 |
-
|
38 |
-
public function __invoke(CommandInterface $command, RequestInterface $request)
|
39 |
-
{
|
40 |
-
$nextHandler = $this->nextHandler;
|
41 |
-
|
42 |
-
$operation = $this->service->getOperation($command->getName());
|
43 |
-
|
44 |
-
if (!empty($operation['endpoint']['hostPrefix'])) {
|
45 |
-
$prefix = $operation['endpoint']['hostPrefix'];
|
46 |
-
|
47 |
-
// Captures endpoint parameters stored in the modeled host.
|
48 |
-
// These are denoted by enclosure in braces, i.e. '{param}'
|
49 |
-
preg_match_all("/\{([a-zA-Z0-9]+)}/", $prefix, $parameters);
|
50 |
-
|
51 |
-
if (!empty($parameters[1])) {
|
52 |
-
|
53 |
-
// Captured parameters without braces stored in $parameters[1],
|
54 |
-
// which should correspond to members in the Command object
|
55 |
-
foreach ($parameters[1] as $index => $parameter) {
|
56 |
-
if (empty($command[$parameter])) {
|
57 |
-
throw new \InvalidArgumentException(
|
58 |
-
"The parameter '{$parameter}' must be set and not empty."
|
59 |
-
);
|
60 |
-
}
|
61 |
-
|
62 |
-
// Captured parameters with braces stored in $parameters[0],
|
63 |
-
// which are replaced by their corresponding Command value
|
64 |
-
$prefix = str_replace(
|
65 |
-
$parameters[0][$index],
|
66 |
-
$command[$parameter],
|
67 |
-
$prefix
|
68 |
-
);
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
$uri = $request->getUri();
|
73 |
-
$host = $prefix . $uri->getHost();
|
74 |
-
if (!\Aws\is_valid_hostname($host)) {
|
75 |
-
throw new \InvalidArgumentException(
|
76 |
-
"The supplied parameters result in an invalid hostname: '{$host}'."
|
77 |
-
);
|
78 |
-
}
|
79 |
-
$request = $request->withUri($uri->withHost($host));
|
80 |
-
}
|
81 |
-
|
82 |
-
return $nextHandler($command, $request);
|
83 |
-
}
|
84 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Exception/AwsException.php
DELETED
@@ -1,237 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Exception;
|
3 |
-
|
4 |
-
use Aws\HasMonitoringEventsTrait;
|
5 |
-
use Aws\MonitoringEventsInterface;
|
6 |
-
use Aws\ResponseContainerInterface;
|
7 |
-
use Psr\Http\Message\ResponseInterface;
|
8 |
-
use Psr\Http\Message\RequestInterface;
|
9 |
-
use Aws\CommandInterface;
|
10 |
-
use Aws\ResultInterface;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Represents an AWS exception that is thrown when a command fails.
|
14 |
-
*/
|
15 |
-
class AwsException extends \RuntimeException implements
|
16 |
-
MonitoringEventsInterface,
|
17 |
-
ResponseContainerInterface
|
18 |
-
{
|
19 |
-
use HasMonitoringEventsTrait;
|
20 |
-
|
21 |
-
/** @var ResponseInterface */
|
22 |
-
private $response;
|
23 |
-
private $request;
|
24 |
-
private $result;
|
25 |
-
private $command;
|
26 |
-
private $requestId;
|
27 |
-
private $errorType;
|
28 |
-
private $errorCode;
|
29 |
-
private $connectionError;
|
30 |
-
private $transferInfo;
|
31 |
-
private $errorMessage;
|
32 |
-
private $maxRetriesExceeded;
|
33 |
-
|
34 |
-
|
35 |
-
/**
|
36 |
-
* @param string $message Exception message
|
37 |
-
* @param CommandInterface $command
|
38 |
-
* @param array $context Exception context
|
39 |
-
* @param \Exception $previous Previous exception (if any)
|
40 |
-
*/
|
41 |
-
public function __construct(
|
42 |
-
$message,
|
43 |
-
CommandInterface $command,
|
44 |
-
array $context = [],
|
45 |
-
\Exception $previous = null
|
46 |
-
) {
|
47 |
-
$this->command = $command;
|
48 |
-
$this->response = isset($context['response']) ? $context['response'] : null;
|
49 |
-
$this->request = isset($context['request']) ? $context['request'] : null;
|
50 |
-
$this->requestId = isset($context['request_id'])
|
51 |
-
? $context['request_id']
|
52 |
-
: null;
|
53 |
-
$this->errorType = isset($context['type']) ? $context['type'] : null;
|
54 |
-
$this->errorCode = isset($context['code']) ? $context['code'] : null;
|
55 |
-
$this->connectionError = !empty($context['connection_error']);
|
56 |
-
$this->result = isset($context['result']) ? $context['result'] : null;
|
57 |
-
$this->transferInfo = isset($context['transfer_stats'])
|
58 |
-
? $context['transfer_stats']
|
59 |
-
: [];
|
60 |
-
$this->errorMessage = isset($context['message'])
|
61 |
-
? $context['message']
|
62 |
-
: null;
|
63 |
-
$this->monitoringEvents = [];
|
64 |
-
$this->maxRetriesExceeded = false;
|
65 |
-
parent::__construct($message, 0, $previous);
|
66 |
-
}
|
67 |
-
|
68 |
-
public function __toString()
|
69 |
-
{
|
70 |
-
if (!$this->getPrevious()) {
|
71 |
-
return parent::__toString();
|
72 |
-
}
|
73 |
-
|
74 |
-
// PHP strangely shows the innermost exception first before the outer
|
75 |
-
// exception message. It also has a default character limit for
|
76 |
-
// exception message strings such that the "next" exception (this one)
|
77 |
-
// might not even get shown, causing developers to attempt to catch
|
78 |
-
// the inner exception instead of the actual exception because they
|
79 |
-
// can't see the outer exception's __toString output.
|
80 |
-
return sprintf(
|
81 |
-
"exception '%s' with message '%s'\n\n%s",
|
82 |
-
get_class($this),
|
83 |
-
$this->getMessage(),
|
84 |
-
parent::__toString()
|
85 |
-
);
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Get the command that was executed.
|
90 |
-
*
|
91 |
-
* @return CommandInterface
|
92 |
-
*/
|
93 |
-
public function getCommand()
|
94 |
-
{
|
95 |
-
return $this->command;
|
96 |
-
}
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Get the concise error message if any.
|
100 |
-
*
|
101 |
-
* @return string|null
|
102 |
-
*/
|
103 |
-
public function getAwsErrorMessage()
|
104 |
-
{
|
105 |
-
return $this->errorMessage;
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Get the sent HTTP request if any.
|
110 |
-
*
|
111 |
-
* @return RequestInterface|null
|
112 |
-
*/
|
113 |
-
public function getRequest()
|
114 |
-
{
|
115 |
-
return $this->request;
|
116 |
-
}
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Get the received HTTP response if any.
|
120 |
-
*
|
121 |
-
* @return ResponseInterface|null
|
122 |
-
*/
|
123 |
-
public function getResponse()
|
124 |
-
{
|
125 |
-
return $this->response;
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Get the result of the exception if available
|
130 |
-
*
|
131 |
-
* @return ResultInterface|null
|
132 |
-
*/
|
133 |
-
public function getResult()
|
134 |
-
{
|
135 |
-
return $this->result;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Returns true if this is a connection error.
|
140 |
-
*
|
141 |
-
* @return bool
|
142 |
-
*/
|
143 |
-
public function isConnectionError()
|
144 |
-
{
|
145 |
-
return $this->connectionError;
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* If available, gets the HTTP status code of the corresponding response
|
150 |
-
*
|
151 |
-
* @return int|null
|
152 |
-
*/
|
153 |
-
public function getStatusCode()
|
154 |
-
{
|
155 |
-
return $this->response ? $this->response->getStatusCode() : null;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Get the request ID of the error. This value is only present if a
|
160 |
-
* response was received and is not present in the event of a networking
|
161 |
-
* error.
|
162 |
-
*
|
163 |
-
* @return string|null Returns null if no response was received
|
164 |
-
*/
|
165 |
-
public function getAwsRequestId()
|
166 |
-
{
|
167 |
-
return $this->requestId;
|
168 |
-
}
|
169 |
-
|
170 |
-
/**
|
171 |
-
* Get the AWS error type.
|
172 |
-
*
|
173 |
-
* @return string|null Returns null if no response was received
|
174 |
-
*/
|
175 |
-
public function getAwsErrorType()
|
176 |
-
{
|
177 |
-
return $this->errorType;
|
178 |
-
}
|
179 |
-
|
180 |
-
/**
|
181 |
-
* Get the AWS error code.
|
182 |
-
*
|
183 |
-
* @return string|null Returns null if no response was received
|
184 |
-
*/
|
185 |
-
public function getAwsErrorCode()
|
186 |
-
{
|
187 |
-
return $this->errorCode;
|
188 |
-
}
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Get all transfer information as an associative array if no $name
|
192 |
-
* argument is supplied, or gets a specific transfer statistic if
|
193 |
-
* a $name attribute is supplied (e.g., 'retries_attempted').
|
194 |
-
*
|
195 |
-
* @param string $name Name of the transfer stat to retrieve
|
196 |
-
*
|
197 |
-
* @return mixed|null|array
|
198 |
-
*/
|
199 |
-
public function getTransferInfo($name = null)
|
200 |
-
{
|
201 |
-
if (!$name) {
|
202 |
-
return $this->transferInfo;
|
203 |
-
}
|
204 |
-
|
205 |
-
return isset($this->transferInfo[$name])
|
206 |
-
? $this->transferInfo[$name]
|
207 |
-
: null;
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Replace the transfer information associated with an exception.
|
212 |
-
*
|
213 |
-
* @param array $info
|
214 |
-
*/
|
215 |
-
public function setTransferInfo(array $info)
|
216 |
-
{
|
217 |
-
$this->transferInfo = $info;
|
218 |
-
}
|
219 |
-
|
220 |
-
/**
|
221 |
-
* Returns whether the max number of retries is exceeded.
|
222 |
-
*
|
223 |
-
* @return bool
|
224 |
-
*/
|
225 |
-
public function isMaxRetriesExceeded()
|
226 |
-
{
|
227 |
-
return $this->maxRetriesExceeded;
|
228 |
-
}
|
229 |
-
|
230 |
-
/**
|
231 |
-
* Sets the flag for max number of retries exceeded.
|
232 |
-
*/
|
233 |
-
public function setMaxRetriesExceeded()
|
234 |
-
{
|
235 |
-
$this->maxRetriesExceeded = true;
|
236 |
-
}
|
237 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Handler/GuzzleV5/GuzzleHandler.php
DELETED
@@ -1,210 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Handler\GuzzleV5;
|
3 |
-
|
4 |
-
use Exception;
|
5 |
-
use GuzzleHttp\Client;
|
6 |
-
use GuzzleHttp\ClientInterface;
|
7 |
-
use GuzzleHttp\Event\EndEvent;
|
8 |
-
use GuzzleHttp\Exception\ConnectException;
|
9 |
-
use GuzzleHttp\Exception\RequestException;
|
10 |
-
use GuzzleHttp\Message\ResponseInterface as GuzzleResponse;
|
11 |
-
use GuzzleHttp\Promise;
|
12 |
-
use GuzzleHttp\Psr7\Response as Psr7Response;
|
13 |
-
use GuzzleHttp\Stream\Stream;
|
14 |
-
use Psr\Http\Message\RequestInterface as Psr7Request;
|
15 |
-
use Psr\Http\Message\StreamInterface as Psr7StreamInterface;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* A request handler that sends PSR-7-compatible requests with Guzzle 5.
|
19 |
-
*
|
20 |
-
* The handler accepts a PSR-7 Request object and an array of transfer options
|
21 |
-
* and returns a Guzzle 6 Promise. The promise is either resolved with a
|
22 |
-
* PSR-7 Response object or rejected with an array of error data.
|
23 |
-
*
|
24 |
-
* @codeCoverageIgnore
|
25 |
-
*/
|
26 |
-
class GuzzleHandler
|
27 |
-
{
|
28 |
-
private static $validOptions = [
|
29 |
-
'proxy' => true,
|
30 |
-
'expect' => true,
|
31 |
-
'verify' => true,
|
32 |
-
'timeout' => true,
|
33 |
-
'debug' => true,
|
34 |
-
'connect_timeout' => true,
|
35 |
-
'stream' => true,
|
36 |
-
'delay' => true,
|
37 |
-
'sink' => true,
|
38 |
-
];
|
39 |
-
|
40 |
-
/** @var ClientInterface */
|
41 |
-
private $client;
|
42 |
-
|
43 |
-
/**
|
44 |
-
* @param ClientInterface $client
|
45 |
-
*/
|
46 |
-
public function __construct(ClientInterface $client = null)
|
47 |
-
{
|
48 |
-
$this->client = $client ?: new Client();
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* @param Psr7Request $request
|
53 |
-
* @param array $options
|
54 |
-
*
|
55 |
-
* @return Promise\Promise
|
56 |
-
*/
|
57 |
-
public function __invoke(Psr7Request $request, array $options = [])
|
58 |
-
{
|
59 |
-
// Create and send a Guzzle 5 request
|
60 |
-
$guzzlePromise = $this->client->send(
|
61 |
-
$this->createGuzzleRequest($request, $options)
|
62 |
-
);
|
63 |
-
|
64 |
-
$promise = new Promise\Promise(
|
65 |
-
function () use ($guzzlePromise) {
|
66 |
-
try {
|
67 |
-
$guzzlePromise->wait();
|
68 |
-
} catch (\Exception $e) {
|
69 |
-
// The promise is already delivered when the exception is
|
70 |
-
// thrown, so don't rethrow it.
|
71 |
-
}
|
72 |
-
},
|
73 |
-
[$guzzlePromise, 'cancel']
|
74 |
-
);
|
75 |
-
|
76 |
-
$guzzlePromise->then([$promise, 'resolve'], [$promise, 'reject']);
|
77 |
-
|
78 |
-
return $promise->then(
|
79 |
-
function (GuzzleResponse $response) {
|
80 |
-
// Adapt the Guzzle 5 Future to a Guzzle 6 ResponsePromise.
|
81 |
-
return $this->createPsr7Response($response);
|
82 |
-
},
|
83 |
-
function (Exception $exception) use ($options) {
|
84 |
-
// If we got a 'sink' that's a path, set the response body to
|
85 |
-
// the contents of the file. This will build the resulting
|
86 |
-
// exception with more information.
|
87 |
-
if ($exception instanceof RequestException) {
|
88 |
-
if (isset($options['sink'])) {
|
89 |
-
if (!($options['sink'] instanceof Psr7StreamInterface)) {
|
90 |
-
$exception->getResponse()->setBody(
|
91 |
-
Stream::factory(
|
92 |
-
file_get_contents($options['sink'])
|
93 |
-
)
|
94 |
-
);
|
95 |
-
}
|
96 |
-
}
|
97 |
-
}
|
98 |
-
// Reject with information about the error.
|
99 |
-
return new Promise\RejectedPromise($this->prepareErrorData($exception));
|
100 |
-
}
|
101 |
-
);
|
102 |
-
}
|
103 |
-
|
104 |
-
private function createGuzzleRequest(Psr7Request $psrRequest, array $options)
|
105 |
-
{
|
106 |
-
$ringConfig = [];
|
107 |
-
$statsCallback = isset($options['http_stats_receiver'])
|
108 |
-
? $options['http_stats_receiver']
|
109 |
-
: null;
|
110 |
-
unset($options['http_stats_receiver']);
|
111 |
-
|
112 |
-
// Remove unsupported options.
|
113 |
-
foreach (array_keys($options) as $key) {
|
114 |
-
if (!isset(self::$validOptions[$key])) {
|
115 |
-
unset($options[$key]);
|
116 |
-
}
|
117 |
-
}
|
118 |
-
|
119 |
-
// Handle delay option.
|
120 |
-
if (isset($options['delay'])) {
|
121 |
-
$ringConfig['delay'] = $options['delay'];
|
122 |
-
unset($options['delay']);
|
123 |
-
}
|
124 |
-
|
125 |
-
// Prepare sink option.
|
126 |
-
if (isset($options['sink'])) {
|
127 |
-
$ringConfig['save_to'] = ($options['sink'] instanceof Psr7StreamInterface)
|
128 |
-
? new GuzzleStream($options['sink'])
|
129 |
-
: $options['sink'];
|
130 |
-
unset($options['sink']);
|
131 |
-
}
|
132 |
-
|
133 |
-
// Ensure that all requests are async and lazy like Guzzle 6.
|
134 |
-
$options['future'] = 'lazy';
|
135 |
-
|
136 |
-
// Create the Guzzle 5 request from the provided PSR7 request.
|
137 |
-
$request = $this->client->createRequest(
|
138 |
-
$psrRequest->getMethod(),
|
139 |
-
$psrRequest->getUri(),
|
140 |
-
$options
|
141 |
-
);
|
142 |
-
|
143 |
-
if (is_callable($statsCallback)) {
|
144 |
-
$request->getEmitter()->on(
|
145 |
-
'end',
|
146 |
-
function (EndEvent $event) use ($statsCallback) {
|
147 |
-
$statsCallback($event->getTransferInfo());
|
148 |
-
}
|
149 |
-
);
|
150 |
-
}
|
151 |
-
|
152 |
-
// For the request body, adapt the PSR stream to a Guzzle stream.
|
153 |
-
$body = $psrRequest->getBody();
|
154 |
-
if ($body->getSize() === 0) {
|
155 |
-
$request->setBody(null);
|
156 |
-
} else {
|
157 |
-
$request->setBody(new GuzzleStream($body));
|
158 |
-
}
|
159 |
-
|
160 |
-
$request->setHeaders($psrRequest->getHeaders());
|
161 |
-
|
162 |
-
$request->setHeader(
|
163 |
-
'User-Agent',
|
164 |
-
$request->getHeader('User-Agent')
|
165 |
-
. ' ' . Client::getDefaultUserAgent()
|
166 |
-
);
|
167 |
-
|
168 |
-
// Make sure the delay is configured, if provided.
|
169 |
-
if ($ringConfig) {
|
170 |
-
foreach ($ringConfig as $k => $v) {
|
171 |
-
$request->getConfig()->set($k, $v);
|
172 |
-
}
|
173 |
-
}
|
174 |
-
|
175 |
-
return $request;
|
176 |
-
}
|
177 |
-
|
178 |
-
private function createPsr7Response(GuzzleResponse $response)
|
179 |
-
{
|
180 |
-
if ($body = $response->getBody()) {
|
181 |
-
$body = new PsrStream($body);
|
182 |
-
}
|
183 |
-
|
184 |
-
return new Psr7Response(
|
185 |
-
$response->getStatusCode(),
|
186 |
-
$response->getHeaders(),
|
187 |
-
$body,
|
188 |
-
$response->getReasonPhrase()
|
189 |
-
);
|
190 |
-
}
|
191 |
-
|
192 |
-
private function prepareErrorData(Exception $e)
|
193 |
-
{
|
194 |
-
$error = [
|
195 |
-
'exception' => $e,
|
196 |
-
'connection_error' => false,
|
197 |
-
'response' => null,
|
198 |
-
];
|
199 |
-
|
200 |
-
if ($e instanceof ConnectException) {
|
201 |
-
$error['connection_error'] = true;
|
202 |
-
}
|
203 |
-
|
204 |
-
if ($e instanceof RequestException && $e->getResponse()) {
|
205 |
-
$error['response'] = $this->createPsr7Response($e->getResponse());
|
206 |
-
}
|
207 |
-
|
208 |
-
return $error;
|
209 |
-
}
|
210 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Handler/GuzzleV6/GuzzleHandler.php
DELETED
@@ -1,85 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Handler\GuzzleV6;
|
3 |
-
|
4 |
-
use Exception;
|
5 |
-
use GuzzleHttp\Exception\ConnectException;
|
6 |
-
use GuzzleHttp\Exception\RequestException;
|
7 |
-
use GuzzleHttp\Promise;
|
8 |
-
use GuzzleHttp\Client;
|
9 |
-
use GuzzleHttp\ClientInterface;
|
10 |
-
use GuzzleHttp\TransferStats;
|
11 |
-
use Psr\Http\Message\RequestInterface as Psr7Request;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* A request handler that sends PSR-7-compatible requests with Guzzle 6.
|
15 |
-
*/
|
16 |
-
class GuzzleHandler
|
17 |
-
{
|
18 |
-
/** @var ClientInterface */
|
19 |
-
private $client;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @param ClientInterface $client
|
23 |
-
*/
|
24 |
-
public function __construct(ClientInterface $client = null)
|
25 |
-
{
|
26 |
-
$this->client = $client ?: new Client();
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* @param Psr7Request $request
|
31 |
-
* @param array $options
|
32 |
-
*
|
33 |
-
* @return Promise\Promise
|
34 |
-
*/
|
35 |
-
public function __invoke(Psr7Request $request, array $options = [])
|
36 |
-
{
|
37 |
-
$request = $request->withHeader(
|
38 |
-
'User-Agent',
|
39 |
-
$request->getHeaderLine('User-Agent')
|
40 |
-
. ' ' . \GuzzleHttp\default_user_agent()
|
41 |
-
);
|
42 |
-
|
43 |
-
return $this->client->sendAsync($request, $this->parseOptions($options))
|
44 |
-
->otherwise(
|
45 |
-
static function (\Exception $e) {
|
46 |
-
$error = [
|
47 |
-
'exception' => $e,
|
48 |
-
'connection_error' => $e instanceof ConnectException,
|
49 |
-
'response' => null,
|
50 |
-
];
|
51 |
-
|
52 |
-
if ($e instanceof RequestException && $e->getResponse()) {
|
53 |
-
$error['response'] = $e->getResponse();
|
54 |
-
}
|
55 |
-
|
56 |
-
return new Promise\RejectedPromise($error);
|
57 |
-
}
|
58 |
-
);
|
59 |
-
}
|
60 |
-
|
61 |
-
private function parseOptions(array $options)
|
62 |
-
{
|
63 |
-
if (isset($options['http_stats_receiver'])) {
|
64 |
-
$fn = $options['http_stats_receiver'];
|
65 |
-
unset($options['http_stats_receiver']);
|
66 |
-
|
67 |
-
$prev = isset($options['on_stats'])
|
68 |
-
? $options['on_stats']
|
69 |
-
: null;
|
70 |
-
|
71 |
-
$options['on_stats'] = static function (
|
72 |
-
TransferStats $stats
|
73 |
-
) use ($fn, $prev) {
|
74 |
-
if (is_callable($prev)) {
|
75 |
-
$prev($stats);
|
76 |
-
}
|
77 |
-
$transferStats = ['total_time' => $stats->getTransferTime()];
|
78 |
-
$transferStats += $stats->getHandlerStats();
|
79 |
-
$fn($transferStats);
|
80 |
-
};
|
81 |
-
}
|
82 |
-
|
83 |
-
return $options;
|
84 |
-
}
|
85 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Middleware.php
DELETED
@@ -1,372 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Api\Service;
|
5 |
-
use Aws\Api\Validator;
|
6 |
-
use Aws\Credentials\CredentialsInterface;
|
7 |
-
use Aws\Exception\AwsException;
|
8 |
-
use GuzzleHttp\Promise;
|
9 |
-
use GuzzleHttp\Psr7;
|
10 |
-
use GuzzleHttp\Psr7\LazyOpenStream;
|
11 |
-
use Psr\Http\Message\RequestInterface;
|
12 |
-
|
13 |
-
final class Middleware
|
14 |
-
{
|
15 |
-
/**
|
16 |
-
* Middleware used to allow a command parameter (e.g., "SourceFile") to
|
17 |
-
* be used to specify the source of data for an upload operation.
|
18 |
-
*
|
19 |
-
* @param Service $api
|
20 |
-
* @param string $bodyParameter
|
21 |
-
* @param string $sourceParameter
|
22 |
-
*
|
23 |
-
* @return callable
|
24 |
-
*/
|
25 |
-
public static function sourceFile(
|
26 |
-
Service $api,
|
27 |
-
$bodyParameter = 'Body',
|
28 |
-
$sourceParameter = 'SourceFile'
|
29 |
-
) {
|
30 |
-
return function (callable $handler) use (
|
31 |
-
$api,
|
32 |
-
$bodyParameter,
|
33 |
-
$sourceParameter
|
34 |
-
) {
|
35 |
-
return function (
|
36 |
-
CommandInterface $command,
|
37 |
-
RequestInterface $request = null)
|
38 |
-
use (
|
39 |
-
$handler,
|
40 |
-
$api,
|
41 |
-
$bodyParameter,
|
42 |
-
$sourceParameter
|
43 |
-
) {
|
44 |
-
$operation = $api->getOperation($command->getName());
|
45 |
-
$source = $command[$sourceParameter];
|
46 |
-
|
47 |
-
if ($source !== null
|
48 |
-
&& $operation->getInput()->hasMember($bodyParameter)
|
49 |
-
) {
|
50 |
-
$command[$bodyParameter] = new LazyOpenStream($source, 'r');
|
51 |
-
unset($command[$sourceParameter]);
|
52 |
-
}
|
53 |
-
|
54 |
-
return $handler($command, $request);
|
55 |
-
};
|
56 |
-
};
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* Adds a middleware that uses client-side validation.
|
61 |
-
*
|
62 |
-
* @param Service $api API being accessed.
|
63 |
-
*
|
64 |
-
* @return callable
|
65 |
-
*/
|
66 |
-
public static function validation(Service $api, Validator $validator = null)
|
67 |
-
{
|
68 |
-
$validator = $validator ?: new Validator();
|
69 |
-
return function (callable $handler) use ($api, $validator) {
|
70 |
-
return function (
|
71 |
-
CommandInterface $command,
|
72 |
-
RequestInterface $request = null
|
73 |
-
) use ($api, $validator, $handler) {
|
74 |
-
$operation = $api->getOperation($command->getName());
|
75 |
-
$validator->validate(
|
76 |
-
$command->getName(),
|
77 |
-
$operation->getInput(),
|
78 |
-
$command->toArray()
|
79 |
-
);
|
80 |
-
return $handler($command, $request);
|
81 |
-
};
|
82 |
-
};
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Builds an HTTP request for a command.
|
87 |
-
*
|
88 |
-
* @param callable $serializer Function used to serialize a request for a
|
89 |
-
* command.
|
90 |
-
* @return callable
|
91 |
-
*/
|
92 |
-
public static function requestBuilder(callable $serializer)
|
93 |
-
{
|
94 |
-
return function (callable $handler) use ($serializer) {
|
95 |
-
return function (CommandInterface $command) use ($serializer, $handler) {
|
96 |
-
return $handler($command, $serializer($command));
|
97 |
-
};
|
98 |
-
};
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Creates a middleware that signs requests for a command.
|
103 |
-
*
|
104 |
-
* @param callable $credProvider Credentials provider function that
|
105 |
-
* returns a promise that is resolved
|
106 |
-
* with a CredentialsInterface object.
|
107 |
-
* @param callable $signatureFunction Function that accepts a Command
|
108 |
-
* object and returns a
|
109 |
-
* SignatureInterface.
|
110 |
-
*
|
111 |
-
* @return callable
|
112 |
-
*/
|
113 |
-
public static function signer(callable $credProvider, callable $signatureFunction)
|
114 |
-
{
|
115 |
-
return function (callable $handler) use ($signatureFunction, $credProvider) {
|
116 |
-
return function (
|
117 |
-
CommandInterface $command,
|
118 |
-
RequestInterface $request
|
119 |
-
) use ($handler, $signatureFunction, $credProvider) {
|
120 |
-
$signer = $signatureFunction($command);
|
121 |
-
return $credProvider()->then(
|
122 |
-
function (CredentialsInterface $creds)
|
123 |
-
use ($handler, $command, $signer, $request) {
|
124 |
-
return $handler(
|
125 |
-
$command,
|
126 |
-
$signer->signRequest($request, $creds)
|
127 |
-
);
|
128 |
-
}
|
129 |
-
);
|
130 |
-
};
|
131 |
-
};
|
132 |
-
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* Creates a middleware that invokes a callback at a given step.
|
136 |
-
*
|
137 |
-
* The tap callback accepts a CommandInterface and RequestInterface as
|
138 |
-
* arguments but is not expected to return a new value or proxy to
|
139 |
-
* downstream middleware. It's simply a way to "tap" into the handler chain
|
140 |
-
* to debug or get an intermediate value.
|
141 |
-
*
|
142 |
-
* @param callable $fn Tap function
|
143 |
-
*
|
144 |
-
* @return callable
|
145 |
-
*/
|
146 |
-
public static function tap(callable $fn)
|
147 |
-
{
|
148 |
-
return function (callable $handler) use ($fn) {
|
149 |
-
return function (
|
150 |
-
CommandInterface $command,
|
151 |
-
RequestInterface $request = null
|
152 |
-
) use ($handler, $fn) {
|
153 |
-
$fn($command, $request);
|
154 |
-
return $handler($command, $request);
|
155 |
-
};
|
156 |
-
};
|
157 |
-
}
|
158 |
-
|
159 |
-
/**
|
160 |
-
* Middleware wrapper function that retries requests based on the boolean
|
161 |
-
* result of invoking the provided "decider" function.
|
162 |
-
*
|
163 |
-
* If no delay function is provided, a simple implementation of exponential
|
164 |
-
* backoff will be utilized.
|
165 |
-
*
|
166 |
-
* @param callable $decider Function that accepts the number of retries,
|
167 |
-
* a request, [result], and [exception] and
|
168 |
-
* returns true if the command is to be retried.
|
169 |
-
* @param callable $delay Function that accepts the number of retries and
|
170 |
-
* returns the number of milliseconds to delay.
|
171 |
-
* @param bool $stats Whether to collect statistics on retries and the
|
172 |
-
* associated delay.
|
173 |
-
*
|
174 |
-
* @return callable
|
175 |
-
*/
|
176 |
-
public static function retry(
|
177 |
-
callable $decider = null,
|
178 |
-
callable $delay = null,
|
179 |
-
$stats = false
|
180 |
-
) {
|
181 |
-
$decider = $decider ?: RetryMiddleware::createDefaultDecider();
|
182 |
-
$delay = $delay ?: [RetryMiddleware::class, 'exponentialDelay'];
|
183 |
-
|
184 |
-
return function (callable $handler) use ($decider, $delay, $stats) {
|
185 |
-
return new RetryMiddleware($decider, $delay, $handler, $stats);
|
186 |
-
};
|
187 |
-
}
|
188 |
-
/**
|
189 |
-
* Middleware wrapper function that adds an invocation id header to
|
190 |
-
* requests, which is only applied after the build step.
|
191 |
-
*
|
192 |
-
* This is a uniquely generated UUID to identify initial and subsequent
|
193 |
-
* retries as part of a complete request lifecycle.
|
194 |
-
*
|
195 |
-
* @return callable
|
196 |
-
*/
|
197 |
-
public static function invocationId()
|
198 |
-
{
|
199 |
-
return function (callable $handler) {
|
200 |
-
return function (
|
201 |
-
CommandInterface $command,
|
202 |
-
RequestInterface $request
|
203 |
-
) use ($handler){
|
204 |
-
return $handler($command, $request->withHeader(
|
205 |
-
'aws-sdk-invocation-id',
|
206 |
-
md5(uniqid(gethostname(), true))
|
207 |
-
));
|
208 |
-
};
|
209 |
-
};
|
210 |
-
}
|
211 |
-
/**
|
212 |
-
* Middleware wrapper function that adds a Content-Type header to requests.
|
213 |
-
* This is only done when the Content-Type has not already been set, and the
|
214 |
-
* request body's URI is available. It then checks the file extension of the
|
215 |
-
* URI to determine the mime-type.
|
216 |
-
*
|
217 |
-
* @param array $operations Operations that Content-Type should be added to.
|
218 |
-
*
|
219 |
-
* @return callable
|
220 |
-
*/
|
221 |
-
public static function contentType(array $operations)
|
222 |
-
{
|
223 |
-
return function (callable $handler) use ($operations) {
|
224 |
-
return function (
|
225 |
-
CommandInterface $command,
|
226 |
-
RequestInterface $request = null
|
227 |
-
) use ($handler, $operations) {
|
228 |
-
if (!$request->hasHeader('Content-Type')
|
229 |
-
&& in_array($command->getName(), $operations, true)
|
230 |
-
&& ($uri = $request->getBody()->getMetadata('uri'))
|
231 |
-
) {
|
232 |
-
$request = $request->withHeader(
|
233 |
-
'Content-Type',
|
234 |
-
Psr7\mimetype_from_filename($uri) ?: 'application/octet-stream'
|
235 |
-
);
|
236 |
-
}
|
237 |
-
|
238 |
-
return $handler($command, $request);
|
239 |
-
};
|
240 |
-
};
|
241 |
-
}
|
242 |
-
|
243 |
-
/**
|
244 |
-
* Tracks command and request history using a history container.
|
245 |
-
*
|
246 |
-
* This is useful for testing.
|
247 |
-
*
|
248 |
-
* @param History $history History container to store entries.
|
249 |
-
*
|
250 |
-
* @return callable
|
251 |
-
*/
|
252 |
-
public static function history(History $history)
|
253 |
-
{
|
254 |
-
return function (callable $handler) use ($history) {
|
255 |
-
return function (
|
256 |
-
CommandInterface $command,
|
257 |
-
RequestInterface $request = null
|
258 |
-
) use ($handler, $history) {
|
259 |
-
$ticket = $history->start($command, $request);
|
260 |
-
return $handler($command, $request)
|
261 |
-
->then(
|
262 |
-
function ($result) use ($history, $ticket) {
|
263 |
-
$history->finish($ticket, $result);
|
264 |
-
return $result;
|
265 |
-
},
|
266 |
-
function ($reason) use ($history, $ticket) {
|
267 |
-
$history->finish($ticket, $reason);
|
268 |
-
return Promise\rejection_for($reason);
|
269 |
-
}
|
270 |
-
);
|
271 |
-
};
|
272 |
-
};
|
273 |
-
}
|
274 |
-
|
275 |
-
/**
|
276 |
-
* Creates a middleware that applies a map function to requests as they
|
277 |
-
* pass through the middleware.
|
278 |
-
*
|
279 |
-
* @param callable $f Map function that accepts a RequestInterface and
|
280 |
-
* returns a RequestInterface.
|
281 |
-
*
|
282 |
-
* @return callable
|
283 |
-
*/
|
284 |
-
public static function mapRequest(callable $f)
|
285 |
-
{
|
286 |
-
return function (callable $handler) use ($f) {
|
287 |
-
return function (
|
288 |
-
CommandInterface $command,
|
289 |
-
RequestInterface $request = null
|
290 |
-
) use ($handler, $f) {
|
291 |
-
return $handler($command, $f($request));
|
292 |
-
};
|
293 |
-
};
|
294 |
-
}
|
295 |
-
|
296 |
-
/**
|
297 |
-
* Creates a middleware that applies a map function to commands as they
|
298 |
-
* pass through the middleware.
|
299 |
-
*
|
300 |
-
* @param callable $f Map function that accepts a command and returns a
|
301 |
-
* command.
|
302 |
-
*
|
303 |
-
* @return callable
|
304 |
-
*/
|
305 |
-
public static function mapCommand(callable $f)
|
306 |
-
{
|
307 |
-
return function (callable $handler) use ($f) {
|
308 |
-
return function (
|
309 |
-
CommandInterface $command,
|
310 |
-
RequestInterface $request = null
|
311 |
-
) use ($handler, $f) {
|
312 |
-
return $handler($f($command), $request);
|
313 |
-
};
|
314 |
-
};
|
315 |
-
}
|
316 |
-
|
317 |
-
/**
|
318 |
-
* Creates a middleware that applies a map function to results.
|
319 |
-
*
|
320 |
-
* @param callable $f Map function that accepts an Aws\ResultInterface and
|
321 |
-
* returns an Aws\ResultInterface.
|
322 |
-
*
|
323 |
-
* @return callable
|
324 |
-
*/
|
325 |
-
public static function mapResult(callable $f)
|
326 |
-
{
|
327 |
-
return function (callable $handler) use ($f) {
|
328 |
-
return function (
|
329 |
-
CommandInterface $command,
|
330 |
-
RequestInterface $request = null
|
331 |
-
) use ($handler, $f) {
|
332 |
-
return $handler($command, $request)->then($f);
|
333 |
-
};
|
334 |
-
};
|
335 |
-
}
|
336 |
-
|
337 |
-
public static function timer()
|
338 |
-
{
|
339 |
-
return function (callable $handler) {
|
340 |
-
return function (
|
341 |
-
CommandInterface $command,
|
342 |
-
RequestInterface $request = null
|
343 |
-
) use ($handler) {
|
344 |
-
$start = microtime(true);
|
345 |
-
return $handler($command, $request)
|
346 |
-
->then(
|
347 |
-
function (ResultInterface $res) use ($start) {
|
348 |
-
if (!isset($res['@metadata'])) {
|
349 |
-
$res['@metadata'] = [];
|
350 |
-
}
|
351 |
-
if (!isset($res['@metadata']['transferStats'])) {
|
352 |
-
$res['@metadata']['transferStats'] = [];
|
353 |
-
}
|
354 |
-
|
355 |
-
$res['@metadata']['transferStats']['total_time']
|
356 |
-
= microtime(true) - $start;
|
357 |
-
|
358 |
-
return $res;
|
359 |
-
},
|
360 |
-
function ($err) use ($start) {
|
361 |
-
if ($err instanceof AwsException) {
|
362 |
-
$err->setTransferInfo([
|
363 |
-
'total_time' => microtime(true) - $start,
|
364 |
-
] + $err->getTransferInfo());
|
365 |
-
}
|
366 |
-
return Promise\rejection_for($err);
|
367 |
-
}
|
368 |
-
);
|
369 |
-
};
|
370 |
-
};
|
371 |
-
}
|
372 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/MockHandler.php
DELETED
@@ -1,145 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Exception\AwsException;
|
5 |
-
use GuzzleHttp\Promise;
|
6 |
-
use GuzzleHttp\Promise\RejectedPromise;
|
7 |
-
use Psr\Http\Message\RequestInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Returns promises that are rejected or fulfilled using a queue of
|
11 |
-
* Aws\ResultInterface and Aws\Exception\AwsException objects.
|
12 |
-
*/
|
13 |
-
class MockHandler implements \Countable
|
14 |
-
{
|
15 |
-
private $queue;
|
16 |
-
private $lastCommand;
|
17 |
-
private $lastRequest;
|
18 |
-
private $onFulfilled;
|
19 |
-
private $onRejected;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* The passed in value must be an array of {@see Aws\ResultInterface} or
|
23 |
-
* {@see AwsException} objects that acts as a queue of results or
|
24 |
-
* exceptions to return each time the handler is invoked.
|
25 |
-
*
|
26 |
-
* @param array $resultOrQueue
|
27 |
-
* @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
|
28 |
-
* @param callable $onRejected Callback to invoke when the return value is rejected.
|
29 |
-
*/
|
30 |
-
public function __construct(
|
31 |
-
array $resultOrQueue = [],
|
32 |
-
callable $onFulfilled = null,
|
33 |
-
callable $onRejected = null
|
34 |
-
) {
|
35 |
-
$this->onFulfilled = $onFulfilled;
|
36 |
-
$this->onRejected = $onRejected;
|
37 |
-
|
38 |
-
if ($resultOrQueue) {
|
39 |
-
call_user_func_array([$this, 'append'], $resultOrQueue);
|
40 |
-
}
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Adds one or more variadic ResultInterface or AwsException objects to the
|
45 |
-
* queue.
|
46 |
-
*/
|
47 |
-
public function append()
|
48 |
-
{
|
49 |
-
foreach (func_get_args() as $value) {
|
50 |
-
if ($value instanceof ResultInterface
|
51 |
-
|| $value instanceof AwsException
|
52 |
-
|| is_callable($value)
|
53 |
-
) {
|
54 |
-
$this->queue[] = $value;
|
55 |
-
} else {
|
56 |
-
throw new \InvalidArgumentException('Expected an Aws\ResultInterface or Aws\Exception\AwsException.');
|
57 |
-
}
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Adds one or more \Exception or \Throwable to the queue
|
63 |
-
*/
|
64 |
-
public function appendException()
|
65 |
-
{
|
66 |
-
foreach (func_get_args() as $value) {
|
67 |
-
if ($value instanceof \Exception || $value instanceof \Throwable) {
|
68 |
-
$this->queue[] = $value;
|
69 |
-
} else {
|
70 |
-
throw new \InvalidArgumentException('Expected an \Exception or \Throwable.');
|
71 |
-
}
|
72 |
-
}
|
73 |
-
}
|
74 |
-
|
75 |
-
public function __invoke(
|
76 |
-
CommandInterface $command,
|
77 |
-
RequestInterface $request
|
78 |
-
) {
|
79 |
-
if (!$this->queue) {
|
80 |
-
$last = $this->lastCommand
|
81 |
-
? ' The last command sent was ' . $this->lastCommand->getName() . '.'
|
82 |
-
: '';
|
83 |
-
throw new \RuntimeException('Mock queue is empty. Trying to send a '
|
84 |
-
. $command->getName() . ' command failed.' . $last);
|
85 |
-
}
|
86 |
-
|
87 |
-
$this->lastCommand = $command;
|
88 |
-
$this->lastRequest = $request;
|
89 |
-
|
90 |
-
$result = array_shift($this->queue);
|
91 |
-
|
92 |
-
if (is_callable($result)) {
|
93 |
-
$result = $result($command, $request);
|
94 |
-
}
|
95 |
-
|
96 |
-
if ($result instanceof \Exception) {
|
97 |
-
$result = new RejectedPromise($result);
|
98 |
-
} else {
|
99 |
-
// Add an effective URI and statusCode if not present.
|
100 |
-
$meta = $result['@metadata'];
|
101 |
-
if (!isset($meta['effectiveUri'])) {
|
102 |
-
$meta['effectiveUri'] = (string) $request->getUri();
|
103 |
-
}
|
104 |
-
if (!isset($meta['statusCode'])) {
|
105 |
-
$meta['statusCode'] = 200;
|
106 |
-
}
|
107 |
-
$result['@metadata'] = $meta;
|
108 |
-
$result = Promise\promise_for($result);
|
109 |
-
}
|
110 |
-
|
111 |
-
$result->then($this->onFulfilled, $this->onRejected);
|
112 |
-
|
113 |
-
return $result;
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Get the last received request.
|
118 |
-
*
|
119 |
-
* @return RequestInterface
|
120 |
-
*/
|
121 |
-
public function getLastRequest()
|
122 |
-
{
|
123 |
-
return $this->lastRequest;
|
124 |
-
}
|
125 |
-
|
126 |
-
/**
|
127 |
-
* Get the last received command.
|
128 |
-
*
|
129 |
-
* @return CommandInterface
|
130 |
-
*/
|
131 |
-
public function getLastCommand()
|
132 |
-
{
|
133 |
-
return $this->lastCommand;
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Returns the number of remaining items in the queue.
|
138 |
-
*
|
139 |
-
* @return int
|
140 |
-
*/
|
141 |
-
public function count()
|
142 |
-
{
|
143 |
-
return count($this->queue);
|
144 |
-
}
|
145 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/MultiRegionClient.php
DELETED
@@ -1,236 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Endpoint\PartitionEndpointProvider;
|
5 |
-
use Aws\Endpoint\PartitionInterface;
|
6 |
-
|
7 |
-
class MultiRegionClient implements AwsClientInterface
|
8 |
-
{
|
9 |
-
use AwsClientTrait;
|
10 |
-
|
11 |
-
/** @var AwsClientInterface[] A pool of clients keyed by region. */
|
12 |
-
private $clientPool = [];
|
13 |
-
/** @var callable */
|
14 |
-
private $factory;
|
15 |
-
/** @var PartitionInterface */
|
16 |
-
private $partition;
|
17 |
-
/** @var array */
|
18 |
-
private $args;
|
19 |
-
/** @var array */
|
20 |
-
private $config;
|
21 |
-
/** @var HandlerList */
|
22 |
-
private $handlerList;
|
23 |
-
|
24 |
-
public static function getArguments()
|
25 |
-
{
|
26 |
-
$args = array_intersect_key(
|
27 |
-
ClientResolver::getDefaultArguments(),
|
28 |
-
['service' => true, 'region' => true]
|
29 |
-
);
|
30 |
-
$args['region']['required'] = false;
|
31 |
-
|
32 |
-
return $args + [
|
33 |
-
'client_factory' => [
|
34 |
-
'type' => 'config',
|
35 |
-
'valid' => ['callable'],
|
36 |
-
'doc' => 'A callable that takes an array of client'
|
37 |
-
. ' configuration arguments and returns a regionalized'
|
38 |
-
. ' client.',
|
39 |
-
'required' => true,
|
40 |
-
'internal' => true,
|
41 |
-
'default' => function (array $args) {
|
42 |
-
$namespace = manifest($args['service'])['namespace'];
|
43 |
-
$klass = "Aws\\{$namespace}\\{$namespace}Client";
|
44 |
-
$region = isset($args['region']) ? $args['region'] : null;
|
45 |
-
|
46 |
-
return function (array $args) use ($klass, $region) {
|
47 |
-
if ($region && empty($args['region'])) {
|
48 |
-
$args['region'] = $region;
|
49 |
-
}
|
50 |
-
|
51 |
-
return new $klass($args);
|
52 |
-
};
|
53 |
-
},
|
54 |
-
],
|
55 |
-
'partition' => [
|
56 |
-
'type' => 'config',
|
57 |
-
'valid' => ['string', PartitionInterface::class],
|
58 |
-
'doc' => 'AWS partition to connect to. Valid partitions'
|
59 |
-
. ' include "aws," "aws-cn," and "aws-us-gov." Used to'
|
60 |
-
. ' restrict the scope of the mapRegions method.',
|
61 |
-
'default' => function (array $args) {
|
62 |
-
$region = isset($args['region']) ? $args['region'] : '';
|
63 |
-
return PartitionEndpointProvider::defaultProvider()
|
64 |
-
->getPartition($region, $args['service']);
|
65 |
-
},
|
66 |
-
'fn' => function ($value, array &$args) {
|
67 |
-
if (is_string($value)) {
|
68 |
-
$value = PartitionEndpointProvider::defaultProvider()
|
69 |
-
->getPartitionByName($value);
|
70 |
-
}
|
71 |
-
|
72 |
-
if (!$value instanceof PartitionInterface) {
|
73 |
-
throw new \InvalidArgumentException('No valid partition'
|
74 |
-
. ' was provided. Provide a concrete partition or'
|
75 |
-
. ' the name of a partition (e.g., "aws," "aws-cn,"'
|
76 |
-
. ' or "aws-us-gov").'
|
77 |
-
);
|
78 |
-
}
|
79 |
-
|
80 |
-
$args['partition'] = $value;
|
81 |
-
$args['endpoint_provider'] = $value;
|
82 |
-
}
|
83 |
-
],
|
84 |
-
];
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* The multi-region client constructor accepts the following options:
|
89 |
-
*
|
90 |
-
* - client_factory: (callable) An optional callable that takes an array of
|
91 |
-
* client configuration arguments and returns a regionalized client.
|
92 |
-
* - partition: (Aws\Endpoint\Partition|string) AWS partition to connect to.
|
93 |
-
* Valid partitions include "aws," "aws-cn," and "aws-us-gov." Used to
|
94 |
-
* restrict the scope of the mapRegions method.
|
95 |
-
* - region: (string) Region to connect to when no override is provided.
|
96 |
-
* Used to create the default client factory and determine the appropriate
|
97 |
-
* AWS partition when present.
|
98 |
-
*
|
99 |
-
* @param array $args Client configuration arguments.
|
100 |
-
*/
|
101 |
-
public function __construct(array $args = [])
|
102 |
-
{
|
103 |
-
if (!isset($args['service'])) {
|
104 |
-
$args['service'] = $this->parseClass();
|
105 |
-
}
|
106 |
-
|
107 |
-
$this->handlerList = new HandlerList(function (
|
108 |
-
CommandInterface $command
|
109 |
-
) {
|
110 |
-
list($region, $args) = $this->getRegionFromArgs($command->toArray());
|
111 |
-
$command = $this->getClientFromPool($region)
|
112 |
-
->getCommand($command->getName(), $args);
|
113 |
-
return $this->executeAsync($command);
|
114 |
-
});
|
115 |
-
|
116 |
-
$argDefinitions = static::getArguments();
|
117 |
-
$resolver = new ClientResolver($argDefinitions);
|
118 |
-
$args = $resolver->resolve($args, $this->handlerList);
|
119 |
-
$this->config = $args['config'];
|
120 |
-
$this->factory = $args['client_factory'];
|
121 |
-
$this->partition = $args['partition'];
|
122 |
-
$this->args = array_diff_key($args, $args['config']);
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Get the region to which the client is configured to send requests by
|
127 |
-
* default.
|
128 |
-
*
|
129 |
-
* @return string
|
130 |
-
*/
|
131 |
-
public function getRegion()
|
132 |
-
{
|
133 |
-
return $this->getClientFromPool()->getRegion();
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Create a command for an operation name.
|
138 |
-
*
|
139 |
-
* Special keys may be set on the command to control how it behaves,
|
140 |
-
* including:
|
141 |
-
*
|
142 |
-
* - @http: Associative array of transfer specific options to apply to the
|
143 |
-
* request that is serialized for this command. Available keys include
|
144 |
-
* "proxy", "verify", "timeout", "connect_timeout", "debug", "delay", and
|
145 |
-
* "headers".
|
146 |
-
* - @region: The region to which the command should be sent.
|
147 |
-
*
|
148 |
-
* @param string $name Name of the operation to use in the command
|
149 |
-
* @param array $args Arguments to pass to the command
|
150 |
-
*
|
151 |
-
* @return CommandInterface
|
152 |
-
* @throws \InvalidArgumentException if no command can be found by name
|
153 |
-
*/
|
154 |
-
public function getCommand($name, array $args = [])
|
155 |
-
{
|
156 |
-
return new Command($name, $args, clone $this->getHandlerList());
|
157 |
-
}
|
158 |
-
|
159 |
-
public function getConfig($option = null)
|
160 |
-
{
|
161 |
-
if (null === $option) {
|
162 |
-
return $this->config;
|
163 |
-
}
|
164 |
-
|
165 |
-
if (isset($this->config[$option])) {
|
166 |
-
return $this->config[$option];
|
167 |
-
}
|
168 |
-
|
169 |
-
return $this->getClientFromPool()->getConfig($option);
|
170 |
-
}
|
171 |
-
|
172 |
-
public function getCredentials()
|
173 |
-
{
|
174 |
-
return $this->getClientFromPool()->getCredentials();
|
175 |
-
}
|
176 |
-
|
177 |
-
public function getHandlerList()
|
178 |
-
{
|
179 |
-
return $this->handlerList;
|
180 |
-
}
|
181 |
-
|
182 |
-
public function getApi()
|
183 |
-
{
|
184 |
-
return $this->getClientFromPool()->getApi();
|
185 |
-
}
|
186 |
-
|
187 |
-
public function getEndpoint()
|
188 |
-
{
|
189 |
-
return $this->getClientFromPool()->getEndpoint();
|
190 |
-
}
|
191 |
-
|
192 |
-
/**
|
193 |
-
* @param string $region Omit this argument or pass in an empty string to
|
194 |
-
* allow the configured client factory to apply the
|
195 |
-
* region.
|
196 |
-
*
|
197 |
-
* @return AwsClientInterface
|
198 |
-
*/
|
199 |
-
protected function getClientFromPool($region = '')
|
200 |
-
{
|
201 |
-
if (empty($this->clientPool[$region])) {
|
202 |
-
$factory = $this->factory;
|
203 |
-
$this->clientPool[$region] = $factory(
|
204 |
-
array_replace($this->args, array_filter(['region' => $region]))
|
205 |
-
);
|
206 |
-
}
|
207 |
-
|
208 |
-
return $this->clientPool[$region];
|
209 |
-
}
|
210 |
-
|
211 |
-
/**
|
212 |
-
* Parse the class name and return the "service" name of the client.
|
213 |
-
*
|
214 |
-
* @return string
|
215 |
-
*/
|
216 |
-
private function parseClass()
|
217 |
-
{
|
218 |
-
$klass = get_class($this);
|
219 |
-
|
220 |
-
if ($klass === __CLASS__) {
|
221 |
-
return '';
|
222 |
-
}
|
223 |
-
|
224 |
-
return strtolower(substr($klass, strrpos($klass, '\\') + 1, -17));
|
225 |
-
}
|
226 |
-
|
227 |
-
private function getRegionFromArgs(array $args)
|
228 |
-
{
|
229 |
-
$region = isset($args['@region'])
|
230 |
-
? $args['@region']
|
231 |
-
: $this->getRegion();
|
232 |
-
unset($args['@region']);
|
233 |
-
|
234 |
-
return [$region, $args];
|
235 |
-
}
|
236 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/PresignUrlMiddleware.php
DELETED
@@ -1,99 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Signature\SignatureV4;
|
5 |
-
use Aws\Endpoint\EndpointProvider;
|
6 |
-
use GuzzleHttp\Psr7\Uri;
|
7 |
-
use Psr\Http\Message\RequestInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* @internal Adds computed values to service operations that need presigned url.
|
11 |
-
*/
|
12 |
-
class PresignUrlMiddleware
|
13 |
-
{
|
14 |
-
private $client;
|
15 |
-
private $endpointProvider;
|
16 |
-
private $nextHandler;
|
17 |
-
/** @var array names of operations that require presign url */
|
18 |
-
private $commandPool;
|
19 |
-
/** @var string */
|
20 |
-
private $serviceName;
|
21 |
-
/** @var string */
|
22 |
-
private $presignParam;
|
23 |
-
/** @var bool */
|
24 |
-
private $requireDifferentRegion;
|
25 |
-
|
26 |
-
public function __construct(
|
27 |
-
array $options,
|
28 |
-
callable $endpointProvider,
|
29 |
-
AwsClientInterface $client,
|
30 |
-
callable $nextHandler
|
31 |
-
) {
|
32 |
-
$this->endpointProvider = $endpointProvider;
|
33 |
-
$this->client = $client;
|
34 |
-
$this->nextHandler = $nextHandler;
|
35 |
-
$this->commandPool = $options['operations'];
|
36 |
-
$this->serviceName = $options['service'];
|
37 |
-
$this->presignParam = $options['presign_param'];
|
38 |
-
$this->requireDifferentRegion = !empty($options['require_different_region']);
|
39 |
-
}
|
40 |
-
|
41 |
-
public static function wrap(
|
42 |
-
AwsClientInterface $client,
|
43 |
-
callable $endpointProvider,
|
44 |
-
array $options = []
|
45 |
-
) {
|
46 |
-
return function (callable $handler) use ($endpointProvider, $client, $options) {
|
47 |
-
$f = new PresignUrlMiddleware($options, $endpointProvider, $client, $handler);
|
48 |
-
return $f;
|
49 |
-
};
|
50 |
-
}
|
51 |
-
|
52 |
-
public function __invoke(CommandInterface $cmd, RequestInterface $request = null)
|
53 |
-
{
|
54 |
-
if (in_array($cmd->getName(), $this->commandPool)
|
55 |
-
&& (!isset($cmd->{'__skip' . $cmd->getName()}))
|
56 |
-
) {
|
57 |
-
$cmd['DestinationRegion'] = $this->client->getRegion();
|
58 |
-
if (!$this->requireDifferentRegion
|
59 |
-
|| (!empty($cmd['SourceRegion'])
|
60 |
-
&& $cmd['SourceRegion'] !== $cmd['DestinationRegion'])
|
61 |
-
) {
|
62 |
-
$cmd[$this->presignParam] = $this->createPresignedUrl($this->client, $cmd);
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
$f = $this->nextHandler;
|
67 |
-
return $f($cmd, $request);
|
68 |
-
}
|
69 |
-
|
70 |
-
private function createPresignedUrl(
|
71 |
-
AwsClientInterface $client,
|
72 |
-
CommandInterface $cmd
|
73 |
-
) {
|
74 |
-
$cmdName = $cmd->getName();
|
75 |
-
$newCmd = $client->getCommand($cmdName, $cmd->toArray());
|
76 |
-
// Avoid infinite recursion by flagging the new command.
|
77 |
-
$newCmd->{'__skip' . $cmdName} = true;
|
78 |
-
|
79 |
-
// Serialize a request for the operation.
|
80 |
-
$request = \Aws\serialize($newCmd);
|
81 |
-
// Create the new endpoint for the target endpoint.
|
82 |
-
$endpoint = EndpointProvider::resolve($this->endpointProvider, [
|
83 |
-
'region' => $cmd['SourceRegion'],
|
84 |
-
'service' => $this->serviceName,
|
85 |
-
])['endpoint'];
|
86 |
-
|
87 |
-
// Set the request to hit the target endpoint.
|
88 |
-
$uri = $request->getUri()->withHost((new Uri($endpoint))->getHost());
|
89 |
-
$request = $request->withUri($uri);
|
90 |
-
// Create a presigned URL for our generated request.
|
91 |
-
$signer = new SignatureV4($this->serviceName, $cmd['SourceRegion']);
|
92 |
-
|
93 |
-
return (string) $signer->presign(
|
94 |
-
SignatureV4::convertPostToGet($request),
|
95 |
-
$client->getCredentials()->wait(),
|
96 |
-
'+1 hour'
|
97 |
-
)->getUri();
|
98 |
-
}
|
99 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/ResponseContainerInterface.php
DELETED
@@ -1,13 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Aws;
|
4 |
-
|
5 |
-
interface ResponseContainerInterface
|
6 |
-
{
|
7 |
-
/**
|
8 |
-
* Get the received HTTP response if any.
|
9 |
-
*
|
10 |
-
* @return ResponseInterface|null
|
11 |
-
*/
|
12 |
-
public function getResponse();
|
13 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/RetryMiddleware.php
DELETED
@@ -1,315 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Exception\AwsException;
|
5 |
-
use GuzzleHttp\Exception\RequestException;
|
6 |
-
use Psr\Http\Message\RequestInterface;
|
7 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
8 |
-
use GuzzleHttp\Promise;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @internal Middleware that retries failures.
|
12 |
-
*/
|
13 |
-
class RetryMiddleware
|
14 |
-
{
|
15 |
-
private static $retryStatusCodes = [
|
16 |
-
500 => true,
|
17 |
-
502 => true,
|
18 |
-
503 => true,
|
19 |
-
504 => true
|
20 |
-
];
|
21 |
-
|
22 |
-
private static $retryCodes = [
|
23 |
-
// Throttling error
|
24 |
-
'RequestLimitExceeded' => true,
|
25 |
-
'Throttling' => true,
|
26 |
-
'ThrottlingException' => true,
|
27 |
-
'ThrottledException' => true,
|
28 |
-
'ProvisionedThroughputExceededException' => true,
|
29 |
-
'RequestThrottled' => true,
|
30 |
-
'BandwidthLimitExceeded' => true,
|
31 |
-
'RequestThrottledException' => true,
|
32 |
-
];
|
33 |
-
|
34 |
-
private $decider;
|
35 |
-
private $delay;
|
36 |
-
private $nextHandler;
|
37 |
-
private $collectStats;
|
38 |
-
|
39 |
-
public function __construct(
|
40 |
-
callable $decider,
|
41 |
-
callable $delay,
|
42 |
-
callable $nextHandler,
|
43 |
-
$collectStats = false
|
44 |
-
) {
|
45 |
-
$this->decider = $decider;
|
46 |
-
$this->delay = $delay;
|
47 |
-
$this->nextHandler = $nextHandler;
|
48 |
-
$this->collectStats = (bool) $collectStats;
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Creates a default AWS retry decider function.
|
53 |
-
*
|
54 |
-
* The optional $additionalRetryConfig parameter is an associative array
|
55 |
-
* that specifies additional retry conditions on top of the ones specified
|
56 |
-
* by default by the Aws\RetryMiddleware class, with the following keys:
|
57 |
-
*
|
58 |
-
* - errorCodes: (string[]) An indexed array of AWS exception codes to retry.
|
59 |
-
* Optional.
|
60 |
-
* - statusCodes: (int[]) An indexed array of HTTP status codes to retry.
|
61 |
-
* Optional.
|
62 |
-
* - curlErrors: (int[]) An indexed array of Curl error codes to retry. Note
|
63 |
-
* these should be valid Curl constants. Optional.
|
64 |
-
*
|
65 |
-
* @param int $maxRetries
|
66 |
-
* @param array $additionalRetryConfig
|
67 |
-
* @return callable
|
68 |
-
*/
|
69 |
-
public static function createDefaultDecider(
|
70 |
-
$maxRetries = 3,
|
71 |
-
$additionalRetryConfig = []
|
72 |
-
) {
|
73 |
-
$retryCurlErrors = [];
|
74 |
-
if (extension_loaded('curl')) {
|
75 |
-
$retryCurlErrors[CURLE_RECV_ERROR] = true;
|
76 |
-
}
|
77 |
-
|
78 |
-
return function (
|
79 |
-
$retries,
|
80 |
-
CommandInterface $command,
|
81 |
-
RequestInterface $request,
|
82 |
-
ResultInterface $result = null,
|
83 |
-
$error = null
|
84 |
-
) use ($maxRetries, $retryCurlErrors, $additionalRetryConfig) {
|
85 |
-
// Allow command-level options to override this value
|
86 |
-
$maxRetries = null !== $command['@retries'] ?
|
87 |
-
$command['@retries']
|
88 |
-
: $maxRetries;
|
89 |
-
|
90 |
-
$isRetryable = self::isRetryable(
|
91 |
-
$result,
|
92 |
-
$error,
|
93 |
-
$retryCurlErrors,
|
94 |
-
$additionalRetryConfig
|
95 |
-
);
|
96 |
-
|
97 |
-
if ($retries >= $maxRetries) {
|
98 |
-
if (!empty($error)
|
99 |
-
&& $error instanceof AwsException
|
100 |
-
&& $isRetryable
|
101 |
-
) {
|
102 |
-
$error->setMaxRetriesExceeded();
|
103 |
-
}
|
104 |
-
return false;
|
105 |
-
}
|
106 |
-
|
107 |
-
return $isRetryable;
|
108 |
-
};
|
109 |
-
}
|
110 |
-
|
111 |
-
private static function isRetryable(
|
112 |
-
$result,
|
113 |
-
$error,
|
114 |
-
$retryCurlErrors,
|
115 |
-
$additionalRetryConfig = []
|
116 |
-
) {
|
117 |
-
$errorCodes = self::$retryCodes;
|
118 |
-
if (!empty($additionalRetryConfig['errorCodes'])
|
119 |
-
&& is_array($additionalRetryConfig['errorCodes'])
|
120 |
-
) {
|
121 |
-
foreach($additionalRetryConfig['errorCodes'] as $code) {
|
122 |
-
$errorCodes[$code] = true;
|
123 |
-
}
|
124 |
-
}
|
125 |
-
|
126 |
-
$statusCodes = self::$retryStatusCodes;
|
127 |
-
if (!empty($additionalRetryConfig['statusCodes'])
|
128 |
-
&& is_array($additionalRetryConfig['statusCodes'])
|
129 |
-
) {
|
130 |
-
foreach($additionalRetryConfig['statusCodes'] as $code) {
|
131 |
-
$statusCodes[$code] = true;
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
if (!empty($additionalRetryConfig['curlErrors'])
|
136 |
-
&& is_array($additionalRetryConfig['curlErrors'])
|
137 |
-
) {
|
138 |
-
foreach($additionalRetryConfig['curlErrors'] as $code) {
|
139 |
-
$retryCurlErrors[$code] = true;
|
140 |
-
}
|
141 |
-
}
|
142 |
-
|
143 |
-
if (!$error) {
|
144 |
-
return isset($statusCodes[$result['@metadata']['statusCode']]);
|
145 |
-
}
|
146 |
-
|
147 |
-
if (!($error instanceof AwsException)) {
|
148 |
-
return false;
|
149 |
-
}
|
150 |
-
|
151 |
-
if ($error->isConnectionError()) {
|
152 |
-
return true;
|
153 |
-
}
|
154 |
-
|
155 |
-
if (isset($errorCodes[$error->getAwsErrorCode()])) {
|
156 |
-
return true;
|
157 |
-
}
|
158 |
-
|
159 |
-
if (isset($statusCodes[$error->getStatusCode()])) {
|
160 |
-
return true;
|
161 |
-
}
|
162 |
-
|
163 |
-
if (count($retryCurlErrors)
|
164 |
-
&& ($previous = $error->getPrevious())
|
165 |
-
&& $previous instanceof RequestException
|
166 |
-
) {
|
167 |
-
if (method_exists($previous, 'getHandlerContext')) {
|
168 |
-
$context = $previous->getHandlerContext();
|
169 |
-
return !empty($context['errno'])
|
170 |
-
&& isset($retryCurlErrors[$context['errno']]);
|
171 |
-
}
|
172 |
-
|
173 |
-
$message = $previous->getMessage();
|
174 |
-
foreach (array_keys($retryCurlErrors) as $curlError) {
|
175 |
-
if (strpos($message, 'cURL error ' . $curlError . ':') === 0) {
|
176 |
-
return true;
|
177 |
-
}
|
178 |
-
}
|
179 |
-
}
|
180 |
-
|
181 |
-
return false;
|
182 |
-
}
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Delay function that calculates an exponential delay.
|
186 |
-
*
|
187 |
-
* Exponential backoff with jitter, 100ms base, 20 sec ceiling
|
188 |
-
*
|
189 |
-
* @param $retries - The number of retries that have already been attempted
|
190 |
-
*
|
191 |
-
* @return int
|
192 |
-
*
|
193 |
-
* @link https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
|
194 |
-
*/
|
195 |
-
public static function exponentialDelay($retries)
|
196 |
-
{
|
197 |
-
return mt_rand(0, (int) min(20000, (int) pow(2, $retries) * 100));
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* @param CommandInterface $command
|
202 |
-
* @param RequestInterface $request
|
203 |
-
*
|
204 |
-
* @return PromiseInterface
|
205 |
-
*/
|
206 |
-
public function __invoke(
|
207 |
-
CommandInterface $command,
|
208 |
-
RequestInterface $request = null
|
209 |
-
) {
|
210 |
-
$retries = 0;
|
211 |
-
$requestStats = [];
|
212 |
-
$monitoringEvents = [];
|
213 |
-
$handler = $this->nextHandler;
|
214 |
-
$decider = $this->decider;
|
215 |
-
$delay = $this->delay;
|
216 |
-
|
217 |
-
$request = $this->addRetryHeader($request, 0, 0);
|
218 |
-
|
219 |
-
$g = function ($value) use (
|
220 |
-
$handler,
|
221 |
-
$decider,
|
222 |
-
$delay,
|
223 |
-
$command,
|
224 |
-
$request,
|
225 |
-
&$retries,
|
226 |
-
&$requestStats,
|
227 |
-
&$monitoringEvents,
|
228 |
-
&$g
|
229 |
-
) {
|
230 |
-
$this->updateHttpStats($value, $requestStats);
|
231 |
-
|
232 |
-
if ($value instanceof MonitoringEventsInterface) {
|
233 |
-
$reversedEvents = array_reverse($monitoringEvents);
|
234 |
-
$monitoringEvents = array_merge($monitoringEvents, $value->getMonitoringEvents());
|
235 |
-
foreach ($reversedEvents as $event) {
|
236 |
-
$value->prependMonitoringEvent($event);
|
237 |
-
}
|
238 |
-
}
|
239 |
-
if ($value instanceof \Exception || $value instanceof \Throwable) {
|
240 |
-
if (!$decider($retries, $command, $request, null, $value)) {
|
241 |
-
return Promise\rejection_for(
|
242 |
-
$this->bindStatsToReturn($value, $requestStats)
|
243 |
-
);
|
244 |
-
}
|
245 |
-
} elseif ($value instanceof ResultInterface
|
246 |
-
&& !$decider($retries, $command, $request, $value, null)
|
247 |
-
) {
|
248 |
-
return $this->bindStatsToReturn($value, $requestStats);
|
249 |
-
}
|
250 |
-
|
251 |
-
// Delay fn is called with 0, 1, ... so increment after the call.
|
252 |
-
$delayBy = $delay($retries++);
|
253 |
-
$command['@http']['delay'] = $delayBy;
|
254 |
-
if ($this->collectStats) {
|
255 |
-
$this->updateStats($retries, $delayBy, $requestStats);
|
256 |
-
}
|
257 |
-
|
258 |
-
// Update retry header with retry count and delayBy
|
259 |
-
$request = $this->addRetryHeader($request, $retries, $delayBy);
|
260 |
-
|
261 |
-
return $handler($command, $request)->then($g, $g);
|
262 |
-
};
|
263 |
-
|
264 |
-
return $handler($command, $request)->then($g, $g);
|
265 |
-
}
|
266 |
-
|
267 |
-
private function addRetryHeader($request, $retries, $delayBy)
|
268 |
-
{
|
269 |
-
return $request->withHeader('aws-sdk-retry', "{$retries}/{$delayBy}");
|
270 |
-
}
|
271 |
-
|
272 |
-
private function updateStats($retries, $delay, array &$stats)
|
273 |
-
{
|
274 |
-
if (!isset($stats['total_retry_delay'])) {
|
275 |
-
$stats['total_retry_delay'] = 0;
|
276 |
-
}
|
277 |
-
|
278 |
-
$stats['total_retry_delay'] += $delay;
|
279 |
-
$stats['retries_attempted'] = $retries;
|
280 |
-
}
|
281 |
-
|
282 |
-
private function updateHttpStats($value, array &$stats)
|
283 |
-
{
|
284 |
-
if (empty($stats['http'])) {
|
285 |
-
$stats['http'] = [];
|
286 |
-
}
|
287 |
-
|
288 |
-
if ($value instanceof AwsException) {
|
289 |
-
$resultStats = isset($value->getTransferInfo('http')[0])
|
290 |
-
? $value->getTransferInfo('http')[0]
|
291 |
-
: [];
|
292 |
-
$stats['http'] []= $resultStats;
|
293 |
-
} elseif ($value instanceof ResultInterface) {
|
294 |
-
$resultStats = isset($value['@metadata']['transferStats']['http'][0])
|
295 |
-
? $value['@metadata']['transferStats']['http'][0]
|
296 |
-
: [];
|
297 |
-
$stats['http'] []= $resultStats;
|
298 |
-
}
|
299 |
-
}
|
300 |
-
|
301 |
-
private function bindStatsToReturn($return, array $stats)
|
302 |
-
{
|
303 |
-
if ($return instanceof ResultInterface) {
|
304 |
-
if (!isset($return['@metadata'])) {
|
305 |
-
$return['@metadata'] = [];
|
306 |
-
}
|
307 |
-
|
308 |
-
$return['@metadata']['transferStats'] = $stats;
|
309 |
-
} elseif ($return instanceof AwsException) {
|
310 |
-
$return->setTransferInfo($stats);
|
311 |
-
}
|
312 |
-
|
313 |
-
return $return;
|
314 |
-
}
|
315 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/AmbiguousSuccessParser.php
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\Api\Parser\AbstractParser;
|
5 |
-
use Aws\Api\StructureShape;
|
6 |
-
use Aws\CommandInterface;
|
7 |
-
use Aws\Exception\AwsException;
|
8 |
-
use Psr\Http\Message\ResponseInterface;
|
9 |
-
use Psr\Http\Message\StreamInterface;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Converts errors returned with a status code of 200 to a retryable error type.
|
13 |
-
*
|
14 |
-
* @internal
|
15 |
-
*/
|
16 |
-
class AmbiguousSuccessParser extends AbstractParser
|
17 |
-
{
|
18 |
-
private static $ambiguousSuccesses = [
|
19 |
-
'UploadPartCopy' => true,
|
20 |
-
'CopyObject' => true,
|
21 |
-
'CompleteMultipartUpload' => true,
|
22 |
-
];
|
23 |
-
|
24 |
-
/** @var callable */
|
25 |
-
private $errorParser;
|
26 |
-
/** @var string */
|
27 |
-
private $exceptionClass;
|
28 |
-
|
29 |
-
public function __construct(
|
30 |
-
callable $parser,
|
31 |
-
callable $errorParser,
|
32 |
-
$exceptionClass = AwsException::class
|
33 |
-
) {
|
34 |
-
$this->parser = $parser;
|
35 |
-
$this->errorParser = $errorParser;
|
36 |
-
$this->exceptionClass = $exceptionClass;
|
37 |
-
}
|
38 |
-
|
39 |
-
public function __invoke(
|
40 |
-
CommandInterface $command,
|
41 |
-
ResponseInterface $response
|
42 |
-
) {
|
43 |
-
if (200 === $response->getStatusCode()
|
44 |
-
&& isset(self::$ambiguousSuccesses[$command->getName()])
|
45 |
-
) {
|
46 |
-
$errorParser = $this->errorParser;
|
47 |
-
$parsed = $errorParser($response);
|
48 |
-
if (isset($parsed['code']) && isset($parsed['message'])) {
|
49 |
-
throw new $this->exceptionClass(
|
50 |
-
$parsed['message'],
|
51 |
-
$command,
|
52 |
-
['connection_error' => true]
|
53 |
-
);
|
54 |
-
}
|
55 |
-
}
|
56 |
-
|
57 |
-
$fn = $this->parser;
|
58 |
-
return $fn($command, $response);
|
59 |
-
}
|
60 |
-
|
61 |
-
public function parseMemberFromStream(
|
62 |
-
StreamInterface $stream,
|
63 |
-
StructureShape $member,
|
64 |
-
$response
|
65 |
-
) {
|
66 |
-
return $this->parser->parseMemberFromStream($stream, $member, $response);
|
67 |
-
}
|
68 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/ApplyChecksumMiddleware.php
DELETED
@@ -1,78 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\CommandInterface;
|
5 |
-
use GuzzleHttp\Psr7;
|
6 |
-
use Psr\Http\Message\RequestInterface;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Apply required or optional MD5s to requests before sending.
|
10 |
-
*
|
11 |
-
* IMPORTANT: This middleware must be added after the "build" step.
|
12 |
-
*
|
13 |
-
* @internal
|
14 |
-
*/
|
15 |
-
class ApplyChecksumMiddleware
|
16 |
-
{
|
17 |
-
private static $md5 = [
|
18 |
-
'DeleteObjects',
|
19 |
-
'PutBucketCors',
|
20 |
-
'PutBucketLifecycle',
|
21 |
-
'PutBucketLifecycleConfiguration',
|
22 |
-
'PutBucketPolicy',
|
23 |
-
'PutBucketTagging',
|
24 |
-
'PutBucketReplication',
|
25 |
-
'PutObjectLegalHold',
|
26 |
-
'PutObjectRetention',
|
27 |
-
'PutObjectLockConfiguration',
|
28 |
-
];
|
29 |
-
|
30 |
-
private static $sha256 = [
|
31 |
-
'PutObject',
|
32 |
-
'UploadPart',
|
33 |
-
];
|
34 |
-
|
35 |
-
private $nextHandler;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Create a middleware wrapper function.
|
39 |
-
*
|
40 |
-
* @return callable
|
41 |
-
*/
|
42 |
-
public static function wrap()
|
43 |
-
{
|
44 |
-
return function (callable $handler) {
|
45 |
-
return new self($handler);
|
46 |
-
};
|
47 |
-
}
|
48 |
-
|
49 |
-
public function __construct(callable $nextHandler)
|
50 |
-
{
|
51 |
-
$this->nextHandler = $nextHandler;
|
52 |
-
}
|
53 |
-
|
54 |
-
public function __invoke(
|
55 |
-
CommandInterface $command,
|
56 |
-
RequestInterface $request
|
57 |
-
) {
|
58 |
-
$next = $this->nextHandler;
|
59 |
-
$name = $command->getName();
|
60 |
-
$body = $request->getBody();
|
61 |
-
|
62 |
-
if (in_array($name, self::$md5) && !$request->hasHeader('Content-MD5')) {
|
63 |
-
// Set the content MD5 header for operations that require it.
|
64 |
-
$request = $request->withHeader(
|
65 |
-
'Content-MD5',
|
66 |
-
base64_encode(Psr7\hash($body, 'md5', true))
|
67 |
-
);
|
68 |
-
} elseif (in_array($name, self::$sha256) && $command['ContentSHA256']) {
|
69 |
-
// Set the content hash header if provided in the parameters.
|
70 |
-
$request = $request->withHeader(
|
71 |
-
'X-Amz-Content-Sha256',
|
72 |
-
$command['ContentSHA256']
|
73 |
-
);
|
74 |
-
}
|
75 |
-
|
76 |
-
return $next($command, $request);
|
77 |
-
}
|
78 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/Crypto/HeadersMetadataStrategy.php
DELETED
@@ -1,52 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3\Crypto;
|
3 |
-
|
4 |
-
use \Aws\Crypto\MetadataStrategyInterface;
|
5 |
-
use \Aws\Crypto\MetadataEnvelope;
|
6 |
-
|
7 |
-
class HeadersMetadataStrategy implements MetadataStrategyInterface
|
8 |
-
{
|
9 |
-
/**
|
10 |
-
* Places the information in the MetadataEnvelope in to the Meatadata for
|
11 |
-
* the PutObject request of the encrypted object.
|
12 |
-
*
|
13 |
-
* @param MetadataEnvelope $envelope Encryption data to save according to
|
14 |
-
* the strategy.
|
15 |
-
* @param array $args Arguments for PutObject that can be manipulated to
|
16 |
-
* store strategy related information.
|
17 |
-
*
|
18 |
-
* @return array Updated arguments for PutObject.
|
19 |
-
*/
|
20 |
-
public function save(MetadataEnvelope $envelope, array $args)
|
21 |
-
{
|
22 |
-
foreach ($envelope as $header=>$value) {
|
23 |
-
$args['Metadata'][$header] = $value;
|
24 |
-
}
|
25 |
-
|
26 |
-
return $args;
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Generates a MetadataEnvelope according to the Metadata headers from the
|
31 |
-
* GetObject result.
|
32 |
-
*
|
33 |
-
* @param array $args Arguments from Command and Result that contains
|
34 |
-
* S3 Object information, relevant headers, and command
|
35 |
-
* configuration.
|
36 |
-
*
|
37 |
-
* @return MetadataEnvelope
|
38 |
-
*/
|
39 |
-
public function load(array $args)
|
40 |
-
{
|
41 |
-
$envelope = new MetadataEnvelope();
|
42 |
-
$constantValues = MetadataEnvelope::getConstantValues();
|
43 |
-
|
44 |
-
foreach ($constantValues as $constant) {
|
45 |
-
if (!empty($args['Metadata'][$constant])) {
|
46 |
-
$envelope[$constant] = $args['Metadata'][$constant];
|
47 |
-
}
|
48 |
-
}
|
49 |
-
|
50 |
-
return $envelope;
|
51 |
-
}
|
52 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/Crypto/S3EncryptionClient.php
DELETED
@@ -1,317 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3\Crypto;
|
3 |
-
|
4 |
-
use Aws\HashingStream;
|
5 |
-
use Aws\PhpHash;
|
6 |
-
use Aws\Crypto\AbstractCryptoClient;
|
7 |
-
use Aws\Crypto\EncryptionTrait;
|
8 |
-
use Aws\Crypto\DecryptionTrait;
|
9 |
-
use Aws\Crypto\MetadataEnvelope;
|
10 |
-
use Aws\Crypto\MaterialsProvider;
|
11 |
-
use Aws\Crypto\Cipher\CipherBuilderTrait;
|
12 |
-
use Aws\S3\S3Client;
|
13 |
-
use GuzzleHttp\Promise;
|
14 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
15 |
-
use GuzzleHttp\Psr7;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Provides a wrapper for an S3Client that supplies functionality to encrypt
|
19 |
-
* data on putObject[Async] calls and decrypt data on getObject[Async] calls.
|
20 |
-
*/
|
21 |
-
class S3EncryptionClient extends AbstractCryptoClient
|
22 |
-
{
|
23 |
-
use EncryptionTrait, DecryptionTrait, CipherBuilderTrait, CryptoParamsTrait;
|
24 |
-
|
25 |
-
private $client;
|
26 |
-
private $instructionFileSuffix;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @param S3Client $client The S3Client to be used for true uploading and
|
30 |
-
* retrieving objects from S3 when using the
|
31 |
-
* encryption client.
|
32 |
-
* @param string|null $instructionFileSuffix Suffix for a client wide
|
33 |
-
* default when using instruction
|
34 |
-
* files for metadata storage.
|
35 |
-
*/
|
36 |
-
public function __construct(
|
37 |
-
S3Client $client,
|
38 |
-
$instructionFileSuffix = null
|
39 |
-
) {
|
40 |
-
$this->client = $client;
|
41 |
-
$this->instructionFileSuffix = $instructionFileSuffix;
|
42 |
-
}
|
43 |
-
|
44 |
-
private static function getDefaultStrategy()
|
45 |
-
{
|
46 |
-
return new HeadersMetadataStrategy();
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Encrypts the data in the 'Body' field of $args and promises to upload it
|
51 |
-
* to the specified location on S3.
|
52 |
-
*
|
53 |
-
* @param array $args Arguments for encrypting an object and uploading it
|
54 |
-
* to S3 via PutObject.
|
55 |
-
*
|
56 |
-
* The required configuration arguments are as follows:
|
57 |
-
*
|
58 |
-
* - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
|
59 |
-
* encrypting/decrypting for encryption metadata.
|
60 |
-
* - @CipherOptions: (array) Cipher options for encrypting data. Only the
|
61 |
-
* Cipher option is required. Accepts the following:
|
62 |
-
* - Cipher: (string) cbc|gcm
|
63 |
-
* See also: AbstractCryptoClient::$supportedCiphers
|
64 |
-
* - KeySize: (int) 128|192|256
|
65 |
-
* See also: MaterialsProvider::$supportedKeySizes
|
66 |
-
* - Aad: (string) Additional authentication data. This option is
|
67 |
-
* passed directly to OpenSSL when using gcm. It is ignored when
|
68 |
-
* using cbc.
|
69 |
-
*
|
70 |
-
* The optional configuration arguments are as follows:
|
71 |
-
*
|
72 |
-
* - @MetadataStrategy: (MetadataStrategy|string|null) Strategy for storing
|
73 |
-
* MetadataEnvelope information. Defaults to using a
|
74 |
-
* HeadersMetadataStrategy. Can either be a class implementing
|
75 |
-
* MetadataStrategy, a class name of a predefined strategy, or empty/null
|
76 |
-
* to default.
|
77 |
-
* - @InstructionFileSuffix: (string|null) Suffix used when writing to an
|
78 |
-
* instruction file if using an InstructionFileMetadataHandler.
|
79 |
-
*
|
80 |
-
* @return PromiseInterface
|
81 |
-
*
|
82 |
-
* @throws \InvalidArgumentException Thrown when arguments above are not
|
83 |
-
* passed or are passed incorrectly.
|
84 |
-
*/
|
85 |
-
public function putObjectAsync(array $args)
|
86 |
-
{
|
87 |
-
$provider = $this->getMaterialsProvider($args);
|
88 |
-
unset($args['@MaterialsProvider']);
|
89 |
-
|
90 |
-
$instructionFileSuffix = $this->getInstructionFileSuffix($args);
|
91 |
-
unset($args['@InstructionFileSuffix']);
|
92 |
-
|
93 |
-
$strategy = $this->getMetadataStrategy($args, $instructionFileSuffix);
|
94 |
-
unset($args['@MetadataStrategy']);
|
95 |
-
|
96 |
-
$envelope = new MetadataEnvelope();
|
97 |
-
|
98 |
-
return Promise\promise_for($this->encrypt(
|
99 |
-
Psr7\stream_for($args['Body']),
|
100 |
-
$args['@CipherOptions'] ?: [],
|
101 |
-
$provider,
|
102 |
-
$envelope
|
103 |
-
))->then(
|
104 |
-
function ($encryptedBodyStream) use ($args) {
|
105 |
-
$hash = new PhpHash('sha256');
|
106 |
-
$hashingEncryptedBodyStream = new HashingStream(
|
107 |
-
$encryptedBodyStream,
|
108 |
-
$hash,
|
109 |
-
self::getContentShaDecorator($args)
|
110 |
-
);
|
111 |
-
return [$hashingEncryptedBodyStream, $args];
|
112 |
-
}
|
113 |
-
)->then(
|
114 |
-
function ($putObjectContents) use ($strategy, $envelope) {
|
115 |
-
list($bodyStream, $args) = $putObjectContents;
|
116 |
-
if ($strategy === null) {
|
117 |
-
$strategy = self::getDefaultStrategy();
|
118 |
-
}
|
119 |
-
|
120 |
-
$updatedArgs = $strategy->save($envelope, $args);
|
121 |
-
$updatedArgs['Body'] = $bodyStream;
|
122 |
-
return $updatedArgs;
|
123 |
-
}
|
124 |
-
)->then(
|
125 |
-
function ($args) {
|
126 |
-
unset($args['@CipherOptions']);
|
127 |
-
return $this->client->putObjectAsync($args);
|
128 |
-
}
|
129 |
-
);
|
130 |
-
}
|
131 |
-
|
132 |
-
private static function getContentShaDecorator(&$args)
|
133 |
-
{
|
134 |
-
return function ($hash) use (&$args) {
|
135 |
-
$args['ContentSHA256'] = bin2hex($hash);
|
136 |
-
};
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Encrypts the data in the 'Body' field of $args and uploads it to the
|
141 |
-
* specified location on S3.
|
142 |
-
*
|
143 |
-
* @param array $args Arguments for encrypting an object and uploading it
|
144 |
-
* to S3 via PutObject.
|
145 |
-
*
|
146 |
-
* The required configuration arguments are as follows:
|
147 |
-
*
|
148 |
-
* - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
|
149 |
-
* encrypting/decrypting for encryption metadata.
|
150 |
-
* - @CipherOptions: (array) Cipher options for encrypting data. A Cipher
|
151 |
-
* is required. Accepts the following options:
|
152 |
-
* - Cipher: (string) cbc|gcm
|
153 |
-
* See also: AbstractCryptoClient::$supportedCiphers
|
154 |
-
* - KeySize: (int) 128|192|256
|
155 |
-
* See also: MaterialsProvider::$supportedKeySizes
|
156 |
-
* - Aad: (string) Additional authentication data. This option is
|
157 |
-
* passed directly to OpenSSL when using gcm. It is ignored when
|
158 |
-
* using cbc.
|
159 |
-
*
|
160 |
-
* The optional configuration arguments are as follows:
|
161 |
-
*
|
162 |
-
* - @MetadataStrategy: (MetadataStrategy|string|null) Strategy for storing
|
163 |
-
* MetadataEnvelope information. Defaults to using a
|
164 |
-
* HeadersMetadataStrategy. Can either be a class implementing
|
165 |
-
* MetadataStrategy, a class name of a predefined strategy, or empty/null
|
166 |
-
* to default.
|
167 |
-
* - @InstructionFileSuffix: (string|null) Suffix used when writing to an
|
168 |
-
* instruction file if an using an InstructionFileMetadataHandler was
|
169 |
-
* determined.
|
170 |
-
*
|
171 |
-
* @return \Aws\Result PutObject call result with the details of uploading
|
172 |
-
* the encrypted file.
|
173 |
-
*
|
174 |
-
* @throws \InvalidArgumentException Thrown when arguments above are not
|
175 |
-
* passed or are passed incorrectly.
|
176 |
-
*/
|
177 |
-
public function putObject(array $args)
|
178 |
-
{
|
179 |
-
return $this->putObjectAsync($args)->wait();
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Promises to retrieve an object from S3 and decrypt the data in the
|
184 |
-
* 'Body' field.
|
185 |
-
*
|
186 |
-
* @param array $args Arguments for retrieving an object from S3 via
|
187 |
-
* GetObject and decrypting it.
|
188 |
-
*
|
189 |
-
* The required configuration argument is as follows:
|
190 |
-
*
|
191 |
-
* - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
|
192 |
-
* encrypting/decrypting for decryption metadata. May have data loaded
|
193 |
-
* from the MetadataEnvelope upon decryption.
|
194 |
-
*
|
195 |
-
* The optional configuration arguments are as follows:
|
196 |
-
*
|
197 |
-
* - SaveAs: (string) The path to a file on disk to save the decrypted
|
198 |
-
* object data. This will be handled by file_put_contents instead of the
|
199 |
-
* Guzzle sink.
|
200 |
-
*
|
201 |
-
* - @MetadataStrategy: (MetadataStrategy|string|null) Strategy for reading
|
202 |
-
* MetadataEnvelope information. Defaults to determining based on object
|
203 |
-
* response headers. Can either be a class implementing MetadataStrategy,
|
204 |
-
* a class name of a predefined strategy, or empty/null to default.
|
205 |
-
* - @InstructionFileSuffix: (string) Suffix used when looking for an
|
206 |
-
* instruction file if an InstructionFileMetadataHandler is being used.
|
207 |
-
* - @CipherOptions: (array) Cipher options for decrypting data. A Cipher
|
208 |
-
* is required. Accepts the following options:
|
209 |
-
* - Aad: (string) Additional authentication data. This option is
|
210 |
-
* passed directly to OpenSSL when using gcm. It is ignored when
|
211 |
-
* using cbc.
|
212 |
-
*
|
213 |
-
* @return PromiseInterface
|
214 |
-
*
|
215 |
-
* @throws \InvalidArgumentException Thrown when required arguments are not
|
216 |
-
* passed or are passed incorrectly.
|
217 |
-
*/
|
218 |
-
public function getObjectAsync(array $args)
|
219 |
-
{
|
220 |
-
$provider = $this->getMaterialsProvider($args);
|
221 |
-
unset($args['@MaterialsProvider']);
|
222 |
-
|
223 |
-
$instructionFileSuffix = $this->getInstructionFileSuffix($args);
|
224 |
-
unset($args['@InstructionFileSuffix']);
|
225 |
-
|
226 |
-
$strategy = $this->getMetadataStrategy($args, $instructionFileSuffix);
|
227 |
-
unset($args['@MetadataStrategy']);
|
228 |
-
|
229 |
-
$saveAs = null;
|
230 |
-
if (!empty($args['SaveAs'])) {
|
231 |
-
$saveAs = $args['SaveAs'];
|
232 |
-
}
|
233 |
-
|
234 |
-
$promise = $this->client->getObjectAsync($args)
|
235 |
-
->then(
|
236 |
-
function ($result) use (
|
237 |
-
$provider,
|
238 |
-
$instructionFileSuffix,
|
239 |
-
$strategy,
|
240 |
-
$args
|
241 |
-
) {
|
242 |
-
if ($strategy === null) {
|
243 |
-
$strategy = $this->determineGetObjectStrategy(
|
244 |
-
$result,
|
245 |
-
$instructionFileSuffix
|
246 |
-
);
|
247 |
-
}
|
248 |
-
|
249 |
-
$envelope = $strategy->load($args + [
|
250 |
-
'Metadata' => $result['Metadata']
|
251 |
-
]);
|
252 |
-
|
253 |
-
$provider = $provider->fromDecryptionEnvelope($envelope);
|
254 |
-
|
255 |
-
$result['Body'] = $this->decrypt(
|
256 |
-
$result['Body'],
|
257 |
-
$provider,
|
258 |
-
$envelope,
|
259 |
-
isset($args['@CipherOptions'])
|
260 |
-
? $args['@CipherOptions']
|
261 |
-
: []
|
262 |
-
);
|
263 |
-
return $result;
|
264 |
-
}
|
265 |
-
)->then(
|
266 |
-
function ($result) use ($saveAs) {
|
267 |
-
if (!empty($saveAs)) {
|
268 |
-
file_put_contents(
|
269 |
-
$saveAs,
|
270 |
-
(string)$result['Body'],
|
271 |
-
LOCK_EX
|
272 |
-
);
|
273 |
-
}
|
274 |
-
return $result;
|
275 |
-
}
|
276 |
-
);
|
277 |
-
|
278 |
-
return $promise;
|
279 |
-
}
|
280 |
-
|
281 |
-
/**
|
282 |
-
* Retrieves an object from S3 and decrypts the data in the 'Body' field.
|
283 |
-
*
|
284 |
-
* @param array $args Arguments for retrieving an object from S3 via
|
285 |
-
* GetObject and decrypting it.
|
286 |
-
*
|
287 |
-
* The required configuration argument is as follows:
|
288 |
-
*
|
289 |
-
* - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
|
290 |
-
* encrypting/decrypting for decryption metadata. May have data loaded
|
291 |
-
* from the MetadataEnvelope upon decryption.
|
292 |
-
*
|
293 |
-
* The optional configuration arguments are as follows:
|
294 |
-
*
|
295 |
-
* - SaveAs: (string) The path to a file on disk to save the decrypted
|
296 |
-
* object data. This will be handled by file_put_contents instead of the
|
297 |
-
* Guzzle sink.
|
298 |
-
* - @InstructionFileSuffix: (string|null) Suffix used when looking for an
|
299 |
-
* instruction file if an InstructionFileMetadataHandler was detected.
|
300 |
-
* - @CipherOptions: (array) Cipher options for encrypting data. A Cipher
|
301 |
-
* is required. Accepts the following options:
|
302 |
-
* - Aad: (string) Additional authentication data. This option is
|
303 |
-
* passed directly to OpenSSL when using gcm. It is ignored when
|
304 |
-
* using cbc.
|
305 |
-
*
|
306 |
-
* @return \Aws\Result GetObject call result with the 'Body' field
|
307 |
-
* wrapped in a decryption stream with its metadata
|
308 |
-
* information.
|
309 |
-
*
|
310 |
-
* @throws \InvalidArgumentException Thrown when arguments above are not
|
311 |
-
* passed or are passed incorrectly.
|
312 |
-
*/
|
313 |
-
public function getObject(array $args)
|
314 |
-
{
|
315 |
-
return $this->getObjectAsync($args)->wait();
|
316 |
-
}
|
317 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/Crypto/S3EncryptionMultipartUploader.php
DELETED
@@ -1,157 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3\Crypto;
|
3 |
-
|
4 |
-
use Aws\Crypto\AbstractCryptoClient;
|
5 |
-
use Aws\Crypto\EncryptionTrait;
|
6 |
-
use Aws\Crypto\MetadataEnvelope;
|
7 |
-
use Aws\Crypto\Cipher\CipherBuilderTrait;
|
8 |
-
use Aws\S3\MultipartUploader;
|
9 |
-
use Aws\S3\S3ClientInterface;
|
10 |
-
use GuzzleHttp\Promise;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Encapsulates the execution of a multipart upload of an encrypted object to S3.
|
14 |
-
*/
|
15 |
-
class S3EncryptionMultipartUploader extends MultipartUploader
|
16 |
-
{
|
17 |
-
use EncryptionTrait, CipherBuilderTrait, CryptoParamsTrait;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Returns if the passed cipher name is supported for encryption by the SDK.
|
21 |
-
*
|
22 |
-
* @param string $cipherName The name of a cipher to verify is registered.
|
23 |
-
*
|
24 |
-
* @return bool If the cipher passed is in our supported list.
|
25 |
-
*/
|
26 |
-
public static function isSupportedCipher($cipherName)
|
27 |
-
{
|
28 |
-
return in_array($cipherName, AbstractCryptoClient::$supportedCiphers);
|
29 |
-
}
|
30 |
-
|
31 |
-
private $provider;
|
32 |
-
private $instructionFileSuffix;
|
33 |
-
private $strategy;
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Creates a multipart upload for an S3 object after encrypting it.
|
37 |
-
*
|
38 |
-
* The required configuration options are as follows:
|
39 |
-
*
|
40 |
-
* - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
|
41 |
-
* encrypting/decrypting for encryption metadata.
|
42 |
-
* - @CipherOptions: (array) Cipher options for encrypting data. A Cipher
|
43 |
-
* is required. Accepts the following options:
|
44 |
-
* - Cipher: (string) cbc|gcm
|
45 |
-
* See also: AbstractCryptoClient::$supportedCiphers
|
46 |
-
* - KeySize: (int) 128|192|256
|
47 |
-
* See also: MaterialsProvider::$supportedKeySizes
|
48 |
-
* - Aad: (string) Additional authentication data. This option is
|
49 |
-
* passed directly to OpenSSL when using gcm. It is ignored when
|
50 |
-
* using cbc.
|
51 |
-
* - bucket: (string) Name of the bucket to which the object is
|
52 |
-
* being uploaded.
|
53 |
-
* - key: (string) Key to use for the object being uploaded.
|
54 |
-
*
|
55 |
-
* The optional configuration arguments are as follows:
|
56 |
-
*
|
57 |
-
* - @MetadataStrategy: (MetadataStrategy|string|null) Strategy for storing
|
58 |
-
* MetadataEnvelope information. Defaults to using a
|
59 |
-
* HeadersMetadataStrategy. Can either be a class implementing
|
60 |
-
* MetadataStrategy, a class name of a predefined strategy, or empty/null
|
61 |
-
* to default.
|
62 |
-
* - @InstructionFileSuffix: (string|null) Suffix used when writing to an
|
63 |
-
* instruction file if an using an InstructionFileMetadataHandler was
|
64 |
-
* determined.
|
65 |
-
* - acl: (string) ACL to set on the object being upload. Objects are
|
66 |
-
* private by default.
|
67 |
-
* - before_complete: (callable) Callback to invoke before the
|
68 |
-
* `CompleteMultipartUpload` operation. The callback should have a
|
69 |
-
* function signature like `function (Aws\Command $command) {...}`.
|
70 |
-
* - before_initiate: (callable) Callback to invoke before the
|
71 |
-
* `CreateMultipartUpload` operation. The callback should have a function
|
72 |
-
* signature like `function (Aws\Command $command) {...}`.
|
73 |
-
* - before_upload: (callable) Callback to invoke before any `UploadPart`
|
74 |
-
* operations. The callback should have a function signature like
|
75 |
-
* `function (Aws\Command $command) {...}`.
|
76 |
-
* - concurrency: (int, default=int(5)) Maximum number of concurrent
|
77 |
-
* `UploadPart` operations allowed during the multipart upload.
|
78 |
-
* - params: (array) An array of key/value parameters that will be applied
|
79 |
-
* to each of the sub-commands run by the uploader as a base.
|
80 |
-
* Auto-calculated options will override these parameters. If you need
|
81 |
-
* more granularity over parameters to each sub-command, use the before_*
|
82 |
-
* options detailed above to update the commands directly.
|
83 |
-
* - part_size: (int, default=int(5242880)) Part size, in bytes, to use when
|
84 |
-
* doing a multipart upload. This must between 5 MB and 5 GB, inclusive.
|
85 |
-
* - state: (Aws\Multipart\UploadState) An object that represents the state
|
86 |
-
* of the multipart upload and that is used to resume a previous upload.
|
87 |
-
* When this option is provided, the `bucket`, `key`, and `part_size`
|
88 |
-
* options are ignored.
|
89 |
-
*
|
90 |
-
* @param S3ClientInterface $client Client used for the upload.
|
91 |
-
* @param mixed $source Source of the data to upload.
|
92 |
-
* @param array $config Configuration used to perform the upload.
|
93 |
-
*/
|
94 |
-
public function __construct(
|
95 |
-
S3ClientInterface $client,
|
96 |
-
$source,
|
97 |
-
array $config = []
|
98 |
-
) {
|
99 |
-
$this->client = $client;
|
100 |
-
$config['params'] = [];
|
101 |
-
if (!empty($config['bucket'])) {
|
102 |
-
$config['params']['Bucket'] = $config['bucket'];
|
103 |
-
}
|
104 |
-
if (!empty($config['key'])) {
|
105 |
-
$config['params']['Key'] = $config['key'];
|
106 |
-
}
|
107 |
-
|
108 |
-
$this->provider = $this->getMaterialsProvider($config);
|
109 |
-
unset($config['@MaterialsProvider']);
|
110 |
-
|
111 |
-
$this->instructionFileSuffix = $this->getInstructionFileSuffix($config);
|
112 |
-
unset($config['@InstructionFileSuffix']);
|
113 |
-
$this->strategy = $this->getMetadataStrategy(
|
114 |
-
$config,
|
115 |
-
$this->instructionFileSuffix
|
116 |
-
);
|
117 |
-
if ($this->strategy === null) {
|
118 |
-
$this->strategy = self::getDefaultStrategy();
|
119 |
-
}
|
120 |
-
unset($config['@MetadataStrategy']);
|
121 |
-
|
122 |
-
$config['prepare_data_source'] = $this->getEncryptingDataPreparer();
|
123 |
-
|
124 |
-
parent::__construct($client, $source, $config);
|
125 |
-
}
|
126 |
-
|
127 |
-
private static function getDefaultStrategy()
|
128 |
-
{
|
129 |
-
return new HeadersMetadataStrategy();
|
130 |
-
}
|
131 |
-
|
132 |
-
private function getEncryptingDataPreparer()
|
133 |
-
{
|
134 |
-
return function() {
|
135 |
-
// Defer encryption work until promise is executed
|
136 |
-
$envelope = new MetadataEnvelope();
|
137 |
-
|
138 |
-
list($this->source, $params) = Promise\promise_for($this->encrypt(
|
139 |
-
$this->source,
|
140 |
-
$this->config['@cipheroptions'] ?: [],
|
141 |
-
$this->provider,
|
142 |
-
$envelope
|
143 |
-
))->then(
|
144 |
-
function ($bodyStream) use ($envelope) {
|
145 |
-
$params = $this->strategy->save(
|
146 |
-
$envelope,
|
147 |
-
$this->config['params']
|
148 |
-
);
|
149 |
-
return [$bodyStream, $params];
|
150 |
-
}
|
151 |
-
)->wait();
|
152 |
-
|
153 |
-
$this->source->rewind();
|
154 |
-
$this->config['params'] = $params;
|
155 |
-
};
|
156 |
-
}
|
157 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/MultipartCopy.php
DELETED
@@ -1,183 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\Multipart\AbstractUploadManager;
|
5 |
-
use Aws\ResultInterface;
|
6 |
-
use GuzzleHttp\Psr7;
|
7 |
-
|
8 |
-
class MultipartCopy extends AbstractUploadManager
|
9 |
-
{
|
10 |
-
use MultipartUploadingTrait;
|
11 |
-
|
12 |
-
/** @var string */
|
13 |
-
private $source;
|
14 |
-
/** @var ResultInterface */
|
15 |
-
private $sourceMetadata;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Creates a multipart upload for copying an S3 object.
|
19 |
-
*
|
20 |
-
* The valid configuration options are as follows:
|
21 |
-
*
|
22 |
-
* - acl: (string) ACL to set on the object being upload. Objects are
|
23 |
-
* private by default.
|
24 |
-
* - before_complete: (callable) Callback to invoke before the
|
25 |
-
* `CompleteMultipartUpload` operation. The callback should have a
|
26 |
-
* function signature like `function (Aws\Command $command) {...}`.
|
27 |
-
* - before_initiate: (callable) Callback to invoke before the
|
28 |
-
* `CreateMultipartUpload` operation. The callback should have a function
|
29 |
-
* signature like `function (Aws\Command $command) {...}`.
|
30 |
-
* - before_upload: (callable) Callback to invoke before `UploadPartCopy`
|
31 |
-
* operations. The callback should have a function signature like
|
32 |
-
* `function (Aws\Command $command) {...}`.
|
33 |
-
* - bucket: (string, required) Name of the bucket to which the object is
|
34 |
-
* being uploaded.
|
35 |
-
* - concurrency: (int, default=int(5)) Maximum number of concurrent
|
36 |
-
* `UploadPart` operations allowed during the multipart upload.
|
37 |
-
* - key: (string, required) Key to use for the object being uploaded.
|
38 |
-
* - params: (array) An array of key/value parameters that will be applied
|
39 |
-
* to each of the sub-commands run by the uploader as a base.
|
40 |
-
* Auto-calculated options will override these parameters. If you need
|
41 |
-
* more granularity over parameters to each sub-command, use the before_*
|
42 |
-
* options detailed above to update the commands directly.
|
43 |
-
* - part_size: (int, default=int(5242880)) Part size, in bytes, to use when
|
44 |
-
* doing a multipart upload. This must between 5 MB and 5 GB, inclusive.
|
45 |
-
* - state: (Aws\Multipart\UploadState) An object that represents the state
|
46 |
-
* of the multipart upload and that is used to resume a previous upload.
|
47 |
-
* When this option is provided, the `bucket`, `key`, and `part_size`
|
48 |
-
* options are ignored.
|
49 |
-
* - source_metadata: (Aws\ResultInterface) An object that represents the
|
50 |
-
* result of executing a HeadObject command on the copy source.
|
51 |
-
*
|
52 |
-
* @param S3ClientInterface $client Client used for the upload.
|
53 |
-
* @param string $source Location of the data to be copied
|
54 |
-
* (in the form /<bucket>/<key>).
|
55 |
-
* @param array $config Configuration used to perform the upload.
|
56 |
-
*/
|
57 |
-
public function __construct(
|
58 |
-
S3ClientInterface $client,
|
59 |
-
$source,
|
60 |
-
array $config = []
|
61 |
-
) {
|
62 |
-
$this->source = '/' . ltrim($source, '/');
|
63 |
-
parent::__construct($client, array_change_key_case($config) + [
|
64 |
-
'source_metadata' => null
|
65 |
-
]);
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* An alias of the self::upload method.
|
70 |
-
*
|
71 |
-
* @see self::upload
|
72 |
-
*/
|
73 |
-
public function copy()
|
74 |
-
{
|
75 |
-
return $this->upload();
|
76 |
-
}
|
77 |
-
|
78 |
-
protected function loadUploadWorkflowInfo()
|
79 |
-
{
|
80 |
-
return [
|
81 |
-
'command' => [
|
82 |
-
'initiate' => 'CreateMultipartUpload',
|
83 |
-
'upload' => 'UploadPartCopy',
|
84 |
-
'complete' => 'CompleteMultipartUpload',
|
85 |
-
],
|
86 |
-
'id' => [
|
87 |
-
'bucket' => 'Bucket',
|
88 |
-
'key' => 'Key',
|
89 |
-
'upload_id' => 'UploadId',
|
90 |
-
],
|
91 |
-
'part_num' => 'PartNumber',
|
92 |
-
];
|
93 |
-
}
|
94 |
-
|
95 |
-
protected function getUploadCommands(callable $resultHandler)
|
96 |
-
{
|
97 |
-
$parts = ceil($this->getSourceSize() / $this->determinePartSize());
|
98 |
-
|
99 |
-
for ($partNumber = 1; $partNumber <= $parts; $partNumber++) {
|
100 |
-
// If we haven't already uploaded this part, yield a new part.
|
101 |
-
if (!$this->state->hasPartBeenUploaded($partNumber)) {
|
102 |
-
$command = $this->client->getCommand(
|
103 |
-
$this->info['command']['upload'],
|
104 |
-
$this->createPart($partNumber, $parts)
|
105 |
-
+ $this->getState()->getId()
|
106 |
-
);
|
107 |
-
$command->getHandlerList()->appendSign($resultHandler, 'mup');
|
108 |
-
yield $command;
|
109 |
-
}
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
private function createPart($partNumber, $partsCount)
|
114 |
-
{
|
115 |
-
$data = [];
|
116 |
-
|
117 |
-
// Apply custom params to UploadPartCopy data
|
118 |
-
$config = $this->getConfig();
|
119 |
-
$params = isset($config['params']) ? $config['params'] : [];
|
120 |
-
foreach ($params as $k => $v) {
|
121 |
-
$data[$k] = $v;
|
122 |
-
}
|
123 |
-
|
124 |
-
$data['CopySource'] = $this->source;
|
125 |
-
$data['PartNumber'] = $partNumber;
|
126 |
-
|
127 |
-
$defaultPartSize = $this->determinePartSize();
|
128 |
-
$startByte = $defaultPartSize * ($partNumber - 1);
|
129 |
-
$data['ContentLength'] = $partNumber < $partsCount
|
130 |
-
? $defaultPartSize
|
131 |
-
: $this->getSourceSize() - ($defaultPartSize * ($partsCount - 1));
|
132 |
-
$endByte = $startByte + $data['ContentLength'] - 1;
|
133 |
-
$data['CopySourceRange'] = "bytes=$startByte-$endByte";
|
134 |
-
|
135 |
-
return $data;
|
136 |
-
}
|
137 |
-
|
138 |
-
protected function extractETag(ResultInterface $result)
|
139 |
-
{
|
140 |
-
return $result->search('CopyPartResult.ETag');
|
141 |
-
}
|
142 |
-
|
143 |
-
protected function getSourceMimeType()
|
144 |
-
{
|
145 |
-
return $this->getSourceMetadata()['ContentType'];
|
146 |
-
}
|
147 |
-
|
148 |
-
protected function getSourceSize()
|
149 |
-
{
|
150 |
-
return $this->getSourceMetadata()['ContentLength'];
|
151 |
-
}
|
152 |
-
|
153 |
-
private function getSourceMetadata()
|
154 |
-
{
|
155 |
-
if (empty($this->sourceMetadata)) {
|
156 |
-
$this->sourceMetadata = $this->fetchSourceMetadata();
|
157 |
-
}
|
158 |
-
|
159 |
-
return $this->sourceMetadata;
|
160 |
-
}
|
161 |
-
|
162 |
-
private function fetchSourceMetadata()
|
163 |
-
{
|
164 |
-
if ($this->config['source_metadata'] instanceof ResultInterface) {
|
165 |
-
return $this->config['source_metadata'];
|
166 |
-
}
|
167 |
-
|
168 |
-
list($bucket, $key) = explode('/', ltrim($this->source, '/'), 2);
|
169 |
-
$headParams = [
|
170 |
-
'Bucket' => $bucket,
|
171 |
-
'Key' => $key,
|
172 |
-
];
|
173 |
-
if (strpos($key, '?')) {
|
174 |
-
list($key, $query) = explode('?', $key, 2);
|
175 |
-
$headParams['Key'] = $key;
|
176 |
-
$query = Psr7\parse_query($query, false);
|
177 |
-
if (isset($query['versionId'])) {
|
178 |
-
$headParams['VersionId'] = $query['versionId'];
|
179 |
-
}
|
180 |
-
}
|
181 |
-
return $this->client->headObject($headParams);
|
182 |
-
}
|
183 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/MultipartUploader.php
DELETED
@@ -1,168 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\HashingStream;
|
5 |
-
use Aws\Multipart\AbstractUploader;
|
6 |
-
use Aws\PhpHash;
|
7 |
-
use Aws\ResultInterface;
|
8 |
-
use GuzzleHttp\Psr7;
|
9 |
-
use Psr\Http\Message\StreamInterface as Stream;
|
10 |
-
use Aws\S3\Exception\S3MultipartUploadException;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Encapsulates the execution of a multipart upload to S3 or Glacier.
|
14 |
-
*/
|
15 |
-
class MultipartUploader extends AbstractUploader
|
16 |
-
{
|
17 |
-
use MultipartUploadingTrait;
|
18 |
-
|
19 |
-
const PART_MIN_SIZE = 5242880;
|
20 |
-
const PART_MAX_SIZE = 5368709120;
|
21 |
-
const PART_MAX_NUM = 10000;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Creates a multipart upload for an S3 object.
|
25 |
-
*
|
26 |
-
* The valid configuration options are as follows:
|
27 |
-
*
|
28 |
-
* - acl: (string) ACL to set on the object being upload. Objects are
|
29 |
-
* private by default.
|
30 |
-
* - before_complete: (callable) Callback to invoke before the
|
31 |
-
* `CompleteMultipartUpload` operation. The callback should have a
|
32 |
-
* function signature like `function (Aws\Command $command) {...}`.
|
33 |
-
* - before_initiate: (callable) Callback to invoke before the
|
34 |
-
* `CreateMultipartUpload` operation. The callback should have a function
|
35 |
-
* signature like `function (Aws\Command $command) {...}`.
|
36 |
-
* - before_upload: (callable) Callback to invoke before any `UploadPart`
|
37 |
-
* operations. The callback should have a function signature like
|
38 |
-
* `function (Aws\Command $command) {...}`.
|
39 |
-
* - bucket: (string, required) Name of the bucket to which the object is
|
40 |
-
* being uploaded.
|
41 |
-
* - concurrency: (int, default=int(5)) Maximum number of concurrent
|
42 |
-
* `UploadPart` operations allowed during the multipart upload.
|
43 |
-
* - key: (string, required) Key to use for the object being uploaded.
|
44 |
-
* - params: (array) An array of key/value parameters that will be applied
|
45 |
-
* to each of the sub-commands run by the uploader as a base.
|
46 |
-
* Auto-calculated options will override these parameters. If you need
|
47 |
-
* more granularity over parameters to each sub-command, use the before_*
|
48 |
-
* options detailed above to update the commands directly.
|
49 |
-
* - part_size: (int, default=int(5242880)) Part size, in bytes, to use when
|
50 |
-
* doing a multipart upload. This must between 5 MB and 5 GB, inclusive.
|
51 |
-
* - prepare_data_source: (callable) Callback to invoke before starting the
|
52 |
-
* multipart upload workflow. The callback should have a function
|
53 |
-
* signature like `function () {...}`.
|
54 |
-
* - state: (Aws\Multipart\UploadState) An object that represents the state
|
55 |
-
* of the multipart upload and that is used to resume a previous upload.
|
56 |
-
* When this option is provided, the `bucket`, `key`, and `part_size`
|
57 |
-
* options are ignored.
|
58 |
-
*
|
59 |
-
* @param S3ClientInterface $client Client used for the upload.
|
60 |
-
* @param mixed $source Source of the data to upload.
|
61 |
-
* @param array $config Configuration used to perform the upload.
|
62 |
-
*/
|
63 |
-
public function __construct(
|
64 |
-
S3ClientInterface $client,
|
65 |
-
$source,
|
66 |
-
array $config = []
|
67 |
-
) {
|
68 |
-
parent::__construct($client, $source, array_change_key_case($config) + [
|
69 |
-
'bucket' => null,
|
70 |
-
'key' => null,
|
71 |
-
'exception_class' => S3MultipartUploadException::class,
|
72 |
-
]);
|
73 |
-
}
|
74 |
-
|
75 |
-
protected function loadUploadWorkflowInfo()
|
76 |
-
{
|
77 |
-
return [
|
78 |
-
'command' => [
|
79 |
-
'initiate' => 'CreateMultipartUpload',
|
80 |
-
'upload' => 'UploadPart',
|
81 |
-
'complete' => 'CompleteMultipartUpload',
|
82 |
-
],
|
83 |
-
'id' => [
|
84 |
-
'bucket' => 'Bucket',
|
85 |
-
'key' => 'Key',
|
86 |
-
'upload_id' => 'UploadId',
|
87 |
-
],
|
88 |
-
'part_num' => 'PartNumber',
|
89 |
-
];
|
90 |
-
}
|
91 |
-
|
92 |
-
protected function createPart($seekable, $number)
|
93 |
-
{
|
94 |
-
// Initialize the array of part data that will be returned.
|
95 |
-
$data = [];
|
96 |
-
|
97 |
-
// Apply custom params to UploadPart data
|
98 |
-
$config = $this->getConfig();
|
99 |
-
$params = isset($config['params']) ? $config['params'] : [];
|
100 |
-
foreach ($params as $k => $v) {
|
101 |
-
$data[$k] = $v;
|
102 |
-
}
|
103 |
-
|
104 |
-
$data['PartNumber'] = $number;
|
105 |
-
|
106 |
-
// Read from the source to create the body stream.
|
107 |
-
if ($seekable) {
|
108 |
-
// Case 1: Source is seekable, use lazy stream to defer work.
|
109 |
-
$body = $this->limitPartStream(
|
110 |
-
new Psr7\LazyOpenStream($this->source->getMetadata('uri'), 'r')
|
111 |
-
);
|
112 |
-
} else {
|
113 |
-
// Case 2: Stream is not seekable; must store in temp stream.
|
114 |
-
$source = $this->limitPartStream($this->source);
|
115 |
-
$source = $this->decorateWithHashes($source, $data);
|
116 |
-
$body = Psr7\stream_for();
|
117 |
-
Psr7\copy_to_stream($source, $body);
|
118 |
-
}
|
119 |
-
|
120 |
-
$contentLength = $body->getSize();
|
121 |
-
|
122 |
-
// Do not create a part if the body size is zero.
|
123 |
-
if ($contentLength === 0) {
|
124 |
-
return false;
|
125 |
-
}
|
126 |
-
|
127 |
-
$body->seek(0);
|
128 |
-
$data['Body'] = $body;
|
129 |
-
$data['ContentLength'] = $contentLength;
|
130 |
-
|
131 |
-
return $data;
|
132 |
-
}
|
133 |
-
|
134 |
-
protected function extractETag(ResultInterface $result)
|
135 |
-
{
|
136 |
-
return $result['ETag'];
|
137 |
-
}
|
138 |
-
|
139 |
-
protected function getSourceMimeType()
|
140 |
-
{
|
141 |
-
if ($uri = $this->source->getMetadata('uri')) {
|
142 |
-
return Psr7\mimetype_from_filename($uri)
|
143 |
-
?: 'application/octet-stream';
|
144 |
-
}
|
145 |
-
}
|
146 |
-
|
147 |
-
protected function getSourceSize()
|
148 |
-
{
|
149 |
-
return $this->source->getSize();
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Decorates a stream with a sha256 linear hashing stream.
|
154 |
-
*
|
155 |
-
* @param Stream $stream Stream to decorate.
|
156 |
-
* @param array $data Part data to augment with the hash result.
|
157 |
-
*
|
158 |
-
* @return Stream
|
159 |
-
*/
|
160 |
-
private function decorateWithHashes(Stream $stream, array &$data)
|
161 |
-
{
|
162 |
-
// Decorate source with a hashing stream
|
163 |
-
$hash = new PhpHash('sha256');
|
164 |
-
return new HashingStream($stream, $hash, function ($result) use (&$data) {
|
165 |
-
$data['ContentSHA256'] = bin2hex($result);
|
166 |
-
});
|
167 |
-
}
|
168 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/ObjectCopier.php
DELETED
@@ -1,150 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\Exception\MultipartUploadException;
|
5 |
-
use Aws\Result;
|
6 |
-
use Aws\S3\Exception\S3Exception;
|
7 |
-
use GuzzleHttp\Promise\PromisorInterface;
|
8 |
-
use InvalidArgumentException;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Copies objects from one S3 location to another, utilizing a multipart copy
|
12 |
-
* when appropriate.
|
13 |
-
*/
|
14 |
-
class ObjectCopier implements PromisorInterface
|
15 |
-
{
|
16 |
-
const DEFAULT_MULTIPART_THRESHOLD = MultipartUploader::PART_MAX_SIZE;
|
17 |
-
|
18 |
-
private $client;
|
19 |
-
private $source;
|
20 |
-
private $destination;
|
21 |
-
private $acl;
|
22 |
-
private $options;
|
23 |
-
|
24 |
-
private static $defaults = [
|
25 |
-
'before_lookup' => null,
|
26 |
-
'before_upload' => null,
|
27 |
-
'concurrency' => 5,
|
28 |
-
'mup_threshold' => self::DEFAULT_MULTIPART_THRESHOLD,
|
29 |
-
'params' => [],
|
30 |
-
'part_size' => null,
|
31 |
-
'version_id' => null,
|
32 |
-
];
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @param S3ClientInterface $client The S3 Client used to execute
|
36 |
-
* the copy command(s).
|
37 |
-
* @param array $source The object to copy, specified as
|
38 |
-
* an array with a 'Bucket' and
|
39 |
-
* 'Key' keys. Provide a
|
40 |
-
* 'VersionID' key to copy a
|
41 |
-
* specified version of an object.
|
42 |
-
* @param array $destination The bucket and key to which to
|
43 |
-
* copy the $source, specified as
|
44 |
-
* an array with a 'Bucket' and
|
45 |
-
* 'Key' keys.
|
46 |
-
* @param string $acl ACL to apply to the copy
|
47 |
-
* (default: private).
|
48 |
-
* @param array $options Options used to configure the
|
49 |
-
* copy process. Options passed in
|
50 |
-
* through 'params' are added to
|
51 |
-
* the sub commands.
|
52 |
-
*
|
53 |
-
* @throws InvalidArgumentException
|
54 |
-
*/
|
55 |
-
public function __construct(
|
56 |
-
S3ClientInterface $client,
|
57 |
-
array $source,
|
58 |
-
array $destination,
|
59 |
-
$acl = 'private',
|
60 |
-
array $options = []
|
61 |
-
) {
|
62 |
-
$this->validateLocation($source);
|
63 |
-
$this->validateLocation($destination);
|
64 |
-
|
65 |
-
$this->client = $client;
|
66 |
-
$this->source = $source;
|
67 |
-
$this->destination = $destination;
|
68 |
-
$this->acl = $acl;
|
69 |
-
$this->options = $options + self::$defaults;
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Perform the configured copy asynchronously. Returns a promise that is
|
74 |
-
* fulfilled with the result of the CompleteMultipartUpload or CopyObject
|
75 |
-
* operation or rejected with an exception.
|
76 |
-
*/
|
77 |
-
public function promise()
|
78 |
-
{
|
79 |
-
return \GuzzleHttp\Promise\coroutine(function () {
|
80 |
-
$headObjectCommand = $this->client->getCommand(
|
81 |
-
'HeadObject',
|
82 |
-
$this->options['params'] + $this->source
|
83 |
-
);
|
84 |
-
if (is_callable($this->options['before_lookup'])) {
|
85 |
-
$this->options['before_lookup']($headObjectCommand);
|
86 |
-
}
|
87 |
-
$objectStats = (yield $this->client->executeAsync(
|
88 |
-
$headObjectCommand
|
89 |
-
));
|
90 |
-
|
91 |
-
if ($objectStats['ContentLength'] > $this->options['mup_threshold']) {
|
92 |
-
$mup = new MultipartCopy(
|
93 |
-
$this->client,
|
94 |
-
$this->getSourcePath(),
|
95 |
-
['source_metadata' => $objectStats, 'acl' => $this->acl]
|
96 |
-
+ $this->destination
|
97 |
-
+ $this->options
|
98 |
-
);
|
99 |
-
|
100 |
-
yield $mup->promise();
|
101 |
-
} else {
|
102 |
-
$defaults = [
|
103 |
-
'ACL' => $this->acl,
|
104 |
-
'MetadataDirective' => 'COPY',
|
105 |
-
'CopySource' => $this->getSourcePath(),
|
106 |
-
];
|
107 |
-
|
108 |
-
$params = array_diff_key($this->options, self::$defaults)
|
109 |
-
+ $this->destination + $defaults + $this->options['params'];
|
110 |
-
|
111 |
-
yield $this->client->executeAsync(
|
112 |
-
$this->client->getCommand('CopyObject', $params)
|
113 |
-
);
|
114 |
-
}
|
115 |
-
});
|
116 |
-
}
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Perform the configured copy synchronously. Returns the result of the
|
120 |
-
* CompleteMultipartUpload or CopyObject operation.
|
121 |
-
*
|
122 |
-
* @return Result
|
123 |
-
*
|
124 |
-
* @throws S3Exception
|
125 |
-
* @throws MultipartUploadException
|
126 |
-
*/
|
127 |
-
public function copy()
|
128 |
-
{
|
129 |
-
return $this->promise()->wait();
|
130 |
-
}
|
131 |
-
|
132 |
-
private function validateLocation(array $location)
|
133 |
-
{
|
134 |
-
if (empty($location['Bucket']) || empty($location['Key'])) {
|
135 |
-
throw new \InvalidArgumentException('Locations provided to an'
|
136 |
-
. ' Aws\S3\ObjectCopier must have a non-empty Bucket and Key');
|
137 |
-
}
|
138 |
-
}
|
139 |
-
|
140 |
-
private function getSourcePath()
|
141 |
-
{
|
142 |
-
$sourcePath = "/{$this->source['Bucket']}/"
|
143 |
-
. rawurlencode($this->source['Key']);
|
144 |
-
if (isset($this->source['VersionId'])) {
|
145 |
-
$sourcePath .= "?versionId={$this->source['VersionId']}";
|
146 |
-
}
|
147 |
-
|
148 |
-
return $sourcePath;
|
149 |
-
}
|
150 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/ObjectUploader.php
DELETED
@@ -1,140 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use GuzzleHttp\Promise\PromisorInterface;
|
5 |
-
use GuzzleHttp\Psr7;
|
6 |
-
use Psr\Http\Message\StreamInterface;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Uploads an object to S3, using a PutObject command or a multipart upload as
|
10 |
-
* appropriate.
|
11 |
-
*/
|
12 |
-
class ObjectUploader implements PromisorInterface
|
13 |
-
{
|
14 |
-
const DEFAULT_MULTIPART_THRESHOLD = 16777216;
|
15 |
-
|
16 |
-
private $client;
|
17 |
-
private $bucket;
|
18 |
-
private $key;
|
19 |
-
private $body;
|
20 |
-
private $acl;
|
21 |
-
private $options;
|
22 |
-
private static $defaults = [
|
23 |
-
'before_upload' => null,
|
24 |
-
'concurrency' => 3,
|
25 |
-
'mup_threshold' => self::DEFAULT_MULTIPART_THRESHOLD,
|
26 |
-
'params' => [],
|
27 |
-
'part_size' => null,
|
28 |
-
];
|
29 |
-
|
30 |
-
/**
|
31 |
-
* @param S3ClientInterface $client The S3 Client used to execute
|
32 |
-
* the upload command(s).
|
33 |
-
* @param string $bucket Bucket to upload the object.
|
34 |
-
* @param string $key Key of the object.
|
35 |
-
* @param mixed $body Object data to upload. Can be a
|
36 |
-
* StreamInterface, PHP stream
|
37 |
-
* resource, or a string of data to
|
38 |
-
* upload.
|
39 |
-
* @param string $acl ACL to apply to the copy
|
40 |
-
* (default: private).
|
41 |
-
* @param array $options Options used to configure the
|
42 |
-
* copy process. Options passed in
|
43 |
-
* through 'params' are added to
|
44 |
-
* the sub command(s).
|
45 |
-
*/
|
46 |
-
public function __construct(
|
47 |
-
S3ClientInterface $client,
|
48 |
-
$bucket,
|
49 |
-
$key,
|
50 |
-
$body,
|
51 |
-
$acl = 'private',
|
52 |
-
array $options = []
|
53 |
-
) {
|
54 |
-
$this->client = $client;
|
55 |
-
$this->bucket = $bucket;
|
56 |
-
$this->key = $key;
|
57 |
-
$this->body = Psr7\stream_for($body);
|
58 |
-
$this->acl = $acl;
|
59 |
-
$this->options = $options + self::$defaults;
|
60 |
-
}
|
61 |
-
|
62 |
-
public function promise()
|
63 |
-
{
|
64 |
-
/** @var int $mup_threshold */
|
65 |
-
$mup_threshold = $this->options['mup_threshold'];
|
66 |
-
if ($this->requiresMultipart($this->body, $mup_threshold)) {
|
67 |
-
// Perform a multipart upload.
|
68 |
-
return (new MultipartUploader($this->client, $this->body, [
|
69 |
-
'bucket' => $this->bucket,
|
70 |
-
'key' => $this->key,
|
71 |
-
'acl' => $this->acl
|
72 |
-
] + $this->options))->promise();
|
73 |
-
}
|
74 |
-
|
75 |
-
// Perform a regular PutObject operation.
|
76 |
-
$command = $this->client->getCommand('PutObject', [
|
77 |
-
'Bucket' => $this->bucket,
|
78 |
-
'Key' => $this->key,
|
79 |
-
'Body' => $this->body,
|
80 |
-
'ACL' => $this->acl,
|
81 |
-
] + $this->options['params']);
|
82 |
-
if (is_callable($this->options['before_upload'])) {
|
83 |
-
$this->options['before_upload']($command);
|
84 |
-
}
|
85 |
-
return $this->client->executeAsync($command);
|
86 |
-
}
|
87 |
-
|
88 |
-
public function upload()
|
89 |
-
{
|
90 |
-
return $this->promise()->wait();
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Determines if the body should be uploaded using PutObject or the
|
95 |
-
* Multipart Upload System. It also modifies the passed-in $body as needed
|
96 |
-
* to support the upload.
|
97 |
-
*
|
98 |
-
* @param StreamInterface $body Stream representing the body.
|
99 |
-
* @param integer $threshold Minimum bytes before using Multipart.
|
100 |
-
*
|
101 |
-
* @return bool
|
102 |
-
*/
|
103 |
-
private function requiresMultipart(StreamInterface &$body, $threshold)
|
104 |
-
{
|
105 |
-
// If body size known, compare to threshold to determine if Multipart.
|
106 |
-
if ($body->getSize() !== null) {
|
107 |
-
return $body->getSize() >= $threshold;
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Handle the situation where the body size is unknown.
|
112 |
-
* Read up to 5MB into a buffer to determine how to upload the body.
|
113 |
-
* @var StreamInterface $buffer
|
114 |
-
*/
|
115 |
-
$buffer = Psr7\stream_for();
|
116 |
-
Psr7\copy_to_stream($body, $buffer, MultipartUploader::PART_MIN_SIZE);
|
117 |
-
|
118 |
-
// If body < 5MB, use PutObject with the buffer.
|
119 |
-
if ($buffer->getSize() < MultipartUploader::PART_MIN_SIZE) {
|
120 |
-
$buffer->seek(0);
|
121 |
-
$body = $buffer;
|
122 |
-
return false;
|
123 |
-
}
|
124 |
-
|
125 |
-
// If body >= 5 MB, then use multipart. [YES]
|
126 |
-
if ($body->isSeekable() && $body->getMetadata('uri') !== 'php://input') {
|
127 |
-
// If the body is seekable, just rewind the body.
|
128 |
-
$body->seek(0);
|
129 |
-
} else {
|
130 |
-
// If the body is non-seekable, stitch the rewind the buffer and
|
131 |
-
// the partially read body together into one stream. This avoids
|
132 |
-
// unnecessary disc usage and does not require seeking on the
|
133 |
-
// original stream.
|
134 |
-
$buffer->seek(0);
|
135 |
-
$body = new Psr7\AppendStream([$buffer, $body]);
|
136 |
-
}
|
137 |
-
|
138 |
-
return true;
|
139 |
-
}
|
140 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/PostObjectV4.php
DELETED
@@ -1,195 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\Credentials\CredentialsInterface;
|
5 |
-
use GuzzleHttp\Psr7\Uri;
|
6 |
-
use Aws\Signature\SignatureTrait;
|
7 |
-
use Aws\Signature\SignatureV4 as SignatureV4;
|
8 |
-
use Aws\Api\TimestampShape as TimestampShape;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Encapsulates the logic for getting the data for an S3 object POST upload form
|
12 |
-
*
|
13 |
-
* @link http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html
|
14 |
-
* @link http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
|
15 |
-
*/
|
16 |
-
class PostObjectV4
|
17 |
-
{
|
18 |
-
use SignatureTrait;
|
19 |
-
|
20 |
-
private $client;
|
21 |
-
private $bucket;
|
22 |
-
private $formAttributes;
|
23 |
-
private $formInputs;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Constructs the PostObject.
|
27 |
-
*
|
28 |
-
* The options array accepts the following keys:
|
29 |
-
* @link http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
|
30 |
-
*
|
31 |
-
* @param S3ClientInterface $client Client used with the POST object
|
32 |
-
* @param string $bucket Bucket to use
|
33 |
-
* @param array $formInputs Associative array of form input
|
34 |
-
* fields.
|
35 |
-
* @param array $options Policy condition options
|
36 |
-
* @param mixed $expiration Upload expiration time value. By
|
37 |
-
* default: 1 hour valid period.
|
38 |
-
*/
|
39 |
-
public function __construct(
|
40 |
-
S3ClientInterface $client,
|
41 |
-
$bucket,
|
42 |
-
array $formInputs,
|
43 |
-
array $options = [],
|
44 |
-
$expiration = '+1 hours'
|
45 |
-
) {
|
46 |
-
$this->client = $client;
|
47 |
-
$this->bucket = $bucket;
|
48 |
-
|
49 |
-
// setup form attributes
|
50 |
-
$this->formAttributes = [
|
51 |
-
'action' => $this->generateUri(),
|
52 |
-
'method' => 'POST',
|
53 |
-
'enctype' => 'multipart/form-data'
|
54 |
-
];
|
55 |
-
|
56 |
-
$credentials = $this->client->getCredentials()->wait();
|
57 |
-
|
58 |
-
if ($securityToken = $credentials->getSecurityToken()) {
|
59 |
-
array_push($options, ['x-amz-security-token' => $securityToken]);
|
60 |
-
$formInputs['X-Amz-Security-Token'] = $securityToken;
|
61 |
-
}
|
62 |
-
|
63 |
-
// setup basic policy
|
64 |
-
$policy = [
|
65 |
-
'expiration' => TimestampShape::format($expiration, 'iso8601'),
|
66 |
-
'conditions' => $options,
|
67 |
-
];
|
68 |
-
|
69 |
-
// setup basic formInputs
|
70 |
-
$this->formInputs = $formInputs + ['key' => '${filename}'];
|
71 |
-
|
72 |
-
// finalize policy and signature
|
73 |
-
|
74 |
-
$this->formInputs += $this->getPolicyAndSignature(
|
75 |
-
$credentials,
|
76 |
-
$policy
|
77 |
-
);
|
78 |
-
}
|
79 |
-
|
80 |
-
/**
|
81 |
-
* Gets the S3 client.
|
82 |
-
*
|
83 |
-
* @return S3ClientInterface
|
84 |
-
*/
|
85 |
-
public function getClient()
|
86 |
-
{
|
87 |
-
return $this->client;
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Gets the bucket name.
|
92 |
-
*
|
93 |
-
* @return string
|
94 |
-
*/
|
95 |
-
public function getBucket()
|
96 |
-
{
|
97 |
-
return $this->bucket;
|
98 |
-
}
|
99 |
-
|
100 |
-
/**
|
101 |
-
* Gets the form attributes as an array.
|
102 |
-
*
|
103 |
-
* @return array
|
104 |
-
*/
|
105 |
-
public function getFormAttributes()
|
106 |
-
{
|
107 |
-
return $this->formAttributes;
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Set a form attribute.
|
112 |
-
*
|
113 |
-
* @param string $attribute Form attribute to set.
|
114 |
-
* @param string $value Value to set.
|
115 |
-
*/
|
116 |
-
public function setFormAttribute($attribute, $value)
|
117 |
-
{
|
118 |
-
$this->formAttributes[$attribute] = $value;
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Gets the form inputs as an array.
|
123 |
-
*
|
124 |
-
* @return array
|
125 |
-
*/
|
126 |
-
public function getFormInputs()
|
127 |
-
{
|
128 |
-
return $this->formInputs;
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Set a form input.
|
133 |
-
*
|
134 |
-
* @param string $field Field name to set
|
135 |
-
* @param string $value Value to set.
|
136 |
-
*/
|
137 |
-
public function setFormInput($field, $value)
|
138 |
-
{
|
139 |
-
$this->formInputs[$field] = $value;
|
140 |
-
}
|
141 |
-
|
142 |
-
private function generateUri()
|
143 |
-
{
|
144 |
-
$uri = new Uri($this->client->getEndpoint());
|
145 |
-
|
146 |
-
if ($this->client->getConfig('use_path_style_endpoint') === true
|
147 |
-
|| ($uri->getScheme() === 'https'
|
148 |
-
&& strpos($this->bucket, '.') !== false)
|
149 |
-
) {
|
150 |
-
// Use path-style URLs
|
151 |
-
$uri = $uri->withPath("/{$this->bucket}");
|
152 |
-
} else {
|
153 |
-
// Use virtual-style URLs if haven't been set up already
|
154 |
-
if (strpos($uri->getHost(), $this->bucket . '.') !== 0) {
|
155 |
-
$uri = $uri->withHost($this->bucket . '.' . $uri->getHost());
|
156 |
-
}
|
157 |
-
}
|
158 |
-
|
159 |
-
return (string) $uri;
|
160 |
-
}
|
161 |
-
|
162 |
-
protected function getPolicyAndSignature(
|
163 |
-
CredentialsInterface $credentials,
|
164 |
-
array $policy
|
165 |
-
){
|
166 |
-
$ldt = gmdate(SignatureV4::ISO8601_BASIC);
|
167 |
-
$sdt = substr($ldt, 0, 8);
|
168 |
-
$policy['conditions'][] = ['X-Amz-Date' => $ldt];
|
169 |
-
|
170 |
-
$region = $this->client->getRegion();
|
171 |
-
$scope = $this->createScope($sdt, $region, 's3');
|
172 |
-
$creds = "{$credentials->getAccessKeyId()}/$scope";
|
173 |
-
$policy['conditions'][] = ['X-Amz-Credential' => $creds];
|
174 |
-
|
175 |
-
$policy['conditions'][] = ['X-Amz-Algorithm' => "AWS4-HMAC-SHA256"];
|
176 |
-
|
177 |
-
$jsonPolicy64 = base64_encode(json_encode($policy));
|
178 |
-
$key = $this->getSigningKey(
|
179 |
-
$sdt,
|
180 |
-
$region,
|
181 |
-
's3',
|
182 |
-
$credentials->getSecretKey()
|
183 |
-
);
|
184 |
-
|
185 |
-
return [
|
186 |
-
'X-Amz-Credential' => $creds,
|
187 |
-
'X-Amz-Algorithm' => "AWS4-HMAC-SHA256",
|
188 |
-
'X-Amz-Date' => $ldt,
|
189 |
-
'Policy' => $jsonPolicy64,
|
190 |
-
'X-Amz-Signature' => bin2hex(
|
191 |
-
hash_hmac('sha256', $jsonPolicy64, $key, true)
|
192 |
-
),
|
193 |
-
];
|
194 |
-
}
|
195 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/PutObjectUrlMiddleware.php
DELETED
@@ -1,57 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\CommandInterface;
|
5 |
-
use Aws\ResultInterface;
|
6 |
-
use Psr\Http\Message\RequestInterface;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Injects ObjectURL into the result of the PutObject operation.
|
10 |
-
*
|
11 |
-
* @internal
|
12 |
-
*/
|
13 |
-
class PutObjectUrlMiddleware
|
14 |
-
{
|
15 |
-
/** @var callable */
|
16 |
-
private $nextHandler;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Create a middleware wrapper function.
|
20 |
-
*
|
21 |
-
* @return callable
|
22 |
-
*/
|
23 |
-
public static function wrap()
|
24 |
-
{
|
25 |
-
return function (callable $handler) {
|
26 |
-
return new self($handler);
|
27 |
-
};
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* @param callable $nextHandler Next handler to invoke.
|
32 |
-
*/
|
33 |
-
public function __construct(callable $nextHandler)
|
34 |
-
{
|
35 |
-
$this->nextHandler = $nextHandler;
|
36 |
-
}
|
37 |
-
|
38 |
-
public function __invoke(CommandInterface $command, RequestInterface $request = null)
|
39 |
-
{
|
40 |
-
$next = $this->nextHandler;
|
41 |
-
return $next($command, $request)->then(
|
42 |
-
function (ResultInterface $result) use ($command) {
|
43 |
-
$name = $command->getName();
|
44 |
-
switch ($name) {
|
45 |
-
case 'PutObject':
|
46 |
-
case 'CopyObject':
|
47 |
-
$result['ObjectURL'] = $result['@metadata']['effectiveUri'];
|
48 |
-
break;
|
49 |
-
case 'CompleteMultipartUpload':
|
50 |
-
$result['ObjectURL'] = $result['Location'];
|
51 |
-
break;
|
52 |
-
}
|
53 |
-
return $result;
|
54 |
-
}
|
55 |
-
);
|
56 |
-
}
|
57 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/S3Client.php
DELETED
@@ -1,633 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\Api\ApiProvider;
|
5 |
-
use Aws\Api\DocModel;
|
6 |
-
use Aws\Api\Service;
|
7 |
-
use Aws\AwsClient;
|
8 |
-
use Aws\ClientResolver;
|
9 |
-
use Aws\Command;
|
10 |
-
use Aws\Exception\AwsException;
|
11 |
-
use Aws\HandlerList;
|
12 |
-
use Aws\Middleware;
|
13 |
-
use Aws\RetryMiddleware;
|
14 |
-
use Aws\ResultInterface;
|
15 |
-
use Aws\CommandInterface;
|
16 |
-
use GuzzleHttp\Exception\RequestException;
|
17 |
-
use Psr\Http\Message\RequestInterface;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Client used to interact with **Amazon Simple Storage Service (Amazon S3)**.
|
21 |
-
*
|
22 |
-
* @method \Aws\Result abortMultipartUpload(array $args = [])
|
23 |
-
* @method \GuzzleHttp\Promise\Promise abortMultipartUploadAsync(array $args = [])
|
24 |
-
* @method \Aws\Result completeMultipartUpload(array $args = [])
|
25 |
-
* @method \GuzzleHttp\Promise\Promise completeMultipartUploadAsync(array $args = [])
|
26 |
-
* @method \Aws\Result copyObject(array $args = [])
|
27 |
-
* @method \GuzzleHttp\Promise\Promise copyObjectAsync(array $args = [])
|
28 |
-
* @method \Aws\Result createBucket(array $args = [])
|
29 |
-
* @method \GuzzleHttp\Promise\Promise createBucketAsync(array $args = [])
|
30 |
-
* @method \Aws\Result createMultipartUpload(array $args = [])
|
31 |
-
* @method \GuzzleHttp\Promise\Promise createMultipartUploadAsync(array $args = [])
|
32 |
-
* @method \Aws\Result deleteBucket(array $args = [])
|
33 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketAsync(array $args = [])
|
34 |
-
* @method \Aws\Result deleteBucketAnalyticsConfiguration(array $args = [])
|
35 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketAnalyticsConfigurationAsync(array $args = [])
|
36 |
-
* @method \Aws\Result deleteBucketCors(array $args = [])
|
37 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketCorsAsync(array $args = [])
|
38 |
-
* @method \Aws\Result deleteBucketEncryption(array $args = [])
|
39 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketEncryptionAsync(array $args = [])
|
40 |
-
* @method \Aws\Result deleteBucketInventoryConfiguration(array $args = [])
|
41 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketInventoryConfigurationAsync(array $args = [])
|
42 |
-
* @method \Aws\Result deleteBucketLifecycle(array $args = [])
|
43 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketLifecycleAsync(array $args = [])
|
44 |
-
* @method \Aws\Result deleteBucketMetricsConfiguration(array $args = [])
|
45 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketMetricsConfigurationAsync(array $args = [])
|
46 |
-
* @method \Aws\Result deleteBucketPolicy(array $args = [])
|
47 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketPolicyAsync(array $args = [])
|
48 |
-
* @method \Aws\Result deleteBucketReplication(array $args = [])
|
49 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketReplicationAsync(array $args = [])
|
50 |
-
* @method \Aws\Result deleteBucketTagging(array $args = [])
|
51 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketTaggingAsync(array $args = [])
|
52 |
-
* @method \Aws\Result deleteBucketWebsite(array $args = [])
|
53 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketWebsiteAsync(array $args = [])
|
54 |
-
* @method \Aws\Result deleteObject(array $args = [])
|
55 |
-
* @method \GuzzleHttp\Promise\Promise deleteObjectAsync(array $args = [])
|
56 |
-
* @method \Aws\Result deleteObjectTagging(array $args = [])
|
57 |
-
* @method \GuzzleHttp\Promise\Promise deleteObjectTaggingAsync(array $args = [])
|
58 |
-
* @method \Aws\Result deleteObjects(array $args = [])
|
59 |
-
* @method \GuzzleHttp\Promise\Promise deleteObjectsAsync(array $args = [])
|
60 |
-
* @method \Aws\Result deletePublicAccessBlock(array $args = [])
|
61 |
-
* @method \GuzzleHttp\Promise\Promise deletePublicAccessBlockAsync(array $args = [])
|
62 |
-
* @method \Aws\Result getBucketAccelerateConfiguration(array $args = [])
|
63 |
-
* @method \GuzzleHttp\Promise\Promise getBucketAccelerateConfigurationAsync(array $args = [])
|
64 |
-
* @method \Aws\Result getBucketAcl(array $args = [])
|
65 |
-
* @method \GuzzleHttp\Promise\Promise getBucketAclAsync(array $args = [])
|
66 |
-
* @method \Aws\Result getBucketAnalyticsConfiguration(array $args = [])
|
67 |
-
* @method \GuzzleHttp\Promise\Promise getBucketAnalyticsConfigurationAsync(array $args = [])
|
68 |
-
* @method \Aws\Result getBucketCors(array $args = [])
|
69 |
-
* @method \GuzzleHttp\Promise\Promise getBucketCorsAsync(array $args = [])
|
70 |
-
* @method \Aws\Result getBucketEncryption(array $args = [])
|
71 |
-
* @method \GuzzleHttp\Promise\Promise getBucketEncryptionAsync(array $args = [])
|
72 |
-
* @method \Aws\Result getBucketInventoryConfiguration(array $args = [])
|
73 |
-
* @method \GuzzleHttp\Promise\Promise getBucketInventoryConfigurationAsync(array $args = [])
|
74 |
-
* @method \Aws\Result getBucketLifecycle(array $args = [])
|
75 |
-
* @method \GuzzleHttp\Promise\Promise getBucketLifecycleAsync(array $args = [])
|
76 |
-
* @method \Aws\Result getBucketLifecycleConfiguration(array $args = [])
|
77 |
-
* @method \GuzzleHttp\Promise\Promise getBucketLifecycleConfigurationAsync(array $args = [])
|
78 |
-
* @method \Aws\Result getBucketLocation(array $args = [])
|
79 |
-
* @method \GuzzleHttp\Promise\Promise getBucketLocationAsync(array $args = [])
|
80 |
-
* @method \Aws\Result getBucketLogging(array $args = [])
|
81 |
-
* @method \GuzzleHttp\Promise\Promise getBucketLoggingAsync(array $args = [])
|
82 |
-
* @method \Aws\Result getBucketMetricsConfiguration(array $args = [])
|
83 |
-
* @method \GuzzleHttp\Promise\Promise getBucketMetricsConfigurationAsync(array $args = [])
|
84 |
-
* @method \Aws\Result getBucketNotification(array $args = [])
|
85 |
-
* @method \GuzzleHttp\Promise\Promise getBucketNotificationAsync(array $args = [])
|
86 |
-
* @method \Aws\Result getBucketNotificationConfiguration(array $args = [])
|
87 |
-
* @method \GuzzleHttp\Promise\Promise getBucketNotificationConfigurationAsync(array $args = [])
|
88 |
-
* @method \Aws\Result getBucketPolicy(array $args = [])
|
89 |
-
* @method \GuzzleHttp\Promise\Promise getBucketPolicyAsync(array $args = [])
|
90 |
-
* @method \Aws\Result getBucketPolicyStatus(array $args = [])
|
91 |
-
* @method \GuzzleHttp\Promise\Promise getBucketPolicyStatusAsync(array $args = [])
|
92 |
-
* @method \Aws\Result getBucketReplication(array $args = [])
|
93 |
-
* @method \GuzzleHttp\Promise\Promise getBucketReplicationAsync(array $args = [])
|
94 |
-
* @method \Aws\Result getBucketRequestPayment(array $args = [])
|
95 |
-
* @method \GuzzleHttp\Promise\Promise getBucketRequestPaymentAsync(array $args = [])
|
96 |
-
* @method \Aws\Result getBucketTagging(array $args = [])
|
97 |
-
* @method \GuzzleHttp\Promise\Promise getBucketTaggingAsync(array $args = [])
|
98 |
-
* @method \Aws\Result getBucketVersioning(array $args = [])
|
99 |
-
* @method \GuzzleHttp\Promise\Promise getBucketVersioningAsync(array $args = [])
|
100 |
-
* @method \Aws\Result getBucketWebsite(array $args = [])
|
101 |
-
* @method \GuzzleHttp\Promise\Promise getBucketWebsiteAsync(array $args = [])
|
102 |
-
* @method \Aws\Result getObject(array $args = [])
|
103 |
-
* @method \GuzzleHttp\Promise\Promise getObjectAsync(array $args = [])
|
104 |
-
* @method \Aws\Result getObjectAcl(array $args = [])
|
105 |
-
* @method \GuzzleHttp\Promise\Promise getObjectAclAsync(array $args = [])
|
106 |
-
* @method \Aws\Result getObjectLegalHold(array $args = [])
|
107 |
-
* @method \GuzzleHttp\Promise\Promise getObjectLegalHoldAsync(array $args = [])
|
108 |
-
* @method \Aws\Result getObjectLockConfiguration(array $args = [])
|
109 |
-
* @method \GuzzleHttp\Promise\Promise getObjectLockConfigurationAsync(array $args = [])
|
110 |
-
* @method \Aws\Result getObjectRetention(array $args = [])
|
111 |
-
* @method \GuzzleHttp\Promise\Promise getObjectRetentionAsync(array $args = [])
|
112 |
-
* @method \Aws\Result getObjectTagging(array $args = [])
|
113 |
-
* @method \GuzzleHttp\Promise\Promise getObjectTaggingAsync(array $args = [])
|
114 |
-
* @method \Aws\Result getObjectTorrent(array $args = [])
|
115 |
-
* @method \GuzzleHttp\Promise\Promise getObjectTorrentAsync(array $args = [])
|
116 |
-
* @method \Aws\Result getPublicAccessBlock(array $args = [])
|
117 |
-
* @method \GuzzleHttp\Promise\Promise getPublicAccessBlockAsync(array $args = [])
|
118 |
-
* @method \Aws\Result headBucket(array $args = [])
|
119 |
-
* @method \GuzzleHttp\Promise\Promise headBucketAsync(array $args = [])
|
120 |
-
* @method \Aws\Result headObject(array $args = [])
|
121 |
-
* @method \GuzzleHttp\Promise\Promise headObjectAsync(array $args = [])
|
122 |
-
* @method \Aws\Result listBucketAnalyticsConfigurations(array $args = [])
|
123 |
-
* @method \GuzzleHttp\Promise\Promise listBucketAnalyticsConfigurationsAsync(array $args = [])
|
124 |
-
* @method \Aws\Result listBucketInventoryConfigurations(array $args = [])
|
125 |
-
* @method \GuzzleHttp\Promise\Promise listBucketInventoryConfigurationsAsync(array $args = [])
|
126 |
-
* @method \Aws\Result listBucketMetricsConfigurations(array $args = [])
|
127 |
-
* @method \GuzzleHttp\Promise\Promise listBucketMetricsConfigurationsAsync(array $args = [])
|
128 |
-
* @method \Aws\Result listBuckets(array $args = [])
|
129 |
-
* @method \GuzzleHttp\Promise\Promise listBucketsAsync(array $args = [])
|
130 |
-
* @method \Aws\Result listMultipartUploads(array $args = [])
|
131 |
-
* @method \GuzzleHttp\Promise\Promise listMultipartUploadsAsync(array $args = [])
|
132 |
-
* @method \Aws\Result listObjectVersions(array $args = [])
|
133 |
-
* @method \GuzzleHttp\Promise\Promise listObjectVersionsAsync(array $args = [])
|
134 |
-
* @method \Aws\Result listObjects(array $args = [])
|
135 |
-
* @method \GuzzleHttp\Promise\Promise listObjectsAsync(array $args = [])
|
136 |
-
* @method \Aws\Result listObjectsV2(array $args = [])
|
137 |
-
* @method \GuzzleHttp\Promise\Promise listObjectsV2Async(array $args = [])
|
138 |
-
* @method \Aws\Result listParts(array $args = [])
|
139 |
-
* @method \GuzzleHttp\Promise\Promise listPartsAsync(array $args = [])
|
140 |
-
* @method \Aws\Result putBucketAccelerateConfiguration(array $args = [])
|
141 |
-
* @method \GuzzleHttp\Promise\Promise putBucketAccelerateConfigurationAsync(array $args = [])
|
142 |
-
* @method \Aws\Result putBucketAcl(array $args = [])
|
143 |
-
* @method \GuzzleHttp\Promise\Promise putBucketAclAsync(array $args = [])
|
144 |
-
* @method \Aws\Result putBucketAnalyticsConfiguration(array $args = [])
|
145 |
-
* @method \GuzzleHttp\Promise\Promise putBucketAnalyticsConfigurationAsync(array $args = [])
|
146 |
-
* @method \Aws\Result putBucketCors(array $args = [])
|
147 |
-
* @method \GuzzleHttp\Promise\Promise putBucketCorsAsync(array $args = [])
|
148 |
-
* @method \Aws\Result putBucketEncryption(array $args = [])
|
149 |
-
* @method \GuzzleHttp\Promise\Promise putBucketEncryptionAsync(array $args = [])
|
150 |
-
* @method \Aws\Result putBucketInventoryConfiguration(array $args = [])
|
151 |
-
* @method \GuzzleHttp\Promise\Promise putBucketInventoryConfigurationAsync(array $args = [])
|
152 |
-
* @method \Aws\Result putBucketLifecycle(array $args = [])
|
153 |
-
* @method \GuzzleHttp\Promise\Promise putBucketLifecycleAsync(array $args = [])
|
154 |
-
* @method \Aws\Result putBucketLifecycleConfiguration(array $args = [])
|
155 |
-
* @method \GuzzleHttp\Promise\Promise putBucketLifecycleConfigurationAsync(array $args = [])
|
156 |
-
* @method \Aws\Result putBucketLogging(array $args = [])
|
157 |
-
* @method \GuzzleHttp\Promise\Promise putBucketLoggingAsync(array $args = [])
|
158 |
-
* @method \Aws\Result putBucketMetricsConfiguration(array $args = [])
|
159 |
-
* @method \GuzzleHttp\Promise\Promise putBucketMetricsConfigurationAsync(array $args = [])
|
160 |
-
* @method \Aws\Result putBucketNotification(array $args = [])
|
161 |
-
* @method \GuzzleHttp\Promise\Promise putBucketNotificationAsync(array $args = [])
|
162 |
-
* @method \Aws\Result putBucketNotificationConfiguration(array $args = [])
|
163 |
-
* @method \GuzzleHttp\Promise\Promise putBucketNotificationConfigurationAsync(array $args = [])
|
164 |
-
* @method \Aws\Result putBucketPolicy(array $args = [])
|
165 |
-
* @method \GuzzleHttp\Promise\Promise putBucketPolicyAsync(array $args = [])
|
166 |
-
* @method \Aws\Result putBucketReplication(array $args = [])
|
167 |
-
* @method \GuzzleHttp\Promise\Promise putBucketReplicationAsync(array $args = [])
|
168 |
-
* @method \Aws\Result putBucketRequestPayment(array $args = [])
|
169 |
-
* @method \GuzzleHttp\Promise\Promise putBucketRequestPaymentAsync(array $args = [])
|
170 |
-
* @method \Aws\Result putBucketTagging(array $args = [])
|
171 |
-
* @method \GuzzleHttp\Promise\Promise putBucketTaggingAsync(array $args = [])
|
172 |
-
* @method \Aws\Result putBucketVersioning(array $args = [])
|
173 |
-
* @method \GuzzleHttp\Promise\Promise putBucketVersioningAsync(array $args = [])
|
174 |
-
* @method \Aws\Result putBucketWebsite(array $args = [])
|
175 |
-
* @method \GuzzleHttp\Promise\Promise putBucketWebsiteAsync(array $args = [])
|
176 |
-
* @method \Aws\Result putObject(array $args = [])
|
177 |
-
* @method \GuzzleHttp\Promise\Promise putObjectAsync(array $args = [])
|
178 |
-
* @method \Aws\Result putObjectAcl(array $args = [])
|
179 |
-
* @method \GuzzleHttp\Promise\Promise putObjectAclAsync(array $args = [])
|
180 |
-
* @method \Aws\Result putObjectLegalHold(array $args = [])
|
181 |
-
* @method \GuzzleHttp\Promise\Promise putObjectLegalHoldAsync(array $args = [])
|
182 |
-
* @method \Aws\Result putObjectLockConfiguration(array $args = [])
|
183 |
-
* @method \GuzzleHttp\Promise\Promise putObjectLockConfigurationAsync(array $args = [])
|
184 |
-
* @method \Aws\Result putObjectRetention(array $args = [])
|
185 |
-
* @method \GuzzleHttp\Promise\Promise putObjectRetentionAsync(array $args = [])
|
186 |
-
* @method \Aws\Result putObjectTagging(array $args = [])
|
187 |
-
* @method \GuzzleHttp\Promise\Promise putObjectTaggingAsync(array $args = [])
|
188 |
-
* @method \Aws\Result putPublicAccessBlock(array $args = [])
|
189 |
-
* @method \GuzzleHttp\Promise\Promise putPublicAccessBlockAsync(array $args = [])
|
190 |
-
* @method \Aws\Result restoreObject(array $args = [])
|
191 |
-
* @method \GuzzleHttp\Promise\Promise restoreObjectAsync(array $args = [])
|
192 |
-
* @method \Aws\Result selectObjectContent(array $args = [])
|
193 |
-
* @method \GuzzleHttp\Promise\Promise selectObjectContentAsync(array $args = [])
|
194 |
-
* @method \Aws\Result uploadPart(array $args = [])
|
195 |
-
* @method \GuzzleHttp\Promise\Promise uploadPartAsync(array $args = [])
|
196 |
-
* @method \Aws\Result uploadPartCopy(array $args = [])
|
197 |
-
* @method \GuzzleHttp\Promise\Promise uploadPartCopyAsync(array $args = [])
|
198 |
-
*/
|
199 |
-
class S3Client extends AwsClient implements S3ClientInterface
|
200 |
-
{
|
201 |
-
use S3ClientTrait;
|
202 |
-
|
203 |
-
public static function getArguments()
|
204 |
-
{
|
205 |
-
$args = parent::getArguments();
|
206 |
-
$args['retries']['fn'] = [__CLASS__, '_applyRetryConfig'];
|
207 |
-
$args['api_provider']['fn'] = [__CLASS__, '_applyApiProvider'];
|
208 |
-
|
209 |
-
return $args + [
|
210 |
-
'bucket_endpoint' => [
|
211 |
-
'type' => 'config',
|
212 |
-
'valid' => ['bool'],
|
213 |
-
'doc' => 'Set to true to send requests to a hardcoded '
|
214 |
-
. 'bucket endpoint rather than create an endpoint as a '
|
215 |
-
. 'result of injecting the bucket into the URL. This '
|
216 |
-
. 'option is useful for interacting with CNAME endpoints.',
|
217 |
-
],
|
218 |
-
'use_accelerate_endpoint' => [
|
219 |
-
'type' => 'config',
|
220 |
-
'valid' => ['bool'],
|
221 |
-
'doc' => 'Set to true to send requests to an S3 Accelerate'
|
222 |
-
. ' endpoint by default. Can be enabled or disabled on'
|
223 |
-
. ' individual operations by setting'
|
224 |
-
. ' \'@use_accelerate_endpoint\' to true or false. Note:'
|
225 |
-
. ' you must enable S3 Accelerate on a bucket before it can'
|
226 |
-
. ' be accessed via an Accelerate endpoint.',
|
227 |
-
'default' => false,
|
228 |
-
],
|
229 |
-
'use_dual_stack_endpoint' => [
|
230 |
-
'type' => 'config',
|
231 |
-
'valid' => ['bool'],
|
232 |
-
'doc' => 'Set to true to send requests to an S3 Dual Stack'
|
233 |
-
. ' endpoint by default, which enables IPv6 Protocol.'
|
234 |
-
. ' Can be enabled or disabled on individual operations by setting'
|
235 |
-
. ' \'@use_dual_stack_endpoint\' to true or false.',
|
236 |
-
'default' => false,
|
237 |
-
],
|
238 |
-
'use_path_style_endpoint' => [
|
239 |
-
'type' => 'config',
|
240 |
-
'valid' => ['bool'],
|
241 |
-
'doc' => 'Set to true to send requests to an S3 path style'
|
242 |
-
. ' endpoint by default.'
|
243 |
-
. ' Can be enabled or disabled on individual operations by setting'
|
244 |
-
. ' \'@use_path_style_endpoint\' to true or false.',
|
245 |
-
'default' => false,
|
246 |
-
],
|
247 |
-
];
|
248 |
-
}
|
249 |
-
|
250 |
-
/**
|
251 |
-
* {@inheritdoc}
|
252 |
-
*
|
253 |
-
* In addition to the options available to
|
254 |
-
* {@see Aws\AwsClient::__construct}, S3Client accepts the following
|
255 |
-
* options:
|
256 |
-
*
|
257 |
-
* - bucket_endpoint: (bool) Set to true to send requests to a
|
258 |
-
* hardcoded bucket endpoint rather than create an endpoint as a result
|
259 |
-
* of injecting the bucket into the URL. This option is useful for
|
260 |
-
* interacting with CNAME endpoints.
|
261 |
-
* - calculate_md5: (bool) Set to false to disable calculating an MD5
|
262 |
-
* for all Amazon S3 signed uploads.
|
263 |
-
* - use_accelerate_endpoint: (bool) Set to true to send requests to an S3
|
264 |
-
* Accelerate endpoint by default. Can be enabled or disabled on
|
265 |
-
* individual operations by setting '@use_accelerate_endpoint' to true or
|
266 |
-
* false. Note: you must enable S3 Accelerate on a bucket before it can be
|
267 |
-
* accessed via an Accelerate endpoint.
|
268 |
-
* - use_dual_stack_endpoint: (bool) Set to true to send requests to an S3
|
269 |
-
* Dual Stack endpoint by default, which enables IPv6 Protocol.
|
270 |
-
* Can be enabled or disabled on individual operations by setting
|
271 |
-
* '@use_dual_stack_endpoint\' to true or false. Note:
|
272 |
-
* you cannot use it together with an accelerate endpoint.
|
273 |
-
* - use_path_style_endpoint: (bool) Set to true to send requests to an S3
|
274 |
-
* path style endpoint by default.
|
275 |
-
* Can be enabled or disabled on individual operations by setting
|
276 |
-
* '@use_path_style_endpoint\' to true or false. Note:
|
277 |
-
* you cannot use it together with an accelerate endpoint.
|
278 |
-
*
|
279 |
-
* @param array $args
|
280 |
-
*/
|
281 |
-
public function __construct(array $args)
|
282 |
-
{
|
283 |
-
parent::__construct($args);
|
284 |
-
$stack = $this->getHandlerList();
|
285 |
-
$stack->appendInit(SSECMiddleware::wrap($this->getEndpoint()->getScheme()), 's3.ssec');
|
286 |
-
$stack->appendBuild(ApplyChecksumMiddleware::wrap(), 's3.checksum');
|
287 |
-
$stack->appendBuild(
|
288 |
-
Middleware::contentType(['PutObject', 'UploadPart']),
|
289 |
-
's3.content_type'
|
290 |
-
);
|
291 |
-
|
292 |
-
|
293 |
-
// Use the bucket style middleware when using a "bucket_endpoint" (for cnames)
|
294 |
-
if ($this->getConfig('bucket_endpoint')) {
|
295 |
-
$stack->appendBuild(BucketEndpointMiddleware::wrap(), 's3.bucket_endpoint');
|
296 |
-
} else {
|
297 |
-
$stack->appendBuild(
|
298 |
-
S3EndpointMiddleware::wrap(
|
299 |
-
$this->getRegion(),
|
300 |
-
[
|
301 |
-
'dual_stack' => $this->getConfig('use_dual_stack_endpoint'),
|
302 |
-
'accelerate' => $this->getConfig('use_accelerate_endpoint'),
|
303 |
-
'path_style' => $this->getConfig('use_path_style_endpoint')
|
304 |
-
]
|
305 |
-
),
|
306 |
-
's3.endpoint_middleware'
|
307 |
-
);
|
308 |
-
}
|
309 |
-
|
310 |
-
$stack->appendSign(PutObjectUrlMiddleware::wrap(), 's3.put_object_url');
|
311 |
-
$stack->appendSign(PermanentRedirectMiddleware::wrap(), 's3.permanent_redirect');
|
312 |
-
$stack->appendInit(Middleware::sourceFile($this->getApi()), 's3.source_file');
|
313 |
-
$stack->appendInit($this->getSaveAsParameter(), 's3.save_as');
|
314 |
-
$stack->appendInit($this->getLocationConstraintMiddleware(), 's3.location');
|
315 |
-
$stack->appendInit($this->getEncodingTypeMiddleware(), 's3.auto_encode');
|
316 |
-
$stack->appendInit($this->getHeadObjectMiddleware(), 's3.head_object');
|
317 |
-
}
|
318 |
-
|
319 |
-
/**
|
320 |
-
* Determine if a string is a valid name for a DNS compatible Amazon S3
|
321 |
-
* bucket.
|
322 |
-
*
|
323 |
-
* DNS compatible bucket names can be used as a subdomain in a URL (e.g.,
|
324 |
-
* "<bucket>.s3.amazonaws.com").
|
325 |
-
*
|
326 |
-
* @param string $bucket Bucket name to check.
|
327 |
-
*
|
328 |
-
* @return bool
|
329 |
-
*/
|
330 |
-
public static function isBucketDnsCompatible($bucket)
|
331 |
-
{
|
332 |
-
$bucketLen = strlen($bucket);
|
333 |
-
|
334 |
-
return ($bucketLen >= 3 && $bucketLen <= 63) &&
|
335 |
-
// Cannot look like an IP address
|
336 |
-
!filter_var($bucket, FILTER_VALIDATE_IP) &&
|
337 |
-
preg_match('/^[a-z0-9]([a-z0-9\-\.]*[a-z0-9])?$/', $bucket);
|
338 |
-
}
|
339 |
-
|
340 |
-
public function createPresignedRequest(CommandInterface $command, $expires)
|
341 |
-
{
|
342 |
-
$command = clone $command;
|
343 |
-
$command->getHandlerList()->remove('signer');
|
344 |
-
|
345 |
-
/** @var \Aws\Signature\SignatureInterface $signer */
|
346 |
-
$signer = call_user_func(
|
347 |
-
$this->getSignatureProvider(),
|
348 |
-
$this->getConfig('signature_version'),
|
349 |
-
$this->getConfig('signing_name'),
|
350 |
-
$this->getConfig('signing_region')
|
351 |
-
);
|
352 |
-
|
353 |
-
return $signer->presign(
|
354 |
-
\Aws\serialize($command),
|
355 |
-
$this->getCredentials()->wait(),
|
356 |
-
$expires
|
357 |
-
);
|
358 |
-
}
|
359 |
-
|
360 |
-
public function getObjectUrl($bucket, $key)
|
361 |
-
{
|
362 |
-
$command = $this->getCommand('GetObject', [
|
363 |
-
'Bucket' => $bucket,
|
364 |
-
'Key' => $key
|
365 |
-
]);
|
366 |
-
|
367 |
-
return (string) \Aws\serialize($command)->getUri();
|
368 |
-
}
|
369 |
-
|
370 |
-
/**
|
371 |
-
* Raw URL encode a key and allow for '/' characters
|
372 |
-
*
|
373 |
-
* @param string $key Key to encode
|
374 |
-
*
|
375 |
-
* @return string Returns the encoded key
|
376 |
-
*/
|
377 |
-
public static function encodeKey($key)
|
378 |
-
{
|
379 |
-
return str_replace('%2F', '/', rawurlencode($key));
|
380 |
-
}
|
381 |
-
|
382 |
-
/**
|
383 |
-
* Provides a middleware that removes the need to specify LocationConstraint on CreateBucket.
|
384 |
-
*
|
385 |
-
* @return \Closure
|
386 |
-
*/
|
387 |
-
private function getLocationConstraintMiddleware()
|
388 |
-
{
|
389 |
-
$region = $this->getRegion();
|
390 |
-
return static function (callable $handler) use ($region) {
|
391 |
-
return function (Command $command, $request = null) use ($handler, $region) {
|
392 |
-
if ($command->getName() === 'CreateBucket') {
|
393 |
-
$locationConstraint = isset($command['CreateBucketConfiguration']['LocationConstraint'])
|
394 |
-
? $command['CreateBucketConfiguration']['LocationConstraint']
|
395 |
-
: null;
|
396 |
-
|
397 |
-
if ($locationConstraint === 'us-east-1') {
|
398 |
-
unset($command['CreateBucketConfiguration']);
|
399 |
-
} elseif ('us-east-1' !== $region && empty($locationConstraint)) {
|
400 |
-
$command['CreateBucketConfiguration'] = ['LocationConstraint' => $region];
|
401 |
-
}
|
402 |
-
}
|
403 |
-
|
404 |
-
return $handler($command, $request);
|
405 |
-
};
|
406 |
-
};
|
407 |
-
}
|
408 |
-
|
409 |
-
/**
|
410 |
-
* Provides a middleware that supports the `SaveAs` parameter.
|
411 |
-
*
|
412 |
-
* @return \Closure
|
413 |
-
*/
|
414 |
-
private function getSaveAsParameter()
|
415 |
-
{
|
416 |
-
return static function (callable $handler) {
|
417 |
-
return function (Command $command, $request = null) use ($handler) {
|
418 |
-
if ($command->getName() === 'GetObject' && isset($command['SaveAs'])) {
|
419 |
-
$command['@http']['sink'] = $command['SaveAs'];
|
420 |
-
unset($command['SaveAs']);
|
421 |
-
}
|
422 |
-
|
423 |
-
return $handler($command, $request);
|
424 |
-
};
|
425 |
-
};
|
426 |
-
}
|
427 |
-
|
428 |
-
/**
|
429 |
-
* Provides a middleware that disables content decoding on HeadObject
|
430 |
-
* commands.
|
431 |
-
*
|
432 |
-
* @return \Closure
|
433 |
-
*/
|
434 |
-
private function getHeadObjectMiddleware()
|
435 |
-
{
|
436 |
-
return static function (callable $handler) {
|
437 |
-
return function (
|
438 |
-
CommandInterface $command,
|
439 |
-
RequestInterface $request = null
|
440 |
-
) use ($handler) {
|
441 |
-
if ($command->getName() === 'HeadObject'
|
442 |
-
&& !isset($command['@http']['decode_content'])
|
443 |
-
) {
|
444 |
-
$command['@http']['decode_content'] = false;
|
445 |
-
}
|
446 |
-
|
447 |
-
return $handler($command, $request);
|
448 |
-
};
|
449 |
-
};
|
450 |
-
}
|
451 |
-
|
452 |
-
/**
|
453 |
-
* Provides a middleware that autopopulates the EncodingType parameter on
|
454 |
-
* ListObjects commands.
|
455 |
-
*
|
456 |
-
* @return \Closure
|
457 |
-
*/
|
458 |
-
private function getEncodingTypeMiddleware()
|
459 |
-
{
|
460 |
-
return static function (callable $handler) {
|
461 |
-
return function (Command $command, $request = null) use ($handler) {
|
462 |
-
$autoSet = false;
|
463 |
-
if ($command->getName() === 'ListObjects'
|
464 |
-
&& empty($command['EncodingType'])
|
465 |
-
) {
|
466 |
-
$command['EncodingType'] = 'url';
|
467 |
-
$autoSet = true;
|
468 |
-
}
|
469 |
-
|
470 |
-
return $handler($command, $request)
|
471 |
-
->then(function (ResultInterface $result) use ($autoSet) {
|
472 |
-
if ($result['EncodingType'] === 'url' && $autoSet) {
|
473 |
-
static $topLevel = [
|
474 |
-
'Delimiter',
|
475 |
-
'Marker',
|
476 |
-
'NextMarker',
|
477 |
-
'Prefix',
|
478 |
-
];
|
479 |
-
static $nested = [
|
480 |
-
['Contents', 'Key'],
|
481 |
-
['CommonPrefixes', 'Prefix'],
|
482 |
-
];
|
483 |
-
|
484 |
-
foreach ($topLevel as $key) {
|
485 |
-
if (isset($result[$key])) {
|
486 |
-
$result[$key] = urldecode($result[$key]);
|
487 |
-
}
|
488 |
-
}
|
489 |
-
foreach ($nested as $steps) {
|
490 |
-
if (isset($result[$steps[0]])) {
|
491 |
-
foreach ($result[$steps[0]] as $key => $part) {
|
492 |
-
if (isset($part[$steps[1]])) {
|
493 |
-
$result[$steps[0]][$key][$steps[1]]
|
494 |
-
= urldecode($part[$steps[1]]);
|
495 |
-
}
|
496 |
-
}
|
497 |
-
}
|
498 |
-
}
|
499 |
-
|
500 |
-
}
|
501 |
-
|
502 |
-
return $result;
|
503 |
-
});
|
504 |
-
};
|
505 |
-
};
|
506 |
-
}
|
507 |
-
|
508 |
-
/** @internal */
|
509 |
-
public static function _applyRetryConfig($value, $_, HandlerList $list)
|
510 |
-
{
|
511 |
-
if (!$value) {
|
512 |
-
return;
|
513 |
-
}
|
514 |
-
|
515 |
-
$decider = RetryMiddleware::createDefaultDecider($value);
|
516 |
-
$decider = function ($retries, $command, $request, $result, $error) use ($decider, $value) {
|
517 |
-
$maxRetries = null !== $command['@retries']
|
518 |
-
? $command['@retries']
|
519 |
-
: $value;
|
520 |
-
|
521 |
-
if ($decider($retries, $command, $request, $result, $error)) {
|
522 |
-
return true;
|
523 |
-
}
|
524 |
-
|
525 |
-
if ($error instanceof AwsException
|
526 |
-
&& $retries < $maxRetries
|
527 |
-
) {
|
528 |
-
if ($error->getResponse()
|
529 |
-
&& $error->getResponse()->getStatusCode() >= 400
|
530 |
-
) {
|
531 |
-
return strpos(
|
532 |
-
$error->getResponse()->getBody(),
|
533 |
-
'Your socket connection to the server'
|
534 |
-
) !== false;
|
535 |
-
}
|
536 |
-
|
537 |
-
if ($error->getPrevious() instanceof RequestException) {
|
538 |
-
// All commands except CompleteMultipartUpload are
|
539 |
-
// idempotent and may be retried without worry if a
|
540 |
-
// networking error has occurred.
|
541 |
-
return $command->getName() !== 'CompleteMultipartUpload';
|
542 |
-
}
|
543 |
-
}
|
544 |
-
|
545 |
-
return false;
|
546 |
-
};
|
547 |
-
|
548 |
-
$delay = [RetryMiddleware::class, 'exponentialDelay'];
|
549 |
-
$list->appendSign(Middleware::retry($decider, $delay), 'retry');
|
550 |
-
}
|
551 |
-
|
552 |
-
/** @internal */
|
553 |
-
public static function _applyApiProvider($value, array &$args, HandlerList $list)
|
554 |
-
{
|
555 |
-
ClientResolver::_apply_api_provider($value, $args, $list);
|
556 |
-
$args['parser'] = new GetBucketLocationParser(
|
557 |
-
new AmbiguousSuccessParser(
|
558 |
-
new RetryableMalformedResponseParser(
|
559 |
-
$args['parser'],
|
560 |
-
$args['exception_class']
|
561 |
-
),
|
562 |
-
$args['error_parser'],
|
563 |
-
$args['exception_class']
|
564 |
-
)
|
565 |
-
);
|
566 |
-
}
|
567 |
-
|
568 |
-
/**
|
569 |
-
* @internal
|
570 |
-
* @codeCoverageIgnore
|
571 |
-
*/
|
572 |
-
public static function applyDocFilters(array $api, array $docs)
|
573 |
-
{
|
574 |
-
$b64 = '<div class="alert alert-info">This value will be base64 encoded on your behalf.</div>';
|
575 |
-
$opt = '<div class="alert alert-info">This value will be computed for you it is not supplied.</div>';
|
576 |
-
|
577 |
-
// Add the SourceFile parameter.
|
578 |
-
$docs['shapes']['SourceFile']['base'] = 'The path to a file on disk to use instead of the Body parameter.';
|
579 |
-
$api['shapes']['SourceFile'] = ['type' => 'string'];
|
580 |
-
$api['shapes']['PutObjectRequest']['members']['SourceFile'] = ['shape' => 'SourceFile'];
|
581 |
-
$api['shapes']['UploadPartRequest']['members']['SourceFile'] = ['shape' => 'SourceFile'];
|
582 |
-
|
583 |
-
// Add the ContentSHA256 parameter.
|
584 |
-
$docs['shapes']['ContentSHA256']['base'] = 'A SHA256 hash of the body content of the request.';
|
585 |
-
$api['shapes']['ContentSHA256'] = ['type' => 'string'];
|
586 |
-
$api['shapes']['PutObjectRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256'];
|
587 |
-
$api['shapes']['UploadPartRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256'];
|
588 |
-
unset($api['shapes']['PutObjectRequest']['members']['ContentMD5']);
|
589 |
-
unset($api['shapes']['UploadPartRequest']['members']['ContentMD5']);
|
590 |
-
$docs['shapes']['ContentSHA256']['append'] = $opt;
|
591 |
-
|
592 |
-
// Add the SaveAs parameter.
|
593 |
-
$docs['shapes']['SaveAs']['base'] = 'The path to a file on disk to save the object data.';
|
594 |
-
$api['shapes']['SaveAs'] = ['type' => 'string'];
|
595 |
-
$api['shapes']['GetObjectRequest']['members']['SaveAs'] = ['shape' => 'SaveAs'];
|
596 |
-
|
597 |
-
// Several SSECustomerKey documentation updates.
|
598 |
-
$docs['shapes']['SSECustomerKey']['append'] = $b64;
|
599 |
-
$docs['shapes']['CopySourceSSECustomerKey']['append'] = $b64;
|
600 |
-
$docs['shapes']['SSECustomerKeyMd5']['append'] = $opt;
|
601 |
-
|
602 |
-
// Add the ObjectURL to various output shapes and documentation.
|
603 |
-
$docs['shapes']['ObjectURL']['base'] = 'The URI of the created object.';
|
604 |
-
$api['shapes']['ObjectURL'] = ['type' => 'string'];
|
605 |
-
$api['shapes']['PutObjectOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
|
606 |
-
$api['shapes']['CopyObjectOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
|
607 |
-
$api['shapes']['CompleteMultipartUploadOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
|
608 |
-
|
609 |
-
// Fix references to Location Constraint.
|
610 |
-
unset($api['shapes']['CreateBucketRequest']['payload']);
|
611 |
-
$api['shapes']['BucketLocationConstraint']['enum'] = [
|
612 |
-
"ap-northeast-1",
|
613 |
-
"ap-southeast-2",
|
614 |
-
"ap-southeast-1",
|
615 |
-
"cn-north-1",
|
616 |
-
"eu-central-1",
|
617 |
-
"eu-west-1",
|
618 |
-
"us-east-1",
|
619 |
-
"us-west-1",
|
620 |
-
"us-west-2",
|
621 |
-
"sa-east-1",
|
622 |
-
];
|
623 |
-
|
624 |
-
// Add a note that the ContentMD5 is optional.
|
625 |
-
$docs['shapes']['ContentMD5']['append'] = '<div class="alert alert-info">The value will be computed on '
|
626 |
-
. 'your behalf.</div>';
|
627 |
-
|
628 |
-
return [
|
629 |
-
new Service($api, ApiProvider::defaultProvider()),
|
630 |
-
new DocModel($docs)
|
631 |
-
];
|
632 |
-
}
|
633 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/S3ClientInterface.php
DELETED
@@ -1,322 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\AwsClientInterface;
|
5 |
-
use Aws\CommandInterface;
|
6 |
-
use Aws\ResultInterface;
|
7 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
8 |
-
use Psr\Http\Message\RequestInterface;
|
9 |
-
|
10 |
-
interface S3ClientInterface extends AwsClientInterface
|
11 |
-
{
|
12 |
-
/**
|
13 |
-
* Create a pre-signed URL for the given S3 command object.
|
14 |
-
*
|
15 |
-
* @param CommandInterface $command Command to create a pre-signed
|
16 |
-
* URL for.
|
17 |
-
* @param int|string|\DateTime $expires The time at which the URL should
|
18 |
-
* expire. This can be a Unix
|
19 |
-
* timestamp, a PHP DateTime object,
|
20 |
-
* or a string that can be evaluated
|
21 |
-
* by strtotime().
|
22 |
-
*
|
23 |
-
* @return RequestInterface
|
24 |
-
*/
|
25 |
-
public function createPresignedRequest(CommandInterface $command, $expires);
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Returns the URL to an object identified by its bucket and key.
|
29 |
-
*
|
30 |
-
* The URL returned by this method is not signed nor does it ensure the the
|
31 |
-
* bucket and key given to the method exist. If you need a signed URL, then
|
32 |
-
* use the {@see \Aws\S3\S3Client::createPresignedRequest} method and get
|
33 |
-
* the URI of the signed request.
|
34 |
-
*
|
35 |
-
* @param string $bucket The name of the bucket where the object is located
|
36 |
-
* @param string $key The key of the object
|
37 |
-
*
|
38 |
-
* @return string The URL to the object
|
39 |
-
*/
|
40 |
-
public function getObjectUrl($bucket, $key);
|
41 |
-
|
42 |
-
/**
|
43 |
-
* Determines whether or not a bucket exists by name.
|
44 |
-
*
|
45 |
-
* @param string $bucket The name of the bucket
|
46 |
-
*
|
47 |
-
* @return bool
|
48 |
-
*/
|
49 |
-
public function doesBucketExist($bucket);
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Determines whether or not an object exists by name.
|
53 |
-
*
|
54 |
-
* @param string $bucket The name of the bucket
|
55 |
-
* @param string $key The key of the object
|
56 |
-
* @param array $options Additional options available in the HeadObject
|
57 |
-
* operation (e.g., VersionId).
|
58 |
-
*
|
59 |
-
* @return bool
|
60 |
-
*/
|
61 |
-
public function doesObjectExist($bucket, $key, array $options = []);
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Register the Amazon S3 stream wrapper with this client instance.
|
65 |
-
*/
|
66 |
-
public function registerStreamWrapper();
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Deletes objects from Amazon S3 that match the result of a ListObjects
|
70 |
-
* operation. For example, this allows you to do things like delete all
|
71 |
-
* objects that match a specific key prefix.
|
72 |
-
*
|
73 |
-
* @param string $bucket Bucket that contains the object keys
|
74 |
-
* @param string $prefix Optionally delete only objects under this key prefix
|
75 |
-
* @param string $regex Delete only objects that match this regex
|
76 |
-
* @param array $options Aws\S3\BatchDelete options array.
|
77 |
-
*
|
78 |
-
* @see Aws\S3\S3Client::listObjects
|
79 |
-
* @throws \RuntimeException if no prefix and no regex is given
|
80 |
-
*/
|
81 |
-
public function deleteMatchingObjects(
|
82 |
-
$bucket,
|
83 |
-
$prefix = '',
|
84 |
-
$regex = '',
|
85 |
-
array $options = []
|
86 |
-
);
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Deletes objects from Amazon S3 that match the result of a ListObjects
|
90 |
-
* operation. For example, this allows you to do things like delete all
|
91 |
-
* objects that match a specific key prefix.
|
92 |
-
*
|
93 |
-
* @param string $bucket Bucket that contains the object keys
|
94 |
-
* @param string $prefix Optionally delete only objects under this key prefix
|
95 |
-
* @param string $regex Delete only objects that match this regex
|
96 |
-
* @param array $options Aws\S3\BatchDelete options array.
|
97 |
-
*
|
98 |
-
* @see Aws\S3\S3Client::listObjects
|
99 |
-
*
|
100 |
-
* @return PromiseInterface A promise that is settled when matching
|
101 |
-
* objects are deleted.
|
102 |
-
*/
|
103 |
-
public function deleteMatchingObjectsAsync(
|
104 |
-
$bucket,
|
105 |
-
$prefix = '',
|
106 |
-
$regex = '',
|
107 |
-
array $options = []
|
108 |
-
);
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Upload a file, stream, or string to a bucket.
|
112 |
-
*
|
113 |
-
* If the upload size exceeds the specified threshold, the upload will be
|
114 |
-
* performed using concurrent multipart uploads.
|
115 |
-
*
|
116 |
-
* The options array accepts the following options:
|
117 |
-
*
|
118 |
-
* - before_upload: (callable) Callback to invoke before any upload
|
119 |
-
* operations during the upload process. The callback should have a
|
120 |
-
* function signature like `function (Aws\Command $command) {...}`.
|
121 |
-
* - concurrency: (int, default=int(3)) Maximum number of concurrent
|
122 |
-
* `UploadPart` operations allowed during a multipart upload.
|
123 |
-
* - mup_threshold: (int, default=int(16777216)) The size, in bytes, allowed
|
124 |
-
* before the upload must be sent via a multipart upload. Default: 16 MB.
|
125 |
-
* - params: (array, default=array([])) Custom parameters to use with the
|
126 |
-
* upload. For single uploads, they must correspond to those used for the
|
127 |
-
* `PutObject` operation. For multipart uploads, they correspond to the
|
128 |
-
* parameters of the `CreateMultipartUpload` operation.
|
129 |
-
* - part_size: (int) Part size to use when doing a multipart upload.
|
130 |
-
*
|
131 |
-
* @param string $bucket Bucket to upload the object.
|
132 |
-
* @param string $key Key of the object.
|
133 |
-
* @param mixed $body Object data to upload. Can be a
|
134 |
-
* StreamInterface, PHP stream resource, or a
|
135 |
-
* string of data to upload.
|
136 |
-
* @param string $acl ACL to apply to the object (default: private).
|
137 |
-
* @param array $options Options used to configure the upload process.
|
138 |
-
*
|
139 |
-
* @see Aws\S3\MultipartUploader for more info about multipart uploads.
|
140 |
-
* @return ResultInterface Returns the result of the upload.
|
141 |
-
*/
|
142 |
-
public function upload(
|
143 |
-
$bucket,
|
144 |
-
$key,
|
145 |
-
$body,
|
146 |
-
$acl = 'private',
|
147 |
-
array $options = []
|
148 |
-
);
|
149 |
-
|
150 |
-
/**
|
151 |
-
* Upload a file, stream, or string to a bucket asynchronously.
|
152 |
-
*
|
153 |
-
* @param string $bucket Bucket to upload the object.
|
154 |
-
* @param string $key Key of the object.
|
155 |
-
* @param mixed $body Object data to upload. Can be a
|
156 |
-
* StreamInterface, PHP stream resource, or a
|
157 |
-
* string of data to upload.
|
158 |
-
* @param string $acl ACL to apply to the object (default: private).
|
159 |
-
* @param array $options Options used to configure the upload process.
|
160 |
-
*
|
161 |
-
* @see self::upload
|
162 |
-
* @return PromiseInterface Returns a promise that will be fulfilled
|
163 |
-
* with the result of the upload.
|
164 |
-
*/
|
165 |
-
public function uploadAsync(
|
166 |
-
$bucket,
|
167 |
-
$key,
|
168 |
-
$body,
|
169 |
-
$acl = 'private',
|
170 |
-
array $options = []
|
171 |
-
);
|
172 |
-
|
173 |
-
/**
|
174 |
-
* Copy an object of any size to a different location.
|
175 |
-
*
|
176 |
-
* If the upload size exceeds the maximum allowable size for direct S3
|
177 |
-
* copying, a multipart copy will be used.
|
178 |
-
*
|
179 |
-
* The options array accepts the following options:
|
180 |
-
*
|
181 |
-
* - before_upload: (callable) Callback to invoke before any upload
|
182 |
-
* operations during the upload process. The callback should have a
|
183 |
-
* function signature like `function (Aws\Command $command) {...}`.
|
184 |
-
* - concurrency: (int, default=int(5)) Maximum number of concurrent
|
185 |
-
* `UploadPart` operations allowed during a multipart upload.
|
186 |
-
* - params: (array, default=array([])) Custom parameters to use with the
|
187 |
-
* upload. For single uploads, they must correspond to those used for the
|
188 |
-
* `CopyObject` operation. For multipart uploads, they correspond to the
|
189 |
-
* parameters of the `CreateMultipartUpload` operation.
|
190 |
-
* - part_size: (int) Part size to use when doing a multipart upload.
|
191 |
-
*
|
192 |
-
* @param string $fromBucket Bucket where the copy source resides.
|
193 |
-
* @param string $fromKey Key of the copy source.
|
194 |
-
* @param string $destBucket Bucket to which to copy the object.
|
195 |
-
* @param string $destKey Key to which to copy the object.
|
196 |
-
* @param string $acl ACL to apply to the copy (default: private).
|
197 |
-
* @param array $options Options used to configure the upload process.
|
198 |
-
*
|
199 |
-
* @see Aws\S3\MultipartCopy for more info about multipart uploads.
|
200 |
-
* @return ResultInterface Returns the result of the copy.
|
201 |
-
*/
|
202 |
-
public function copy(
|
203 |
-
$fromBucket,
|
204 |
-
$fromKey,
|
205 |
-
$destBucket,
|
206 |
-
$destKey,
|
207 |
-
$acl = 'private',
|
208 |
-
array $options = []
|
209 |
-
);
|
210 |
-
|
211 |
-
/**
|
212 |
-
* Copy an object of any size to a different location asynchronously.
|
213 |
-
*
|
214 |
-
* @param string $fromBucket Bucket where the copy source resides.
|
215 |
-
* @param string $fromKey Key of the copy source.
|
216 |
-
* @param string $destBucket Bucket to which to copy the object.
|
217 |
-
* @param string $destKey Key to which to copy the object.
|
218 |
-
* @param string $acl ACL to apply to the copy (default: private).
|
219 |
-
* @param array $options Options used to configure the upload process.
|
220 |
-
*
|
221 |
-
* @see self::copy for more info about the parameters above.
|
222 |
-
* @return PromiseInterface Returns a promise that will be fulfilled
|
223 |
-
* with the result of the copy.
|
224 |
-
*/
|
225 |
-
public function copyAsync(
|
226 |
-
$fromBucket,
|
227 |
-
$fromKey,
|
228 |
-
$destBucket,
|
229 |
-
$destKey,
|
230 |
-
$acl = 'private',
|
231 |
-
array $options = []
|
232 |
-
);
|
233 |
-
|
234 |
-
/**
|
235 |
-
* Recursively uploads all files in a given directory to a given bucket.
|
236 |
-
*
|
237 |
-
* @param string $directory Full path to a directory to upload
|
238 |
-
* @param string $bucket Name of the bucket
|
239 |
-
* @param string $keyPrefix Virtual directory key prefix to add to each upload
|
240 |
-
* @param array $options Options available in Aws\S3\Transfer::__construct
|
241 |
-
*
|
242 |
-
* @see Aws\S3\Transfer for more options and customization
|
243 |
-
*/
|
244 |
-
public function uploadDirectory(
|
245 |
-
$directory,
|
246 |
-
$bucket,
|
247 |
-
$keyPrefix = null,
|
248 |
-
array $options = []
|
249 |
-
);
|
250 |
-
|
251 |
-
/**
|
252 |
-
* Recursively uploads all files in a given directory to a given bucket.
|
253 |
-
*
|
254 |
-
* @param string $directory Full path to a directory to upload
|
255 |
-
* @param string $bucket Name of the bucket
|
256 |
-
* @param string $keyPrefix Virtual directory key prefix to add to each upload
|
257 |
-
* @param array $options Options available in Aws\S3\Transfer::__construct
|
258 |
-
*
|
259 |
-
* @see Aws\S3\Transfer for more options and customization
|
260 |
-
*
|
261 |
-
* @return PromiseInterface A promise that is settled when the upload is
|
262 |
-
* complete.
|
263 |
-
*/
|
264 |
-
public function uploadDirectoryAsync(
|
265 |
-
$directory,
|
266 |
-
$bucket,
|
267 |
-
$keyPrefix = null,
|
268 |
-
array $options = []
|
269 |
-
);
|
270 |
-
|
271 |
-
/**
|
272 |
-
* Downloads a bucket to the local filesystem
|
273 |
-
*
|
274 |
-
* @param string $directory Directory to download to
|
275 |
-
* @param string $bucket Bucket to download from
|
276 |
-
* @param string $keyPrefix Only download objects that use this key prefix
|
277 |
-
* @param array $options Options available in Aws\S3\Transfer::__construct
|
278 |
-
*/
|
279 |
-
public function downloadBucket(
|
280 |
-
$directory,
|
281 |
-
$bucket,
|
282 |
-
$keyPrefix = '',
|
283 |
-
array $options = []
|
284 |
-
);
|
285 |
-
|
286 |
-
/**
|
287 |
-
* Downloads a bucket to the local filesystem
|
288 |
-
*
|
289 |
-
* @param string $directory Directory to download to
|
290 |
-
* @param string $bucket Bucket to download from
|
291 |
-
* @param string $keyPrefix Only download objects that use this key prefix
|
292 |
-
* @param array $options Options available in Aws\S3\Transfer::__construct
|
293 |
-
*
|
294 |
-
* @return PromiseInterface A promise that is settled when the download is
|
295 |
-
* complete.
|
296 |
-
*/
|
297 |
-
public function downloadBucketAsync(
|
298 |
-
$directory,
|
299 |
-
$bucket,
|
300 |
-
$keyPrefix = '',
|
301 |
-
array $options = []
|
302 |
-
);
|
303 |
-
|
304 |
-
/**
|
305 |
-
* Returns the region in which a given bucket is located.
|
306 |
-
*
|
307 |
-
* @param string $bucketName
|
308 |
-
*
|
309 |
-
* @return string
|
310 |
-
*/
|
311 |
-
public function determineBucketRegion($bucketName);
|
312 |
-
|
313 |
-
/**
|
314 |
-
* Returns a promise fulfilled with the region in which a given bucket is
|
315 |
-
* located.
|
316 |
-
*
|
317 |
-
* @param string $bucketName
|
318 |
-
*
|
319 |
-
* @return PromiseInterface
|
320 |
-
*/
|
321 |
-
public function determineBucketRegionAsync($bucketName);
|
322 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/S3EndpointMiddleware.php
DELETED
@@ -1,234 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\CommandInterface;
|
5 |
-
use Psr\Http\Message\RequestInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Used to update the URL used for S3 requests to support:
|
9 |
-
* S3 Accelerate, S3 DualStack or Both. It will build to
|
10 |
-
* host style paths unless specified, including for S3
|
11 |
-
* DualStack.
|
12 |
-
*
|
13 |
-
* IMPORTANT: this middleware must be added after the "build" step.
|
14 |
-
*
|
15 |
-
* @internal
|
16 |
-
*/
|
17 |
-
class S3EndpointMiddleware
|
18 |
-
{
|
19 |
-
private static $exclusions = [
|
20 |
-
'CreateBucket' => true,
|
21 |
-
'DeleteBucket' => true,
|
22 |
-
'ListBuckets' => true,
|
23 |
-
];
|
24 |
-
|
25 |
-
const NO_PATTERN = 0;
|
26 |
-
const DUALSTACK = 1;
|
27 |
-
const ACCELERATE = 2;
|
28 |
-
const ACCELERATE_DUALSTACK = 3;
|
29 |
-
const PATH_STYLE = 4;
|
30 |
-
const HOST_STYLE = 5;
|
31 |
-
|
32 |
-
/** @var bool */
|
33 |
-
private $accelerateByDefault;
|
34 |
-
/** @var bool */
|
35 |
-
private $dualStackByDefault;
|
36 |
-
/** @var bool */
|
37 |
-
private $pathStyleByDefault;
|
38 |
-
/** @var string */
|
39 |
-
private $region;
|
40 |
-
/** @var callable */
|
41 |
-
private $nextHandler;
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Create a middleware wrapper function
|
45 |
-
*
|
46 |
-
* @param string $region
|
47 |
-
* @param array $options
|
48 |
-
*
|
49 |
-
* @return callable
|
50 |
-
*/
|
51 |
-
public static function wrap($region, array $options)
|
52 |
-
{
|
53 |
-
return function (callable $handler) use ($region, $options) {
|
54 |
-
return new self($handler, $region, $options);
|
55 |
-
};
|
56 |
-
}
|
57 |
-
|
58 |
-
public function __construct(
|
59 |
-
callable $nextHandler,
|
60 |
-
$region,
|
61 |
-
array $options
|
62 |
-
) {
|
63 |
-
$this->pathStyleByDefault = isset($options['path_style'])
|
64 |
-
? (bool) $options['path_style'] : false;
|
65 |
-
$this->dualStackByDefault = isset($options['dual_stack'])
|
66 |
-
? (bool) $options['dual_stack'] : false;
|
67 |
-
$this->accelerateByDefault = isset($options['accelerate'])
|
68 |
-
? (bool) $options['accelerate'] : false;
|
69 |
-
$this->region = (string) $region;
|
70 |
-
$this->nextHandler = $nextHandler;
|
71 |
-
}
|
72 |
-
|
73 |
-
public function __invoke(CommandInterface $command, RequestInterface $request)
|
74 |
-
{
|
75 |
-
switch ($this->endpointPatternDecider($command, $request)) {
|
76 |
-
case self::HOST_STYLE:
|
77 |
-
$request = $this->applyHostStyleEndpoint($command, $request);
|
78 |
-
break;
|
79 |
-
case self::NO_PATTERN:
|
80 |
-
case self::PATH_STYLE:
|
81 |
-
break;
|
82 |
-
case self::DUALSTACK:
|
83 |
-
$request = $this->applyDualStackEndpoint($command, $request);
|
84 |
-
break;
|
85 |
-
case self::ACCELERATE:
|
86 |
-
$request = $this->applyAccelerateEndpoint(
|
87 |
-
$command,
|
88 |
-
$request,
|
89 |
-
's3-accelerate'
|
90 |
-
);
|
91 |
-
break;
|
92 |
-
case self::ACCELERATE_DUALSTACK:
|
93 |
-
$request = $this->applyAccelerateEndpoint(
|
94 |
-
$command,
|
95 |
-
$request,
|
96 |
-
's3-accelerate.dualstack'
|
97 |
-
);
|
98 |
-
break;
|
99 |
-
}
|
100 |
-
|
101 |
-
$nextHandler = $this->nextHandler;
|
102 |
-
return $nextHandler($command, $request);
|
103 |
-
}
|
104 |
-
|
105 |
-
private static function isRequestHostStyleCompatible(
|
106 |
-
CommandInterface $command,
|
107 |
-
RequestInterface $request
|
108 |
-
) {
|
109 |
-
return S3Client::isBucketDnsCompatible($command['Bucket'])
|
110 |
-
&& (
|
111 |
-
$request->getUri()->getScheme() === 'http'
|
112 |
-
|| strpos($command['Bucket'], '.') === false
|
113 |
-
);
|
114 |
-
}
|
115 |
-
|
116 |
-
private function endpointPatternDecider(
|
117 |
-
CommandInterface $command,
|
118 |
-
RequestInterface $request
|
119 |
-
) {
|
120 |
-
$accelerate = isset($command['@use_accelerate_endpoint'])
|
121 |
-
? $command['@use_accelerate_endpoint'] : $this->accelerateByDefault;
|
122 |
-
$dualStack = isset($command['@use_dual_stack_endpoint'])
|
123 |
-
? $command['@use_dual_stack_endpoint'] : $this->dualStackByDefault;
|
124 |
-
$pathStyle = isset($command['@use_path_style_endpoint'])
|
125 |
-
? $command['@use_path_style_endpoint'] : $this->pathStyleByDefault;
|
126 |
-
|
127 |
-
if ($accelerate && $dualStack) {
|
128 |
-
// When try to enable both for operations excluded from s3-accelerate,
|
129 |
-
// only dualstack endpoints will be enabled.
|
130 |
-
return $this->canAccelerate($command)
|
131 |
-
? self::ACCELERATE_DUALSTACK
|
132 |
-
: self::DUALSTACK;
|
133 |
-
}
|
134 |
-
|
135 |
-
if ($accelerate && $this->canAccelerate($command)) {
|
136 |
-
return self::ACCELERATE;
|
137 |
-
}
|
138 |
-
|
139 |
-
if ($dualStack) {
|
140 |
-
return self::DUALSTACK;
|
141 |
-
}
|
142 |
-
|
143 |
-
if (!$pathStyle
|
144 |
-
&& self::isRequestHostStyleCompatible($command, $request)
|
145 |
-
) {
|
146 |
-
return self::HOST_STYLE;
|
147 |
-
}
|
148 |
-
|
149 |
-
return self::PATH_STYLE;
|
150 |
-
}
|
151 |
-
|
152 |
-
private function canAccelerate(CommandInterface $command)
|
153 |
-
{
|
154 |
-
return empty(self::$exclusions[$command->getName()])
|
155 |
-
&& S3Client::isBucketDnsCompatible($command['Bucket']);
|
156 |
-
}
|
157 |
-
|
158 |
-
private function getBucketStyleHost(CommandInterface $command, $host)
|
159 |
-
{
|
160 |
-
// For operations on the base host (e.g. ListBuckets)
|
161 |
-
if (!isset($command['Bucket'])) {
|
162 |
-
return $host;
|
163 |
-
}
|
164 |
-
|
165 |
-
return "{$command['Bucket']}.{$host}";
|
166 |
-
}
|
167 |
-
|
168 |
-
private function applyHostStyleEndpoint(
|
169 |
-
CommandInterface $command,
|
170 |
-
RequestInterface $request
|
171 |
-
) {
|
172 |
-
$uri = $request->getUri();
|
173 |
-
$request = $request->withUri(
|
174 |
-
$uri->withHost($this->getBucketStyleHost(
|
175 |
-
$command,
|
176 |
-
$uri->getHost()
|
177 |
-
))
|
178 |
-
->withPath($this->getBucketlessPath(
|
179 |
-
$uri->getPath(),
|
180 |
-
$command
|
181 |
-
))
|
182 |
-
);
|
183 |
-
return $request;
|
184 |
-
}
|
185 |
-
|
186 |
-
private function applyDualStackEndpoint(
|
187 |
-
CommandInterface $command,
|
188 |
-
RequestInterface $request
|
189 |
-
) {
|
190 |
-
$request = $request->withUri(
|
191 |
-
$request->getUri()
|
192 |
-
->withHost($this->getDualStackHost())
|
193 |
-
);
|
194 |
-
if (empty($command['@use_path_style_endpoint'])
|
195 |
-
&& !$this->pathStyleByDefault
|
196 |
-
&& self::isRequestHostStyleCompatible($command, $request)
|
197 |
-
) {
|
198 |
-
$request = $this->applyHostStyleEndpoint($command, $request);
|
199 |
-
}
|
200 |
-
return $request;
|
201 |
-
}
|
202 |
-
|
203 |
-
private function getDualStackHost()
|
204 |
-
{
|
205 |
-
return "s3.dualstack.{$this->region}.amazonaws.com";
|
206 |
-
}
|
207 |
-
|
208 |
-
private function applyAccelerateEndpoint(
|
209 |
-
CommandInterface $command,
|
210 |
-
RequestInterface $request,
|
211 |
-
$pattern
|
212 |
-
) {
|
213 |
-
$request = $request->withUri(
|
214 |
-
$request->getUri()
|
215 |
-
->withHost($this->getAccelerateHost($command, $pattern))
|
216 |
-
->withPath($this->getBucketlessPath(
|
217 |
-
$request->getUri()->getPath(),
|
218 |
-
$command
|
219 |
-
))
|
220 |
-
);
|
221 |
-
return $request;
|
222 |
-
}
|
223 |
-
|
224 |
-
private function getAccelerateHost(CommandInterface $command, $pattern)
|
225 |
-
{
|
226 |
-
return "{$command['Bucket']}.{$pattern}.amazonaws.com";
|
227 |
-
}
|
228 |
-
|
229 |
-
private function getBucketlessPath($path, CommandInterface $command)
|
230 |
-
{
|
231 |
-
$pattern = '/^\\/' . preg_quote($command['Bucket'], '/') . '/';
|
232 |
-
return preg_replace($pattern, '', $path) ?: '/';
|
233 |
-
}
|
234 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/S3MultiRegionClient.php
DELETED
@@ -1,339 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\CacheInterface;
|
5 |
-
use Aws\CommandInterface;
|
6 |
-
use Aws\LruArrayCache;
|
7 |
-
use Aws\MultiRegionClient as BaseClient;
|
8 |
-
use Aws\Exception\AwsException;
|
9 |
-
use Aws\S3\Exception\PermanentRedirectException;
|
10 |
-
use GuzzleHttp\Promise;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* **Amazon Simple Storage Service** multi-region client.
|
14 |
-
*
|
15 |
-
* @method \Aws\Result abortMultipartUpload(array $args = [])
|
16 |
-
* @method \GuzzleHttp\Promise\Promise abortMultipartUploadAsync(array $args = [])
|
17 |
-
* @method \Aws\Result completeMultipartUpload(array $args = [])
|
18 |
-
* @method \GuzzleHttp\Promise\Promise completeMultipartUploadAsync(array $args = [])
|
19 |
-
* @method \Aws\Result copyObject(array $args = [])
|
20 |
-
* @method \GuzzleHttp\Promise\Promise copyObjectAsync(array $args = [])
|
21 |
-
* @method \Aws\Result createBucket(array $args = [])
|
22 |
-
* @method \GuzzleHttp\Promise\Promise createBucketAsync(array $args = [])
|
23 |
-
* @method \Aws\Result createMultipartUpload(array $args = [])
|
24 |
-
* @method \GuzzleHttp\Promise\Promise createMultipartUploadAsync(array $args = [])
|
25 |
-
* @method \Aws\Result deleteBucket(array $args = [])
|
26 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketAsync(array $args = [])
|
27 |
-
* @method \Aws\Result deleteBucketAnalyticsConfiguration(array $args = [])
|
28 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketAnalyticsConfigurationAsync(array $args = [])
|
29 |
-
* @method \Aws\Result deleteBucketCors(array $args = [])
|
30 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketCorsAsync(array $args = [])
|
31 |
-
* @method \Aws\Result deleteBucketEncryption(array $args = [])
|
32 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketEncryptionAsync(array $args = [])
|
33 |
-
* @method \Aws\Result deleteBucketInventoryConfiguration(array $args = [])
|
34 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketInventoryConfigurationAsync(array $args = [])
|
35 |
-
* @method \Aws\Result deleteBucketLifecycle(array $args = [])
|
36 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketLifecycleAsync(array $args = [])
|
37 |
-
* @method \Aws\Result deleteBucketMetricsConfiguration(array $args = [])
|
38 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketMetricsConfigurationAsync(array $args = [])
|
39 |
-
* @method \Aws\Result deleteBucketPolicy(array $args = [])
|
40 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketPolicyAsync(array $args = [])
|
41 |
-
* @method \Aws\Result deleteBucketReplication(array $args = [])
|
42 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketReplicationAsync(array $args = [])
|
43 |
-
* @method \Aws\Result deleteBucketTagging(array $args = [])
|
44 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketTaggingAsync(array $args = [])
|
45 |
-
* @method \Aws\Result deleteBucketWebsite(array $args = [])
|
46 |
-
* @method \GuzzleHttp\Promise\Promise deleteBucketWebsiteAsync(array $args = [])
|
47 |
-
* @method \Aws\Result deleteObject(array $args = [])
|
48 |
-
* @method \GuzzleHttp\Promise\Promise deleteObjectAsync(array $args = [])
|
49 |
-
* @method \Aws\Result deleteObjectTagging(array $args = [])
|
50 |
-
* @method \GuzzleHttp\Promise\Promise deleteObjectTaggingAsync(array $args = [])
|
51 |
-
* @method \Aws\Result deleteObjects(array $args = [])
|
52 |
-
* @method \GuzzleHttp\Promise\Promise deleteObjectsAsync(array $args = [])
|
53 |
-
* @method \Aws\Result deletePublicAccessBlock(array $args = [])
|
54 |
-
* @method \GuzzleHttp\Promise\Promise deletePublicAccessBlockAsync(array $args = [])
|
55 |
-
* @method \Aws\Result getBucketAccelerateConfiguration(array $args = [])
|
56 |
-
* @method \GuzzleHttp\Promise\Promise getBucketAccelerateConfigurationAsync(array $args = [])
|
57 |
-
* @method \Aws\Result getBucketAcl(array $args = [])
|
58 |
-
* @method \GuzzleHttp\Promise\Promise getBucketAclAsync(array $args = [])
|
59 |
-
* @method \Aws\Result getBucketAnalyticsConfiguration(array $args = [])
|
60 |
-
* @method \GuzzleHttp\Promise\Promise getBucketAnalyticsConfigurationAsync(array $args = [])
|
61 |
-
* @method \Aws\Result getBucketCors(array $args = [])
|
62 |
-
* @method \GuzzleHttp\Promise\Promise getBucketCorsAsync(array $args = [])
|
63 |
-
* @method \Aws\Result getBucketEncryption(array $args = [])
|
64 |
-
* @method \GuzzleHttp\Promise\Promise getBucketEncryptionAsync(array $args = [])
|
65 |
-
* @method \Aws\Result getBucketInventoryConfiguration(array $args = [])
|
66 |
-
* @method \GuzzleHttp\Promise\Promise getBucketInventoryConfigurationAsync(array $args = [])
|
67 |
-
* @method \Aws\Result getBucketLifecycle(array $args = [])
|
68 |
-
* @method \GuzzleHttp\Promise\Promise getBucketLifecycleAsync(array $args = [])
|
69 |
-
* @method \Aws\Result getBucketLifecycleConfiguration(array $args = [])
|
70 |
-
* @method \GuzzleHttp\Promise\Promise getBucketLifecycleConfigurationAsync(array $args = [])
|
71 |
-
* @method \Aws\Result getBucketLocation(array $args = [])
|
72 |
-
* @method \GuzzleHttp\Promise\Promise getBucketLocationAsync(array $args = [])
|
73 |
-
* @method \Aws\Result getBucketLogging(array $args = [])
|
74 |
-
* @method \GuzzleHttp\Promise\Promise getBucketLoggingAsync(array $args = [])
|
75 |
-
* @method \Aws\Result getBucketMetricsConfiguration(array $args = [])
|
76 |
-
* @method \GuzzleHttp\Promise\Promise getBucketMetricsConfigurationAsync(array $args = [])
|
77 |
-
* @method \Aws\Result getBucketNotification(array $args = [])
|
78 |
-
* @method \GuzzleHttp\Promise\Promise getBucketNotificationAsync(array $args = [])
|
79 |
-
* @method \Aws\Result getBucketNotificationConfiguration(array $args = [])
|
80 |
-
* @method \GuzzleHttp\Promise\Promise getBucketNotificationConfigurationAsync(array $args = [])
|
81 |
-
* @method \Aws\Result getBucketPolicy(array $args = [])
|
82 |
-
* @method \GuzzleHttp\Promise\Promise getBucketPolicyAsync(array $args = [])
|
83 |
-
* @method \Aws\Result getBucketPolicyStatus(array $args = [])
|
84 |
-
* @method \GuzzleHttp\Promise\Promise getBucketPolicyStatusAsync(array $args = [])
|
85 |
-
* @method \Aws\Result getBucketReplication(array $args = [])
|
86 |
-
* @method \GuzzleHttp\Promise\Promise getBucketReplicationAsync(array $args = [])
|
87 |
-
* @method \Aws\Result getBucketRequestPayment(array $args = [])
|
88 |
-
* @method \GuzzleHttp\Promise\Promise getBucketRequestPaymentAsync(array $args = [])
|
89 |
-
* @method \Aws\Result getBucketTagging(array $args = [])
|
90 |
-
* @method \GuzzleHttp\Promise\Promise getBucketTaggingAsync(array $args = [])
|
91 |
-
* @method \Aws\Result getBucketVersioning(array $args = [])
|
92 |
-
* @method \GuzzleHttp\Promise\Promise getBucketVersioningAsync(array $args = [])
|
93 |
-
* @method \Aws\Result getBucketWebsite(array $args = [])
|
94 |
-
* @method \GuzzleHttp\Promise\Promise getBucketWebsiteAsync(array $args = [])
|
95 |
-
* @method \Aws\Result getObject(array $args = [])
|
96 |
-
* @method \GuzzleHttp\Promise\Promise getObjectAsync(array $args = [])
|
97 |
-
* @method \Aws\Result getObjectAcl(array $args = [])
|
98 |
-
* @method \GuzzleHttp\Promise\Promise getObjectAclAsync(array $args = [])
|
99 |
-
* @method \Aws\Result getObjectLegalHold(array $args = [])
|
100 |
-
* @method \GuzzleHttp\Promise\Promise getObjectLegalHoldAsync(array $args = [])
|
101 |
-
* @method \Aws\Result getObjectLockConfiguration(array $args = [])
|
102 |
-
* @method \GuzzleHttp\Promise\Promise getObjectLockConfigurationAsync(array $args = [])
|
103 |
-
* @method \Aws\Result getObjectRetention(array $args = [])
|
104 |
-
* @method \GuzzleHttp\Promise\Promise getObjectRetentionAsync(array $args = [])
|
105 |
-
* @method \Aws\Result getObjectTagging(array $args = [])
|
106 |
-
* @method \GuzzleHttp\Promise\Promise getObjectTaggingAsync(array $args = [])
|
107 |
-
* @method \Aws\Result getObjectTorrent(array $args = [])
|
108 |
-
* @method \GuzzleHttp\Promise\Promise getObjectTorrentAsync(array $args = [])
|
109 |
-
* @method \Aws\Result getPublicAccessBlock(array $args = [])
|
110 |
-
* @method \GuzzleHttp\Promise\Promise getPublicAccessBlockAsync(array $args = [])
|
111 |
-
* @method \Aws\Result headBucket(array $args = [])
|
112 |
-
* @method \GuzzleHttp\Promise\Promise headBucketAsync(array $args = [])
|
113 |
-
* @method \Aws\Result headObject(array $args = [])
|
114 |
-
* @method \GuzzleHttp\Promise\Promise headObjectAsync(array $args = [])
|
115 |
-
* @method \Aws\Result listBucketAnalyticsConfigurations(array $args = [])
|
116 |
-
* @method \GuzzleHttp\Promise\Promise listBucketAnalyticsConfigurationsAsync(array $args = [])
|
117 |
-
* @method \Aws\Result listBucketInventoryConfigurations(array $args = [])
|
118 |
-
* @method \GuzzleHttp\Promise\Promise listBucketInventoryConfigurationsAsync(array $args = [])
|
119 |
-
* @method \Aws\Result listBucketMetricsConfigurations(array $args = [])
|
120 |
-
* @method \GuzzleHttp\Promise\Promise listBucketMetricsConfigurationsAsync(array $args = [])
|
121 |
-
* @method \Aws\Result listBuckets(array $args = [])
|
122 |
-
* @method \GuzzleHttp\Promise\Promise listBucketsAsync(array $args = [])
|
123 |
-
* @method \Aws\Result listMultipartUploads(array $args = [])
|
124 |
-
* @method \GuzzleHttp\Promise\Promise listMultipartUploadsAsync(array $args = [])
|
125 |
-
* @method \Aws\Result listObjectVersions(array $args = [])
|
126 |
-
* @method \GuzzleHttp\Promise\Promise listObjectVersionsAsync(array $args = [])
|
127 |
-
* @method \Aws\Result listObjects(array $args = [])
|
128 |
-
* @method \GuzzleHttp\Promise\Promise listObjectsAsync(array $args = [])
|
129 |
-
* @method \Aws\Result listObjectsV2(array $args = [])
|
130 |
-
* @method \GuzzleHttp\Promise\Promise listObjectsV2Async(array $args = [])
|
131 |
-
* @method \Aws\Result listParts(array $args = [])
|
132 |
-
* @method \GuzzleHttp\Promise\Promise listPartsAsync(array $args = [])
|
133 |
-
* @method \Aws\Result putBucketAccelerateConfiguration(array $args = [])
|
134 |
-
* @method \GuzzleHttp\Promise\Promise putBucketAccelerateConfigurationAsync(array $args = [])
|
135 |
-
* @method \Aws\Result putBucketAcl(array $args = [])
|
136 |
-
* @method \GuzzleHttp\Promise\Promise putBucketAclAsync(array $args = [])
|
137 |
-
* @method \Aws\Result putBucketAnalyticsConfiguration(array $args = [])
|
138 |
-
* @method \GuzzleHttp\Promise\Promise putBucketAnalyticsConfigurationAsync(array $args = [])
|
139 |
-
* @method \Aws\Result putBucketCors(array $args = [])
|
140 |
-
* @method \GuzzleHttp\Promise\Promise putBucketCorsAsync(array $args = [])
|
141 |
-
* @method \Aws\Result putBucketEncryption(array $args = [])
|
142 |
-
* @method \GuzzleHttp\Promise\Promise putBucketEncryptionAsync(array $args = [])
|
143 |
-
* @method \Aws\Result putBucketInventoryConfiguration(array $args = [])
|
144 |
-
* @method \GuzzleHttp\Promise\Promise putBucketInventoryConfigurationAsync(array $args = [])
|
145 |
-
* @method \Aws\Result putBucketLifecycle(array $args = [])
|
146 |
-
* @method \GuzzleHttp\Promise\Promise putBucketLifecycleAsync(array $args = [])
|
147 |
-
* @method \Aws\Result putBucketLifecycleConfiguration(array $args = [])
|
148 |
-
* @method \GuzzleHttp\Promise\Promise putBucketLifecycleConfigurationAsync(array $args = [])
|
149 |
-
* @method \Aws\Result putBucketLogging(array $args = [])
|
150 |
-
* @method \GuzzleHttp\Promise\Promise putBucketLoggingAsync(array $args = [])
|
151 |
-
* @method \Aws\Result putBucketMetricsConfiguration(array $args = [])
|
152 |
-
* @method \GuzzleHttp\Promise\Promise putBucketMetricsConfigurationAsync(array $args = [])
|
153 |
-
* @method \Aws\Result putBucketNotification(array $args = [])
|
154 |
-
* @method \GuzzleHttp\Promise\Promise putBucketNotificationAsync(array $args = [])
|
155 |
-
* @method \Aws\Result putBucketNotificationConfiguration(array $args = [])
|
156 |
-
* @method \GuzzleHttp\Promise\Promise putBucketNotificationConfigurationAsync(array $args = [])
|
157 |
-
* @method \Aws\Result putBucketPolicy(array $args = [])
|
158 |
-
* @method \GuzzleHttp\Promise\Promise putBucketPolicyAsync(array $args = [])
|
159 |
-
* @method \Aws\Result putBucketReplication(array $args = [])
|
160 |
-
* @method \GuzzleHttp\Promise\Promise putBucketReplicationAsync(array $args = [])
|
161 |
-
* @method \Aws\Result putBucketRequestPayment(array $args = [])
|
162 |
-
* @method \GuzzleHttp\Promise\Promise putBucketRequestPaymentAsync(array $args = [])
|
163 |
-
* @method \Aws\Result putBucketTagging(array $args = [])
|
164 |
-
* @method \GuzzleHttp\Promise\Promise putBucketTaggingAsync(array $args = [])
|
165 |
-
* @method \Aws\Result putBucketVersioning(array $args = [])
|
166 |
-
* @method \GuzzleHttp\Promise\Promise putBucketVersioningAsync(array $args = [])
|
167 |
-
* @method \Aws\Result putBucketWebsite(array $args = [])
|
168 |
-
* @method \GuzzleHttp\Promise\Promise putBucketWebsiteAsync(array $args = [])
|
169 |
-
* @method \Aws\Result putObject(array $args = [])
|
170 |
-
* @method \GuzzleHttp\Promise\Promise putObjectAsync(array $args = [])
|
171 |
-
* @method \Aws\Result putObjectAcl(array $args = [])
|
172 |
-
* @method \GuzzleHttp\Promise\Promise putObjectAclAsync(array $args = [])
|
173 |
-
* @method \Aws\Result putObjectLegalHold(array $args = [])
|
174 |
-
* @method \GuzzleHttp\Promise\Promise putObjectLegalHoldAsync(array $args = [])
|
175 |
-
* @method \Aws\Result putObjectLockConfiguration(array $args = [])
|
176 |
-
* @method \GuzzleHttp\Promise\Promise putObjectLockConfigurationAsync(array $args = [])
|
177 |
-
* @method \Aws\Result putObjectRetention(array $args = [])
|
178 |
-
* @method \GuzzleHttp\Promise\Promise putObjectRetentionAsync(array $args = [])
|
179 |
-
* @method \Aws\Result putObjectTagging(array $args = [])
|
180 |
-
* @method \GuzzleHttp\Promise\Promise putObjectTaggingAsync(array $args = [])
|
181 |
-
* @method \Aws\Result putPublicAccessBlock(array $args = [])
|
182 |
-
* @method \GuzzleHttp\Promise\Promise putPublicAccessBlockAsync(array $args = [])
|
183 |
-
* @method \Aws\Result restoreObject(array $args = [])
|
184 |
-
* @method \GuzzleHttp\Promise\Promise restoreObjectAsync(array $args = [])
|
185 |
-
* @method \Aws\Result selectObjectContent(array $args = [])
|
186 |
-
* @method \GuzzleHttp\Promise\Promise selectObjectContentAsync(array $args = [])
|
187 |
-
* @method \Aws\Result uploadPart(array $args = [])
|
188 |
-
* @method \GuzzleHttp\Promise\Promise uploadPartAsync(array $args = [])
|
189 |
-
* @method \Aws\Result uploadPartCopy(array $args = [])
|
190 |
-
* @method \GuzzleHttp\Promise\Promise uploadPartCopyAsync(array $args = [])
|
191 |
-
*/
|
192 |
-
class S3MultiRegionClient extends BaseClient implements S3ClientInterface
|
193 |
-
{
|
194 |
-
use S3ClientTrait;
|
195 |
-
|
196 |
-
/** @var CacheInterface */
|
197 |
-
private $cache;
|
198 |
-
|
199 |
-
public static function getArguments()
|
200 |
-
{
|
201 |
-
$args = parent::getArguments();
|
202 |
-
$regionDef = $args['region'] + ['default' => function (array &$args) {
|
203 |
-
$availableRegions = array_keys($args['partition']['regions']);
|
204 |
-
return end($availableRegions);
|
205 |
-
}];
|
206 |
-
unset($args['region']);
|
207 |
-
|
208 |
-
return $args + [
|
209 |
-
'bucket_region_cache' => [
|
210 |
-
'type' => 'config',
|
211 |
-
'valid' => [CacheInterface::class],
|
212 |
-
'doc' => 'Cache of regions in which given buckets are located.',
|
213 |
-
'default' => function () { return new LruArrayCache; },
|
214 |
-
],
|
215 |
-
'region' => $regionDef,
|
216 |
-
];
|
217 |
-
}
|
218 |
-
|
219 |
-
public function __construct(array $args)
|
220 |
-
{
|
221 |
-
parent::__construct($args);
|
222 |
-
$this->cache = $this->getConfig('bucket_region_cache');
|
223 |
-
|
224 |
-
$this->getHandlerList()->prependInit(
|
225 |
-
$this->determineRegionMiddleware(),
|
226 |
-
'determine_region'
|
227 |
-
);
|
228 |
-
}
|
229 |
-
|
230 |
-
private function determineRegionMiddleware()
|
231 |
-
{
|
232 |
-
return function (callable $handler) {
|
233 |
-
return function (CommandInterface $command) use ($handler) {
|
234 |
-
$cacheKey = $this->getCacheKey($command['Bucket']);
|
235 |
-
if (
|
236 |
-
empty($command['@region']) &&
|
237 |
-
$region = $this->cache->get($cacheKey)
|
238 |
-
) {
|
239 |
-
$command['@region'] = $region;
|
240 |
-
}
|
241 |
-
|
242 |
-
return Promise\coroutine(function () use (
|
243 |
-
$handler,
|
244 |
-
$command,
|
245 |
-
$cacheKey
|
246 |
-
) {
|
247 |
-
try {
|
248 |
-
yield $handler($command);
|
249 |
-
} catch (PermanentRedirectException $e) {
|
250 |
-
if (empty($command['Bucket'])) {
|
251 |
-
throw $e;
|
252 |
-
}
|
253 |
-
$result = $e->getResult();
|
254 |
-
$region = null;
|
255 |
-
if (isset($result['@metadata']['headers']['x-amz-bucket-region'])) {
|
256 |
-
$region = $result['@metadata']['headers']['x-amz-bucket-region'];
|
257 |
-
$this->cache->set($cacheKey, $region);
|
258 |
-
} else {
|
259 |
-
$region = (yield $this->determineBucketRegionAsync(
|
260 |
-
$command['Bucket']
|
261 |
-
));
|
262 |
-
}
|
263 |
-
|
264 |
-
$command['@region'] = $region;
|
265 |
-
yield $handler($command);
|
266 |
-
} catch (AwsException $e) {
|
267 |
-
if ($e->getAwsErrorCode() === 'AuthorizationHeaderMalformed') {
|
268 |
-
$region = $this->determineBucketRegionFromExceptionBody(
|
269 |
-
$e->getResponse()
|
270 |
-
);
|
271 |
-
if (!empty($region)) {
|
272 |
-
$this->cache->set($cacheKey, $region);
|
273 |
-
|
274 |
-
$command['@region'] = $region;
|
275 |
-
yield $handler($command);
|
276 |
-
} else {
|
277 |
-
throw $e;
|
278 |
-
}
|
279 |
-
} else {
|
280 |
-
throw $e;
|
281 |
-
}
|
282 |
-
}
|
283 |
-
});
|
284 |
-
};
|
285 |
-
};
|
286 |
-
}
|
287 |
-
|
288 |
-
public function createPresignedRequest(CommandInterface $command, $expires)
|
289 |
-
{
|
290 |
-
if (empty($command['Bucket'])) {
|
291 |
-
throw new \InvalidArgumentException('The S3\\MultiRegionClient'
|
292 |
-
. ' cannot create presigned requests for commands without a'
|
293 |
-
. ' specified bucket.');
|
294 |
-
}
|
295 |
-
|
296 |
-
/** @var S3ClientInterface $client */
|
297 |
-
$client = $this->getClientFromPool(
|
298 |
-
$this->determineBucketRegion($command['Bucket'])
|
299 |
-
);
|
300 |
-
return $client->createPresignedRequest(
|
301 |
-
$client->getCommand($command->getName(), $command->toArray()),
|
302 |
-
$expires
|
303 |
-
);
|
304 |
-
}
|
305 |
-
|
306 |
-
public function getObjectUrl($bucket, $key)
|
307 |
-
{
|
308 |
-
/** @var S3Client $regionalClient */
|
309 |
-
$regionalClient = $this->getClientFromPool(
|
310 |
-
$this->determineBucketRegion($bucket)
|
311 |
-
);
|
312 |
-
|
313 |
-
return $regionalClient->getObjectUrl($bucket, $key);
|
314 |
-
}
|
315 |
-
|
316 |
-
public function determineBucketRegionAsync($bucketName)
|
317 |
-
{
|
318 |
-
$cacheKey = $this->getCacheKey($bucketName);
|
319 |
-
if ($cached = $this->cache->get($cacheKey)) {
|
320 |
-
return Promise\promise_for($cached);
|
321 |
-
}
|
322 |
-
|
323 |
-
/** @var S3ClientInterface $regionalClient */
|
324 |
-
$regionalClient = $this->getClientFromPool();
|
325 |
-
return $regionalClient->determineBucketRegionAsync($bucketName)
|
326 |
-
->then(
|
327 |
-
function ($region) use ($cacheKey) {
|
328 |
-
$this->cache->set($cacheKey, $region);
|
329 |
-
|
330 |
-
return $region;
|
331 |
-
}
|
332 |
-
);
|
333 |
-
}
|
334 |
-
|
335 |
-
private function getCacheKey($bucketName)
|
336 |
-
{
|
337 |
-
return "aws:s3:{$bucketName}:location";
|
338 |
-
}
|
339 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/S3UriParser.php
DELETED
@@ -1,133 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use GuzzleHttp\Psr7;
|
5 |
-
use Psr\Http\Message\UriInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Extracts a region, bucket, key, and and if a URI is in path-style
|
9 |
-
*/
|
10 |
-
class S3UriParser
|
11 |
-
{
|
12 |
-
private $pattern = '/^(.+\\.)?s3[.-]([A-Za-z0-9-]+)\\./';
|
13 |
-
private $streamWrapperScheme = 's3';
|
14 |
-
|
15 |
-
private static $defaultResult = [
|
16 |
-
'path_style' => true,
|
17 |
-
'bucket' => null,
|
18 |
-
'key' => null,
|
19 |
-
'region' => null
|
20 |
-
];
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Parses a URL or S3 StreamWrapper Uri (s3://) into an associative array
|
24 |
-
* of Amazon S3 data including:
|
25 |
-
*
|
26 |
-
* - bucket: The Amazon S3 bucket (null if none)
|
27 |
-
* - key: The Amazon S3 key (null if none)
|
28 |
-
* - path_style: Set to true if using path style, or false if not
|
29 |
-
* - region: Set to a string if a non-class endpoint is used or null.
|
30 |
-
*
|
31 |
-
* @param string|UriInterface $uri
|
32 |
-
*
|
33 |
-
* @return array
|
34 |
-
* @throws \InvalidArgumentException
|
35 |
-
*/
|
36 |
-
public function parse($uri)
|
37 |
-
{
|
38 |
-
$url = Psr7\uri_for($uri);
|
39 |
-
|
40 |
-
if ($url->getScheme() == $this->streamWrapperScheme) {
|
41 |
-
return $this->parseStreamWrapper($url);
|
42 |
-
}
|
43 |
-
|
44 |
-
if (!$url->getHost()) {
|
45 |
-
throw new \InvalidArgumentException('No hostname found in URI: '
|
46 |
-
. $uri);
|
47 |
-
}
|
48 |
-
|
49 |
-
if (!preg_match($this->pattern, $url->getHost(), $matches)) {
|
50 |
-
return $this->parseCustomEndpoint($url);
|
51 |
-
}
|
52 |
-
|
53 |
-
// Parse the URI based on the matched format (path / virtual)
|
54 |
-
$result = empty($matches[1])
|
55 |
-
? $this->parsePathStyle($url)
|
56 |
-
: $this->parseVirtualHosted($url, $matches);
|
57 |
-
|
58 |
-
// Add the region if one was found and not the classic endpoint
|
59 |
-
$result['region'] = $matches[2] == 'amazonaws' ? null : $matches[2];
|
60 |
-
|
61 |
-
return $result;
|
62 |
-
}
|
63 |
-
|
64 |
-
private function parseStreamWrapper(UriInterface $url)
|
65 |
-
{
|
66 |
-
$result = self::$defaultResult;
|
67 |
-
$result['path_style'] = false;
|
68 |
-
|
69 |
-
$result['bucket'] = $url->getHost();
|
70 |
-
if ($url->getPath()) {
|
71 |
-
$key = ltrim($url->getPath(), '/ ');
|
72 |
-
if (!empty($key)) {
|
73 |
-
$result['key'] = $key;
|
74 |
-
}
|
75 |
-
}
|
76 |
-
|
77 |
-
return $result;
|
78 |
-
}
|
79 |
-
|
80 |
-
private function parseCustomEndpoint(UriInterface $url)
|
81 |
-
{
|
82 |
-
$result = self::$defaultResult;
|
83 |
-
$path = ltrim($url->getPath(), '/ ');
|
84 |
-
$segments = explode('/', $path, 2);
|
85 |
-
|
86 |
-
if (isset($segments[0])) {
|
87 |
-
$result['bucket'] = $segments[0];
|
88 |
-
if (isset($segments[1])) {
|
89 |
-
$result['key'] = $segments[1];
|
90 |
-
}
|
91 |
-
}
|
92 |
-
|
93 |
-
return $result;
|
94 |
-
}
|
95 |
-
|
96 |
-
private function parsePathStyle(UriInterface $url)
|
97 |
-
{
|
98 |
-
$result = self::$defaultResult;
|
99 |
-
|
100 |
-
if ($url->getPath() != '/') {
|
101 |
-
$path = ltrim($url->getPath(), '/');
|
102 |
-
if ($path) {
|
103 |
-
$pathPos = strpos($path, '/');
|
104 |
-
if ($pathPos === false) {
|
105 |
-
// https://s3.amazonaws.com/bucket
|
106 |
-
$result['bucket'] = $path;
|
107 |
-
} elseif ($pathPos == strlen($path) - 1) {
|
108 |
-
// https://s3.amazonaws.com/bucket/
|
109 |
-
$result['bucket'] = substr($path, 0, -1);
|
110 |
-
} else {
|
111 |
-
// https://s3.amazonaws.com/bucket/key
|
112 |
-
$result['bucket'] = substr($path, 0, $pathPos);
|
113 |
-
$result['key'] = substr($path, $pathPos + 1) ?: null;
|
114 |
-
}
|
115 |
-
}
|
116 |
-
}
|
117 |
-
|
118 |
-
return $result;
|
119 |
-
}
|
120 |
-
|
121 |
-
private function parseVirtualHosted(UriInterface $url, array $matches)
|
122 |
-
{
|
123 |
-
$result = self::$defaultResult;
|
124 |
-
$result['path_style'] = false;
|
125 |
-
// Remove trailing "." from the prefix to get the bucket
|
126 |
-
$result['bucket'] = substr($matches[1], 0, -1);
|
127 |
-
$path = $url->getPath();
|
128 |
-
// Check if a key was present, and if so, removing the leading "/"
|
129 |
-
$result['key'] = !$path || $path == '/' ? null : substr($path, 1);
|
130 |
-
|
131 |
-
return $result;
|
132 |
-
}
|
133 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/StreamWrapper.php
DELETED
@@ -1,958 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws\CacheInterface;
|
5 |
-
use Aws\LruArrayCache;
|
6 |
-
use Aws\Result;
|
7 |
-
use Aws\S3\Exception\S3Exception;
|
8 |
-
use GuzzleHttp\Psr7;
|
9 |
-
use GuzzleHttp\Psr7\Stream;
|
10 |
-
use GuzzleHttp\Psr7\CachingStream;
|
11 |
-
use Psr\Http\Message\StreamInterface;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Amazon S3 stream wrapper to use "s3://<bucket>/<key>" files with PHP
|
15 |
-
* streams, supporting "r", "w", "a", "x".
|
16 |
-
*
|
17 |
-
* # Opening "r" (read only) streams:
|
18 |
-
*
|
19 |
-
* Read only streams are truly streaming by default and will not allow you to
|
20 |
-
* seek. This is because data read from the stream is not kept in memory or on
|
21 |
-
* the local filesystem. You can force a "r" stream to be seekable by setting
|
22 |
-
* the "seekable" stream context option true. This will allow true streaming of
|
23 |
-
* data from Amazon S3, but will maintain a buffer of previously read bytes in
|
24 |
-
* a 'php://temp' stream to allow seeking to previously read bytes from the
|
25 |
-
* stream.
|
26 |
-
*
|
27 |
-
* You may pass any GetObject parameters as 's3' stream context options. These
|
28 |
-
* options will affect how the data is downloaded from Amazon S3.
|
29 |
-
*
|
30 |
-
* # Opening "w" and "x" (write only) streams:
|
31 |
-
*
|
32 |
-
* Because Amazon S3 requires a Content-Length header, write only streams will
|
33 |
-
* maintain a 'php://temp' stream to buffer data written to the stream until
|
34 |
-
* the stream is flushed (usually by closing the stream with fclose).
|
35 |
-
*
|
36 |
-
* You may pass any PutObject parameters as 's3' stream context options. These
|
37 |
-
* options will affect how the data is uploaded to Amazon S3.
|
38 |
-
*
|
39 |
-
* When opening an "x" stream, the file must exist on Amazon S3 for the stream
|
40 |
-
* to open successfully.
|
41 |
-
*
|
42 |
-
* # Opening "a" (write only append) streams:
|
43 |
-
*
|
44 |
-
* Similar to "w" streams, opening append streams requires that the data be
|
45 |
-
* buffered in a "php://temp" stream. Append streams will attempt to download
|
46 |
-
* the contents of an object in Amazon S3, seek to the end of the object, then
|
47 |
-
* allow you to append to the contents of the object. The data will then be
|
48 |
-
* uploaded using a PutObject operation when the stream is flushed (usually
|
49 |
-
* with fclose).
|
50 |
-
*
|
51 |
-
* You may pass any GetObject and/or PutObject parameters as 's3' stream
|
52 |
-
* context options. These options will affect how the data is downloaded and
|
53 |
-
* uploaded from Amazon S3.
|
54 |
-
*
|
55 |
-
* Stream context options:
|
56 |
-
*
|
57 |
-
* - "seekable": Set to true to create a seekable "r" (read only) stream by
|
58 |
-
* using a php://temp stream buffer
|
59 |
-
* - For "unlink" only: Any option that can be passed to the DeleteObject
|
60 |
-
* operation
|
61 |
-
*/
|
62 |
-
class StreamWrapper
|
63 |
-
{
|
64 |
-
/** @var resource|null Stream context (this is set by PHP) */
|
65 |
-
public $context;
|
66 |
-
|
67 |
-
/** @var StreamInterface Underlying stream resource */
|
68 |
-
private $body;
|
69 |
-
|
70 |
-
/** @var int Size of the body that is opened */
|
71 |
-
private $size;
|
72 |
-
|
73 |
-
/** @var array Hash of opened stream parameters */
|
74 |
-
private $params = [];
|
75 |
-
|
76 |
-
/** @var string Mode in which the stream was opened */
|
77 |
-
private $mode;
|
78 |
-
|
79 |
-
/** @var \Iterator Iterator used with opendir() related calls */
|
80 |
-
private $objectIterator;
|
81 |
-
|
82 |
-
/** @var string The bucket that was opened when opendir() was called */
|
83 |
-
private $openedBucket;
|
84 |
-
|
85 |
-
/** @var string The prefix of the bucket that was opened with opendir() */
|
86 |
-
private $openedBucketPrefix;
|
87 |
-
|
88 |
-
/** @var string Opened bucket path */
|
89 |
-
private $openedPath;
|
90 |
-
|
91 |
-
/** @var CacheInterface Cache for object and dir lookups */
|
92 |
-
private $cache;
|
93 |
-
|
94 |
-
/** @var string The opened protocol (e.g., "s3") */
|
95 |
-
private $protocol = 's3';
|
96 |
-
|
97 |
-
/** @var bool Keeps track of whether stream has been flushed since opening */
|
98 |
-
private $isFlushed = false;
|
99 |
-
|
100 |
-
/**
|
101 |
-
* Register the 's3://' stream wrapper
|
102 |
-
*
|
103 |
-
* @param S3ClientInterface $client Client to use with the stream wrapper
|
104 |
-
* @param string $protocol Protocol to register as.
|
105 |
-
* @param CacheInterface $cache Default cache for the protocol.
|
106 |
-
*/
|
107 |
-
public static function register(
|
108 |
-
S3ClientInterface $client,
|
109 |
-
$protocol = 's3',
|
110 |
-
CacheInterface $cache = null
|
111 |
-
) {
|
112 |
-
if (in_array($protocol, stream_get_wrappers())) {
|
113 |
-
stream_wrapper_unregister($protocol);
|
114 |
-
}
|
115 |
-
|
116 |
-
// Set the client passed in as the default stream context client
|
117 |
-
stream_wrapper_register($protocol, get_called_class(), STREAM_IS_URL);
|
118 |
-
$default = stream_context_get_options(stream_context_get_default());
|
119 |
-
$default[$protocol]['client'] = $client;
|
120 |
-
|
121 |
-
if ($cache) {
|
122 |
-
$default[$protocol]['cache'] = $cache;
|
123 |
-
} elseif (!isset($default[$protocol]['cache'])) {
|
124 |
-
// Set a default cache adapter.
|
125 |
-
$default[$protocol]['cache'] = new LruArrayCache();
|
126 |
-
}
|
127 |
-
|
128 |
-
stream_context_set_default($default);
|
129 |
-
}
|
130 |
-
|
131 |
-
public function stream_close()
|
132 |
-
{
|
133 |
-
if ($this->body->getSize() === 0 && !($this->isFlushed)) {
|
134 |
-
$this->stream_flush();
|
135 |
-
}
|
136 |
-
$this->body = $this->cache = null;
|
137 |
-
}
|
138 |
-
|
139 |
-
public function stream_open($path, $mode, $options, &$opened_path)
|
140 |
-
{
|
141 |
-
$this->initProtocol($path);
|
142 |
-
$this->isFlushed = false;
|
143 |
-
$this->params = $this->getBucketKey($path);
|
144 |
-
$this->mode = rtrim($mode, 'bt');
|
145 |
-
|
146 |
-
if ($errors = $this->validate($path, $this->mode)) {
|
147 |
-
return $this->triggerError($errors);
|
148 |
-
}
|
149 |
-
|
150 |
-
return $this->boolCall(function() use ($path) {
|
151 |
-
switch ($this->mode) {
|
152 |
-
case 'r': return $this->openReadStream($path);
|
153 |
-
case 'a': return $this->openAppendStream($path);
|
154 |
-
default: return $this->openWriteStream($path);
|
155 |
-
}
|
156 |
-
});
|
157 |
-
}
|
158 |
-
|
159 |
-
public function stream_eof()
|
160 |
-
{
|
161 |
-
return $this->body->eof();
|
162 |
-
}
|
163 |
-
|
164 |
-
public function stream_flush()
|
165 |
-
{
|
166 |
-
$this->isFlushed = true;
|
167 |
-
if ($this->mode == 'r') {
|
168 |
-
return false;
|
169 |
-
}
|
170 |
-
|
171 |
-
if ($this->body->isSeekable()) {
|
172 |
-
$this->body->seek(0);
|
173 |
-
}
|
174 |
-
$params = $this->getOptions(true);
|
175 |
-
$params['Body'] = $this->body;
|
176 |
-
|
177 |
-
// Attempt to guess the ContentType of the upload based on the
|
178 |
-
// file extension of the key
|
179 |
-
if (!isset($params['ContentType']) &&
|
180 |
-
($type = Psr7\mimetype_from_filename($params['Key']))
|
181 |
-
) {
|
182 |
-
$params['ContentType'] = $type;
|
183 |
-
}
|
184 |
-
|
185 |
-
$this->clearCacheKey("s3://{$params['Bucket']}/{$params['Key']}");
|
186 |
-
return $this->boolCall(function () use ($params) {
|
187 |
-
return (bool) $this->getClient()->putObject($params);
|
188 |
-
});
|
189 |
-
}
|
190 |
-
|
191 |
-
public function stream_read($count)
|
192 |
-
{
|
193 |
-
return $this->body->read($count);
|
194 |
-
}
|
195 |
-
|
196 |
-
public function stream_seek($offset, $whence = SEEK_SET)
|
197 |
-
{
|
198 |
-
return !$this->body->isSeekable()
|
199 |
-
? false
|
200 |
-
: $this->boolCall(function () use ($offset, $whence) {
|
201 |
-
$this->body->seek($offset, $whence);
|
202 |
-
return true;
|
203 |
-
});
|
204 |
-
}
|
205 |
-
|
206 |
-
public function stream_tell()
|
207 |
-
{
|
208 |
-
return $this->boolCall(function() { return $this->body->tell(); });
|
209 |
-
}
|
210 |
-
|
211 |
-
public function stream_write($data)
|
212 |
-
{
|
213 |
-
return $this->body->write($data);
|
214 |
-
}
|
215 |
-
|
216 |
-
public function unlink($path)
|
217 |
-
{
|
218 |
-
$this->initProtocol($path);
|
219 |
-
|
220 |
-
return $this->boolCall(function () use ($path) {
|
221 |
-
$this->clearCacheKey($path);
|
222 |
-
$this->getClient()->deleteObject($this->withPath($path));
|
223 |
-
return true;
|
224 |
-
});
|
225 |
-
}
|
226 |
-
|
227 |
-
public function stream_stat()
|
228 |
-
{
|
229 |
-
$stat = $this->getStatTemplate();
|
230 |
-
$stat[7] = $stat['size'] = $this->getSize();
|
231 |
-
$stat[2] = $stat['mode'] = $this->mode;
|
232 |
-
|
233 |
-
return $stat;
|
234 |
-
}
|
235 |
-
|
236 |
-
/**
|
237 |
-
* Provides information for is_dir, is_file, filesize, etc. Works on
|
238 |
-
* buckets, keys, and prefixes.
|
239 |
-
* @link http://www.php.net/manual/en/streamwrapper.url-stat.php
|
240 |
-
*/
|
241 |
-
public function url_stat($path, $flags)
|
242 |
-
{
|
243 |
-
$this->initProtocol($path);
|
244 |
-
|
245 |
-
// Some paths come through as S3:// for some reason.
|
246 |
-
$split = explode('://', $path);
|
247 |
-
$path = strtolower($split[0]) . '://' . $split[1];
|
248 |
-
|
249 |
-
// Check if this path is in the url_stat cache
|
250 |
-
if ($value = $this->getCacheStorage()->get($path)) {
|
251 |
-
return $value;
|
252 |
-
}
|
253 |
-
|
254 |
-
$stat = $this->createStat($path, $flags);
|
255 |
-
|
256 |
-
if (is_array($stat)) {
|
257 |
-
$this->getCacheStorage()->set($path, $stat);
|
258 |
-
}
|
259 |
-
|
260 |
-
return $stat;
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* Parse the protocol out of the given path.
|
265 |
-
*
|
266 |
-
* @param $path
|
267 |
-
*/
|
268 |
-
private function initProtocol($path)
|
269 |
-
{
|
270 |
-
$parts = explode('://', $path, 2);
|
271 |
-
$this->protocol = $parts[0] ?: 's3';
|
272 |
-
}
|
273 |
-
|
274 |
-
private function createStat($path, $flags)
|
275 |
-
{
|
276 |
-
$this->initProtocol($path);
|
277 |
-
$parts = $this->withPath($path);
|
278 |
-
|
279 |
-
if (!$parts['Key']) {
|
280 |
-
return $this->statDirectory($parts, $path, $flags);
|
281 |
-
}
|
282 |
-
|
283 |
-
return $this->boolCall(function () use ($parts, $path) {
|
284 |
-
try {
|
285 |
-
$result = $this->getClient()->headObject($parts);
|
286 |
-
if (substr($parts['Key'], -1, 1) == '/' &&
|
287 |
-
$result['ContentLength'] == 0
|
288 |
-
) {
|
289 |
-
// Return as if it is a bucket to account for console
|
290 |
-
// bucket objects (e.g., zero-byte object "foo/")
|
291 |
-
return $this->formatUrlStat($path);
|
292 |
-
}
|
293 |
-
|
294 |
-
// Attempt to stat and cache regular object
|
295 |
-
return $this->formatUrlStat($result->toArray());
|
296 |
-
} catch (S3Exception $e) {
|
297 |
-
// Maybe this isn't an actual key, but a prefix. Do a prefix
|
298 |
-
// listing of objects to determine.
|
299 |
-
$result = $this->getClient()->listObjects([
|
300 |
-
'Bucket' => $parts['Bucket'],
|
301 |
-
'Prefix' => rtrim($parts['Key'], '/') . '/',
|
302 |
-
'MaxKeys' => 1
|
303 |
-
]);
|
304 |
-
if (!$result['Contents'] && !$result['CommonPrefixes']) {
|
305 |
-
throw new \Exception("File or directory not found: $path");
|
306 |
-
}
|
307 |
-
return $this->formatUrlStat($path);
|
308 |
-
}
|
309 |
-
}, $flags);
|
310 |
-
}
|
311 |
-
|
312 |
-
private function statDirectory($parts, $path, $flags)
|
313 |
-
{
|
314 |
-
// Stat "directories": buckets, or "s3://"
|
315 |
-
if (!$parts['Bucket'] ||
|
316 |
-
$this->getClient()->doesBucketExist($parts['Bucket'])
|
317 |
-
) {
|
318 |
-
return $this->formatUrlStat($path);
|
319 |
-
}
|
320 |
-
|
321 |
-
return $this->triggerError("File or directory not found: $path", $flags);
|
322 |
-
}
|
323 |
-
|
324 |
-
/**
|
325 |
-
* Support for mkdir().
|
326 |
-
*
|
327 |
-
* @param string $path Directory which should be created.
|
328 |
-
* @param int $mode Permissions. 700-range permissions map to
|
329 |
-
* ACL_PUBLIC. 600-range permissions map to
|
330 |
-
* ACL_AUTH_READ. All other permissions map to
|
331 |
-
* ACL_PRIVATE. Expects octal form.
|
332 |
-
* @param int $options A bitwise mask of values, such as
|
333 |
-
* STREAM_MKDIR_RECURSIVE.
|
334 |
-
*
|
335 |
-
* @return bool
|
336 |
-
* @link http://www.php.net/manual/en/streamwrapper.mkdir.php
|
337 |
-
*/
|
338 |
-
public function mkdir($path, $mode, $options)
|
339 |
-
{
|
340 |
-
$this->initProtocol($path);
|
341 |
-
$params = $this->withPath($path);
|
342 |
-
$this->clearCacheKey($path);
|
343 |
-
if (!$params['Bucket']) {
|
344 |
-
return false;
|
345 |
-
}
|
346 |
-
|
347 |
-
if (!isset($params['ACL'])) {
|
348 |
-
$params['ACL'] = $this->determineAcl($mode);
|
349 |
-
}
|
350 |
-
|
351 |
-
return empty($params['Key'])
|
352 |
-
? $this->createBucket($path, $params)
|
353 |
-
: $this->createSubfolder($path, $params);
|
354 |
-
}
|
355 |
-
|
356 |
-
public function rmdir($path, $options)
|
357 |
-
{
|
358 |
-
$this->initProtocol($path);
|
359 |
-
$this->clearCacheKey($path);
|
360 |
-
$params = $this->withPath($path);
|
361 |
-
$client = $this->getClient();
|
362 |
-
|
363 |
-
if (!$params['Bucket']) {
|
364 |
-
return $this->triggerError('You must specify a bucket');
|
365 |
-
}
|
366 |
-
|
367 |
-
return $this->boolCall(function () use ($params, $path, $client) {
|
368 |
-
if (!$params['Key']) {
|
369 |
-
$client->deleteBucket(['Bucket' => $params['Bucket']]);
|
370 |
-
return true;
|
371 |
-
}
|
372 |
-
return $this->deleteSubfolder($path, $params);
|
373 |
-
});
|
374 |
-
}
|
375 |
-
|
376 |
-
/**
|
377 |
-
* Support for opendir().
|
378 |
-
*
|
379 |
-
* The opendir() method of the Amazon S3 stream wrapper supports a stream
|
380 |
-
* context option of "listFilter". listFilter must be a callable that
|
381 |
-
* accepts an associative array of object data and returns true if the
|
382 |
-
* object should be yielded when iterating the keys in a bucket.
|
383 |
-
*
|
384 |
-
* @param string $path The path to the directory
|
385 |
-
* (e.g. "s3://dir[</prefix>]")
|
386 |
-
* @param string $options Unused option variable
|
387 |
-
*
|
388 |
-
* @return bool true on success
|
389 |
-
* @see http://www.php.net/manual/en/function.opendir.php
|
390 |
-
*/
|
391 |
-
public function dir_opendir($path, $options)
|
392 |
-
{
|
393 |
-
$this->initProtocol($path);
|
394 |
-
$this->openedPath = $path;
|
395 |
-
$params = $this->withPath($path);
|
396 |
-
$delimiter = $this->getOption('delimiter');
|
397 |
-
/** @var callable $filterFn */
|
398 |
-
$filterFn = $this->getOption('listFilter');
|
399 |
-
$op = ['Bucket' => $params['Bucket']];
|
400 |
-
$this->openedBucket = $params['Bucket'];
|
401 |
-
|
402 |
-
if ($delimiter === null) {
|
403 |
-
$delimiter = '/';
|
404 |
-
}
|
405 |
-
|
406 |
-
if ($delimiter) {
|
407 |
-
$op['Delimiter'] = $delimiter;
|
408 |
-
}
|
409 |
-
|
410 |
-
if ($params['Key']) {
|
411 |
-
$params['Key'] = rtrim($params['Key'], $delimiter) . $delimiter;
|
412 |
-
$op['Prefix'] = $params['Key'];
|
413 |
-
}
|
414 |
-
|
415 |
-
$this->openedBucketPrefix = $params['Key'];
|
416 |
-
|
417 |
-
// Filter our "/" keys added by the console as directories, and ensure
|
418 |
-
// that if a filter function is provided that it passes the filter.
|
419 |
-
$this->objectIterator = \Aws\flatmap(
|
420 |
-
$this->getClient()->getPaginator('ListObjects', $op),
|
421 |
-
function (Result $result) use ($filterFn) {
|
422 |
-
$contentsAndPrefixes = $result->search('[Contents[], CommonPrefixes[]][]');
|
423 |
-
// Filter out dir place holder keys and use the filter fn.
|
424 |
-
return array_filter(
|
425 |
-
$contentsAndPrefixes,
|
426 |
-
function ($key) use ($filterFn) {
|
427 |
-
return (!$filterFn || call_user_func($filterFn, $key))
|
428 |
-
&& (!isset($key['Key']) || substr($key['Key'], -1, 1) !== '/');
|
429 |
-
}
|
430 |
-
);
|
431 |
-
}
|
432 |
-
);
|
433 |
-
|
434 |
-
return true;
|
435 |
-
}
|
436 |
-
|
437 |
-
/**
|
438 |
-
* Close the directory listing handles
|
439 |
-
*
|
440 |
-
* @return bool true on success
|
441 |
-
*/
|
442 |
-
public function dir_closedir()
|
443 |
-
{
|
444 |
-
$this->objectIterator = null;
|
445 |
-
gc_collect_cycles();
|
446 |
-
|
447 |
-
return true;
|
448 |
-
}
|
449 |
-
|
450 |
-
/**
|
451 |
-
* This method is called in response to rewinddir()
|
452 |
-
*
|
453 |
-
* @return boolean true on success
|
454 |
-
*/
|
455 |
-
public function dir_rewinddir()
|
456 |
-
{
|
457 |
-
return $this->boolCall(function() {
|
458 |
-
$this->objectIterator = null;
|
459 |
-
$this->dir_opendir($this->openedPath, null);
|
460 |
-
return true;
|
461 |
-
});
|
462 |
-
}
|
463 |
-
|
464 |
-
/**
|
465 |
-
* This method is called in response to readdir()
|
466 |
-
*
|
467 |
-
* @return string Should return a string representing the next filename, or
|
468 |
-
* false if there is no next file.
|
469 |
-
* @link http://www.php.net/manual/en/function.readdir.php
|
470 |
-
*/
|
471 |
-
public function dir_readdir()
|
472 |
-
{
|
473 |
-
// Skip empty result keys
|
474 |
-
if (!$this->objectIterator->valid()) {
|
475 |
-
return false;
|
476 |
-
}
|
477 |
-
|
478 |
-
// First we need to create a cache key. This key is the full path to
|
479 |
-
// then object in s3: protocol://bucket/key.
|
480 |
-
// Next we need to create a result value. The result value is the
|
481 |
-
// current value of the iterator without the opened bucket prefix to
|
482 |
-
// emulate how readdir() works on directories.
|
483 |
-
// The cache key and result value will depend on if this is a prefix
|
484 |
-
// or a key.
|
485 |
-
$cur = $this->objectIterator->current();
|
486 |
-
if (isset($cur['Prefix'])) {
|
487 |
-
// Include "directories". Be sure to strip a trailing "/"
|
488 |
-
// on prefixes.
|
489 |
-
$result = rtrim($cur['Prefix'], '/');
|
490 |
-
$key = $this->formatKey($result);
|
491 |
-
$stat = $this->formatUrlStat($key);
|
492 |
-
} else {
|
493 |
-
$result = $cur['Key'];
|
494 |
-
$key = $this->formatKey($cur['Key']);
|
495 |
-
$stat = $this->formatUrlStat($cur);
|
496 |
-
}
|
497 |
-
|
498 |
-
// Cache the object data for quick url_stat lookups used with
|
499 |
-
// RecursiveDirectoryIterator.
|
500 |
-
$this->getCacheStorage()->set($key, $stat);
|
501 |
-
$this->objectIterator->next();
|
502 |
-
|
503 |
-
// Remove the prefix from the result to emulate other stream wrappers.
|
504 |
-
return $this->openedBucketPrefix
|
505 |
-
? substr($result, strlen($this->openedBucketPrefix))
|
506 |
-
: $result;
|
507 |
-
}
|
508 |
-
|
509 |
-
private function formatKey($key)
|
510 |
-
{
|
511 |
-
$protocol = explode('://', $this->openedPath)[0];
|
512 |
-
return "{$protocol}://{$this->openedBucket}/{$key}";
|
513 |
-
}
|
514 |
-
|
515 |
-
/**
|
516 |
-
* Called in response to rename() to rename a file or directory. Currently
|
517 |
-
* only supports renaming objects.
|
518 |
-
*
|
519 |
-
* @param string $path_from the path to the file to rename
|
520 |
-
* @param string $path_to the new path to the file
|
521 |
-
*
|
522 |
-
* @return bool true if file was successfully renamed
|
523 |
-
* @link http://www.php.net/manual/en/function.rename.php
|
524 |
-
*/
|
525 |
-
public function rename($path_from, $path_to)
|
526 |
-
{
|
527 |
-
// PHP will not allow rename across wrapper types, so we can safely
|
528 |
-
// assume $path_from and $path_to have the same protocol
|
529 |
-
$this->initProtocol($path_from);
|
530 |
-
$partsFrom = $this->withPath($path_from);
|
531 |
-
$partsTo = $this->withPath($path_to);
|
532 |
-
$this->clearCacheKey($path_from);
|
533 |
-
$this->clearCacheKey($path_to);
|
534 |
-
|
535 |
-
if (!$partsFrom['Key'] || !$partsTo['Key']) {
|
536 |
-
return $this->triggerError('The Amazon S3 stream wrapper only '
|
537 |
-
. 'supports copying objects');
|
538 |
-
}
|
539 |
-
|
540 |
-
return $this->boolCall(function () use ($partsFrom, $partsTo) {
|
541 |
-
$options = $this->getOptions(true);
|
542 |
-
// Copy the object and allow overriding default parameters if
|
543 |
-
// desired, but by default copy metadata
|
544 |
-
$this->getClient()->copy(
|
545 |
-
$partsFrom['Bucket'],
|
546 |
-
$partsFrom['Key'],
|
547 |
-
$partsTo['Bucket'],
|
548 |
-
$partsTo['Key'],
|
549 |
-
isset($options['acl']) ? $options['acl'] : 'private',
|
550 |
-
$options
|
551 |
-
);
|
552 |
-
// Delete the original object
|
553 |
-
$this->getClient()->deleteObject([
|
554 |
-
'Bucket' => $partsFrom['Bucket'],
|
555 |
-
'Key' => $partsFrom['Key']
|
556 |
-
] + $options);
|
557 |
-
return true;
|
558 |
-
});
|
559 |
-
}
|
560 |
-
|
561 |
-
public function stream_cast($cast_as)
|
562 |
-
{
|
563 |
-
return false;
|
564 |
-
}
|
565 |
-
|
566 |
-
/**
|
567 |
-
* Validates the provided stream arguments for fopen and returns an array
|
568 |
-
* of errors.
|
569 |
-
*/
|
570 |
-
private function validate($path, $mode)
|
571 |
-
{
|
572 |
-
$errors = [];
|
573 |
-
|
574 |
-
if (!$this->getOption('Key')) {
|
575 |
-
$errors[] = 'Cannot open a bucket. You must specify a path in the '
|
576 |
-
. 'form of s3://bucket/key';
|
577 |
-
}
|
578 |
-
|
579 |
-
if (!in_array($mode, ['r', 'w', 'a', 'x'])) {
|
580 |
-
$errors[] = "Mode not supported: {$mode}. "
|
581 |
-
. "Use one 'r', 'w', 'a', or 'x'.";
|
582 |
-
}
|
583 |
-
|
584 |
-
// When using mode "x" validate if the file exists before attempting
|
585 |
-
// to read
|
586 |
-
if ($mode == 'x' &&
|
587 |
-
$this->getClient()->doesObjectExist(
|
588 |
-
$this->getOption('Bucket'),
|
589 |
-
$this->getOption('Key'),
|
590 |
-
$this->getOptions(true)
|
591 |
-
)
|
592 |
-
) {
|
593 |
-
$errors[] = "{$path} already exists on Amazon S3";
|
594 |
-
}
|
595 |
-
|
596 |
-
return $errors;
|
597 |
-
}
|
598 |
-
|
599 |
-
/**
|
600 |
-
* Get the stream context options available to the current stream
|
601 |
-
*
|
602 |
-
* @param bool $removeContextData Set to true to remove contextual kvp's
|
603 |
-
* like 'client' from the result.
|
604 |
-
*
|
605 |
-
* @return array
|
606 |
-
*/
|
607 |
-
private function getOptions($removeContextData = false)
|
608 |
-
{
|
609 |
-
// Context is not set when doing things like stat
|
610 |
-
if ($this->context === null) {
|
611 |
-
$options = [];
|
612 |
-
} else {
|
613 |
-
$options = stream_context_get_options($this->context);
|
614 |
-
$options = isset($options[$this->protocol])
|
615 |
-
? $options[$this->protocol]
|
616 |
-
: [];
|
617 |
-
}
|
618 |
-
|
619 |
-
$default = stream_context_get_options(stream_context_get_default());
|
620 |
-
$default = isset($default[$this->protocol])
|
621 |
-
? $default[$this->protocol]
|
622 |
-
: [];
|
623 |
-
$result = $this->params + $options + $default;
|
624 |
-
|
625 |
-
if ($removeContextData) {
|
626 |
-
unset($result['client'], $result['seekable'], $result['cache']);
|
627 |
-
}
|
628 |
-
|
629 |
-
return $result;
|
630 |
-
}
|
631 |
-
|
632 |
-
/**
|
633 |
-
* Get a specific stream context option
|
634 |
-
*
|
635 |
-
* @param string $name Name of the option to retrieve
|
636 |
-
*
|
637 |
-
* @return mixed|null
|
638 |
-
*/
|
639 |
-
private function getOption($name)
|
640 |
-
{
|
641 |
-
$options = $this->getOptions();
|
642 |
-
|
643 |
-
return isset($options[$name]) ? $options[$name] : null;
|
644 |
-
}
|
645 |
-
|
646 |
-
/**
|
647 |
-
* Gets the client from the stream context
|
648 |
-
*
|
649 |
-
* @return S3ClientInterface
|
650 |
-
* @throws \RuntimeException if no client has been configured
|
651 |
-
*/
|
652 |
-
private function getClient()
|
653 |
-
{
|
654 |
-
if (!$client = $this->getOption('client')) {
|
655 |
-
throw new \RuntimeException('No client in stream context');
|
656 |
-
}
|
657 |
-
|
658 |
-
return $client;
|
659 |
-
}
|
660 |
-
|
661 |
-
private function getBucketKey($path)
|
662 |
-
{
|
663 |
-
// Remove the protocol
|
664 |
-
$parts = explode('://', $path);
|
665 |
-
// Get the bucket, key
|
666 |
-
$parts = explode('/', $parts[1], 2);
|
667 |
-
|
668 |
-
return [
|
669 |
-
'Bucket' => $parts[0],
|
670 |
-
'Key' => isset($parts[1]) ? $parts[1] : null
|
671 |
-
];
|
672 |
-
}
|
673 |
-
|
674 |
-
/**
|
675 |
-
* Get the bucket and key from the passed path (e.g. s3://bucket/key)
|
676 |
-
*
|
677 |
-
* @param string $path Path passed to the stream wrapper
|
678 |
-
*
|
679 |
-
* @return array Hash of 'Bucket', 'Key', and custom params from the context
|
680 |
-
*/
|
681 |
-
private function withPath($path)
|
682 |
-
{
|
683 |
-
$params = $this->getOptions(true);
|
684 |
-
|
685 |
-
return $this->getBucketKey($path) + $params;
|
686 |
-
}
|
687 |
-
|
688 |
-
private function openReadStream()
|
689 |
-
{
|
690 |
-
$client = $this->getClient();
|
691 |
-
$command = $client->getCommand('GetObject', $this->getOptions(true));
|
692 |
-
$command['@http']['stream'] = true;
|
693 |
-
$result = $client->execute($command);
|
694 |
-
$this->size = $result['ContentLength'];
|
695 |
-
$this->body = $result['Body'];
|
696 |
-
|
697 |
-
// Wrap the body in a caching entity body if seeking is allowed
|
698 |
-
if ($this->getOption('seekable') && !$this->body->isSeekable()) {
|
699 |
-
$this->body = new CachingStream($this->body);
|
700 |
-
}
|
701 |
-
|
702 |
-
return true;
|
703 |
-
}
|
704 |
-
|
705 |
-
private function openWriteStream()
|
706 |
-
{
|
707 |
-
$this->body = new Stream(fopen('php://temp', 'r+'));
|
708 |
-
return true;
|
709 |
-
}
|
710 |
-
|
711 |
-
private function openAppendStream()
|
712 |
-
{
|
713 |
-
try {
|
714 |
-
// Get the body of the object and seek to the end of the stream
|
715 |
-
$client = $this->getClient();
|
716 |
-
$this->body = $client->getObject($this->getOptions(true))['Body'];
|
717 |
-
$this->body->seek(0, SEEK_END);
|
718 |
-
return true;
|
719 |
-
} catch (S3Exception $e) {
|
720 |
-
// The object does not exist, so use a simple write stream
|
721 |
-
return $this->openWriteStream();
|
722 |
-
}
|
723 |
-
}
|
724 |
-
|
725 |
-
/**
|
726 |
-
* Trigger one or more errors
|
727 |
-
*
|
728 |
-
* @param string|array $errors Errors to trigger
|
729 |
-
* @param mixed $flags If set to STREAM_URL_STAT_QUIET, then no
|
730 |
-
* error or exception occurs
|
731 |
-
*
|
732 |
-
* @return bool Returns false
|
733 |
-
* @throws \RuntimeException if throw_errors is true
|
734 |
-
*/
|
735 |
-
private function triggerError($errors, $flags = null)
|
736 |
-
{
|
737 |
-
// This is triggered with things like file_exists()
|
738 |
-
if ($flags & STREAM_URL_STAT_QUIET) {
|
739 |
-
return $flags & STREAM_URL_STAT_LINK
|
740 |
-
// This is triggered for things like is_link()
|
741 |
-
? $this->formatUrlStat(false)
|
742 |
-
: false;
|
743 |
-
}
|
744 |
-
|
745 |
-
// This is triggered when doing things like lstat() or stat()
|
746 |
-
trigger_error(implode("\n", (array) $errors), E_USER_WARNING);
|
747 |
-
|
748 |
-
return false;
|
749 |
-
}
|
750 |
-
|
751 |
-
/**
|
752 |
-
* Prepare a url_stat result array
|
753 |
-
*
|
754 |
-
* @param string|array $result Data to add
|
755 |
-
*
|
756 |
-
* @return array Returns the modified url_stat result
|
757 |
-
*/
|
758 |
-
private function formatUrlStat($result = null)
|
759 |
-
{
|
760 |
-
$stat = $this->getStatTemplate();
|
761 |
-
switch (gettype($result)) {
|
762 |
-
case 'NULL':
|
763 |
-
case 'string':
|
764 |
-
// Directory with 0777 access - see "man 2 stat".
|
765 |
-
$stat['mode'] = $stat[2] = 0040777;
|
766 |
-
break;
|
767 |
-
case 'array':
|
768 |
-
// Regular file with 0777 access - see "man 2 stat".
|
769 |
-
$stat['mode'] = $stat[2] = 0100777;
|
770 |
-
// Pluck the content-length if available.
|
771 |
-
if (isset($result['ContentLength'])) {
|
772 |
-
$stat['size'] = $stat[7] = $result['ContentLength'];
|
773 |
-
} elseif (isset($result['Size'])) {
|
774 |
-
$stat['size'] = $stat[7] = $result['Size'];
|
775 |
-
}
|
776 |
-
if (isset($result['LastModified'])) {
|
777 |
-
// ListObjects or HeadObject result
|
778 |
-
$stat['mtime'] = $stat[9] = $stat['ctime'] = $stat[10]
|
779 |
-
= strtotime($result['LastModified']);
|
780 |
-
}
|
781 |
-
}
|
782 |
-
|
783 |
-
return $stat;
|
784 |
-
}
|
785 |
-
|
786 |
-
/**
|
787 |
-
* Creates a bucket for the given parameters.
|
788 |
-
*
|
789 |
-
* @param string $path Stream wrapper path
|
790 |
-
* @param array $params A result of StreamWrapper::withPath()
|
791 |
-
*
|
792 |
-
* @return bool Returns true on success or false on failure
|
793 |
-
*/
|
794 |
-
private function createBucket($path, array $params)
|
795 |
-
{
|
796 |
-
if ($this->getClient()->doesBucketExist($params['Bucket'])) {
|
797 |
-
return $this->triggerError("Bucket already exists: {$path}");
|
798 |
-
}
|
799 |
-
|
800 |
-
return $this->boolCall(function () use ($params, $path) {
|
801 |
-
$this->getClient()->createBucket($params);
|
802 |
-
$this->clearCacheKey($path);
|
803 |
-
return true;
|
804 |
-
});
|
805 |
-
}
|
806 |
-
|
807 |
-
/**
|
808 |
-
* Creates a pseudo-folder by creating an empty "/" suffixed key
|
809 |
-
*
|
810 |
-
* @param string $path Stream wrapper path
|
811 |
-
* @param array $params A result of StreamWrapper::withPath()
|
812 |
-
*
|
813 |
-
* @return bool
|
814 |
-
*/
|
815 |
-
private function createSubfolder($path, array $params)
|
816 |
-
{
|
817 |
-
// Ensure the path ends in "/" and the body is empty.
|
818 |
-
$params['Key'] = rtrim($params['Key'], '/') . '/';
|
819 |
-
$params['Body'] = '';
|
820 |
-
|
821 |
-
// Fail if this pseudo directory key already exists
|
822 |
-
if ($this->getClient()->doesObjectExist(
|
823 |
-
$params['Bucket'],
|
824 |
-
$params['Key'])
|
825 |
-
) {
|
826 |
-
return $this->triggerError("Subfolder already exists: {$path}");
|
827 |
-
}
|
828 |
-
|
829 |
-
return $this->boolCall(function () use ($params, $path) {
|
830 |
-
$this->getClient()->putObject($params);
|
831 |
-
$this->clearCacheKey($path);
|
832 |
-
return true;
|
833 |
-
});
|
834 |
-
}
|
835 |
-
|
836 |
-
/**
|
837 |
-
* Deletes a nested subfolder if it is empty.
|
838 |
-
*
|
839 |
-
* @param string $path Path that is being deleted (e.g., 's3://a/b/c')
|
840 |
-
* @param array $params A result of StreamWrapper::withPath()
|
841 |
-
*
|
842 |
-
* @return bool
|
843 |
-
*/
|
844 |
-
private function deleteSubfolder($path, $params)
|
845 |
-
{
|
846 |
-
// Use a key that adds a trailing slash if needed.
|
847 |
-
$prefix = rtrim($params['Key'], '/') . '/';
|
848 |
-
$result = $this->getClient()->listObjects([
|
849 |
-
'Bucket' => $params['Bucket'],
|
850 |
-
'Prefix' => $prefix,
|
851 |
-
'MaxKeys' => 1
|
852 |
-
]);
|
853 |
-
|
854 |
-
// Check if the bucket contains keys other than the placeholder
|
855 |
-
if ($contents = $result['Contents']) {
|
856 |
-
return (count($contents) > 1 || $contents[0]['Key'] != $prefix)
|
857 |
-
? $this->triggerError('Subfolder is not empty')
|
858 |
-
: $this->unlink(rtrim($path, '/') . '/');
|
859 |
-
}
|
860 |
-
|
861 |
-
return $result['CommonPrefixes']
|
862 |
-
? $this->triggerError('Subfolder contains nested folders')
|
863 |
-
: true;
|
864 |
-
}
|
865 |
-
|
866 |
-
/**
|
867 |
-
* Determine the most appropriate ACL based on a file mode.
|
868 |
-
*
|
869 |
-
* @param int $mode File mode
|
870 |
-
*
|
871 |
-
* @return string
|
872 |
-
*/
|
873 |
-
private function determineAcl($mode)
|
874 |
-
{
|
875 |
-
switch (substr(decoct($mode), 0, 1)) {
|
876 |
-
case '7': return 'public-read';
|
877 |
-
case '6': return 'authenticated-read';
|
878 |
-
default: return 'private';
|
879 |
-
}
|
880 |
-
}
|
881 |
-
|
882 |
-
/**
|
883 |
-
* Gets a URL stat template with default values
|
884 |
-
*
|
885 |
-
* @return array
|
886 |
-
*/
|
887 |
-
private function getStatTemplate()
|
888 |
-
{
|
889 |
-
return [
|
890 |
-
0 => 0, 'dev' => 0,
|
891 |
-
1 => 0, 'ino' => 0,
|
892 |
-
2 => 0, 'mode' => 0,
|
893 |
-
3 => 0, 'nlink' => 0,
|
894 |
-
4 => 0, 'uid' => 0,
|
895 |
-
5 => 0, 'gid' => 0,
|
896 |
-
6 => -1, 'rdev' => -1,
|
897 |
-
7 => 0, 'size' => 0,
|
898 |
-
8 => 0, 'atime' => 0,
|
899 |
-
9 => 0, 'mtime' => 0,
|
900 |
-
10 => 0, 'ctime' => 0,
|
901 |
-
11 => -1, 'blksize' => -1,
|
902 |
-
12 => -1, 'blocks' => -1,
|
903 |
-
];
|
904 |
-
}
|
905 |
-
|
906 |
-
/**
|
907 |
-
* Invokes a callable and triggers an error if an exception occurs while
|
908 |
-
* calling the function.
|
909 |
-
*
|
910 |
-
* @param callable $fn
|
911 |
-
* @param int $flags
|
912 |
-
*
|
913 |
-
* @return bool
|
914 |
-
*/
|
915 |
-
private function boolCall(callable $fn, $flags = null)
|
916 |
-
{
|
917 |
-
try {
|
918 |
-
return $fn();
|
919 |
-
} catch (\Exception $e) {
|
920 |
-
return $this->triggerError($e->getMessage(), $flags);
|
921 |
-
}
|
922 |
-
}
|
923 |
-
|
924 |
-
/**
|
925 |
-
* @return LruArrayCache
|
926 |
-
*/
|
927 |
-
private function getCacheStorage()
|
928 |
-
{
|
929 |
-
if (!$this->cache) {
|
930 |
-
$this->cache = $this->getOption('cache') ?: new LruArrayCache();
|
931 |
-
}
|
932 |
-
|
933 |
-
return $this->cache;
|
934 |
-
}
|
935 |
-
|
936 |
-
/**
|
937 |
-
* Clears a specific stat cache value from the stat cache and LRU cache.
|
938 |
-
*
|
939 |
-
* @param string $key S3 path (s3://bucket/key).
|
940 |
-
*/
|
941 |
-
private function clearCacheKey($key)
|
942 |
-
{
|
943 |
-
clearstatcache(true, $key);
|
944 |
-
$this->getCacheStorage()->remove($key);
|
945 |
-
}
|
946 |
-
|
947 |
-
/**
|
948 |
-
* Returns the size of the opened object body.
|
949 |
-
*
|
950 |
-
* @return int|null
|
951 |
-
*/
|
952 |
-
private function getSize()
|
953 |
-
{
|
954 |
-
$size = $this->body->getSize();
|
955 |
-
|
956 |
-
return $size !== null ? $size : $this->size;
|
957 |
-
}
|
958 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/S3/Transfer.php
DELETED
@@ -1,428 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\S3;
|
3 |
-
|
4 |
-
use Aws;
|
5 |
-
use Aws\CommandInterface;
|
6 |
-
use Aws\Exception\AwsException;
|
7 |
-
use GuzzleHttp\Promise;
|
8 |
-
use GuzzleHttp\Promise\PromisorInterface;
|
9 |
-
use Iterator;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Transfers files from the local filesystem to S3 or from S3 to the local
|
13 |
-
* filesystem.
|
14 |
-
*
|
15 |
-
* This class does not support copying from the local filesystem to somewhere
|
16 |
-
* else on the local filesystem or from one S3 bucket to another.
|
17 |
-
*/
|
18 |
-
class Transfer implements PromisorInterface
|
19 |
-
{
|
20 |
-
private $client;
|
21 |
-
private $promise;
|
22 |
-
private $source;
|
23 |
-
private $sourceMetadata;
|
24 |
-
private $destination;
|
25 |
-
private $concurrency;
|
26 |
-
private $mupThreshold;
|
27 |
-
private $before;
|
28 |
-
private $s3Args = [];
|
29 |
-
|
30 |
-
/**
|
31 |
-
* When providing the $source argument, you may provide a string referencing
|
32 |
-
* the path to a directory on disk to upload, an s3 scheme URI that contains
|
33 |
-
* the bucket and key (e.g., "s3://bucket/key"), or an \Iterator object
|
34 |
-
* that yields strings containing filenames that are the path to a file on
|
35 |
-
* disk or an s3 scheme URI. The "/key" portion of an s3 URI is optional.
|
36 |
-
*
|
37 |
-
* When providing an iterator for the $source argument, you must also
|
38 |
-
* provide a 'base_dir' key value pair in the $options argument.
|
39 |
-
*
|
40 |
-
* The $dest argument can be the path to a directory on disk or an s3
|
41 |
-
* scheme URI (e.g., "s3://bucket/key").
|
42 |
-
*
|
43 |
-
* The options array can contain the following key value pairs:
|
44 |
-
*
|
45 |
-
* - base_dir: (string) Base directory of the source, if $source is an
|
46 |
-
* iterator. If the $source option is not an array, then this option is
|
47 |
-
* ignored.
|
48 |
-
* - before: (callable) A callback to invoke before each transfer. The
|
49 |
-
* callback accepts a single argument: Aws\CommandInterface $command.
|
50 |
-
* The provided command will be either a GetObject, PutObject,
|
51 |
-
* InitiateMultipartUpload, or UploadPart command.
|
52 |
-
* - mup_threshold: (int) Size in bytes in which a multipart upload should
|
53 |
-
* be used instead of PutObject. Defaults to 20971520 (20 MB).
|
54 |
-
* - concurrency: (int, default=5) Number of files to upload concurrently.
|
55 |
-
* The ideal concurrency value will vary based on the number of files
|
56 |
-
* being uploaded and the average size of each file. Generally speaking,
|
57 |
-
* smaller files benefit from a higher concurrency while larger files
|
58 |
-
* will not.
|
59 |
-
* - debug: (bool) Set to true to print out debug information for
|
60 |
-
* transfers. Set to an fopen() resource to write to a specific stream
|
61 |
-
* rather than writing to STDOUT.
|
62 |
-
*
|
63 |
-
* @param S3ClientInterface $client Client used for transfers.
|
64 |
-
* @param string|Iterator $source Where the files are transferred from.
|
65 |
-
* @param string $dest Where the files are transferred to.
|
66 |
-
* @param array $options Hash of options.
|
67 |
-
*/
|
68 |
-
public function __construct(
|
69 |
-
S3ClientInterface $client,
|
70 |
-
$source,
|
71 |
-
$dest,
|
72 |
-
array $options = []
|
73 |
-
) {
|
74 |
-
$this->client = $client;
|
75 |
-
|
76 |
-
// Prepare the destination.
|
77 |
-
$this->destination = $this->prepareTarget($dest);
|
78 |
-
if ($this->destination['scheme'] === 's3') {
|
79 |
-
$this->s3Args = $this->getS3Args($this->destination['path']);
|
80 |
-
}
|
81 |
-
|
82 |
-
// Prepare the source.
|
83 |
-
if (is_string($source)) {
|
84 |
-
$this->sourceMetadata = $this->prepareTarget($source);
|
85 |
-
$this->source = $source;
|
86 |
-
} elseif ($source instanceof Iterator) {
|
87 |
-
if (empty($options['base_dir'])) {
|
88 |
-
throw new \InvalidArgumentException('You must provide the source'
|
89 |
-
. ' argument as a string or provide the "base_dir" option.');
|
90 |
-
}
|
91 |
-
|
92 |
-
$this->sourceMetadata = $this->prepareTarget($options['base_dir']);
|
93 |
-
$this->source = $source;
|
94 |
-
} else {
|
95 |
-
throw new \InvalidArgumentException('source must be the path to a '
|
96 |
-
. 'directory or an iterator that yields file names.');
|
97 |
-
}
|
98 |
-
|
99 |
-
// Validate schemes.
|
100 |
-
if ($this->sourceMetadata['scheme'] === $this->destination['scheme']) {
|
101 |
-
throw new \InvalidArgumentException("You cannot copy from"
|
102 |
-
. " {$this->sourceMetadata['scheme']} to"
|
103 |
-
. " {$this->destination['scheme']}."
|
104 |
-
);
|
105 |
-
}
|
106 |
-
|
107 |
-
// Handle multipart-related options.
|
108 |
-
$this->concurrency = isset($options['concurrency'])
|
109 |
-
? $options['concurrency']
|
110 |
-
: MultipartUploader::DEFAULT_CONCURRENCY;
|
111 |
-
$this->mupThreshold = isset($options['mup_threshold'])
|
112 |
-
? $options['mup_threshold']
|
113 |
-
: 16777216;
|
114 |
-
if ($this->mupThreshold < MultipartUploader::PART_MIN_SIZE) {
|
115 |
-
throw new \InvalidArgumentException('mup_threshold must be >= 5MB');
|
116 |
-
}
|
117 |
-
|
118 |
-
// Handle "before" callback option.
|
119 |
-
if (isset($options['before'])) {
|
120 |
-
$this->before = $options['before'];
|
121 |
-
if (!is_callable($this->before)) {
|
122 |
-
throw new \InvalidArgumentException('before must be a callable.');
|
123 |
-
}
|
124 |
-
}
|
125 |
-
|
126 |
-
// Handle "debug" option.
|
127 |
-
if (isset($options['debug'])) {
|
128 |
-
if ($options['debug'] === true) {
|
129 |
-
$options['debug'] = fopen('php://output', 'w');
|
130 |
-
}
|
131 |
-
$this->addDebugToBefore($options['debug']);
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
/**
|
136 |
-
* Transfers the files.
|
137 |
-
*/
|
138 |
-
public function promise()
|
139 |
-
{
|
140 |
-
// If the promise has been created, just return it.
|
141 |
-
if (!$this->promise) {
|
142 |
-
// Create an upload/download promise for the transfer.
|
143 |
-
$this->promise = $this->sourceMetadata['scheme'] === 'file'
|
144 |
-
? $this->createUploadPromise()
|
145 |
-
: $this->createDownloadPromise();
|
146 |
-
}
|
147 |
-
|
148 |
-
return $this->promise;
|
149 |
-
}
|
150 |
-
|
151 |
-
/**
|
152 |
-
* Transfers the files synchronously.
|
153 |
-
*/
|
154 |
-
public function transfer()
|
155 |
-
{
|
156 |
-
$this->promise()->wait();
|
157 |
-
}
|
158 |
-
|
159 |
-
private function prepareTarget($targetPath)
|
160 |
-
{
|
161 |
-
$target = [
|
162 |
-
'path' => $this->normalizePath($targetPath),
|
163 |
-
'scheme' => $this->determineScheme($targetPath),
|
164 |
-
];
|
165 |
-
|
166 |
-
if ($target['scheme'] !== 's3' && $target['scheme'] !== 'file') {
|
167 |
-
throw new \InvalidArgumentException('Scheme must be "s3" or "file".');
|
168 |
-
}
|
169 |
-
|
170 |
-
return $target;
|
171 |
-
}
|
172 |
-
|
173 |
-
/**
|
174 |
-
* Creates an array that contains Bucket and Key by parsing the filename.
|
175 |
-
*
|
176 |
-
* @param string $path Path to parse.
|
177 |
-
*
|
178 |
-
* @return array
|
179 |
-
*/
|
180 |
-
private function getS3Args($path)
|
181 |
-
{
|
182 |
-
$parts = explode('/', str_replace('s3://', '', $path), 2);
|
183 |
-
$args = ['Bucket' => $parts[0]];
|
184 |
-
if (isset($parts[1])) {
|
185 |
-
$args['Key'] = $parts[1];
|
186 |
-
}
|
187 |
-
|
188 |
-
return $args;
|
189 |
-
}
|
190 |
-
|
191 |
-
/**
|
192 |
-
* Parses the scheme from a filename.
|
193 |
-
*
|
194 |
-
* @param string $path Path to parse.
|
195 |
-
*
|
196 |
-
* @return string
|
197 |
-
*/
|
198 |
-
private function determineScheme($path)
|
199 |
-
{
|
200 |
-
return !strpos($path, '://') ? 'file' : explode('://', $path)[0];
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* Normalize a path so that it has UNIX-style directory separators and no trailing /
|
205 |
-
*
|
206 |
-
* @param string $path
|
207 |
-
*
|
208 |
-
* @return string
|
209 |
-
*/
|
210 |
-
private function normalizePath($path)
|
211 |
-
{
|
212 |
-
return rtrim(str_replace('\\', '/', $path), '/');
|
213 |
-
}
|
214 |
-
|
215 |
-
private function resolveUri($uri)
|
216 |
-
{
|
217 |
-
$resolved = [];
|
218 |
-
$sections = explode('/', $uri);
|
219 |
-
foreach ($sections as $section) {
|
220 |
-
if ($section === '.' || $section === '') {
|
221 |
-
continue;
|
222 |
-
}
|
223 |
-
if ($section === '..') {
|
224 |
-
array_pop($resolved);
|
225 |
-
} else {
|
226 |
-
$resolved []= $section;
|
227 |
-
}
|
228 |
-
}
|
229 |
-
|
230 |
-
return ($uri[0] === '/' ? '/' : '')
|
231 |
-
. implode('/', $resolved);
|
232 |
-
}
|
233 |
-
|
234 |
-
private function createDownloadPromise()
|
235 |
-
{
|
236 |
-
$parts = $this->getS3Args($this->sourceMetadata['path']);
|
237 |
-
$prefix = "s3://{$parts['Bucket']}/"
|
238 |
-
. (isset($parts['Key']) ? $parts['Key'] . '/' : '');
|
239 |
-
|
240 |
-
|
241 |
-
$commands = [];
|
242 |
-
foreach ($this->getDownloadsIterator() as $object) {
|
243 |
-
// Prepare the sink.
|
244 |
-
$objectKey = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $object);
|
245 |
-
|
246 |
-
$resolveSink = $this->destination['path'] . '/';
|
247 |
-
if (isset($parts['Key']) && strpos($objectKey, $parts['Key']) !== 0) {
|
248 |
-
$resolveSink .= $parts['Key'] . '/';
|
249 |
-
}
|
250 |
-
$resolveSink .= $objectKey;
|
251 |
-
$sink = $this->destination['path'] . '/' . $objectKey;
|
252 |
-
|
253 |
-
$command = $this->client->getCommand(
|
254 |
-
'GetObject',
|
255 |
-
$this->getS3Args($object) + ['@http' => ['sink' => $sink]]
|
256 |
-
);
|
257 |
-
|
258 |
-
if (strpos(
|
259 |
-
$this->resolveUri($resolveSink),
|
260 |
-
$this->destination['path']
|
261 |
-
) !== 0
|
262 |
-
) {
|
263 |
-
throw new AwsException(
|
264 |
-
'Cannot download key ' . $objectKey
|
265 |
-
. ', its relative path resolves outside the'
|
266 |
-
. ' parent directory', $command);
|
267 |
-
}
|
268 |
-
|
269 |
-
// Create the directory if needed.
|
270 |
-
$dir = dirname($sink);
|
271 |
-
if (!is_dir($dir) && !mkdir($dir, 0777, true)) {
|
272 |
-
throw new \RuntimeException("Could not create dir: {$dir}");
|
273 |
-
}
|
274 |
-
|
275 |
-
// Create the command.
|
276 |
-
$commands []= $command;
|
277 |
-
}
|
278 |
-
|
279 |
-
// Create a GetObject command pool and return the promise.
|
280 |
-
return (new Aws\CommandPool($this->client, $commands, [
|
281 |
-
'concurrency' => $this->concurrency,
|
282 |
-
'before' => $this->before,
|
283 |
-
'rejected' => function ($reason, $idx, Promise\PromiseInterface $p) {
|
284 |
-
$p->reject($reason);
|
285 |
-
}
|
286 |
-
]))->promise();
|
287 |
-
}
|
288 |
-
|
289 |
-
private function createUploadPromise()
|
290 |
-
{
|
291 |
-
// Map each file into a promise that performs the actual transfer.
|
292 |
-
$files = \Aws\map($this->getUploadsIterator(), function ($file) {
|
293 |
-
return (filesize($file) >= $this->mupThreshold)
|
294 |
-
? $this->uploadMultipart($file)
|
295 |
-
: $this->upload($file);
|
296 |
-
});
|
297 |
-
|
298 |
-
// Create an EachPromise, that will concurrently handle the upload
|
299 |
-
// operations' yielded promises from the iterator.
|
300 |
-
return Promise\each_limit_all($files, $this->concurrency);
|
301 |
-
}
|
302 |
-
|
303 |
-
/** @return Iterator */
|
304 |
-
private function getUploadsIterator()
|
305 |
-
{
|
306 |
-
if (is_string($this->source)) {
|
307 |
-
return Aws\filter(
|
308 |
-
Aws\recursive_dir_iterator($this->sourceMetadata['path']),
|
309 |
-
function ($file) { return !is_dir($file); }
|
310 |
-
);
|
311 |
-
}
|
312 |
-
|
313 |
-
return $this->source;
|
314 |
-
}
|
315 |
-
|
316 |
-
/** @return Iterator */
|
317 |
-
private function getDownloadsIterator()
|
318 |
-
{
|
319 |
-
if (is_string($this->source)) {
|
320 |
-
$listArgs = $this->getS3Args($this->sourceMetadata['path']);
|
321 |
-
if (isset($listArgs['Key'])) {
|
322 |
-
$listArgs['Prefix'] = $listArgs['Key'] . '/';
|
323 |
-
unset($listArgs['Key']);
|
324 |
-
}
|
325 |
-
|
326 |
-
$files = $this->client
|
327 |
-
->getPaginator('ListObjects', $listArgs)
|
328 |
-
->search('Contents[].Key');
|
329 |
-
$files = Aws\map($files, function ($key) use ($listArgs) {
|
330 |
-
return "s3://{$listArgs['Bucket']}/$key";
|
331 |
-
});
|
332 |
-
return Aws\filter($files, function ($key) {
|
333 |
-
return substr($key, -1, 1) !== '/';
|
334 |
-
});
|
335 |
-
}
|
336 |
-
|
337 |
-
return $this->source;
|
338 |
-
}
|
339 |
-
|
340 |
-
private function upload($filename)
|
341 |
-
{
|
342 |
-
$args = $this->s3Args;
|
343 |
-
$args['SourceFile'] = $filename;
|
344 |
-
$args['Key'] = $this->createS3Key($filename);
|
345 |
-
$command = $this->client->getCommand('PutObject', $args);
|
346 |
-
$this->before and call_user_func($this->before, $command);
|
347 |
-
|
348 |
-
return $this->client->executeAsync($command);
|
349 |
-
}
|
350 |
-
|
351 |
-
private function uploadMultipart($filename)
|
352 |
-
{
|
353 |
-
$args = $this->s3Args;
|
354 |
-
$args['Key'] = $this->createS3Key($filename);
|
355 |
-
|
356 |
-
return (new MultipartUploader($this->client, $filename, [
|
357 |
-
'bucket' => $args['Bucket'],
|
358 |
-
'key' => $args['Key'],
|
359 |
-
'before_initiate' => $this->before,
|
360 |
-
'before_upload' => $this->before,
|
361 |
-
'before_complete' => $this->before,
|
362 |
-
'concurrency' => $this->concurrency,
|
363 |
-
]))->promise();
|
364 |
-
}
|
365 |
-
|
366 |
-
private function createS3Key($filename)
|
367 |
-
{
|
368 |
-
$filename = $this->normalizePath($filename);
|
369 |
-
$relative_file_path = ltrim(
|
370 |
-
preg_replace('#^' . preg_quote($this->sourceMetadata['path']) . '#', '', $filename),
|
371 |
-
'/\\'
|
372 |
-
);
|
373 |
-
|
374 |
-
if (isset($this->s3Args['Key'])) {
|
375 |
-
return rtrim($this->s3Args['Key'], '/').'/'.$relative_file_path;
|
376 |
-
}
|
377 |
-
|
378 |
-
return $relative_file_path;
|
379 |
-
}
|
380 |
-
|
381 |
-
private function addDebugToBefore($debug)
|
382 |
-
{
|
383 |
-
$before = $this->before;
|
384 |
-
$sourcePath = $this->sourceMetadata['path'];
|
385 |
-
$s3Args = $this->s3Args;
|
386 |
-
|
387 |
-
$this->before = static function (
|
388 |
-
CommandInterface $command
|
389 |
-
) use ($before, $debug, $sourcePath, $s3Args) {
|
390 |
-
// Call the composed before function.
|
391 |
-
$before and $before($command);
|
392 |
-
|
393 |
-
// Determine the source and dest values based on operation.
|
394 |
-
switch ($operation = $command->getName()) {
|
395 |
-
case 'GetObject':
|
396 |
-
$source = "s3://{$command['Bucket']}/{$command['Key']}";
|
397 |
-
$dest = $command['@http']['sink'];
|
398 |
-
break;
|
399 |
-
case 'PutObject':
|
400 |
-
$source = $command['SourceFile'];
|
401 |
-
$dest = "s3://{$command['Bucket']}/{$command['Key']}";
|
402 |
-
break;
|
403 |
-
case 'UploadPart':
|
404 |
-
$part = $command['PartNumber'];
|
405 |
-
case 'CreateMultipartUpload':
|
406 |
-
case 'CompleteMultipartUpload':
|
407 |
-
$sourceKey = $command['Key'];
|
408 |
-
if (isset($s3Args['Key']) && strpos($sourceKey, $s3Args['Key']) === 0) {
|
409 |
-
$sourceKey = substr($sourceKey, strlen($s3Args['Key']) + 1);
|
410 |
-
}
|
411 |
-
$source = "{$sourcePath}/{$sourceKey}";
|
412 |
-
$dest = "s3://{$command['Bucket']}/{$command['Key']}";
|
413 |
-
break;
|
414 |
-
default:
|
415 |
-
throw new \UnexpectedValueException(
|
416 |
-
"Transfer encountered an unexpected operation: {$operation}."
|
417 |
-
);
|
418 |
-
}
|
419 |
-
|
420 |
-
// Print the debugging message.
|
421 |
-
$context = sprintf('%s -> %s (%s)', $source, $dest, $operation);
|
422 |
-
if (isset($part)) {
|
423 |
-
$context .= " : Part={$part}";
|
424 |
-
}
|
425 |
-
fwrite($debug, "Transferring {$context}\n");
|
426 |
-
};
|
427 |
-
}
|
428 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Sdk.php
DELETED
@@ -1,466 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Builds AWS clients based on configuration settings.
|
6 |
-
*
|
7 |
-
* @method \Aws\ACMPCA\ACMPCAClient createACMPCA(array $args = [])
|
8 |
-
* @method \Aws\MultiRegionClient createMultiRegionACMPCA(array $args = [])
|
9 |
-
* @method \Aws\Acm\AcmClient createAcm(array $args = [])
|
10 |
-
* @method \Aws\MultiRegionClient createMultiRegionAcm(array $args = [])
|
11 |
-
* @method \Aws\AlexaForBusiness\AlexaForBusinessClient createAlexaForBusiness(array $args = [])
|
12 |
-
* @method \Aws\MultiRegionClient createMultiRegionAlexaForBusiness(array $args = [])
|
13 |
-
* @method \Aws\Amplify\AmplifyClient createAmplify(array $args = [])
|
14 |
-
* @method \Aws\MultiRegionClient createMultiRegionAmplify(array $args = [])
|
15 |
-
* @method \Aws\ApiGateway\ApiGatewayClient createApiGateway(array $args = [])
|
16 |
-
* @method \Aws\MultiRegionClient createMultiRegionApiGateway(array $args = [])
|
17 |
-
* @method \Aws\ApiGatewayManagementApi\ApiGatewayManagementApiClient createApiGatewayManagementApi(array $args = [])
|
18 |
-
* @method \Aws\MultiRegionClient createMultiRegionApiGatewayManagementApi(array $args = [])
|
19 |
-
* @method \Aws\ApiGatewayV2\ApiGatewayV2Client createApiGatewayV2(array $args = [])
|
20 |
-
* @method \Aws\MultiRegionClient createMultiRegionApiGatewayV2(array $args = [])
|
21 |
-
* @method \Aws\AppMesh\AppMeshClient createAppMesh(array $args = [])
|
22 |
-
* @method \Aws\MultiRegionClient createMultiRegionAppMesh(array $args = [])
|
23 |
-
* @method \Aws\AppSync\AppSyncClient createAppSync(array $args = [])
|
24 |
-
* @method \Aws\MultiRegionClient createMultiRegionAppSync(array $args = [])
|
25 |
-
* @method \Aws\ApplicationAutoScaling\ApplicationAutoScalingClient createApplicationAutoScaling(array $args = [])
|
26 |
-
* @method \Aws\MultiRegionClient createMultiRegionApplicationAutoScaling(array $args = [])
|
27 |
-
* @method \Aws\ApplicationDiscoveryService\ApplicationDiscoveryServiceClient createApplicationDiscoveryService(array $args = [])
|
28 |
-
* @method \Aws\MultiRegionClient createMultiRegionApplicationDiscoveryService(array $args = [])
|
29 |
-
* @method \Aws\Appstream\AppstreamClient createAppstream(array $args = [])
|
30 |
-
* @method \Aws\MultiRegionClient createMultiRegionAppstream(array $args = [])
|
31 |
-
* @method \Aws\Athena\AthenaClient createAthena(array $args = [])
|
32 |
-
* @method \Aws\MultiRegionClient createMultiRegionAthena(array $args = [])
|
33 |
-
* @method \Aws\AutoScaling\AutoScalingClient createAutoScaling(array $args = [])
|
34 |
-
* @method \Aws\MultiRegionClient createMultiRegionAutoScaling(array $args = [])
|
35 |
-
* @method \Aws\AutoScalingPlans\AutoScalingPlansClient createAutoScalingPlans(array $args = [])
|
36 |
-
* @method \Aws\MultiRegionClient createMultiRegionAutoScalingPlans(array $args = [])
|
37 |
-
* @method \Aws\Backup\BackupClient createBackup(array $args = [])
|
38 |
-
* @method \Aws\MultiRegionClient createMultiRegionBackup(array $args = [])
|
39 |
-
* @method \Aws\Batch\BatchClient createBatch(array $args = [])
|
40 |
-
* @method \Aws\MultiRegionClient createMultiRegionBatch(array $args = [])
|
41 |
-
* @method \Aws\Budgets\BudgetsClient createBudgets(array $args = [])
|
42 |
-
* @method \Aws\MultiRegionClient createMultiRegionBudgets(array $args = [])
|
43 |
-
* @method \Aws\Chime\ChimeClient createChime(array $args = [])
|
44 |
-
* @method \Aws\MultiRegionClient createMultiRegionChime(array $args = [])
|
45 |
-
* @method \Aws\Cloud9\Cloud9Client createCloud9(array $args = [])
|
46 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloud9(array $args = [])
|
47 |
-
* @method \Aws\CloudDirectory\CloudDirectoryClient createCloudDirectory(array $args = [])
|
48 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudDirectory(array $args = [])
|
49 |
-
* @method \Aws\CloudFormation\CloudFormationClient createCloudFormation(array $args = [])
|
50 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudFormation(array $args = [])
|
51 |
-
* @method \Aws\CloudFront\CloudFrontClient createCloudFront(array $args = [])
|
52 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudFront(array $args = [])
|
53 |
-
* @method \Aws\CloudHSMV2\CloudHSMV2Client createCloudHSMV2(array $args = [])
|
54 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudHSMV2(array $args = [])
|
55 |
-
* @method \Aws\CloudHsm\CloudHsmClient createCloudHsm(array $args = [])
|
56 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudHsm(array $args = [])
|
57 |
-
* @method \Aws\CloudSearch\CloudSearchClient createCloudSearch(array $args = [])
|
58 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudSearch(array $args = [])
|
59 |
-
* @method \Aws\CloudSearchDomain\CloudSearchDomainClient createCloudSearchDomain(array $args = [])
|
60 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudSearchDomain(array $args = [])
|
61 |
-
* @method \Aws\CloudTrail\CloudTrailClient createCloudTrail(array $args = [])
|
62 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudTrail(array $args = [])
|
63 |
-
* @method \Aws\CloudWatch\CloudWatchClient createCloudWatch(array $args = [])
|
64 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudWatch(array $args = [])
|
65 |
-
* @method \Aws\CloudWatchEvents\CloudWatchEventsClient createCloudWatchEvents(array $args = [])
|
66 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudWatchEvents(array $args = [])
|
67 |
-
* @method \Aws\CloudWatchLogs\CloudWatchLogsClient createCloudWatchLogs(array $args = [])
|
68 |
-
* @method \Aws\MultiRegionClient createMultiRegionCloudWatchLogs(array $args = [])
|
69 |
-
* @method \Aws\CodeBuild\CodeBuildClient createCodeBuild(array $args = [])
|
70 |
-
* @method \Aws\MultiRegionClient createMultiRegionCodeBuild(array $args = [])
|
71 |
-
* @method \Aws\CodeCommit\CodeCommitClient createCodeCommit(array $args = [])
|
72 |
-
* @method \Aws\MultiRegionClient createMultiRegionCodeCommit(array $args = [])
|
73 |
-
* @method \Aws\CodeDeploy\CodeDeployClient createCodeDeploy(array $args = [])
|
74 |
-
* @method \Aws\MultiRegionClient createMultiRegionCodeDeploy(array $args = [])
|
75 |
-
* @method \Aws\CodePipeline\CodePipelineClient createCodePipeline(array $args = [])
|
76 |
-
* @method \Aws\MultiRegionClient createMultiRegionCodePipeline(array $args = [])
|
77 |
-
* @method \Aws\CodeStar\CodeStarClient createCodeStar(array $args = [])
|
78 |
-
* @method \Aws\MultiRegionClient createMultiRegionCodeStar(array $args = [])
|
79 |
-
* @method \Aws\CognitoIdentity\CognitoIdentityClient createCognitoIdentity(array $args = [])
|
80 |
-
* @method \Aws\MultiRegionClient createMultiRegionCognitoIdentity(array $args = [])
|
81 |
-
* @method \Aws\CognitoIdentityProvider\CognitoIdentityProviderClient createCognitoIdentityProvider(array $args = [])
|
82 |
-
* @method \Aws\MultiRegionClient createMultiRegionCognitoIdentityProvider(array $args = [])
|
83 |
-
* @method \Aws\CognitoSync\CognitoSyncClient createCognitoSync(array $args = [])
|
84 |
-
* @method \Aws\MultiRegionClient createMultiRegionCognitoSync(array $args = [])
|
85 |
-
* @method \Aws\Comprehend\ComprehendClient createComprehend(array $args = [])
|
86 |
-
* @method \Aws\MultiRegionClient createMultiRegionComprehend(array $args = [])
|
87 |
-
* @method \Aws\ComprehendMedical\ComprehendMedicalClient createComprehendMedical(array $args = [])
|
88 |
-
* @method \Aws\MultiRegionClient createMultiRegionComprehendMedical(array $args = [])
|
89 |
-
* @method \Aws\ConfigService\ConfigServiceClient createConfigService(array $args = [])
|
90 |
-
* @method \Aws\MultiRegionClient createMultiRegionConfigService(array $args = [])
|
91 |
-
* @method \Aws\Connect\ConnectClient createConnect(array $args = [])
|
92 |
-
* @method \Aws\MultiRegionClient createMultiRegionConnect(array $args = [])
|
93 |
-
* @method \Aws\CostExplorer\CostExplorerClient createCostExplorer(array $args = [])
|
94 |
-
* @method \Aws\MultiRegionClient createMultiRegionCostExplorer(array $args = [])
|
95 |
-
* @method \Aws\CostandUsageReportService\CostandUsageReportServiceClient createCostandUsageReportService(array $args = [])
|
96 |
-
* @method \Aws\MultiRegionClient createMultiRegionCostandUsageReportService(array $args = [])
|
97 |
-
* @method \Aws\DAX\DAXClient createDAX(array $args = [])
|
98 |
-
* @method \Aws\MultiRegionClient createMultiRegionDAX(array $args = [])
|
99 |
-
* @method \Aws\DLM\DLMClient createDLM(array $args = [])
|
100 |
-
* @method \Aws\MultiRegionClient createMultiRegionDLM(array $args = [])
|
101 |
-
* @method \Aws\DataPipeline\DataPipelineClient createDataPipeline(array $args = [])
|
102 |
-
* @method \Aws\MultiRegionClient createMultiRegionDataPipeline(array $args = [])
|
103 |
-
* @method \Aws\DataSync\DataSyncClient createDataSync(array $args = [])
|
104 |
-
* @method \Aws\MultiRegionClient createMultiRegionDataSync(array $args = [])
|
105 |
-
* @method \Aws\DatabaseMigrationService\DatabaseMigrationServiceClient createDatabaseMigrationService(array $args = [])
|
106 |
-
* @method \Aws\MultiRegionClient createMultiRegionDatabaseMigrationService(array $args = [])
|
107 |
-
* @method \Aws\DeviceFarm\DeviceFarmClient createDeviceFarm(array $args = [])
|
108 |
-
* @method \Aws\MultiRegionClient createMultiRegionDeviceFarm(array $args = [])
|
109 |
-
* @method \Aws\DirectConnect\DirectConnectClient createDirectConnect(array $args = [])
|
110 |
-
* @method \Aws\MultiRegionClient createMultiRegionDirectConnect(array $args = [])
|
111 |
-
* @method \Aws\DirectoryService\DirectoryServiceClient createDirectoryService(array $args = [])
|
112 |
-
* @method \Aws\MultiRegionClient createMultiRegionDirectoryService(array $args = [])
|
113 |
-
* @method \Aws\DocDB\DocDBClient createDocDB(array $args = [])
|
114 |
-
* @method \Aws\MultiRegionClient createMultiRegionDocDB(array $args = [])
|
115 |
-
* @method \Aws\DynamoDb\DynamoDbClient createDynamoDb(array $args = [])
|
116 |
-
* @method \Aws\MultiRegionClient createMultiRegionDynamoDb(array $args = [])
|
117 |
-
* @method \Aws\DynamoDbStreams\DynamoDbStreamsClient createDynamoDbStreams(array $args = [])
|
118 |
-
* @method \Aws\MultiRegionClient createMultiRegionDynamoDbStreams(array $args = [])
|
119 |
-
* @method \Aws\EKS\EKSClient createEKS(array $args = [])
|
120 |
-
* @method \Aws\MultiRegionClient createMultiRegionEKS(array $args = [])
|
121 |
-
* @method \Aws\Ec2\Ec2Client createEc2(array $args = [])
|
122 |
-
* @method \Aws\MultiRegionClient createMultiRegionEc2(array $args = [])
|
123 |
-
* @method \Aws\Ecr\EcrClient createEcr(array $args = [])
|
124 |
-
* @method \Aws\MultiRegionClient createMultiRegionEcr(array $args = [])
|
125 |
-
* @method \Aws\Ecs\EcsClient createEcs(array $args = [])
|
126 |
-
* @method \Aws\MultiRegionClient createMultiRegionEcs(array $args = [])
|
127 |
-
* @method \Aws\Efs\EfsClient createEfs(array $args = [])
|
128 |
-
* @method \Aws\MultiRegionClient createMultiRegionEfs(array $args = [])
|
129 |
-
* @method \Aws\ElastiCache\ElastiCacheClient createElastiCache(array $args = [])
|
130 |
-
* @method \Aws\MultiRegionClient createMultiRegionElastiCache(array $args = [])
|
131 |
-
* @method \Aws\ElasticBeanstalk\ElasticBeanstalkClient createElasticBeanstalk(array $args = [])
|
132 |
-
* @method \Aws\MultiRegionClient createMultiRegionElasticBeanstalk(array $args = [])
|
133 |
-
* @method \Aws\ElasticLoadBalancing\ElasticLoadBalancingClient createElasticLoadBalancing(array $args = [])
|
134 |
-
* @method \Aws\MultiRegionClient createMultiRegionElasticLoadBalancing(array $args = [])
|
135 |
-
* @method \Aws\ElasticLoadBalancingV2\ElasticLoadBalancingV2Client createElasticLoadBalancingV2(array $args = [])
|
136 |
-
* @method \Aws\MultiRegionClient createMultiRegionElasticLoadBalancingV2(array $args = [])
|
137 |
-
* @method \Aws\ElasticTranscoder\ElasticTranscoderClient createElasticTranscoder(array $args = [])
|
138 |
-
* @method \Aws\MultiRegionClient createMultiRegionElasticTranscoder(array $args = [])
|
139 |
-
* @method \Aws\ElasticsearchService\ElasticsearchServiceClient createElasticsearchService(array $args = [])
|
140 |
-
* @method \Aws\MultiRegionClient createMultiRegionElasticsearchService(array $args = [])
|
141 |
-
* @method \Aws\Emr\EmrClient createEmr(array $args = [])
|
142 |
-
* @method \Aws\MultiRegionClient createMultiRegionEmr(array $args = [])
|
143 |
-
* @method \Aws\FMS\FMSClient createFMS(array $args = [])
|
144 |
-
* @method \Aws\MultiRegionClient createMultiRegionFMS(array $args = [])
|
145 |
-
* @method \Aws\FSx\FSxClient createFSx(array $args = [])
|
146 |
-
* @method \Aws\MultiRegionClient createMultiRegionFSx(array $args = [])
|
147 |
-
* @method \Aws\Firehose\FirehoseClient createFirehose(array $args = [])
|
148 |
-
* @method \Aws\MultiRegionClient createMultiRegionFirehose(array $args = [])
|
149 |
-
* @method \Aws\GameLift\GameLiftClient createGameLift(array $args = [])
|
150 |
-
* @method \Aws\MultiRegionClient createMultiRegionGameLift(array $args = [])
|
151 |
-
* @method \Aws\Glacier\GlacierClient createGlacier(array $args = [])
|
152 |
-
* @method \Aws\MultiRegionClient createMultiRegionGlacier(array $args = [])
|
153 |
-
* @method \Aws\GlobalAccelerator\GlobalAcceleratorClient createGlobalAccelerator(array $args = [])
|
154 |
-
* @method \Aws\MultiRegionClient createMultiRegionGlobalAccelerator(array $args = [])
|
155 |
-
* @method \Aws\Glue\GlueClient createGlue(array $args = [])
|
156 |
-
* @method \Aws\MultiRegionClient createMultiRegionGlue(array $args = [])
|
157 |
-
* @method \Aws\Greengrass\GreengrassClient createGreengrass(array $args = [])
|
158 |
-
* @method \Aws\MultiRegionClient createMultiRegionGreengrass(array $args = [])
|
159 |
-
* @method \Aws\GuardDuty\GuardDutyClient createGuardDuty(array $args = [])
|
160 |
-
* @method \Aws\MultiRegionClient createMultiRegionGuardDuty(array $args = [])
|
161 |
-
* @method \Aws\Health\HealthClient createHealth(array $args = [])
|
162 |
-
* @method \Aws\MultiRegionClient createMultiRegionHealth(array $args = [])
|
163 |
-
* @method \Aws\Iam\IamClient createIam(array $args = [])
|
164 |
-
* @method \Aws\MultiRegionClient createMultiRegionIam(array $args = [])
|
165 |
-
* @method \Aws\ImportExport\ImportExportClient createImportExport(array $args = [])
|
166 |
-
* @method \Aws\MultiRegionClient createMultiRegionImportExport(array $args = [])
|
167 |
-
* @method \Aws\Inspector\InspectorClient createInspector(array $args = [])
|
168 |
-
* @method \Aws\MultiRegionClient createMultiRegionInspector(array $args = [])
|
169 |
-
* @method \Aws\IoT1ClickDevicesService\IoT1ClickDevicesServiceClient createIoT1ClickDevicesService(array $args = [])
|
170 |
-
* @method \Aws\MultiRegionClient createMultiRegionIoT1ClickDevicesService(array $args = [])
|
171 |
-
* @method \Aws\IoT1ClickProjects\IoT1ClickProjectsClient createIoT1ClickProjects(array $args = [])
|
172 |
-
* @method \Aws\MultiRegionClient createMultiRegionIoT1ClickProjects(array $args = [])
|
173 |
-
* @method \Aws\IoTAnalytics\IoTAnalyticsClient createIoTAnalytics(array $args = [])
|
174 |
-
* @method \Aws\MultiRegionClient createMultiRegionIoTAnalytics(array $args = [])
|
175 |
-
* @method \Aws\IoTJobsDataPlane\IoTJobsDataPlaneClient createIoTJobsDataPlane(array $args = [])
|
176 |
-
* @method \Aws\MultiRegionClient createMultiRegionIoTJobsDataPlane(array $args = [])
|
177 |
-
* @method \Aws\Iot\IotClient createIot(array $args = [])
|
178 |
-
* @method \Aws\MultiRegionClient createMultiRegionIot(array $args = [])
|
179 |
-
* @method \Aws\IotDataPlane\IotDataPlaneClient createIotDataPlane(array $args = [])
|
180 |
-
* @method \Aws\MultiRegionClient createMultiRegionIotDataPlane(array $args = [])
|
181 |
-
* @method \Aws\Kafka\KafkaClient createKafka(array $args = [])
|
182 |
-
* @method \Aws\MultiRegionClient createMultiRegionKafka(array $args = [])
|
183 |
-
* @method \Aws\Kinesis\KinesisClient createKinesis(array $args = [])
|
184 |
-
* @method \Aws\MultiRegionClient createMultiRegionKinesis(array $args = [])
|
185 |
-
* @method \Aws\KinesisAnalytics\KinesisAnalyticsClient createKinesisAnalytics(array $args = [])
|
186 |
-
* @method \Aws\MultiRegionClient createMultiRegionKinesisAnalytics(array $args = [])
|
187 |
-
* @method \Aws\KinesisAnalyticsV2\KinesisAnalyticsV2Client createKinesisAnalyticsV2(array $args = [])
|
188 |
-
* @method \Aws\MultiRegionClient createMultiRegionKinesisAnalyticsV2(array $args = [])
|
189 |
-
* @method \Aws\KinesisVideo\KinesisVideoClient createKinesisVideo(array $args = [])
|
190 |
-
* @method \Aws\MultiRegionClient createMultiRegionKinesisVideo(array $args = [])
|
191 |
-
* @method \Aws\KinesisVideoArchivedMedia\KinesisVideoArchivedMediaClient createKinesisVideoArchivedMedia(array $args = [])
|
192 |
-
* @method \Aws\MultiRegionClient createMultiRegionKinesisVideoArchivedMedia(array $args = [])
|
193 |
-
* @method \Aws\KinesisVideoMedia\KinesisVideoMediaClient createKinesisVideoMedia(array $args = [])
|
194 |
-
* @method \Aws\MultiRegionClient createMultiRegionKinesisVideoMedia(array $args = [])
|
195 |
-
* @method \Aws\Kms\KmsClient createKms(array $args = [])
|
196 |
-
* @method \Aws\MultiRegionClient createMultiRegionKms(array $args = [])
|
197 |
-
* @method \Aws\Lambda\LambdaClient createLambda(array $args = [])
|
198 |
-
* @method \Aws\MultiRegionClient createMultiRegionLambda(array $args = [])
|
199 |
-
* @method \Aws\LexModelBuildingService\LexModelBuildingServiceClient createLexModelBuildingService(array $args = [])
|
200 |
-
* @method \Aws\MultiRegionClient createMultiRegionLexModelBuildingService(array $args = [])
|
201 |
-
* @method \Aws\LexRuntimeService\LexRuntimeServiceClient createLexRuntimeService(array $args = [])
|
202 |
-
* @method \Aws\MultiRegionClient createMultiRegionLexRuntimeService(array $args = [])
|
203 |
-
* @method \Aws\LicenseManager\LicenseManagerClient createLicenseManager(array $args = [])
|
204 |
-
* @method \Aws\MultiRegionClient createMultiRegionLicenseManager(array $args = [])
|
205 |
-
* @method \Aws\Lightsail\LightsailClient createLightsail(array $args = [])
|
206 |
-
* @method \Aws\MultiRegionClient createMultiRegionLightsail(array $args = [])
|
207 |
-
* @method \Aws\MQ\MQClient createMQ(array $args = [])
|
208 |
-
* @method \Aws\MultiRegionClient createMultiRegionMQ(array $args = [])
|
209 |
-
* @method \Aws\MTurk\MTurkClient createMTurk(array $args = [])
|
210 |
-
* @method \Aws\MultiRegionClient createMultiRegionMTurk(array $args = [])
|
211 |
-
* @method \Aws\MachineLearning\MachineLearningClient createMachineLearning(array $args = [])
|
212 |
-
* @method \Aws\MultiRegionClient createMultiRegionMachineLearning(array $args = [])
|
213 |
-
* @method \Aws\Macie\MacieClient createMacie(array $args = [])
|
214 |
-
* @method \Aws\MultiRegionClient createMultiRegionMacie(array $args = [])
|
215 |
-
* @method \Aws\ManagedBlockchain\ManagedBlockchainClient createManagedBlockchain(array $args = [])
|
216 |
-
* @method \Aws\MultiRegionClient createMultiRegionManagedBlockchain(array $args = [])
|
217 |
-
* @method \Aws\MarketplaceCommerceAnalytics\MarketplaceCommerceAnalyticsClient createMarketplaceCommerceAnalytics(array $args = [])
|
218 |
-
* @method \Aws\MultiRegionClient createMultiRegionMarketplaceCommerceAnalytics(array $args = [])
|
219 |
-
* @method \Aws\MarketplaceEntitlementService\MarketplaceEntitlementServiceClient createMarketplaceEntitlementService(array $args = [])
|
220 |
-
* @method \Aws\MultiRegionClient createMultiRegionMarketplaceEntitlementService(array $args = [])
|
221 |
-
* @method \Aws\MarketplaceMetering\MarketplaceMeteringClient createMarketplaceMetering(array $args = [])
|
222 |
-
* @method \Aws\MultiRegionClient createMultiRegionMarketplaceMetering(array $args = [])
|
223 |
-
* @method \Aws\MediaConnect\MediaConnectClient createMediaConnect(array $args = [])
|
224 |
-
* @method \Aws\MultiRegionClient createMultiRegionMediaConnect(array $args = [])
|
225 |
-
* @method \Aws\MediaConvert\MediaConvertClient createMediaConvert(array $args = [])
|
226 |
-
* @method \Aws\MultiRegionClient createMultiRegionMediaConvert(array $args = [])
|
227 |
-
* @method \Aws\MediaLive\MediaLiveClient createMediaLive(array $args = [])
|
228 |
-
* @method \Aws\MultiRegionClient createMultiRegionMediaLive(array $args = [])
|
229 |
-
* @method \Aws\MediaPackage\MediaPackageClient createMediaPackage(array $args = [])
|
230 |
-
* @method \Aws\MultiRegionClient createMultiRegionMediaPackage(array $args = [])
|
231 |
-
* @method \Aws\MediaStore\MediaStoreClient createMediaStore(array $args = [])
|
232 |
-
* @method \Aws\MultiRegionClient createMultiRegionMediaStore(array $args = [])
|
233 |
-
* @method \Aws\MediaStoreData\MediaStoreDataClient createMediaStoreData(array $args = [])
|
234 |
-
* @method \Aws\MultiRegionClient createMultiRegionMediaStoreData(array $args = [])
|
235 |
-
* @method \Aws\MediaTailor\MediaTailorClient createMediaTailor(array $args = [])
|
236 |
-
* @method \Aws\MultiRegionClient createMultiRegionMediaTailor(array $args = [])
|
237 |
-
* @method \Aws\MigrationHub\MigrationHubClient createMigrationHub(array $args = [])
|
238 |
-
* @method \Aws\MultiRegionClient createMultiRegionMigrationHub(array $args = [])
|
239 |
-
* @method \Aws\Mobile\MobileClient createMobile(array $args = [])
|
240 |
-
* @method \Aws\MultiRegionClient createMultiRegionMobile(array $args = [])
|
241 |
-
* @method \Aws\Neptune\NeptuneClient createNeptune(array $args = [])
|
242 |
-
* @method \Aws\MultiRegionClient createMultiRegionNeptune(array $args = [])
|
243 |
-
* @method \Aws\OpsWorks\OpsWorksClient createOpsWorks(array $args = [])
|
244 |
-
* @method \Aws\MultiRegionClient createMultiRegionOpsWorks(array $args = [])
|
245 |
-
* @method \Aws\OpsWorksCM\OpsWorksCMClient createOpsWorksCM(array $args = [])
|
246 |
-
* @method \Aws\MultiRegionClient createMultiRegionOpsWorksCM(array $args = [])
|
247 |
-
* @method \Aws\Organizations\OrganizationsClient createOrganizations(array $args = [])
|
248 |
-
* @method \Aws\MultiRegionClient createMultiRegionOrganizations(array $args = [])
|
249 |
-
* @method \Aws\PI\PIClient createPI(array $args = [])
|
250 |
-
* @method \Aws\MultiRegionClient createMultiRegionPI(array $args = [])
|
251 |
-
* @method \Aws\Pinpoint\PinpointClient createPinpoint(array $args = [])
|
252 |
-
* @method \Aws\MultiRegionClient createMultiRegionPinpoint(array $args = [])
|
253 |
-
* @method \Aws\PinpointEmail\PinpointEmailClient createPinpointEmail(array $args = [])
|
254 |
-
* @method \Aws\MultiRegionClient createMultiRegionPinpointEmail(array $args = [])
|
255 |
-
* @method \Aws\PinpointSMSVoice\PinpointSMSVoiceClient createPinpointSMSVoice(array $args = [])
|
256 |
-
* @method \Aws\MultiRegionClient createMultiRegionPinpointSMSVoice(array $args = [])
|
257 |
-
* @method \Aws\Polly\PollyClient createPolly(array $args = [])
|
258 |
-
* @method \Aws\MultiRegionClient createMultiRegionPolly(array $args = [])
|
259 |
-
* @method \Aws\Pricing\PricingClient createPricing(array $args = [])
|
260 |
-
* @method \Aws\MultiRegionClient createMultiRegionPricing(array $args = [])
|
261 |
-
* @method \Aws\QuickSight\QuickSightClient createQuickSight(array $args = [])
|
262 |
-
* @method \Aws\MultiRegionClient createMultiRegionQuickSight(array $args = [])
|
263 |
-
* @method \Aws\RAM\RAMClient createRAM(array $args = [])
|
264 |
-
* @method \Aws\MultiRegionClient createMultiRegionRAM(array $args = [])
|
265 |
-
* @method \Aws\RDSDataService\RDSDataServiceClient createRDSDataService(array $args = [])
|
266 |
-
* @method \Aws\MultiRegionClient createMultiRegionRDSDataService(array $args = [])
|
267 |
-
* @method \Aws\Rds\RdsClient createRds(array $args = [])
|
268 |
-
* @method \Aws\MultiRegionClient createMultiRegionRds(array $args = [])
|
269 |
-
* @method \Aws\Redshift\RedshiftClient createRedshift(array $args = [])
|
270 |
-
* @method \Aws\MultiRegionClient createMultiRegionRedshift(array $args = [])
|
271 |
-
* @method \Aws\Rekognition\RekognitionClient createRekognition(array $args = [])
|
272 |
-
* @method \Aws\MultiRegionClient createMultiRegionRekognition(array $args = [])
|
273 |
-
* @method \Aws\ResourceGroups\ResourceGroupsClient createResourceGroups(array $args = [])
|
274 |
-
* @method \Aws\MultiRegionClient createMultiRegionResourceGroups(array $args = [])
|
275 |
-
* @method \Aws\ResourceGroupsTaggingAPI\ResourceGroupsTaggingAPIClient createResourceGroupsTaggingAPI(array $args = [])
|
276 |
-
* @method \Aws\MultiRegionClient createMultiRegionResourceGroupsTaggingAPI(array $args = [])
|
277 |
-
* @method \Aws\RoboMaker\RoboMakerClient createRoboMaker(array $args = [])
|
278 |
-
* @method \Aws\MultiRegionClient createMultiRegionRoboMaker(array $args = [])
|
279 |
-
* @method \Aws\Route53\Route53Client createRoute53(array $args = [])
|
280 |
-
* @method \Aws\MultiRegionClient createMultiRegionRoute53(array $args = [])
|
281 |
-
* @method \Aws\Route53Domains\Route53DomainsClient createRoute53Domains(array $args = [])
|
282 |
-
* @method \Aws\MultiRegionClient createMultiRegionRoute53Domains(array $args = [])
|
283 |
-
* @method \Aws\Route53Resolver\Route53ResolverClient createRoute53Resolver(array $args = [])
|
284 |
-
* @method \Aws\MultiRegionClient createMultiRegionRoute53Resolver(array $args = [])
|
285 |
-
* @method \Aws\S3\S3Client createS3(array $args = [])
|
286 |
-
* @method \Aws\S3\S3MultiRegionClient createMultiRegionS3(array $args = [])
|
287 |
-
* @method \Aws\S3Control\S3ControlClient createS3Control(array $args = [])
|
288 |
-
* @method \Aws\MultiRegionClient createMultiRegionS3Control(array $args = [])
|
289 |
-
* @method \Aws\SageMaker\SageMakerClient createSageMaker(array $args = [])
|
290 |
-
* @method \Aws\MultiRegionClient createMultiRegionSageMaker(array $args = [])
|
291 |
-
* @method \Aws\SageMakerRuntime\SageMakerRuntimeClient createSageMakerRuntime(array $args = [])
|
292 |
-
* @method \Aws\MultiRegionClient createMultiRegionSageMakerRuntime(array $args = [])
|
293 |
-
* @method \Aws\SecretsManager\SecretsManagerClient createSecretsManager(array $args = [])
|
294 |
-
* @method \Aws\MultiRegionClient createMultiRegionSecretsManager(array $args = [])
|
295 |
-
* @method \Aws\SecurityHub\SecurityHubClient createSecurityHub(array $args = [])
|
296 |
-
* @method \Aws\MultiRegionClient createMultiRegionSecurityHub(array $args = [])
|
297 |
-
* @method \Aws\ServerlessApplicationRepository\ServerlessApplicationRepositoryClient createServerlessApplicationRepository(array $args = [])
|
298 |
-
* @method \Aws\MultiRegionClient createMultiRegionServerlessApplicationRepository(array $args = [])
|
299 |
-
* @method \Aws\ServiceCatalog\ServiceCatalogClient createServiceCatalog(array $args = [])
|
300 |
-
* @method \Aws\MultiRegionClient createMultiRegionServiceCatalog(array $args = [])
|
301 |
-
* @method \Aws\ServiceDiscovery\ServiceDiscoveryClient createServiceDiscovery(array $args = [])
|
302 |
-
* @method \Aws\MultiRegionClient createMultiRegionServiceDiscovery(array $args = [])
|
303 |
-
* @method \Aws\Ses\SesClient createSes(array $args = [])
|
304 |
-
* @method \Aws\MultiRegionClient createMultiRegionSes(array $args = [])
|
305 |
-
* @method \Aws\Sfn\SfnClient createSfn(array $args = [])
|
306 |
-
* @method \Aws\MultiRegionClient createMultiRegionSfn(array $args = [])
|
307 |
-
* @method \Aws\Shield\ShieldClient createShield(array $args = [])
|
308 |
-
* @method \Aws\MultiRegionClient createMultiRegionShield(array $args = [])
|
309 |
-
* @method \Aws\Sms\SmsClient createSms(array $args = [])
|
310 |
-
* @method \Aws\MultiRegionClient createMultiRegionSms(array $args = [])
|
311 |
-
* @method \Aws\SnowBall\SnowBallClient createSnowBall(array $args = [])
|
312 |
-
* @method \Aws\MultiRegionClient createMultiRegionSnowBall(array $args = [])
|
313 |
-
* @method \Aws\Sns\SnsClient createSns(array $args = [])
|
314 |
-
* @method \Aws\MultiRegionClient createMultiRegionSns(array $args = [])
|
315 |
-
* @method \Aws\Sqs\SqsClient createSqs(array $args = [])
|
316 |
-
* @method \Aws\MultiRegionClient createMultiRegionSqs(array $args = [])
|
317 |
-
* @method \Aws\Ssm\SsmClient createSsm(array $args = [])
|
318 |
-
* @method \Aws\MultiRegionClient createMultiRegionSsm(array $args = [])
|
319 |
-
* @method \Aws\StorageGateway\StorageGatewayClient createStorageGateway(array $args = [])
|
320 |
-
* @method \Aws\MultiRegionClient createMultiRegionStorageGateway(array $args = [])
|
321 |
-
* @method \Aws\Sts\StsClient createSts(array $args = [])
|
322 |
-
* @method \Aws\MultiRegionClient createMultiRegionSts(array $args = [])
|
323 |
-
* @method \Aws\Support\SupportClient createSupport(array $args = [])
|
324 |
-
* @method \Aws\MultiRegionClient createMultiRegionSupport(array $args = [])
|
325 |
-
* @method \Aws\Swf\SwfClient createSwf(array $args = [])
|
326 |
-
* @method \Aws\MultiRegionClient createMultiRegionSwf(array $args = [])
|
327 |
-
* @method \Aws\Textract\TextractClient createTextract(array $args = [])
|
328 |
-
* @method \Aws\MultiRegionClient createMultiRegionTextract(array $args = [])
|
329 |
-
* @method \Aws\TranscribeService\TranscribeServiceClient createTranscribeService(array $args = [])
|
330 |
-
* @method \Aws\MultiRegionClient createMultiRegionTranscribeService(array $args = [])
|
331 |
-
* @method \Aws\Transfer\TransferClient createTransfer(array $args = [])
|
332 |
-
* @method \Aws\MultiRegionClient createMultiRegionTransfer(array $args = [])
|
333 |
-
* @method \Aws\Translate\TranslateClient createTranslate(array $args = [])
|
334 |
-
* @method \Aws\MultiRegionClient createMultiRegionTranslate(array $args = [])
|
335 |
-
* @method \Aws\Waf\WafClient createWaf(array $args = [])
|
336 |
-
* @method \Aws\MultiRegionClient createMultiRegionWaf(array $args = [])
|
337 |
-
* @method \Aws\WafRegional\WafRegionalClient createWafRegional(array $args = [])
|
338 |
-
* @method \Aws\MultiRegionClient createMultiRegionWafRegional(array $args = [])
|
339 |
-
* @method \Aws\WorkDocs\WorkDocsClient createWorkDocs(array $args = [])
|
340 |
-
* @method \Aws\MultiRegionClient createMultiRegionWorkDocs(array $args = [])
|
341 |
-
* @method \Aws\WorkLink\WorkLinkClient createWorkLink(array $args = [])
|
342 |
-
* @method \Aws\MultiRegionClient createMultiRegionWorkLink(array $args = [])
|
343 |
-
* @method \Aws\WorkMail\WorkMailClient createWorkMail(array $args = [])
|
344 |
-
* @method \Aws\MultiRegionClient createMultiRegionWorkMail(array $args = [])
|
345 |
-
* @method \Aws\WorkSpaces\WorkSpacesClient createWorkSpaces(array $args = [])
|
346 |
-
* @method \Aws\MultiRegionClient createMultiRegionWorkSpaces(array $args = [])
|
347 |
-
* @method \Aws\XRay\XRayClient createXRay(array $args = [])
|
348 |
-
* @method \Aws\MultiRegionClient createMultiRegionXRay(array $args = [])
|
349 |
-
* @method \Aws\signer\signerClient createsigner(array $args = [])
|
350 |
-
* @method \Aws\MultiRegionClient createMultiRegionsigner(array $args = [])
|
351 |
-
*/
|
352 |
-
class Sdk
|
353 |
-
{
|
354 |
-
const VERSION = '3.93.9';
|
355 |
-
|
356 |
-
/** @var array Arguments for creating clients */
|
357 |
-
private $args;
|
358 |
-
|
359 |
-
/**
|
360 |
-
* Constructs a new SDK object with an associative array of default
|
361 |
-
* client settings.
|
362 |
-
*
|
363 |
-
* @param array $args
|
364 |
-
*
|
365 |
-
* @throws \InvalidArgumentException
|
366 |
-
* @see Aws\AwsClient::__construct for a list of available options.
|
367 |
-
*/
|
368 |
-
public function __construct(array $args = [])
|
369 |
-
{
|
370 |
-
$this->args = $args;
|
371 |
-
|
372 |
-
if (!isset($args['handler']) && !isset($args['http_handler'])) {
|
373 |
-
$this->args['http_handler'] = default_http_handler();
|
374 |
-
}
|
375 |
-
}
|
376 |
-
|
377 |
-
public function __call($name, array $args)
|
378 |
-
{
|
379 |
-
$args = isset($args[0]) ? $args[0] : [];
|
380 |
-
if (strpos($name, 'createMultiRegion') === 0) {
|
381 |
-
return $this->createMultiRegionClient(substr($name, 17), $args);
|
382 |
-
}
|
383 |
-
|
384 |
-
if (strpos($name, 'create') === 0) {
|
385 |
-
return $this->createClient(substr($name, 6), $args);
|
386 |
-
}
|
387 |
-
|
388 |
-
throw new \BadMethodCallException("Unknown method: {$name}.");
|
389 |
-
}
|
390 |
-
|
391 |
-
/**
|
392 |
-
* Get a client by name using an array of constructor options.
|
393 |
-
*
|
394 |
-
* @param string $name Service name or namespace (e.g., DynamoDb, s3).
|
395 |
-
* @param array $args Arguments to configure the client.
|
396 |
-
*
|
397 |
-
* @return AwsClientInterface
|
398 |
-
* @throws \InvalidArgumentException if any required options are missing or
|
399 |
-
* the service is not supported.
|
400 |
-
* @see Aws\AwsClient::__construct for a list of available options for args.
|
401 |
-
*/
|
402 |
-
public function createClient($name, array $args = [])
|
403 |
-
{
|
404 |
-
// Get information about the service from the manifest file.
|
405 |
-
$service = manifest($name);
|
406 |
-
$namespace = $service['namespace'];
|
407 |
-
|
408 |
-
// Instantiate the client class.
|
409 |
-
$client = "Aws\\{$namespace}\\{$namespace}Client";
|
410 |
-
return new $client($this->mergeArgs($namespace, $service, $args));
|
411 |
-
}
|
412 |
-
|
413 |
-
public function createMultiRegionClient($name, array $args = [])
|
414 |
-
{
|
415 |
-
// Get information about the service from the manifest file.
|
416 |
-
$service = manifest($name);
|
417 |
-
$namespace = $service['namespace'];
|
418 |
-
|
419 |
-
$klass = "Aws\\{$namespace}\\{$namespace}MultiRegionClient";
|
420 |
-
$klass = class_exists($klass) ? $klass : 'Aws\\MultiRegionClient';
|
421 |
-
|
422 |
-
return new $klass($this->mergeArgs($namespace, $service, $args));
|
423 |
-
}
|
424 |
-
|
425 |
-
/**
|
426 |
-
* Clone existing SDK instance with ability to pass an associative array
|
427 |
-
* of extra client settings.
|
428 |
-
*
|
429 |
-
* @param array $args
|
430 |
-
*
|
431 |
-
* @return self
|
432 |
-
*/
|
433 |
-
public function copy(array $args = [])
|
434 |
-
{
|
435 |
-
return new self($args + $this->args);
|
436 |
-
}
|
437 |
-
|
438 |
-
private function mergeArgs($namespace, array $manifest, array $args = [])
|
439 |
-
{
|
440 |
-
// Merge provided args with stored, service-specific args.
|
441 |
-
if (isset($this->args[$namespace])) {
|
442 |
-
$args += $this->args[$namespace];
|
443 |
-
}
|
444 |
-
|
445 |
-
// Provide the endpoint prefix in the args.
|
446 |
-
if (!isset($args['service'])) {
|
447 |
-
$args['service'] = $manifest['endpoint'];
|
448 |
-
}
|
449 |
-
|
450 |
-
return $args + $this->args;
|
451 |
-
}
|
452 |
-
|
453 |
-
/**
|
454 |
-
* Determine the endpoint prefix from a client namespace.
|
455 |
-
*
|
456 |
-
* @param string $name Namespace name
|
457 |
-
*
|
458 |
-
* @return string
|
459 |
-
* @internal
|
460 |
-
* @deprecated Use the `\Aws\manifest()` function instead.
|
461 |
-
*/
|
462 |
-
public static function getEndpointPrefix($name)
|
463 |
-
{
|
464 |
-
return manifest($name)['endpoint'];
|
465 |
-
}
|
466 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Signature/AnonymousSignature.php
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Signature;
|
3 |
-
|
4 |
-
use Aws\Credentials\CredentialsInterface;
|
5 |
-
use Psr\Http\Message\RequestInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Provides anonymous client access (does not sign requests).
|
9 |
-
*/
|
10 |
-
class AnonymousSignature implements SignatureInterface
|
11 |
-
{
|
12 |
-
public function signRequest(
|
13 |
-
RequestInterface $request,
|
14 |
-
CredentialsInterface $credentials
|
15 |
-
) {
|
16 |
-
return $request;
|
17 |
-
}
|
18 |
-
|
19 |
-
public function presign(
|
20 |
-
RequestInterface $request,
|
21 |
-
CredentialsInterface $credentials,
|
22 |
-
$expires
|
23 |
-
) {
|
24 |
-
return $request;
|
25 |
-
}
|
26 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Signature/S3SignatureV4.php
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Signature;
|
3 |
-
|
4 |
-
use Aws\Credentials\CredentialsInterface;
|
5 |
-
use Psr\Http\Message\RequestInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Amazon S3 signature version 4 support.
|
9 |
-
*/
|
10 |
-
class S3SignatureV4 extends SignatureV4
|
11 |
-
{
|
12 |
-
/**
|
13 |
-
* Always add a x-amz-content-sha-256 for data integrity.
|
14 |
-
*/
|
15 |
-
public function signRequest(
|
16 |
-
RequestInterface $request,
|
17 |
-
CredentialsInterface $credentials
|
18 |
-
) {
|
19 |
-
if (!$request->hasHeader('x-amz-content-sha256')) {
|
20 |
-
$request = $request->withHeader(
|
21 |
-
'X-Amz-Content-Sha256',
|
22 |
-
$this->getPayload($request)
|
23 |
-
);
|
24 |
-
}
|
25 |
-
|
26 |
-
return parent::signRequest($request, $credentials);
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Always add a x-amz-content-sha-256 for data integrity.
|
31 |
-
*/
|
32 |
-
public function presign(
|
33 |
-
RequestInterface $request,
|
34 |
-
CredentialsInterface $credentials,
|
35 |
-
$expires,
|
36 |
-
array $options = []
|
37 |
-
) {
|
38 |
-
if (!$request->hasHeader('x-amz-content-sha256')) {
|
39 |
-
$request = $request->withHeader(
|
40 |
-
'X-Amz-Content-Sha256',
|
41 |
-
$this->getPresignedPayload($request)
|
42 |
-
);
|
43 |
-
}
|
44 |
-
|
45 |
-
return parent::presign($request, $credentials, $expires, $options);
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Override used to allow pre-signed URLs to be created for an
|
50 |
-
* in-determinate request payload.
|
51 |
-
*/
|
52 |
-
protected function getPresignedPayload(RequestInterface $request)
|
53 |
-
{
|
54 |
-
return SignatureV4::UNSIGNED_PAYLOAD;
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Amazon S3 does not double-encode the path component in the canonical request
|
59 |
-
*/
|
60 |
-
protected function createCanonicalizedPath($path)
|
61 |
-
{
|
62 |
-
// Only remove one slash in case of keys that have a preceding slash
|
63 |
-
if (substr($path, 0, 1) === '/') {
|
64 |
-
$path = substr($path, 1);
|
65 |
-
}
|
66 |
-
return '/' . $path;
|
67 |
-
}
|
68 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Signature/SignatureInterface.php
DELETED
@@ -1,44 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Signature;
|
3 |
-
|
4 |
-
use Aws\Credentials\CredentialsInterface;
|
5 |
-
use Psr\Http\Message\RequestInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Interface used to provide interchangeable strategies for signing requests
|
9 |
-
* using the various AWS signature protocols.
|
10 |
-
*/
|
11 |
-
interface SignatureInterface
|
12 |
-
{
|
13 |
-
/**
|
14 |
-
* Signs the specified request with an AWS signing protocol by using the
|
15 |
-
* provided AWS account credentials and adding the required headers to the
|
16 |
-
* request.
|
17 |
-
*
|
18 |
-
* @param RequestInterface $request Request to sign
|
19 |
-
* @param CredentialsInterface $credentials Signing credentials
|
20 |
-
*
|
21 |
-
* @return RequestInterface Returns the modified request.
|
22 |
-
*/
|
23 |
-
public function signRequest(
|
24 |
-
RequestInterface $request,
|
25 |
-
CredentialsInterface $credentials
|
26 |
-
);
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Create a pre-signed request.
|
30 |
-
*
|
31 |
-
* @param RequestInterface $request Request to sign
|
32 |
-
* @param CredentialsInterface $credentials Credentials used to sign
|
33 |
-
* @param int|string|\DateTime $expires The time at which the URL should
|
34 |
-
* expire. This can be a Unix timestamp, a PHP DateTime object, or a
|
35 |
-
* string that can be evaluated by strtotime.
|
36 |
-
*
|
37 |
-
* @return RequestInterface
|
38 |
-
*/
|
39 |
-
public function presign(
|
40 |
-
RequestInterface $request,
|
41 |
-
CredentialsInterface $credentials,
|
42 |
-
$expires
|
43 |
-
);
|
44 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Signature/SignatureProvider.php
DELETED
@@ -1,131 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Signature;
|
3 |
-
|
4 |
-
use Aws\Exception\UnresolvedSignatureException;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Signature providers.
|
8 |
-
*
|
9 |
-
* A signature provider is a function that accepts a version, service, and
|
10 |
-
* region and returns a {@see SignatureInterface} object on success or NULL if
|
11 |
-
* no signature can be created from the provided arguments.
|
12 |
-
*
|
13 |
-
* You can wrap your calls to a signature provider with the
|
14 |
-
* {@see SignatureProvider::resolve} function to ensure that a signature object
|
15 |
-
* is created. If a signature object is not created, then the resolve()
|
16 |
-
* function will throw a {@see Aws\Exception\UnresolvedSignatureException}.
|
17 |
-
*
|
18 |
-
* use Aws\Signature\SignatureProvider;
|
19 |
-
* $provider = SignatureProvider::defaultProvider();
|
20 |
-
* // Returns a SignatureInterface or NULL.
|
21 |
-
* $signer = $provider('v4', 's3', 'us-west-2');
|
22 |
-
* // Returns a SignatureInterface or throws.
|
23 |
-
* $signer = SignatureProvider::resolve($provider, 'no', 's3', 'foo');
|
24 |
-
*
|
25 |
-
* You can compose multiple providers into a single provider using
|
26 |
-
* {@see Aws\or_chain}. This function accepts providers as arguments and
|
27 |
-
* returns a new function that will invoke each provider until a non-null value
|
28 |
-
* is returned.
|
29 |
-
*
|
30 |
-
* $a = SignatureProvider::defaultProvider();
|
31 |
-
* $b = function ($version, $service, $region) {
|
32 |
-
* if ($version === 'foo') {
|
33 |
-
* return new MyFooSignature();
|
34 |
-
* }
|
35 |
-
* };
|
36 |
-
* $c = \Aws\or_chain($a, $b);
|
37 |
-
* $signer = $c('v4', 'abc', '123'); // $a handles this.
|
38 |
-
* $signer = $c('foo', 'abc', '123'); // $b handles this.
|
39 |
-
* $nullValue = $c('???', 'abc', '123'); // Neither can handle this.
|
40 |
-
*/
|
41 |
-
class SignatureProvider
|
42 |
-
{
|
43 |
-
private static $s3v4SignedServices = [
|
44 |
-
's3' => true,
|
45 |
-
's3control' => true,
|
46 |
-
];
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Resolves and signature provider and ensures a non-null return value.
|
50 |
-
*
|
51 |
-
* @param callable $provider Provider function to invoke.
|
52 |
-
* @param string $version Signature version.
|
53 |
-
* @param string $service Service name.
|
54 |
-
* @param string $region Region name.
|
55 |
-
*
|
56 |
-
* @return SignatureInterface
|
57 |
-
* @throws UnresolvedSignatureException
|
58 |
-
*/
|
59 |
-
public static function resolve(callable $provider, $version, $service, $region)
|
60 |
-
{
|
61 |
-
$result = $provider($version, $service, $region);
|
62 |
-
if ($result instanceof SignatureInterface) {
|
63 |
-
return $result;
|
64 |
-
}
|
65 |
-
|
66 |
-
throw new UnresolvedSignatureException(
|
67 |
-
"Unable to resolve a signature for $version/$service/$region.\n"
|
68 |
-
. "Valid signature versions include v4 and anonymous."
|
69 |
-
);
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Default SDK signature provider.
|
74 |
-
*
|
75 |
-
* @return callable
|
76 |
-
*/
|
77 |
-
public static function defaultProvider()
|
78 |
-
{
|
79 |
-
return self::memoize(self::version());
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Creates a signature provider that caches previously created signature
|
84 |
-
* objects. The computed cache key is the concatenation of the version,
|
85 |
-
* service, and region.
|
86 |
-
*
|
87 |
-
* @param callable $provider Signature provider to wrap.
|
88 |
-
*
|
89 |
-
* @return callable
|
90 |
-
*/
|
91 |
-
public static function memoize(callable $provider)
|
92 |
-
{
|
93 |
-
$cache = [];
|
94 |
-
return function ($version, $service, $region) use (&$cache, $provider) {
|
95 |
-
$key = "($version)($service)($region)";
|
96 |
-
if (!isset($cache[$key])) {
|
97 |
-
$cache[$key] = $provider($version, $service, $region);
|
98 |
-
}
|
99 |
-
return $cache[$key];
|
100 |
-
};
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Creates signature objects from known signature versions.
|
105 |
-
*
|
106 |
-
* This provider currently recognizes the following signature versions:
|
107 |
-
*
|
108 |
-
* - v4: Signature version 4.
|
109 |
-
* - anonymous: Does not sign requests.
|
110 |
-
*
|
111 |
-
* @return callable
|
112 |
-
*/
|
113 |
-
public static function version()
|
114 |
-
{
|
115 |
-
return function ($version, $service, $region) {
|
116 |
-
switch ($version) {
|
117 |
-
case 's3v4':
|
118 |
-
case 'v4':
|
119 |
-
return !empty(self::$s3v4SignedServices[$service])
|
120 |
-
? new S3SignatureV4($service, $region)
|
121 |
-
: new SignatureV4($service, $region);
|
122 |
-
case 'v4-unsigned-body':
|
123 |
-
return new SignatureV4($service, $region, ['unsigned-body' => 'true']);
|
124 |
-
case 'anonymous':
|
125 |
-
return new AnonymousSignature();
|
126 |
-
default:
|
127 |
-
return null;
|
128 |
-
}
|
129 |
-
};
|
130 |
-
}
|
131 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Signature/SignatureV4.php
DELETED
@@ -1,412 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Signature;
|
3 |
-
|
4 |
-
use Aws\Credentials\CredentialsInterface;
|
5 |
-
use Aws\Exception\CouldNotCreateChecksumException;
|
6 |
-
use GuzzleHttp\Psr7;
|
7 |
-
use Psr\Http\Message\RequestInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Signature Version 4
|
11 |
-
* @link http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
|
12 |
-
*/
|
13 |
-
class SignatureV4 implements SignatureInterface
|
14 |
-
{
|
15 |
-
use SignatureTrait;
|
16 |
-
const ISO8601_BASIC = 'Ymd\THis\Z';
|
17 |
-
const UNSIGNED_PAYLOAD = 'UNSIGNED-PAYLOAD';
|
18 |
-
const AMZ_CONTENT_SHA256_HEADER = 'X-Amz-Content-Sha256';
|
19 |
-
|
20 |
-
/** @var string */
|
21 |
-
private $service;
|
22 |
-
|
23 |
-
/** @var string */
|
24 |
-
private $region;
|
25 |
-
|
26 |
-
/** @var bool */
|
27 |
-
private $unsigned;
|
28 |
-
|
29 |
-
/**
|
30 |
-
* The following headers are not signed because signing these headers
|
31 |
-
* would potentially cause a signature mismatch when sending a request
|
32 |
-
* through a proxy or if modified at the HTTP client level.
|
33 |
-
*
|
34 |
-
* @return array
|
35 |
-
*/
|
36 |
-
private function getHeaderBlacklist()
|
37 |
-
{
|
38 |
-
return [
|
39 |
-
'cache-control' => true,
|
40 |
-
'content-type' => true,
|
41 |
-
'content-length' => true,
|
42 |
-
'expect' => true,
|
43 |
-
'max-forwards' => true,
|
44 |
-
'pragma' => true,
|
45 |
-
'range' => true,
|
46 |
-
'te' => true,
|
47 |
-
'if-match' => true,
|
48 |
-
'if-none-match' => true,
|
49 |
-
'if-modified-since' => true,
|
50 |
-
'if-unmodified-since' => true,
|
51 |
-
'if-range' => true,
|
52 |
-
'accept' => true,
|
53 |
-
'authorization' => true,
|
54 |
-
'proxy-authorization' => true,
|
55 |
-
'from' => true,
|
56 |
-
'referer' => true,
|
57 |
-
'user-agent' => true,
|
58 |
-
'x-amzn-trace-id' => true,
|
59 |
-
'aws-sdk-invocation-id' => true,
|
60 |
-
'aws-sdk-retry' => true,
|
61 |
-
];
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* @param string $service Service name to use when signing
|
66 |
-
* @param string $region Region name to use when signing
|
67 |
-
* @param array $options Array of configuration options used when signing
|
68 |
-
* - unsigned-body: Flag to make request have unsigned payload.
|
69 |
-
* Unsigned body is used primarily for streaming requests.
|
70 |
-
*/
|
71 |
-
public function __construct($service, $region, array $options = [])
|
72 |
-
{
|
73 |
-
$this->service = $service;
|
74 |
-
$this->region = $region;
|
75 |
-
$this->unsigned = isset($options['unsigned-body']) ? $options['unsigned-body'] : false;
|
76 |
-
}
|
77 |
-
|
78 |
-
public function signRequest(
|
79 |
-
RequestInterface $request,
|
80 |
-
CredentialsInterface $credentials
|
81 |
-
) {
|
82 |
-
$ldt = gmdate(self::ISO8601_BASIC);
|
83 |
-
$sdt = substr($ldt, 0, 8);
|
84 |
-
$parsed = $this->parseRequest($request);
|
85 |
-
$parsed['headers']['X-Amz-Date'] = [$ldt];
|
86 |
-
|
87 |
-
if ($token = $credentials->getSecurityToken()) {
|
88 |
-
$parsed['headers']['X-Amz-Security-Token'] = [$token];
|
89 |
-
}
|
90 |
-
$cs = $this->createScope($sdt, $this->region, $this->service);
|
91 |
-
$payload = $this->getPayload($request);
|
92 |
-
|
93 |
-
if ($payload == self::UNSIGNED_PAYLOAD) {
|
94 |
-
$parsed['headers'][self::AMZ_CONTENT_SHA256_HEADER] = [$payload];
|
95 |
-
}
|
96 |
-
|
97 |
-
$context = $this->createContext($parsed, $payload);
|
98 |
-
$toSign = $this->createStringToSign($ldt, $cs, $context['creq']);
|
99 |
-
$signingKey = $this->getSigningKey(
|
100 |
-
$sdt,
|
101 |
-
$this->region,
|
102 |
-
$this->service,
|
103 |
-
$credentials->getSecretKey()
|
104 |
-
);
|
105 |
-
$signature = hash_hmac('sha256', $toSign, $signingKey);
|
106 |
-
$parsed['headers']['Authorization'] = [
|
107 |
-
"AWS4-HMAC-SHA256 "
|
108 |
-
. "Credential={$credentials->getAccessKeyId()}/{$cs}, "
|
109 |
-
. "SignedHeaders={$context['headers']}, Signature={$signature}"
|
110 |
-
];
|
111 |
-
|
112 |
-
return $this->buildRequest($parsed);
|
113 |
-
}
|
114 |
-
|
115 |
-
/**
|
116 |
-
* Get the headers that were used to pre-sign the request.
|
117 |
-
* Used for the X-Amz-SignedHeaders header.
|
118 |
-
*
|
119 |
-
* @param array $headers
|
120 |
-
* @return array
|
121 |
-
*/
|
122 |
-
private function getPresignHeaders(array $headers)
|
123 |
-
{
|
124 |
-
$presignHeaders = [];
|
125 |
-
$blacklist = $this->getHeaderBlacklist();
|
126 |
-
foreach ($headers as $name => $value) {
|
127 |
-
$lName = strtolower($name);
|
128 |
-
if (!isset($blacklist[$lName])
|
129 |
-
&& $name !== self::AMZ_CONTENT_SHA256_HEADER
|
130 |
-
) {
|
131 |
-
$presignHeaders[] = $lName;
|
132 |
-
}
|
133 |
-
}
|
134 |
-
return $presignHeaders;
|
135 |
-
}
|
136 |
-
|
137 |
-
public function presign(
|
138 |
-
RequestInterface $request,
|
139 |
-
CredentialsInterface $credentials,
|
140 |
-
$expires,
|
141 |
-
array $options = []
|
142 |
-
) {
|
143 |
-
|
144 |
-
$startTimestamp = isset($options['start_time'])
|
145 |
-
? $this->convertToTimestamp($options['start_time'], null)
|
146 |
-
: time();
|
147 |
-
|
148 |
-
$expiresTimestamp = $this->convertToTimestamp($expires, $startTimestamp);
|
149 |
-
|
150 |
-
$parsed = $this->createPresignedRequest($request, $credentials);
|
151 |
-
$payload = $this->getPresignedPayload($request);
|
152 |
-
$httpDate = gmdate(self::ISO8601_BASIC, $startTimestamp);
|
153 |
-
$shortDate = substr($httpDate, 0, 8);
|
154 |
-
$scope = $this->createScope($shortDate, $this->region, $this->service);
|
155 |
-
$credential = $credentials->getAccessKeyId() . '/' . $scope;
|
156 |
-
if ($credentials->getSecurityToken()) {
|
157 |
-
unset($parsed['headers']['X-Amz-Security-Token']);
|
158 |
-
}
|
159 |
-
$parsed['query']['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';
|
160 |
-
$parsed['query']['X-Amz-Credential'] = $credential;
|
161 |
-
$parsed['query']['X-Amz-Date'] = gmdate('Ymd\THis\Z', $startTimestamp);
|
162 |
-
$parsed['query']['X-Amz-SignedHeaders'] = implode(';', $this->getPresignHeaders($parsed['headers']));
|
163 |
-
$parsed['query']['X-Amz-Expires'] = $this->convertExpires($expiresTimestamp, $startTimestamp);
|
164 |
-
$context = $this->createContext($parsed, $payload);
|
165 |
-
$stringToSign = $this->createStringToSign($httpDate, $scope, $context['creq']);
|
166 |
-
$key = $this->getSigningKey(
|
167 |
-
$shortDate,
|
168 |
-
$this->region,
|
169 |
-
$this->service,
|
170 |
-
$credentials->getSecretKey()
|
171 |
-
);
|
172 |
-
$parsed['query']['X-Amz-Signature'] = hash_hmac('sha256', $stringToSign, $key);
|
173 |
-
|
174 |
-
return $this->buildRequest($parsed);
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Converts a POST request to a GET request by moving POST fields into the
|
179 |
-
* query string.
|
180 |
-
*
|
181 |
-
* Useful for pre-signing query protocol requests.
|
182 |
-
*
|
183 |
-
* @param RequestInterface $request Request to clone
|
184 |
-
*
|
185 |
-
* @return RequestInterface
|
186 |
-
* @throws \InvalidArgumentException if the method is not POST
|
187 |
-
*/
|
188 |
-
public static function convertPostToGet(RequestInterface $request)
|
189 |
-
{
|
190 |
-
if ($request->getMethod() !== 'POST') {
|
191 |
-
throw new \InvalidArgumentException('Expected a POST request but '
|
192 |
-
. 'received a ' . $request->getMethod() . ' request.');
|
193 |
-
}
|
194 |
-
|
195 |
-
$sr = $request->withMethod('GET')
|
196 |
-
->withBody(Psr7\stream_for(''))
|
197 |
-
->withoutHeader('Content-Type')
|
198 |
-
->withoutHeader('Content-Length');
|
199 |
-
|
200 |
-
// Move POST fields to the query if they are present
|
201 |
-
if ($request->getHeaderLine('Content-Type') === 'application/x-www-form-urlencoded') {
|
202 |
-
$body = (string) $request->getBody();
|
203 |
-
$sr = $sr->withUri($sr->getUri()->withQuery($body));
|
204 |
-
}
|
205 |
-
|
206 |
-
return $sr;
|
207 |
-
}
|
208 |
-
|
209 |
-
protected function getPayload(RequestInterface $request)
|
210 |
-
{
|
211 |
-
if ($this->unsigned && $request->getUri()->getScheme() == 'https') {
|
212 |
-
return self::UNSIGNED_PAYLOAD;
|
213 |
-
}
|
214 |
-
// Calculate the request signature payload
|
215 |
-
if ($request->hasHeader(self::AMZ_CONTENT_SHA256_HEADER)) {
|
216 |
-
// Handle streaming operations (e.g. Glacier.UploadArchive)
|
217 |
-
return $request->getHeaderLine(self::AMZ_CONTENT_SHA256_HEADER);
|
218 |
-
}
|
219 |
-
|
220 |
-
if (!$request->getBody()->isSeekable()) {
|
221 |
-
throw new CouldNotCreateChecksumException('sha256');
|
222 |
-
}
|
223 |
-
|
224 |
-
try {
|
225 |
-
return Psr7\hash($request->getBody(), 'sha256');
|
226 |
-
} catch (\Exception $e) {
|
227 |
-
throw new CouldNotCreateChecksumException('sha256', $e);
|
228 |
-
}
|
229 |
-
}
|
230 |
-
|
231 |
-
protected function getPresignedPayload(RequestInterface $request)
|
232 |
-
{
|
233 |
-
return $this->getPayload($request);
|
234 |
-
}
|
235 |
-
|
236 |
-
protected function createCanonicalizedPath($path)
|
237 |
-
{
|
238 |
-
$doubleEncoded = rawurlencode(ltrim($path, '/'));
|
239 |
-
|
240 |
-
return '/' . str_replace('%2F', '/', $doubleEncoded);
|
241 |
-
}
|
242 |
-
|
243 |
-
private function createStringToSign($longDate, $credentialScope, $creq)
|
244 |
-
{
|
245 |
-
$hash = hash('sha256', $creq);
|
246 |
-
|
247 |
-
return "AWS4-HMAC-SHA256\n{$longDate}\n{$credentialScope}\n{$hash}";
|
248 |
-
}
|
249 |
-
|
250 |
-
private function createPresignedRequest(
|
251 |
-
RequestInterface $request,
|
252 |
-
CredentialsInterface $credentials
|
253 |
-
) {
|
254 |
-
$parsedRequest = $this->parseRequest($request);
|
255 |
-
|
256 |
-
// Make sure to handle temporary credentials
|
257 |
-
if ($token = $credentials->getSecurityToken()) {
|
258 |
-
$parsedRequest['headers']['X-Amz-Security-Token'] = [$token];
|
259 |
-
}
|
260 |
-
|
261 |
-
return $this->moveHeadersToQuery($parsedRequest);
|
262 |
-
}
|
263 |
-
|
264 |
-
/**
|
265 |
-
* @param array $parsedRequest
|
266 |
-
* @param string $payload Hash of the request payload
|
267 |
-
* @return array Returns an array of context information
|
268 |
-
*/
|
269 |
-
private function createContext(array $parsedRequest, $payload)
|
270 |
-
{
|
271 |
-
$blacklist = $this->getHeaderBlacklist();
|
272 |
-
|
273 |
-
// Normalize the path as required by SigV4
|
274 |
-
$canon = $parsedRequest['method'] . "\n"
|
275 |
-
. $this->createCanonicalizedPath($parsedRequest['path']) . "\n"
|
276 |
-
. $this->getCanonicalizedQuery($parsedRequest['query']) . "\n";
|
277 |
-
|
278 |
-
// Case-insensitively aggregate all of the headers.
|
279 |
-
$aggregate = [];
|
280 |
-
foreach ($parsedRequest['headers'] as $key => $values) {
|
281 |
-
$key = strtolower($key);
|
282 |
-
if (!isset($blacklist[$key])) {
|
283 |
-
foreach ($values as $v) {
|
284 |
-
$aggregate[$key][] = $v;
|
285 |
-
}
|
286 |
-
}
|
287 |
-
}
|
288 |
-
|
289 |
-
ksort($aggregate);
|
290 |
-
$canonHeaders = [];
|
291 |
-
foreach ($aggregate as $k => $v) {
|
292 |
-
if (count($v) > 0) {
|
293 |
-
sort($v);
|
294 |
-
}
|
295 |
-
$canonHeaders[] = $k . ':' . preg_replace('/\s+/', ' ', implode(',', $v));
|
296 |
-
}
|
297 |
-
|
298 |
-
$signedHeadersString = implode(';', array_keys($aggregate));
|
299 |
-
$canon .= implode("\n", $canonHeaders) . "\n\n"
|
300 |
-
. $signedHeadersString . "\n"
|
301 |
-
. $payload;
|
302 |
-
|
303 |
-
return ['creq' => $canon, 'headers' => $signedHeadersString];
|
304 |
-
}
|
305 |
-
|
306 |
-
private function getCanonicalizedQuery(array $query)
|
307 |
-
{
|
308 |
-
unset($query['X-Amz-Signature']);
|
309 |
-
|
310 |
-
if (!$query) {
|
311 |
-
return '';
|
312 |
-
}
|
313 |
-
|
314 |
-
$qs = '';
|
315 |
-
ksort($query);
|
316 |
-
foreach ($query as $k => $v) {
|
317 |
-
if (!is_array($v)) {
|
318 |
-
$qs .= rawurlencode($k) . '=' . rawurlencode($v) . '&';
|
319 |
-
} else {
|
320 |
-
sort($v);
|
321 |
-
foreach ($v as $value) {
|
322 |
-
$qs .= rawurlencode($k) . '=' . rawurlencode($value) . '&';
|
323 |
-
}
|
324 |
-
}
|
325 |
-
}
|
326 |
-
|
327 |
-
return substr($qs, 0, -1);
|
328 |
-
}
|
329 |
-
|
330 |
-
private function convertToTimestamp($dateValue, $relativeTimeBase = null)
|
331 |
-
{
|
332 |
-
if ($dateValue instanceof \DateTimeInterface) {
|
333 |
-
$timestamp = $dateValue->getTimestamp();
|
334 |
-
} elseif (!is_numeric($dateValue)) {
|
335 |
-
$timestamp = strtotime($dateValue,
|
336 |
-
$relativeTimeBase === null ? time() : $relativeTimeBase
|
337 |
-
);
|
338 |
-
} else {
|
339 |
-
$timestamp = $dateValue;
|
340 |
-
}
|
341 |
-
|
342 |
-
return $timestamp;
|
343 |
-
}
|
344 |
-
|
345 |
-
private function convertExpires($expiresTimestamp, $startTimestamp)
|
346 |
-
{
|
347 |
-
$duration = $expiresTimestamp - $startTimestamp;
|
348 |
-
|
349 |
-
// Ensure that the duration of the signature is not longer than a week
|
350 |
-
if ($duration > 604800) {
|
351 |
-
throw new \InvalidArgumentException('The expiration date of a '
|
352 |
-
. 'signature version 4 presigned URL must be less than one '
|
353 |
-
. 'week');
|
354 |
-
}
|
355 |
-
|
356 |
-
return $duration;
|
357 |
-
}
|
358 |
-
|
359 |
-
private function moveHeadersToQuery(array $parsedRequest)
|
360 |
-
{
|
361 |
-
foreach ($parsedRequest['headers'] as $name => $header) {
|
362 |
-
$lname = strtolower($name);
|
363 |
-
if (substr($lname, 0, 5) == 'x-amz') {
|
364 |
-
$parsedRequest['query'][$name] = $header;
|
365 |
-
}
|
366 |
-
$blacklist = $this->getHeaderBlacklist();
|
367 |
-
if (isset($blacklist[$lname])
|
368 |
-
|| $lname === strtolower(self::AMZ_CONTENT_SHA256_HEADER)
|
369 |
-
) {
|
370 |
-
unset($parsedRequest['headers'][$name]);
|
371 |
-
}
|
372 |
-
}
|
373 |
-
|
374 |
-
return $parsedRequest;
|
375 |
-
}
|
376 |
-
|
377 |
-
private function parseRequest(RequestInterface $request)
|
378 |
-
{
|
379 |
-
// Clean up any previously set headers.
|
380 |
-
/** @var RequestInterface $request */
|
381 |
-
$request = $request
|
382 |
-
->withoutHeader('X-Amz-Date')
|
383 |
-
->withoutHeader('Date')
|
384 |
-
->withoutHeader('Authorization');
|
385 |
-
$uri = $request->getUri();
|
386 |
-
|
387 |
-
return [
|
388 |
-
'method' => $request->getMethod(),
|
389 |
-
'path' => $uri->getPath(),
|
390 |
-
'query' => Psr7\parse_query($uri->getQuery()),
|
391 |
-
'uri' => $uri,
|
392 |
-
'headers' => $request->getHeaders(),
|
393 |
-
'body' => $request->getBody(),
|
394 |
-
'version' => $request->getProtocolVersion()
|
395 |
-
];
|
396 |
-
}
|
397 |
-
|
398 |
-
private function buildRequest(array $req)
|
399 |
-
{
|
400 |
-
if ($req['query']) {
|
401 |
-
$req['uri'] = $req['uri']->withQuery(Psr7\build_query($req['query']));
|
402 |
-
}
|
403 |
-
|
404 |
-
return new Psr7\Request(
|
405 |
-
$req['method'],
|
406 |
-
$req['uri'],
|
407 |
-
$req['headers'],
|
408 |
-
$req['body'],
|
409 |
-
$req['version']
|
410 |
-
);
|
411 |
-
}
|
412 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Sns/Exception/InvalidSnsMessageException.php
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Sns\Exception;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Runtime exception thrown by the SNS Message Validator.
|
6 |
-
*/
|
7 |
-
class InvalidSnsMessageException extends \RuntimeException
|
8 |
-
{
|
9 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Sns/Message.php
DELETED
@@ -1,156 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Sns;
|
3 |
-
|
4 |
-
use Psr\Http\Message\RequestInterface;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Represents an SNS message received over http(s).
|
8 |
-
*/
|
9 |
-
class Message implements \ArrayAccess, \IteratorAggregate
|
10 |
-
{
|
11 |
-
private static $requiredKeys = [
|
12 |
-
'Message',
|
13 |
-
'MessageId',
|
14 |
-
'Timestamp',
|
15 |
-
'TopicArn',
|
16 |
-
'Type',
|
17 |
-
'Signature',
|
18 |
-
['SigningCertURL', 'SigningCertUrl'],
|
19 |
-
'SignatureVersion',
|
20 |
-
];
|
21 |
-
|
22 |
-
private static $subscribeKeys = [
|
23 |
-
['SubscribeURL', 'SubscribeUrl'],
|
24 |
-
'Token'
|
25 |
-
];
|
26 |
-
|
27 |
-
/** @var array The message data */
|
28 |
-
private $data;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Creates a Message object from the raw POST data
|
32 |
-
*
|
33 |
-
* @return Message
|
34 |
-
* @throws \RuntimeException If the POST data is absent, or not a valid JSON document
|
35 |
-
*/
|
36 |
-
public static function fromRawPostData()
|
37 |
-
{
|
38 |
-
// Make sure the SNS-provided header exists.
|
39 |
-
if (!isset($_SERVER['HTTP_X_AMZ_SNS_MESSAGE_TYPE'])) {
|
40 |
-
throw new \RuntimeException('SNS message type header not provided.');
|
41 |
-
}
|
42 |
-
|
43 |
-
// Read the raw POST data and JSON-decode it into a message.
|
44 |
-
return self::fromJsonString(file_get_contents('php://input'));
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Creates a Message object from a PSR-7 Request or ServerRequest object.
|
49 |
-
*
|
50 |
-
* @param RequestInterface $request
|
51 |
-
* @return Message
|
52 |
-
*/
|
53 |
-
public static function fromPsrRequest(RequestInterface $request)
|
54 |
-
{
|
55 |
-
return self::fromJsonString($request->getBody());
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Creates a Message object from a JSON-decodable string.
|
60 |
-
*
|
61 |
-
* @param string $requestBody
|
62 |
-
* @return Message
|
63 |
-
*/
|
64 |
-
private static function fromJsonString($requestBody)
|
65 |
-
{
|
66 |
-
$data = json_decode($requestBody, true);
|
67 |
-
if (JSON_ERROR_NONE !== json_last_error() || !is_array($data)) {
|
68 |
-
throw new \RuntimeException('Invalid POST data.');
|
69 |
-
}
|
70 |
-
|
71 |
-
return new Message($data);
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Creates a Message object from an array of raw message data.
|
76 |
-
*
|
77 |
-
* @param array $data The message data.
|
78 |
-
*
|
79 |
-
* @throws \InvalidArgumentException If a valid type is not provided or
|
80 |
-
* there are other required keys missing.
|
81 |
-
*/
|
82 |
-
public function __construct(array $data)
|
83 |
-
{
|
84 |
-
// Ensure that all the required keys for the message's type are present.
|
85 |
-
$this->validateRequiredKeys($data, self::$requiredKeys);
|
86 |
-
if ($data['Type'] === 'SubscriptionConfirmation'
|
87 |
-
|| $data['Type'] === 'UnsubscribeConfirmation'
|
88 |
-
) {
|
89 |
-
$this->validateRequiredKeys($data, self::$subscribeKeys);
|
90 |
-
}
|
91 |
-
|
92 |
-
$this->data = $data;
|
93 |
-
}
|
94 |
-
|
95 |
-
public function getIterator()
|
96 |
-
{
|
97 |
-
return new \ArrayIterator($this->data);
|
98 |
-
}
|
99 |
-
|
100 |
-
public function offsetExists($key)
|
101 |
-
{
|
102 |
-
return isset($this->data[$key]);
|
103 |
-
}
|
104 |
-
|
105 |
-
public function offsetGet($key)
|
106 |
-
{
|
107 |
-
return isset($this->data[$key]) ? $this->data[$key] : null;
|
108 |
-
}
|
109 |
-
|
110 |
-
public function offsetSet($key, $value)
|
111 |
-
{
|
112 |
-
$this->data[$key] = $value;
|
113 |
-
}
|
114 |
-
|
115 |
-
public function offsetUnset($key)
|
116 |
-
{
|
117 |
-
unset($this->data[$key]);
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* Get all the message data as a plain array.
|
122 |
-
*
|
123 |
-
* @return array
|
124 |
-
*/
|
125 |
-
public function toArray()
|
126 |
-
{
|
127 |
-
return $this->data;
|
128 |
-
}
|
129 |
-
|
130 |
-
private function validateRequiredKeys(array $data, array $keys)
|
131 |
-
{
|
132 |
-
foreach ($keys as $key) {
|
133 |
-
$keyIsArray = is_array($key);
|
134 |
-
if (!$keyIsArray) {
|
135 |
-
$found = isset($data[$key]);
|
136 |
-
} else {
|
137 |
-
$found = false;
|
138 |
-
foreach ($key as $keyOption) {
|
139 |
-
if (isset($data[$keyOption])) {
|
140 |
-
$found = true;
|
141 |
-
break;
|
142 |
-
}
|
143 |
-
}
|
144 |
-
}
|
145 |
-
|
146 |
-
if (!$found) {
|
147 |
-
if ($keyIsArray) {
|
148 |
-
$key = $key[0];
|
149 |
-
}
|
150 |
-
throw new \InvalidArgumentException(
|
151 |
-
"\"{$key}\" is required to verify the SNS Message."
|
152 |
-
);
|
153 |
-
}
|
154 |
-
}
|
155 |
-
}
|
156 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/Sns/MessageValidator.php
DELETED
@@ -1,190 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\Sns;
|
3 |
-
|
4 |
-
use Aws\Sns\Exception\InvalidSnsMessageException;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Uses openssl to verify SNS messages to ensure that they were sent by AWS.
|
8 |
-
*/
|
9 |
-
class MessageValidator
|
10 |
-
{
|
11 |
-
const SIGNATURE_VERSION_1 = '1';
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var callable Callable used to download the certificate content.
|
15 |
-
*/
|
16 |
-
private $certClient;
|
17 |
-
|
18 |
-
/** @var string */
|
19 |
-
private $hostPattern;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @var string A pattern that will match all regional SNS endpoints, e.g.:
|
23 |
-
* - sns.<region>.amazonaws.com (AWS)
|
24 |
-
* - sns.us-gov-west-1.amazonaws.com (AWS GovCloud)
|
25 |
-
* - sns.cn-north-1.amazonaws.com.cn (AWS China)
|
26 |
-
*/
|
27 |
-
private static $defaultHostPattern
|
28 |
-
= '/^sns\.[a-zA-Z0-9\-]{3,}\.amazonaws\.com(\.cn)?$/';
|
29 |
-
|
30 |
-
private static function isLambdaStyle(Message $message)
|
31 |
-
{
|
32 |
-
return isset($message['SigningCertUrl']);
|
33 |
-
}
|
34 |
-
|
35 |
-
private static function convertLambdaMessage(Message $lambdaMessage)
|
36 |
-
{
|
37 |
-
$keyReplacements = [
|
38 |
-
'SigningCertUrl' => 'SigningCertURL',
|
39 |
-
'SubscribeUrl' => 'SubscribeURL',
|
40 |
-
'UnsubscribeUrl' => 'UnsubscribeURL',
|
41 |
-
];
|
42 |
-
|
43 |
-
$message = clone $lambdaMessage;
|
44 |
-
foreach ($keyReplacements as $lambdaKey => $canonicalKey) {
|
45 |
-
if (isset($message[$lambdaKey])) {
|
46 |
-
$message[$canonicalKey] = $message[$lambdaKey];
|
47 |
-
unset($message[$lambdaKey]);
|
48 |
-
}
|
49 |
-
}
|
50 |
-
|
51 |
-
return $message;
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Constructs the Message Validator object and ensures that openssl is
|
56 |
-
* installed.
|
57 |
-
*
|
58 |
-
* @param callable $certClient Callable used to download the certificate.
|
59 |
-
* Should have the following function signature:
|
60 |
-
* `function (string $certUrl) : string $certContent`
|
61 |
-
* @param string $hostNamePattern
|
62 |
-
*/
|
63 |
-
public function __construct(
|
64 |
-
callable $certClient = null,
|
65 |
-
$hostNamePattern = ''
|
66 |
-
) {
|
67 |
-
$this->certClient = $certClient ?: 'file_get_contents';
|
68 |
-
$this->hostPattern = $hostNamePattern ?: self::$defaultHostPattern;
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Validates a message from SNS to ensure that it was delivered by AWS.
|
73 |
-
*
|
74 |
-
* @param Message $message Message to validate.
|
75 |
-
*
|
76 |
-
* @throws InvalidSnsMessageException If the cert cannot be retrieved or its
|
77 |
-
* source verified, or the message
|
78 |
-
* signature is invalid.
|
79 |
-
*/
|
80 |
-
public function validate(Message $message)
|
81 |
-
{
|
82 |
-
if (self::isLambdaStyle($message)) {
|
83 |
-
$message = self::convertLambdaMessage($message);
|
84 |
-
}
|
85 |
-
|
86 |
-
// Get the certificate.
|
87 |
-
$this->validateUrl($message['SigningCertURL']);
|
88 |
-
$certificate = call_user_func($this->certClient, $message['SigningCertURL']);
|
89 |
-
if ($certificate === false) {
|
90 |
-
throw new InvalidSnsMessageException(
|
91 |
-
"Cannot get the certificate from \"{$message['SigningCertURL']}\"."
|
92 |
-
);
|
93 |
-
}
|
94 |
-
|
95 |
-
// Extract the public key.
|
96 |
-
$key = openssl_get_publickey($certificate);
|
97 |
-
if (!$key) {
|
98 |
-
throw new InvalidSnsMessageException(
|
99 |
-
'Cannot get the public key from the certificate.'
|
100 |
-
);
|
101 |
-
}
|
102 |
-
|
103 |
-
// Verify the signature of the message.
|
104 |
-
$content = $this->getStringToSign($message);
|
105 |
-
$signature = base64_decode($message['Signature']);
|
106 |
-
if (openssl_verify($content, $signature, $key, OPENSSL_ALGO_SHA1) != 1) {
|
107 |
-
throw new InvalidSnsMessageException(
|
108 |
-
'The message signature is invalid.'
|
109 |
-
);
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Determines if a message is valid and that is was delivered by AWS. This
|
115 |
-
* method does not throw exceptions and returns a simple boolean value.
|
116 |
-
*
|
117 |
-
* @param Message $message The message to validate
|
118 |
-
*
|
119 |
-
* @return bool
|
120 |
-
*/
|
121 |
-
public function isValid(Message $message)
|
122 |
-
{
|
123 |
-
try {
|
124 |
-
$this->validate($message);
|
125 |
-
return true;
|
126 |
-
} catch (InvalidSnsMessageException $e) {
|
127 |
-
return false;
|
128 |
-
}
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Builds string-to-sign according to the SNS message spec.
|
133 |
-
*
|
134 |
-
* @param Message $message Message for which to build the string-to-sign.
|
135 |
-
*
|
136 |
-
* @return string
|
137 |
-
* @link http://docs.aws.amazon.com/sns/latest/gsg/SendMessageToHttp.verify.signature.html
|
138 |
-
*/
|
139 |
-
public function getStringToSign(Message $message)
|
140 |
-
{
|
141 |
-
static $signableKeys = [
|
142 |
-
'Message',
|
143 |
-
'MessageId',
|
144 |
-
'Subject',
|
145 |
-
'SubscribeURL',
|
146 |
-
'Timestamp',
|
147 |
-
'Token',
|
148 |
-
'TopicArn',
|
149 |
-
'Type',
|
150 |
-
];
|
151 |
-
|
152 |
-
if ($message['SignatureVersion'] !== self::SIGNATURE_VERSION_1) {
|
153 |
-
throw new InvalidSnsMessageException(
|
154 |
-
"The SignatureVersion \"{$message['SignatureVersion']}\" is not supported."
|
155 |
-
);
|
156 |
-
}
|
157 |
-
|
158 |
-
$stringToSign = '';
|
159 |
-
foreach ($signableKeys as $key) {
|
160 |
-
if (isset($message[$key])) {
|
161 |
-
$stringToSign .= "{$key}\n{$message[$key]}\n";
|
162 |
-
}
|
163 |
-
}
|
164 |
-
|
165 |
-
return $stringToSign;
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* Ensures that the URL of the certificate is one belonging to AWS, and not
|
170 |
-
* just something from the amazonaws domain, which could include S3 buckets.
|
171 |
-
*
|
172 |
-
* @param string $url Certificate URL
|
173 |
-
*
|
174 |
-
* @throws InvalidSnsMessageException if the cert url is invalid.
|
175 |
-
*/
|
176 |
-
private function validateUrl($url)
|
177 |
-
{
|
178 |
-
$parsed = parse_url($url);
|
179 |
-
if (empty($parsed['scheme'])
|
180 |
-
|| empty($parsed['host'])
|
181 |
-
|| $parsed['scheme'] !== 'https'
|
182 |
-
|| substr($url, -4) !== '.pem'
|
183 |
-
|| !preg_match($this->hostPattern, $parsed['host'])
|
184 |
-
) {
|
185 |
-
throw new InvalidSnsMessageException(
|
186 |
-
'The certificate is located on an invalid domain.'
|
187 |
-
);
|
188 |
-
}
|
189 |
-
}
|
190 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/TraceMiddleware.php
DELETED
@@ -1,314 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Exception\AwsException;
|
5 |
-
use GuzzleHttp\Promise\RejectedPromise;
|
6 |
-
use Psr\Http\Message\RequestInterface;
|
7 |
-
use Psr\Http\Message\ResponseInterface;
|
8 |
-
use Psr\Http\Message\StreamInterface;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Traces state changes between middlewares.
|
12 |
-
*/
|
13 |
-
class TraceMiddleware
|
14 |
-
{
|
15 |
-
private $prevOutput;
|
16 |
-
private $prevInput;
|
17 |
-
private $config;
|
18 |
-
|
19 |
-
private static $authHeaders = [
|
20 |
-
'X-Amz-Security-Token' => '[TOKEN]',
|
21 |
-
];
|
22 |
-
|
23 |
-
private static $authStrings = [
|
24 |
-
// S3Signature
|
25 |
-
'/AWSAccessKeyId=[A-Z0-9]{20}&/i' => 'AWSAccessKeyId=[KEY]&',
|
26 |
-
// SignatureV4 Signature and S3Signature
|
27 |
-
'/Signature=.+/i' => 'Signature=[SIGNATURE]',
|
28 |
-
// SignatureV4 access key ID
|
29 |
-
'/Credential=[A-Z0-9]{20}\//i' => 'Credential=[KEY]/',
|
30 |
-
// S3 signatures
|
31 |
-
'/AWS [A-Z0-9]{20}:.+/' => 'AWS AKI[KEY]:[SIGNATURE]',
|
32 |
-
// STS Presigned URLs
|
33 |
-
'/X-Amz-Security-Token=[^&]+/i' => 'X-Amz-Security-Token=[TOKEN]',
|
34 |
-
// Crypto *Stream Keys
|
35 |
-
'/\["key.{27,36}Stream.{9}\]=>\s+.{7}\d{2}\) "\X{16,64}"/U' => '["key":[CONTENT KEY]]',
|
36 |
-
];
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Configuration array can contain the following key value pairs.
|
40 |
-
*
|
41 |
-
* - logfn: (callable) Function that is invoked with log messages. By
|
42 |
-
* default, PHP's "echo" function will be utilized.
|
43 |
-
* - stream_size: (int) When the size of a stream is greater than this
|
44 |
-
* number, the stream data will not be logged. Set to "0" to not log any
|
45 |
-
* stream data.
|
46 |
-
* - scrub_auth: (bool) Set to false to disable the scrubbing of auth data
|
47 |
-
* from the logged messages.
|
48 |
-
* - http: (bool) Set to false to disable the "debug" feature of lower
|
49 |
-
* level HTTP adapters (e.g., verbose curl output).
|
50 |
-
* - auth_strings: (array) A mapping of authentication string regular
|
51 |
-
* expressions to scrubbed strings. These mappings are passed directly to
|
52 |
-
* preg_replace (e.g., preg_replace($key, $value, $debugOutput) if
|
53 |
-
* "scrub_auth" is set to true.
|
54 |
-
* - auth_headers: (array) A mapping of header names known to contain
|
55 |
-
* sensitive data to what the scrubbed value should be. The value of any
|
56 |
-
* headers contained in this array will be replaced with the if
|
57 |
-
* "scrub_auth" is set to true.
|
58 |
-
*/
|
59 |
-
public function __construct(array $config = [])
|
60 |
-
{
|
61 |
-
$this->config = $config + [
|
62 |
-
'logfn' => function ($value) { echo $value; },
|
63 |
-
'stream_size' => 524288,
|
64 |
-
'scrub_auth' => true,
|
65 |
-
'http' => true,
|
66 |
-
'auth_strings' => [],
|
67 |
-
'auth_headers' => [],
|
68 |
-
];
|
69 |
-
|
70 |
-
$this->config['auth_strings'] += self::$authStrings;
|
71 |
-
$this->config['auth_headers'] += self::$authHeaders;
|
72 |
-
}
|
73 |
-
|
74 |
-
public function __invoke($step, $name)
|
75 |
-
{
|
76 |
-
$this->prevOutput = $this->prevInput = [];
|
77 |
-
|
78 |
-
return function (callable $next) use ($step, $name) {
|
79 |
-
return function (
|
80 |
-
CommandInterface $command,
|
81 |
-
RequestInterface $request = null
|
82 |
-
) use ($next, $step, $name) {
|
83 |
-
$this->createHttpDebug($command);
|
84 |
-
$start = microtime(true);
|
85 |
-
$this->stepInput([
|
86 |
-
'step' => $step,
|
87 |
-
'name' => $name,
|
88 |
-
'request' => $this->requestArray($request),
|
89 |
-
'command' => $this->commandArray($command)
|
90 |
-
]);
|
91 |
-
|
92 |
-
return $next($command, $request)->then(
|
93 |
-
function ($value) use ($step, $name, $command, $start) {
|
94 |
-
$this->flushHttpDebug($command);
|
95 |
-
$this->stepOutput($start, [
|
96 |
-
'step' => $step,
|
97 |
-
'name' => $name,
|
98 |
-
'result' => $this->resultArray($value),
|
99 |
-
'error' => null
|
100 |
-
]);
|
101 |
-
return $value;
|
102 |
-
},
|
103 |
-
function ($reason) use ($step, $name, $start, $command) {
|
104 |
-
$this->flushHttpDebug($command);
|
105 |
-
$this->stepOutput($start, [
|
106 |
-
'step' => $step,
|
107 |
-
'name' => $name,
|
108 |
-
'result' => null,
|
109 |
-
'error' => $this->exceptionArray($reason)
|
110 |
-
]);
|
111 |
-
return new RejectedPromise($reason);
|
112 |
-
}
|
113 |
-
);
|
114 |
-
};
|
115 |
-
};
|
116 |
-
}
|
117 |
-
|
118 |
-
private function stepInput($entry)
|
119 |
-
{
|
120 |
-
static $keys = ['command', 'request'];
|
121 |
-
$this->compareStep($this->prevInput, $entry, '-> Entering', $keys);
|
122 |
-
$this->write("\n");
|
123 |
-
$this->prevInput = $entry;
|
124 |
-
}
|
125 |
-
|
126 |
-
private function stepOutput($start, $entry)
|
127 |
-
{
|
128 |
-
static $keys = ['result', 'error'];
|
129 |
-
$this->compareStep($this->prevOutput, $entry, '<- Leaving', $keys);
|
130 |
-
$totalTime = microtime(true) - $start;
|
131 |
-
$this->write(" Inclusive step time: " . $totalTime . "\n\n");
|
132 |
-
$this->prevOutput = $entry;
|
133 |
-
}
|
134 |
-
|
135 |
-
private function compareStep(array $a, array $b, $title, array $keys)
|
136 |
-
{
|
137 |
-
$changes = [];
|
138 |
-
foreach ($keys as $key) {
|
139 |
-
$av = isset($a[$key]) ? $a[$key] : null;
|
140 |
-
$bv = isset($b[$key]) ? $b[$key] : null;
|
141 |
-
$this->compareArray($av, $bv, $key, $changes);
|
142 |
-
}
|
143 |
-
$str = "\n{$title} step {$b['step']}, name '{$b['name']}'";
|
144 |
-
$str .= "\n" . str_repeat('-', strlen($str) - 1) . "\n\n ";
|
145 |
-
$str .= $changes
|
146 |
-
? implode("\n ", str_replace("\n", "\n ", $changes))
|
147 |
-
: 'no changes';
|
148 |
-
$this->write($str . "\n");
|
149 |
-
}
|
150 |
-
|
151 |
-
private function commandArray(CommandInterface $cmd)
|
152 |
-
{
|
153 |
-
return [
|
154 |
-
'instance' => spl_object_hash($cmd),
|
155 |
-
'name' => $cmd->getName(),
|
156 |
-
'params' => $cmd->toArray()
|
157 |
-
];
|
158 |
-
}
|
159 |
-
|
160 |
-
private function requestArray(RequestInterface $request = null)
|
161 |
-
{
|
162 |
-
return !$request ? [] : array_filter([
|
163 |
-
'instance' => spl_object_hash($request),
|
164 |
-
'method' => $request->getMethod(),
|
165 |
-
'headers' => $this->redactHeaders($request->getHeaders()),
|
166 |
-
'body' => $this->streamStr($request->getBody()),
|
167 |
-
'scheme' => $request->getUri()->getScheme(),
|
168 |
-
'port' => $request->getUri()->getPort(),
|
169 |
-
'path' => $request->getUri()->getPath(),
|
170 |
-
'query' => $request->getUri()->getQuery(),
|
171 |
-
]);
|
172 |
-
}
|
173 |
-
|
174 |
-
private function responseArray(ResponseInterface $response = null)
|
175 |
-
{
|
176 |
-
return !$response ? [] : [
|
177 |
-
'instance' => spl_object_hash($response),
|
178 |
-
'statusCode' => $response->getStatusCode(),
|
179 |
-
'headers' => $this->redactHeaders($response->getHeaders()),
|
180 |
-
'body' => $this->streamStr($response->getBody())
|
181 |
-
];
|
182 |
-
}
|
183 |
-
|
184 |
-
private function resultArray($value)
|
185 |
-
{
|
186 |
-
return $value instanceof ResultInterface
|
187 |
-
? [
|
188 |
-
'instance' => spl_object_hash($value),
|
189 |
-
'data' => $value->toArray()
|
190 |
-
] : $value;
|
191 |
-
}
|
192 |
-
|
193 |
-
private function exceptionArray($e)
|
194 |
-
{
|
195 |
-
if (!($e instanceof \Exception)) {
|
196 |
-
return $e;
|
197 |
-
}
|
198 |
-
|
199 |
-
$result = [
|
200 |
-
'instance' => spl_object_hash($e),
|
201 |
-
'class' => get_class($e),
|
202 |
-
'message' => $e->getMessage(),
|
203 |
-
'file' => $e->getFile(),
|
204 |
-
'line' => $e->getLine(),
|
205 |
-
'trace' => $e->getTraceAsString(),
|
206 |
-
];
|
207 |
-
|
208 |
-
if ($e instanceof AwsException) {
|
209 |
-
$result += [
|
210 |
-
'type' => $e->getAwsErrorType(),
|
211 |
-
'code' => $e->getAwsErrorCode(),
|
212 |
-
'requestId' => $e->getAwsRequestId(),
|
213 |
-
'statusCode' => $e->getStatusCode(),
|
214 |
-
'result' => $this->resultArray($e->getResult()),
|
215 |
-
'request' => $this->requestArray($e->getRequest()),
|
216 |
-
'response' => $this->responseArray($e->getResponse()),
|
217 |
-
];
|
218 |
-
}
|
219 |
-
|
220 |
-
return $result;
|
221 |
-
}
|
222 |
-
|
223 |
-
private function compareArray($a, $b, $path, array &$diff)
|
224 |
-
{
|
225 |
-
if ($a === $b) {
|
226 |
-
return;
|
227 |
-
}
|
228 |
-
|
229 |
-
if (is_array($a)) {
|
230 |
-
$b = (array) $b;
|
231 |
-
$keys = array_unique(array_merge(array_keys($a), array_keys($b)));
|
232 |
-
foreach ($keys as $k) {
|
233 |
-
if (!array_key_exists($k, $a)) {
|
234 |
-
$this->compareArray(null, $b[$k], "{$path}.{$k}", $diff);
|
235 |
-
} elseif (!array_key_exists($k, $b)) {
|
236 |
-
$this->compareArray($a[$k], null, "{$path}.{$k}", $diff);
|
237 |
-
} else {
|
238 |
-
$this->compareArray($a[$k], $b[$k], "{$path}.{$k}", $diff);
|
239 |
-
}
|
240 |
-
}
|
241 |
-
} elseif ($a !== null && $b === null) {
|
242 |
-
$diff[] = "{$path} was unset";
|
243 |
-
} elseif ($a === null && $b !== null) {
|
244 |
-
$diff[] = sprintf("%s was set to %s", $path, $this->str($b));
|
245 |
-
} else {
|
246 |
-
$diff[] = sprintf("%s changed from %s to %s", $path, $this->str($a), $this->str($b));
|
247 |
-
}
|
248 |
-
}
|
249 |
-
|
250 |
-
private function str($value)
|
251 |
-
{
|
252 |
-
if (is_scalar($value)) {
|
253 |
-
return (string) $value;
|
254 |
-
}
|
255 |
-
|
256 |
-
if ($value instanceof \Exception) {
|
257 |
-
$value = $this->exceptionArray($value);
|
258 |
-
}
|
259 |
-
|
260 |
-
ob_start();
|
261 |
-
var_dump($value);
|
262 |
-
return ob_get_clean();
|
263 |
-
}
|
264 |
-
|
265 |
-
private function streamStr(StreamInterface $body)
|
266 |
-
{
|
267 |
-
return $body->getSize() < $this->config['stream_size']
|
268 |
-
? (string) $body
|
269 |
-
: 'stream(size=' . $body->getSize() . ')';
|
270 |
-
}
|
271 |
-
|
272 |
-
private function createHttpDebug(CommandInterface $command)
|
273 |
-
{
|
274 |
-
if ($this->config['http'] && !isset($command['@http']['debug'])) {
|
275 |
-
$command['@http']['debug'] = fopen('php://temp', 'w+');
|
276 |
-
}
|
277 |
-
}
|
278 |
-
|
279 |
-
private function flushHttpDebug(CommandInterface $command)
|
280 |
-
{
|
281 |
-
if ($res = $command['@http']['debug']) {
|
282 |
-
rewind($res);
|
283 |
-
$this->write(stream_get_contents($res));
|
284 |
-
fclose($res);
|
285 |
-
$command['@http']['debug'] = null;
|
286 |
-
}
|
287 |
-
}
|
288 |
-
|
289 |
-
private function write($value)
|
290 |
-
{
|
291 |
-
if ($this->config['scrub_auth']) {
|
292 |
-
foreach ($this->config['auth_strings'] as $pattern => $replacement) {
|
293 |
-
$value = preg_replace_callback(
|
294 |
-
$pattern,
|
295 |
-
function ($matches) use ($replacement) {
|
296 |
-
return $replacement;
|
297 |
-
},
|
298 |
-
$value
|
299 |
-
);
|
300 |
-
}
|
301 |
-
}
|
302 |
-
|
303 |
-
call_user_func($this->config['logfn'], $value);
|
304 |
-
}
|
305 |
-
|
306 |
-
private function redactHeaders(array $headers)
|
307 |
-
{
|
308 |
-
if ($this->config['scrub_auth']) {
|
309 |
-
$headers = $this->config['auth_headers'] + $headers;
|
310 |
-
}
|
311 |
-
|
312 |
-
return $headers;
|
313 |
-
}
|
314 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/WrappedHttpHandler.php
DELETED
@@ -1,203 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Aws\Api\Parser\Exception\ParserException;
|
5 |
-
use GuzzleHttp\Promise;
|
6 |
-
use Psr\Http\Message\RequestInterface;
|
7 |
-
use Psr\Http\Message\ResponseInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Converts an HTTP handler into a Command HTTP handler.
|
11 |
-
*
|
12 |
-
* HTTP handlers have the following signature:
|
13 |
-
* function(RequestInterface $request, array $options) : PromiseInterface
|
14 |
-
*
|
15 |
-
* The promise returned form an HTTP handler must resolve to a PSR-7 response
|
16 |
-
* object when fulfilled or an error array when rejected. The error array
|
17 |
-
* can contain the following data:
|
18 |
-
*
|
19 |
-
* - exception: (required, Exception) Exception that was encountered.
|
20 |
-
* - response: (ResponseInterface) PSR-7 response that was received (if a
|
21 |
-
* response) was received.
|
22 |
-
* - connection_error: (bool) True if the error is the result of failing to
|
23 |
-
* connect.
|
24 |
-
*/
|
25 |
-
class WrappedHttpHandler
|
26 |
-
{
|
27 |
-
private $httpHandler;
|
28 |
-
private $parser;
|
29 |
-
private $errorParser;
|
30 |
-
private $exceptionClass;
|
31 |
-
private $collectStats;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* @param callable $httpHandler Function that accepts a request and array
|
35 |
-
* of request options and returns a promise
|
36 |
-
* that fulfills with a response or rejects
|
37 |
-
* with an error array.
|
38 |
-
* @param callable $parser Function that accepts a response object
|
39 |
-
* and returns an AWS result object.
|
40 |
-
* @param callable $errorParser Function that parses a response object
|
41 |
-
* into AWS error data.
|
42 |
-
* @param string $exceptionClass Exception class to throw.
|
43 |
-
* @param bool $collectStats Whether to collect HTTP transfer
|
44 |
-
* information.
|
45 |
-
*/
|
46 |
-
public function __construct(
|
47 |
-
callable $httpHandler,
|
48 |
-
callable $parser,
|
49 |
-
callable $errorParser,
|
50 |
-
$exceptionClass = 'Aws\Exception\AwsException',
|
51 |
-
$collectStats = false
|
52 |
-
) {
|
53 |
-
$this->httpHandler = $httpHandler;
|
54 |
-
$this->parser = $parser;
|
55 |
-
$this->errorParser = $errorParser;
|
56 |
-
$this->exceptionClass = $exceptionClass;
|
57 |
-
$this->collectStats = $collectStats;
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Calls the simpler HTTP specific handler and wraps the returned promise
|
62 |
-
* with AWS specific values (e.g., a result object or AWS exception).
|
63 |
-
*
|
64 |
-
* @param CommandInterface $command Command being executed.
|
65 |
-
* @param RequestInterface $request Request to send.
|
66 |
-
*
|
67 |
-
* @return Promise\PromiseInterface
|
68 |
-
*/
|
69 |
-
public function __invoke(
|
70 |
-
CommandInterface $command,
|
71 |
-
RequestInterface $request
|
72 |
-
) {
|
73 |
-
$fn = $this->httpHandler;
|
74 |
-
$options = $command['@http'] ?: [];
|
75 |
-
$stats = [];
|
76 |
-
if ($this->collectStats || !empty($options['collect_stats'])) {
|
77 |
-
$options['http_stats_receiver'] = static function (
|
78 |
-
array $transferStats
|
79 |
-
) use (&$stats) {
|
80 |
-
$stats = $transferStats;
|
81 |
-
};
|
82 |
-
} elseif (isset($options['http_stats_receiver'])) {
|
83 |
-
throw new \InvalidArgumentException('Providing a custom HTTP stats'
|
84 |
-
. ' receiver to Aws\WrappedHttpHandler is not supported.');
|
85 |
-
}
|
86 |
-
|
87 |
-
return Promise\promise_for($fn($request, $options))
|
88 |
-
->then(
|
89 |
-
function (
|
90 |
-
ResponseInterface $res
|
91 |
-
) use ($command, $request, &$stats) {
|
92 |
-
return $this->parseResponse($command, $request, $res, $stats);
|
93 |
-
},
|
94 |
-
function ($err) use ($request, $command, &$stats) {
|
95 |
-
if (is_array($err)) {
|
96 |
-
$err = $this->parseError(
|
97 |
-
$err,
|
98 |
-
$request,
|
99 |
-
$command,
|
100 |
-
$stats
|
101 |
-
);
|
102 |
-
}
|
103 |
-
return new Promise\RejectedPromise($err);
|
104 |
-
}
|
105 |
-
);
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* @param CommandInterface $command
|
110 |
-
* @param RequestInterface $request
|
111 |
-
* @param ResponseInterface $response
|
112 |
-
* @param array $stats
|
113 |
-
*
|
114 |
-
* @return ResultInterface
|
115 |
-
*/
|
116 |
-
private function parseResponse(
|
117 |
-
CommandInterface $command,
|
118 |
-
RequestInterface $request,
|
119 |
-
ResponseInterface $response,
|
120 |
-
array $stats
|
121 |
-
) {
|
122 |
-
$parser = $this->parser;
|
123 |
-
$status = $response->getStatusCode();
|
124 |
-
$result = $status < 300
|
125 |
-
? $parser($command, $response)
|
126 |
-
: new Result();
|
127 |
-
|
128 |
-
$metadata = [
|
129 |
-
'statusCode' => $status,
|
130 |
-
'effectiveUri' => (string) $request->getUri(),
|
131 |
-
'headers' => [],
|
132 |
-
'transferStats' => [],
|
133 |
-
];
|
134 |
-
if (!empty($stats)) {
|
135 |
-
$metadata['transferStats']['http'] = [$stats];
|
136 |
-
}
|
137 |
-
|
138 |
-
// Bring headers into the metadata array.
|
139 |
-
foreach ($response->getHeaders() as $name => $values) {
|
140 |
-
$metadata['headers'][strtolower($name)] = $values[0];
|
141 |
-
}
|
142 |
-
|
143 |
-
$result['@metadata'] = $metadata;
|
144 |
-
|
145 |
-
return $result;
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* Parses a rejection into an AWS error.
|
150 |
-
*
|
151 |
-
* @param array $err Rejection error array.
|
152 |
-
* @param RequestInterface $request Request that was sent.
|
153 |
-
* @param CommandInterface $command Command being sent.
|
154 |
-
* @param array $stats Transfer statistics
|
155 |
-
*
|
156 |
-
* @return \Exception
|
157 |
-
*/
|
158 |
-
private function parseError(
|
159 |
-
array $err,
|
160 |
-
RequestInterface $request,
|
161 |
-
CommandInterface $command,
|
162 |
-
array $stats
|
163 |
-
) {
|
164 |
-
if (!isset($err['exception'])) {
|
165 |
-
throw new \RuntimeException('The HTTP handler was rejected without an "exception" key value pair.');
|
166 |
-
}
|
167 |
-
|
168 |
-
$serviceError = "AWS HTTP error: " . $err['exception']->getMessage();
|
169 |
-
|
170 |
-
if (!isset($err['response'])) {
|
171 |
-
$parts = ['response' => null];
|
172 |
-
} else {
|
173 |
-
try {
|
174 |
-
$parts = call_user_func($this->errorParser, $err['response']);
|
175 |
-
$serviceError .= " {$parts['code']} ({$parts['type']}): "
|
176 |
-
. "{$parts['message']} - " . $err['response']->getBody();
|
177 |
-
} catch (ParserException $e) {
|
178 |
-
$parts = [];
|
179 |
-
$serviceError .= ' Unable to parse error information from '
|
180 |
-
. "response - {$e->getMessage()}";
|
181 |
-
}
|
182 |
-
|
183 |
-
$parts['response'] = $err['response'];
|
184 |
-
}
|
185 |
-
|
186 |
-
$parts['exception'] = $err['exception'];
|
187 |
-
$parts['request'] = $request;
|
188 |
-
$parts['connection_error'] = !empty($err['connection_error']);
|
189 |
-
$parts['transfer_stats'] = $stats;
|
190 |
-
|
191 |
-
return new $this->exceptionClass(
|
192 |
-
sprintf(
|
193 |
-
'Error executing "%s" on "%s"; %s',
|
194 |
-
$command->getName(),
|
195 |
-
$request->getUri(),
|
196 |
-
$serviceError
|
197 |
-
),
|
198 |
-
$command,
|
199 |
-
$parts,
|
200 |
-
$err['exception']
|
201 |
-
);
|
202 |
-
}
|
203 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/data/endpoints.json.php
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// This file was auto-generated from sdk-root/src/data/endpoints.json
|
3 |
-
return [ 'partitions' => [ [ 'defaults' => [ 'hostname' => '{service}.{region}.{dnsSuffix}', 'protocols' => [ 'https', ], 'signatureVersions' => [ 'v4', ], ], 'dnsSuffix' => 'amazonaws.com', 'partition' => 'aws', 'partitionName' => 'AWS Standard', 'regionRegex' => '^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$', 'regions' => [ 'ap-east-1' => [ 'description' => 'Asia Pacific (Hong Kong)', ], 'ap-northeast-1' => [ 'description' => 'Asia Pacific (Tokyo)', ], 'ap-northeast-2' => [ 'description' => 'Asia Pacific (Seoul)', ], 'ap-south-1' => [ 'description' => 'Asia Pacific (Mumbai)', ], 'ap-southeast-1' => [ 'description' => 'Asia Pacific (Singapore)', ], 'ap-southeast-2' => [ 'description' => 'Asia Pacific (Sydney)', ], 'ca-central-1' => [ 'description' => 'Canada (Central)', ], 'eu-central-1' => [ 'description' => 'EU (Frankfurt)', ], 'eu-north-1' => [ 'description' => 'EU (Stockholm)', ], 'eu-west-1' => [ 'description' => 'EU (Ireland)', ], 'eu-west-2' => [ 'description' => 'EU (London)', ], 'eu-west-3' => [ 'description' => 'EU (Paris)', ], 'sa-east-1' => [ 'description' => 'South America (Sao Paulo)', ], 'us-east-1' => [ 'description' => 'US East (N. Virginia)', ], 'us-east-2' => [ 'description' => 'US East (Ohio)', ], 'us-west-1' => [ 'description' => 'US West (N. California)', ], 'us-west-2' => [ 'description' => 'US West (Oregon)', ], ], 'services' => [ 'a4b' => [ 'endpoints' => [ 'us-east-1' => [], ], ], 'acm' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'acm-pca' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'api.ecr' => [ 'endpoints' => [ 'ap-east-1' => [ 'credentialScope' => [ 'region' => 'ap-east-1', ], 'hostname' => 'api.ecr.ap-east-1.amazonaws.com', ], 'ap-northeast-1' => [ 'credentialScope' => [ 'region' => 'ap-northeast-1', ], 'hostname' => 'api.ecr.ap-northeast-1.amazonaws.com', ], 'ap-northeast-2' => [ 'credentialScope' => [ 'region' => 'ap-northeast-2', ], 'hostname' => 'api.ecr.ap-northeast-2.amazonaws.com', ], 'ap-south-1' => [ 'credentialScope' => [ 'region' => 'ap-south-1', ], 'hostname' => 'api.ecr.ap-south-1.amazonaws.com', ], 'ap-southeast-1' => [ 'credentialScope' => [ 'region' => 'ap-southeast-1', ], 'hostname' => 'api.ecr.ap-southeast-1.amazonaws.com', ], 'ap-southeast-2' => [ 'credentialScope' => [ 'region' => 'ap-southeast-2', ], 'hostname' => 'api.ecr.ap-southeast-2.amazonaws.com', ], 'ca-central-1' => [ 'credentialScope' => [ 'region' => 'ca-central-1', ], 'hostname' => 'api.ecr.ca-central-1.amazonaws.com', ], 'eu-central-1' => [ 'credentialScope' => [ 'region' => 'eu-central-1', ], 'hostname' => 'api.ecr.eu-central-1.amazonaws.com', ], 'eu-north-1' => [ 'credentialScope' => [ 'region' => 'eu-north-1', ], 'hostname' => 'api.ecr.eu-north-1.amazonaws.com', ], 'eu-west-1' => [ 'credentialScope' => [ 'region' => 'eu-west-1', ], 'hostname' => 'api.ecr.eu-west-1.amazonaws.com', ], 'eu-west-2' => [ 'credentialScope' => [ 'region' => 'eu-west-2', ], 'hostname' => 'api.ecr.eu-west-2.amazonaws.com', ], 'eu-west-3' => [ 'credentialScope' => [ 'region' => 'eu-west-3', ], 'hostname' => 'api.ecr.eu-west-3.amazonaws.com', ], 'sa-east-1' => [ 'credentialScope' => [ 'region' => 'sa-east-1', ], 'hostname' => 'api.ecr.sa-east-1.amazonaws.com', ], 'us-east-1' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'api.ecr.us-east-1.amazonaws.com', ], 'us-east-2' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'api.ecr.us-east-2.amazonaws.com', ], 'us-west-1' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'api.ecr.us-west-1.amazonaws.com', ], 'us-west-2' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'api.ecr.us-west-2.amazonaws.com', ], ], ], 'api.mediatailor' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'api.pricing' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'pricing', ], ], 'endpoints' => [ 'ap-south-1' => [], 'us-east-1' => [], ], ], 'api.sagemaker' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'api-fips.sagemaker.us-east-1.amazonaws.com', ], 'us-east-2' => [], 'us-east-2-fips' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'api-fips.sagemaker.us-east-2.amazonaws.com', ], 'us-west-1' => [], 'us-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'api-fips.sagemaker.us-west-1.amazonaws.com', ], 'us-west-2' => [], 'us-west-2-fips' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'api-fips.sagemaker.us-west-2.amazonaws.com', ], ], ], 'apigateway' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'application-autoscaling' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'application-autoscaling', ], 'hostname' => 'autoscaling.{region}.amazonaws.com', 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'appstream2' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'appstream', ], 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'appsync' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'athena' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'autoscaling' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'autoscaling-plans' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'autoscaling-plans', ], 'hostname' => 'autoscaling.{region}.amazonaws.com', 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'batch' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'budgets' => [ 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'budgets.amazonaws.com', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'ce' => [ 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'ce.us-east-1.amazonaws.com', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'chime' => [ 'defaults' => [ 'protocols' => [ 'https', ], 'sslCommonName' => 'service.chime.aws.amazon.com', ], 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'service.chime.aws.amazon.com', 'protocols' => [ 'https', ], ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'cloud9' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'clouddirectory' => [ 'endpoints' => [ 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'cloudformation' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'cloudfront' => [ 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'cloudfront.amazonaws.com', 'protocols' => [ 'http', 'https', ], ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'cloudhsm' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'cloudhsmv2' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'cloudhsm', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'cloudsearch' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'cloudtrail' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'codebuild' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'codebuild-fips.us-east-1.amazonaws.com', ], 'us-east-2' => [], 'us-east-2-fips' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'codebuild-fips.us-east-2.amazonaws.com', ], 'us-west-1' => [], 'us-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'codebuild-fips.us-west-1.amazonaws.com', ], 'us-west-2' => [], 'us-west-2-fips' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'codebuild-fips.us-west-2.amazonaws.com', ], ], ], 'codecommit' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'fips' => [ 'credentialScope' => [ 'region' => 'ca-central-1', ], 'hostname' => 'codecommit-fips.ca-central-1.amazonaws.com', ], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'codedeploy' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'codedeploy-fips.us-east-1.amazonaws.com', ], 'us-east-2' => [], 'us-east-2-fips' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'codedeploy-fips.us-east-2.amazonaws.com', ], 'us-west-1' => [], 'us-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'codedeploy-fips.us-west-1.amazonaws.com', ], 'us-west-2' => [], 'us-west-2-fips' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'codedeploy-fips.us-west-2.amazonaws.com', ], ], ], 'codepipeline' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'codestar' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'cognito-identity' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'cognito-idp' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'cognito-sync' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'comprehend' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'comprehendmedical' => [ 'endpoints' => [ 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'config' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'cur' => [ 'endpoints' => [ 'us-east-1' => [], ], ], 'data.iot' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'iotdata', ], 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'data.mediastore' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'datapipeline' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-2' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'datasync' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'dax' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'devicefarm' => [ 'endpoints' => [ 'us-west-2' => [], ], ], 'directconnect' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'discovery' => [ 'endpoints' => [ 'us-west-2' => [], ], ], 'dms' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'docdb' => [ 'endpoints' => [ 'ap-northeast-1' => [ 'credentialScope' => [ 'region' => 'ap-northeast-1', ], 'hostname' => 'rds.ap-northeast-1.amazonaws.com', ], 'ap-northeast-2' => [ 'credentialScope' => [ 'region' => 'ap-northeast-2', ], 'hostname' => 'rds.ap-northeast-2.amazonaws.com', ], 'eu-central-1' => [ 'credentialScope' => [ 'region' => 'eu-central-1', ], 'hostname' => 'rds.eu-central-1.amazonaws.com', ], 'eu-west-1' => [ 'credentialScope' => [ 'region' => 'eu-west-1', ], 'hostname' => 'rds.eu-west-1.amazonaws.com', ], 'us-east-1' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'rds.us-east-1.amazonaws.com', ], 'us-east-2' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'rds.us-east-2.amazonaws.com', ], 'us-west-2' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'rds.us-west-2.amazonaws.com', ], ], ], 'ds' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'dynamodb' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'local' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'localhost:8000', 'protocols' => [ 'http', ], ], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'ec2' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'ecs' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'elasticache' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'elasticache-fips.us-west-1.amazonaws.com', ], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'elasticbeanstalk' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'elasticfilesystem' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'elasticloadbalancing' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'elasticmapreduce' => [ 'defaults' => [ 'protocols' => [ 'https', ], 'sslCommonName' => '{region}.{service}.{dnsSuffix}', ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [ 'sslCommonName' => '{service}.{region}.{dnsSuffix}', ], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [ 'sslCommonName' => '{service}.{region}.{dnsSuffix}', ], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'elastictranscoder' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'email' => [ 'endpoints' => [ 'ap-south-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'entitlement.marketplace' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'aws-marketplace', ], ], 'endpoints' => [ 'us-east-1' => [], ], ], 'es' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'es-fips.us-west-1.amazonaws.com', ], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'events' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'firehose' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'fms' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'fsx' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-2' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'gamelift' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'glacier' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'glue' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'greengrass' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], 'isRegionalized' => true, ], 'guardduty' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], 'isRegionalized' => true, ], 'health' => [ 'endpoints' => [ 'us-east-1' => [], ], ], 'iam' => [ 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'iam.amazonaws.com', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'importexport' => [ 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', 'service' => 'IngestionService', ], 'hostname' => 'importexport.amazonaws.com', 'signatureVersions' => [ 'v2', 'v4', ], ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'inspector' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'iot' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'execute-api', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'iotanalytics' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'kafka' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'kinesis' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'kinesisanalytics' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'kinesisvideo' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'kms' => [ 'endpoints' => [ 'ProdFips' => [ 'credentialScope' => [ 'region' => 'ca-central-1', ], 'hostname' => 'kms-fips.ca-central-1.amazonaws.com', ], 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'lambda' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'license-manager' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'lightsail' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'logs' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'machinelearning' => [ 'endpoints' => [ 'eu-west-1' => [], 'us-east-1' => [], ], ], 'marketplacecommerceanalytics' => [ 'endpoints' => [ 'us-east-1' => [], ], ], 'mediaconnect' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'mediaconvert' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'medialive' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'mediapackage' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'mediastore' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'metering.marketplace' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'aws-marketplace', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'mgh' => [ 'endpoints' => [ 'us-west-2' => [], ], ], 'mobileanalytics' => [ 'endpoints' => [ 'us-east-1' => [], ], ], 'models.lex' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'lex', ], ], 'endpoints' => [ 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'monitoring' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'mq' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'mturk-requester' => [ 'endpoints' => [ 'sandbox' => [ 'hostname' => 'mturk-requester-sandbox.us-east-1.amazonaws.com', ], 'us-east-1' => [], ], 'isRegionalized' => false, ], 'neptune' => [ 'endpoints' => [ 'ap-northeast-1' => [ 'credentialScope' => [ 'region' => 'ap-northeast-1', ], 'hostname' => 'rds.ap-northeast-1.amazonaws.com', ], 'ap-northeast-2' => [ 'credentialScope' => [ 'region' => 'ap-northeast-2', ], 'hostname' => 'rds.ap-northeast-2.amazonaws.com', ], 'ap-south-1' => [ 'credentialScope' => [ 'region' => 'ap-south-1', ], 'hostname' => 'rds.ap-south-1.amazonaws.com', ], 'ap-southeast-1' => [ 'credentialScope' => [ 'region' => 'ap-southeast-1', ], 'hostname' => 'rds.ap-southeast-1.amazonaws.com', ], 'ap-southeast-2' => [ 'credentialScope' => [ 'region' => 'ap-southeast-2', ], 'hostname' => 'rds.ap-southeast-2.amazonaws.com', ], 'eu-central-1' => [ 'credentialScope' => [ 'region' => 'eu-central-1', ], 'hostname' => 'rds.eu-central-1.amazonaws.com', ], 'eu-west-1' => [ 'credentialScope' => [ 'region' => 'eu-west-1', ], 'hostname' => 'rds.eu-west-1.amazonaws.com', ], 'eu-west-2' => [ 'credentialScope' => [ 'region' => 'eu-west-2', ], 'hostname' => 'rds.eu-west-2.amazonaws.com', ], 'us-east-1' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'rds.us-east-1.amazonaws.com', ], 'us-east-2' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'rds.us-east-2.amazonaws.com', ], 'us-west-2' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'rds.us-west-2.amazonaws.com', ], ], ], 'opsworks' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'opsworks-cm' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'organizations' => [ 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'organizations.us-east-1.amazonaws.com', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'pinpoint' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'mobiletargeting', ], ], 'endpoints' => [ 'ap-south-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'polly' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'ram' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'rds' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [ 'sslCommonName' => '{service}.{dnsSuffix}', ], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'redshift' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'rekognition' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-2' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-2' => [], ], ], 'resource-groups' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'robomaker' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'route53' => [ 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'route53.amazonaws.com', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'route53domains' => [ 'endpoints' => [ 'us-east-1' => [], ], ], 'route53resolver' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'runtime.lex' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'lex', ], ], 'endpoints' => [ 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'runtime.sagemaker' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 's3' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], 'signatureVersions' => [ 's3v4', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [ 'hostname' => 's3.ap-northeast-1.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [ 'hostname' => 's3.ap-southeast-1.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], 'ap-southeast-2' => [ 'hostname' => 's3.ap-southeast-2.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [ 'hostname' => 's3.eu-west-1.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], 'eu-west-2' => [], 'eu-west-3' => [], 's3-external-1' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 's3-external-1.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], 'sa-east-1' => [ 'hostname' => 's3.sa-east-1.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], 'us-east-1' => [ 'hostname' => 's3.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], 'us-east-2' => [], 'us-west-1' => [ 'hostname' => 's3.us-west-1.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], 'us-west-2' => [ 'hostname' => 's3.us-west-2.amazonaws.com', 'signatureVersions' => [ 's3', 's3v4', ], ], ], 'isRegionalized' => true, 'partitionEndpoint' => 'us-east-1', ], 's3-control' => [ 'defaults' => [ 'protocols' => [ 'https', ], 'signatureVersions' => [ 's3v4', ], ], 'endpoints' => [ 'ap-northeast-1' => [ 'credentialScope' => [ 'region' => 'ap-northeast-1', ], 'hostname' => 's3-control.ap-northeast-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'ap-northeast-2' => [ 'credentialScope' => [ 'region' => 'ap-northeast-2', ], 'hostname' => 's3-control.ap-northeast-2.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'ap-south-1' => [ 'credentialScope' => [ 'region' => 'ap-south-1', ], 'hostname' => 's3-control.ap-south-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'ap-southeast-1' => [ 'credentialScope' => [ 'region' => 'ap-southeast-1', ], 'hostname' => 's3-control.ap-southeast-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'ap-southeast-2' => [ 'credentialScope' => [ 'region' => 'ap-southeast-2', ], 'hostname' => 's3-control.ap-southeast-2.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'ca-central-1' => [ 'credentialScope' => [ 'region' => 'ca-central-1', ], 'hostname' => 's3-control.ca-central-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'eu-central-1' => [ 'credentialScope' => [ 'region' => 'eu-central-1', ], 'hostname' => 's3-control.eu-central-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'eu-north-1' => [ 'credentialScope' => [ 'region' => 'eu-north-1', ], 'hostname' => 's3-control.eu-north-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'eu-west-1' => [ 'credentialScope' => [ 'region' => 'eu-west-1', ], 'hostname' => 's3-control.eu-west-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'eu-west-2' => [ 'credentialScope' => [ 'region' => 'eu-west-2', ], 'hostname' => 's3-control.eu-west-2.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'eu-west-3' => [ 'credentialScope' => [ 'region' => 'eu-west-3', ], 'hostname' => 's3-control.eu-west-3.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'sa-east-1' => [ 'credentialScope' => [ 'region' => 'sa-east-1', ], 'hostname' => 's3-control.sa-east-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-east-1' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 's3-control.us-east-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 's3-control-fips.us-east-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-east-2' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 's3-control.us-east-2.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-east-2-fips' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 's3-control-fips.us-east-2.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-west-1' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 's3-control.us-west-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 's3-control-fips.us-west-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-west-2' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 's3-control.us-west-2.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-west-2-fips' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 's3-control-fips.us-west-2.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], ], ], 'sdb' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], 'signatureVersions' => [ 'v2', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-west-1' => [], 'sa-east-1' => [], 'us-east-1' => [ 'hostname' => 'sdb.amazonaws.com', ], 'us-west-1' => [], 'us-west-2' => [], ], ], 'secretsmanager' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'secretsmanager-fips.us-east-1.amazonaws.com', ], 'us-east-2' => [], 'us-east-2-fips' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'secretsmanager-fips.us-east-2.amazonaws.com', ], 'us-west-1' => [], 'us-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'secretsmanager-fips.us-west-1.amazonaws.com', ], 'us-west-2' => [], 'us-west-2-fips' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'secretsmanager-fips.us-west-2.amazonaws.com', ], ], ], 'securityhub' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'serverlessrepo' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [ 'protocols' => [ 'https', ], ], 'ap-northeast-2' => [ 'protocols' => [ 'https', ], ], 'ap-south-1' => [ 'protocols' => [ 'https', ], ], 'ap-southeast-1' => [ 'protocols' => [ 'https', ], ], 'ap-southeast-2' => [ 'protocols' => [ 'https', ], ], 'ca-central-1' => [ 'protocols' => [ 'https', ], ], 'eu-central-1' => [ 'protocols' => [ 'https', ], ], 'eu-north-1' => [ 'protocols' => [ 'https', ], ], 'eu-west-1' => [ 'protocols' => [ 'https', ], ], 'eu-west-2' => [ 'protocols' => [ 'https', ], ], 'eu-west-3' => [ 'protocols' => [ 'https', ], ], 'sa-east-1' => [ 'protocols' => [ 'https', ], ], 'us-east-1' => [ 'protocols' => [ 'https', ], ], 'us-east-2' => [ 'protocols' => [ 'https', ], ], 'us-west-1' => [ 'protocols' => [ 'https', ], ], 'us-west-2' => [ 'protocols' => [ 'https', ], ], ], ], 'servicecatalog' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'servicecatalog-fips.us-east-1.amazonaws.com', ], 'us-east-2' => [], 'us-east-2-fips' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'servicecatalog-fips.us-east-2.amazonaws.com', ], 'us-west-1' => [], 'us-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'servicecatalog-fips.us-west-1.amazonaws.com', ], 'us-west-2' => [], 'us-west-2-fips' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'servicecatalog-fips.us-west-2.amazonaws.com', ], ], ], 'servicediscovery' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'shield' => [ 'defaults' => [ 'protocols' => [ 'https', ], 'sslCommonName' => 'shield.us-east-1.amazonaws.com', ], 'endpoints' => [ 'us-east-1' => [], ], 'isRegionalized' => false, ], 'sms' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'snowball' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'sns' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'sqs' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], 'sslCommonName' => '{region}.queue.{dnsSuffix}', ], 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'fips-us-east-1' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'sqs-fips.us-east-1.amazonaws.com', ], 'fips-us-east-2' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'sqs-fips.us-east-2.amazonaws.com', ], 'fips-us-west-1' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'sqs-fips.us-west-1.amazonaws.com', ], 'fips-us-west-2' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'sqs-fips.us-west-2.amazonaws.com', ], 'sa-east-1' => [], 'us-east-1' => [ 'sslCommonName' => 'queue.{dnsSuffix}', ], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'ssm' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'states' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'storagegateway' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'streams.dynamodb' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'dynamodb', ], 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'local' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'localhost:8000', 'protocols' => [ 'http', ], ], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'sts' => [ 'defaults' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'sts.amazonaws.com', ], 'endpoints' => [ 'ap-east-1' => [ 'credentialScope' => [ 'region' => 'ap-east-1', ], 'hostname' => 'sts.ap-east-1.amazonaws.com', ], 'ap-northeast-1' => [], 'ap-northeast-2' => [ 'credentialScope' => [ 'region' => 'ap-northeast-2', ], 'hostname' => 'sts.ap-northeast-2.amazonaws.com', ], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'aws-global' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'sts-fips.us-east-1.amazonaws.com', ], 'us-east-2' => [], 'us-east-2-fips' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'sts-fips.us-east-2.amazonaws.com', ], 'us-west-1' => [], 'us-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-west-1', ], 'hostname' => 'sts-fips.us-west-1.amazonaws.com', ], 'us-west-2' => [], 'us-west-2-fips' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'sts-fips.us-west-2.amazonaws.com', ], ], 'partitionEndpoint' => 'aws-global', ], 'support' => [ 'endpoints' => [ 'us-east-1' => [], ], ], 'swf' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'tagging' => [ 'endpoints' => [ 'ap-east-1' => [], 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'transfer' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'translate' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'ap-northeast-2' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'translate-fips.us-east-1.amazonaws.com', ], 'us-east-2' => [], 'us-east-2-fips' => [ 'credentialScope' => [ 'region' => 'us-east-2', ], 'hostname' => 'translate-fips.us-east-2.amazonaws.com', ], 'us-west-2' => [], 'us-west-2-fips' => [ 'credentialScope' => [ 'region' => 'us-west-2', ], 'hostname' => 'translate-fips.us-west-2.amazonaws.com', ], ], ], 'waf' => [ 'endpoints' => [ 'aws-global' => [ 'credentialScope' => [ 'region' => 'us-east-1', ], 'hostname' => 'waf.amazonaws.com', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-global', ], 'waf-regional' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], 'workdocs' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'workmail' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'eu-west-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'workspaces' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-west-2' => [], ], ], 'xray' => [ 'endpoints' => [ 'ap-northeast-1' => [], 'ap-northeast-2' => [], 'ap-south-1' => [], 'ap-southeast-1' => [], 'ap-southeast-2' => [], 'ca-central-1' => [], 'eu-central-1' => [], 'eu-north-1' => [], 'eu-west-1' => [], 'eu-west-2' => [], 'eu-west-3' => [], 'sa-east-1' => [], 'us-east-1' => [], 'us-east-2' => [], 'us-west-1' => [], 'us-west-2' => [], ], ], ], ], [ 'defaults' => [ 'hostname' => '{service}.{region}.{dnsSuffix}', 'protocols' => [ 'https', ], 'signatureVersions' => [ 'v4', ], ], 'dnsSuffix' => 'amazonaws.com.cn', 'partition' => 'aws-cn', 'partitionName' => 'AWS China', 'regionRegex' => '^cn\\-\\w+\\-\\d+$', 'regions' => [ 'cn-north-1' => [ 'description' => 'China (Beijing)', ], 'cn-northwest-1' => [ 'description' => 'China (Ningxia)', ], ], 'services' => [ 'api.ecr' => [ 'endpoints' => [ 'cn-north-1' => [ 'credentialScope' => [ 'region' => 'cn-north-1', ], 'hostname' => 'api.ecr.cn-north-1.amazonaws.com.cn', ], 'cn-northwest-1' => [ 'credentialScope' => [ 'region' => 'cn-northwest-1', ], 'hostname' => 'api.ecr.cn-northwest-1.amazonaws.com.cn', ], ], ], 'apigateway' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'application-autoscaling' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'application-autoscaling', ], 'hostname' => 'autoscaling.{region}.amazonaws.com', 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'autoscaling' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'cloudformation' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'cloudfront' => [ 'endpoints' => [ 'aws-cn-global' => [ 'credentialScope' => [ 'region' => 'cn-northwest-1', ], 'hostname' => 'cloudfront.cn-northwest-1.amazonaws.com.cn', 'protocols' => [ 'http', 'https', ], ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-cn-global', ], 'cloudtrail' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'codebuild' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'codedeploy' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'cognito-identity' => [ 'endpoints' => [ 'cn-north-1' => [], ], ], 'config' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'data.iot' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'iotdata', ], 'protocols' => [ 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], ], ], 'directconnect' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'dms' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'ds' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'dynamodb' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'ec2' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'ecs' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'elasticache' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'elasticbeanstalk' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'elasticloadbalancing' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'elasticmapreduce' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'es' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'events' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'firehose' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'gamelift' => [ 'endpoints' => [ 'cn-north-1' => [], ], ], 'glacier' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'iam' => [ 'endpoints' => [ 'aws-cn-global' => [ 'credentialScope' => [ 'region' => 'cn-north-1', ], 'hostname' => 'iam.cn-north-1.amazonaws.com.cn', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-cn-global', ], 'iot' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'execute-api', ], ], 'endpoints' => [ 'cn-north-1' => [], ], ], 'kinesis' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'lambda' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'logs' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'mediaconvert' => [ 'endpoints' => [ 'cn-northwest-1' => [ 'credentialScope' => [ 'region' => 'cn-northwest-1', ], 'hostname' => 'subscribe.mediaconvert.cn-northwest-1.amazonaws.com.cn', ], ], ], 'monitoring' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'polly' => [ 'endpoints' => [ 'cn-northwest-1' => [], ], ], 'rds' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'redshift' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 's3' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], 'signatureVersions' => [ 's3v4', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 's3-control' => [ 'defaults' => [ 'protocols' => [ 'https', ], 'signatureVersions' => [ 's3v4', ], ], 'endpoints' => [ 'cn-north-1' => [ 'credentialScope' => [ 'region' => 'cn-north-1', ], 'hostname' => 's3-control.cn-north-1.amazonaws.com.cn', 'signatureVersions' => [ 's3v4', ], ], 'cn-northwest-1' => [ 'credentialScope' => [ 'region' => 'cn-northwest-1', ], 'hostname' => 's3-control.cn-northwest-1.amazonaws.com.cn', 'signatureVersions' => [ 's3v4', ], ], ], ], 'sms' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'snowball' => [ 'endpoints' => [ 'cn-north-1' => [], ], ], 'sns' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'sqs' => [ 'defaults' => [ 'protocols' => [ 'http', 'https', ], 'sslCommonName' => '{region}.queue.{dnsSuffix}', ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'ssm' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'states' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'storagegateway' => [ 'endpoints' => [ 'cn-north-1' => [], ], ], 'streams.dynamodb' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'dynamodb', ], 'protocols' => [ 'http', 'https', ], ], 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'sts' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'swf' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], 'tagging' => [ 'endpoints' => [ 'cn-north-1' => [], 'cn-northwest-1' => [], ], ], ], ], [ 'defaults' => [ 'hostname' => '{service}.{region}.{dnsSuffix}', 'protocols' => [ 'https', ], 'signatureVersions' => [ 'v4', ], ], 'dnsSuffix' => 'amazonaws.com', 'partition' => 'aws-us-gov', 'partitionName' => 'AWS GovCloud (US)', 'regionRegex' => '^us\\-gov\\-\\w+\\-\\d+$', 'regions' => [ 'us-gov-east-1' => [ 'description' => 'AWS GovCloud (US-East)', ], 'us-gov-west-1' => [ 'description' => 'AWS GovCloud (US)', ], ], 'services' => [ 'acm' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'acm-pca' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'api.ecr' => [ 'endpoints' => [ 'us-gov-east-1' => [ 'credentialScope' => [ 'region' => 'us-gov-east-1', ], 'hostname' => 'api.ecr.us-gov-east-1.amazonaws.com', ], 'us-gov-west-1' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'api.ecr.us-gov-west-1.amazonaws.com', ], ], ], 'api.sagemaker' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'apigateway' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'application-autoscaling' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'athena' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'autoscaling' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [ 'protocols' => [ 'http', 'https', ], ], ], ], 'clouddirectory' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'cloudformation' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'cloudhsm' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'cloudhsmv2' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'cloudhsm', ], ], 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'cloudtrail' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'codecommit' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'codedeploy' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-gov-east-1', ], 'hostname' => 'codedeploy-fips.us-gov-east-1.amazonaws.com', ], 'us-gov-west-1' => [], 'us-gov-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'codedeploy-fips.us-gov-west-1.amazonaws.com', ], ], ], 'comprehend' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'config' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'data.iot' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'iotdata', ], 'protocols' => [ 'https', ], ], 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'directconnect' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'dms' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'ds' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'dynamodb' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], 'us-gov-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'dynamodb.us-gov-west-1.amazonaws.com', ], ], ], 'ec2' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'ecs' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'elasticache' => [ 'endpoints' => [ 'fips' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'elasticache-fips.us-gov-west-1.amazonaws.com', ], 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'elasticbeanstalk' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'elasticfilesystem' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'elasticloadbalancing' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [ 'protocols' => [ 'http', 'https', ], ], ], ], 'elasticmapreduce' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [ 'protocols' => [ 'https', ], ], ], ], 'es' => [ 'endpoints' => [ 'fips' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'es-fips.us-gov-west-1.amazonaws.com', ], 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'events' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'firehose' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'glacier' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [ 'protocols' => [ 'http', 'https', ], ], ], ], 'glue' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'guardduty' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'us-gov-west-1' => [], ], 'isRegionalized' => true, ], 'iam' => [ 'endpoints' => [ 'aws-us-gov-global' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'iam.us-gov.amazonaws.com', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-us-gov-global', ], 'inspector' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'iot' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'execute-api', ], ], 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'kinesis' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'kms' => [ 'endpoints' => [ 'ProdFips' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'kms-fips.us-gov-west-1.amazonaws.com', ], 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'lambda' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'license-manager' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'logs' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'mediaconvert' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'metering.marketplace' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'aws-marketplace', ], ], 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'monitoring' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'organizations' => [ 'endpoints' => [ 'aws-us-gov-global' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'organizations.us-gov-west-1.amazonaws.com', ], ], 'isRegionalized' => false, 'partitionEndpoint' => 'aws-us-gov-global', ], 'polly' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'rds' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'redshift' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'rekognition' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'runtime.sagemaker' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 's3' => [ 'defaults' => [ 'signatureVersions' => [ 's3', 's3v4', ], ], 'endpoints' => [ 'fips-us-gov-west-1' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 's3-fips-us-gov-west-1.amazonaws.com', ], 'us-gov-east-1' => [ 'hostname' => 's3.us-gov-east-1.amazonaws.com', 'protocols' => [ 'http', 'https', ], ], 'us-gov-west-1' => [ 'hostname' => 's3.us-gov-west-1.amazonaws.com', 'protocols' => [ 'http', 'https', ], ], ], ], 's3-control' => [ 'defaults' => [ 'protocols' => [ 'https', ], 'signatureVersions' => [ 's3v4', ], ], 'endpoints' => [ 'us-gov-east-1' => [ 'credentialScope' => [ 'region' => 'us-gov-east-1', ], 'hostname' => 's3-control.us-gov-east-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-gov-east-1-fips' => [ 'credentialScope' => [ 'region' => 'us-gov-east-1', ], 'hostname' => 's3-control-fips.us-gov-east-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-gov-west-1' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 's3-control.us-gov-west-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], 'us-gov-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 's3-control-fips.us-gov-west-1.amazonaws.com', 'signatureVersions' => [ 's3v4', ], ], ], ], 'sms' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'snowball' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'sns' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [ 'protocols' => [ 'http', 'https', ], ], ], ], 'sqs' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [ 'protocols' => [ 'http', 'https', ], 'sslCommonName' => '{region}.queue.{dnsSuffix}', ], ], ], 'ssm' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'states' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'storagegateway' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'streams.dynamodb' => [ 'defaults' => [ 'credentialScope' => [ 'service' => 'dynamodb', ], ], 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], 'us-gov-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'dynamodb.us-gov-west-1.amazonaws.com', ], ], ], 'sts' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'swf' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'tagging' => [ 'endpoints' => [ 'us-gov-east-1' => [], 'us-gov-west-1' => [], ], ], 'translate' => [ 'defaults' => [ 'protocols' => [ 'https', ], ], 'endpoints' => [ 'us-gov-west-1' => [], 'us-gov-west-1-fips' => [ 'credentialScope' => [ 'region' => 'us-gov-west-1', ], 'hostname' => 'translate-fips.us-gov-west-1.amazonaws.com', ], ], ], 'waf-regional' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], 'workspaces' => [ 'endpoints' => [ 'us-gov-west-1' => [], ], ], ], ], ], 'version' => 3,];
|
|
|
|
|
|
lib/Aws/Aws/data/endpoints_prefix_history.json.php
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// This file was auto-generated from sdk-root/src/data/endpoints_prefix_history.json
|
3 |
-
return [ 'prefix-groups' => [ 'api.ecr' => [ 'ecr', ], 'api.sagemaker' => [ 'sagemaker', ], 'ecr' => [ 'api.ecr', ], 'sagemaker' => [ 'api.sagemaker', ], ],];
|
|
|
|
|
|
lib/Aws/Aws/data/manifest.json.php
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// This file was auto-generated from sdk-root/src/data/manifest.json
|
3 |
-
return [ 'acm-pca' => [ 'namespace' => 'ACMPCA', 'versions' => [ 'latest' => '2017-08-22', '2017-08-22' => '2017-08-22', ], ], 'acm' => [ 'namespace' => 'Acm', 'versions' => [ 'latest' => '2015-12-08', '2015-12-08' => '2015-12-08', ], ], 'alexaforbusiness' => [ 'namespace' => 'AlexaForBusiness', 'versions' => [ 'latest' => '2017-11-09', '2017-11-09' => '2017-11-09', ], ], 'amplify' => [ 'namespace' => 'Amplify', 'versions' => [ 'latest' => '2017-07-25', '2017-07-25' => '2017-07-25', ], ], 'apigateway' => [ 'namespace' => 'ApiGateway', 'versions' => [ 'latest' => '2015-07-09', '2015-07-09' => '2015-07-09', '2015-06-01' => '2015-07-09', ], ], 'apigatewaymanagementapi' => [ 'namespace' => 'ApiGatewayManagementApi', 'versions' => [ 'latest' => '2018-11-29', '2018-11-29' => '2018-11-29', ], ], 'apigatewayv2' => [ 'namespace' => 'ApiGatewayV2', 'versions' => [ 'latest' => '2018-11-29', '2018-11-29' => '2018-11-29', ], ], 'application-autoscaling' => [ 'namespace' => 'ApplicationAutoScaling', 'versions' => [ 'latest' => '2016-02-06', '2016-02-06' => '2016-02-06', ], ], 'appmesh' => [ 'namespace' => 'AppMesh', 'versions' => [ 'latest' => '2019-01-25', '2019-01-25' => '2019-01-25', '2018-10-01' => '2018-10-01', ], ], 'appstream' => [ 'namespace' => 'Appstream', 'versions' => [ 'latest' => '2016-12-01', '2016-12-01' => '2016-12-01', ], ], 'appsync' => [ 'namespace' => 'AppSync', 'versions' => [ 'latest' => '2017-07-25', '2017-07-25' => '2017-07-25', ], ], 'athena' => [ 'namespace' => 'Athena', 'versions' => [ 'latest' => '2017-05-18', '2017-05-18' => '2017-05-18', ], ], 'autoscaling-plans' => [ 'namespace' => 'AutoScalingPlans', 'versions' => [ 'latest' => '2018-01-06', '2018-01-06' => '2018-01-06', ], ], 'autoscaling' => [ 'namespace' => 'AutoScaling', 'versions' => [ 'latest' => '2011-01-01', '2011-01-01' => '2011-01-01', ], ], 'backup' => [ 'namespace' => 'Backup', 'versions' => [ 'latest' => '2018-11-15', '2018-11-15' => '2018-11-15', ], ], 'batch' => [ 'namespace' => 'Batch', 'versions' => [ 'latest' => '2016-08-10', '2016-08-10' => '2016-08-10', ], ], 'budgets' => [ 'namespace' => 'Budgets', 'versions' => [ 'latest' => '2016-10-20', '2016-10-20' => '2016-10-20', ], ], 'ce' => [ 'namespace' => 'CostExplorer', 'versions' => [ 'latest' => '2017-10-25', '2017-10-25' => '2017-10-25', ], ], 'chime' => [ 'namespace' => 'Chime', 'versions' => [ 'latest' => '2018-05-01', '2018-05-01' => '2018-05-01', ], ], 'cloud9' => [ 'namespace' => 'Cloud9', 'versions' => [ 'latest' => '2017-09-23', '2017-09-23' => '2017-09-23', ], ], 'clouddirectory' => [ 'namespace' => 'CloudDirectory', 'versions' => [ 'latest' => '2017-01-11', '2017-01-11' => '2017-01-11', '2016-05-10' => '2016-05-10', ], ], 'cloudformation' => [ 'namespace' => 'CloudFormation', 'versions' => [ 'latest' => '2010-05-15', '2010-05-15' => '2010-05-15', ], ], 'cloudfront' => [ 'namespace' => 'CloudFront', 'versions' => [ 'latest' => '2018-11-05', '2018-11-05' => '2018-11-05', '2018-06-18' => '2018-06-18', '2017-10-30' => '2017-10-30', '2017-03-25' => '2017-03-25', '2016-11-25' => '2016-11-25', '2016-09-29' => '2016-09-29', '2016-09-07' => '2016-09-07', '2016-08-20' => '2016-08-20', '2016-08-01' => '2016-08-01', '2016-01-28' => '2016-01-28', '2016-01-13' => '2018-11-05', '2015-09-17' => '2018-11-05', '2015-07-27' => '2015-07-27', '2015-04-17' => '2015-07-27', '2014-11-06' => '2015-07-27', ], ], 'cloudhsm' => [ 'namespace' => 'CloudHsm', 'versions' => [ 'latest' => '2014-05-30', '2014-05-30' => '2014-05-30', ], ], 'cloudhsmv2' => [ 'namespace' => 'CloudHSMV2', 'versions' => [ 'latest' => '2017-04-28', '2017-04-28' => '2017-04-28', ], ], 'cloudsearch' => [ 'namespace' => 'CloudSearch', 'versions' => [ 'latest' => '2013-01-01', '2013-01-01' => '2013-01-01', ], ], 'cloudsearchdomain' => [ 'namespace' => 'CloudSearchDomain', 'versions' => [ 'latest' => '2013-01-01', '2013-01-01' => '2013-01-01', ], ], 'cloudtrail' => [ 'namespace' => 'CloudTrail', 'versions' => [ 'latest' => '2013-11-01', '2013-11-01' => '2013-11-01', ], ], 'codebuild' => [ 'namespace' => 'CodeBuild', 'versions' => [ 'latest' => '2016-10-06', '2016-10-06' => '2016-10-06', ], ], 'codecommit' => [ 'namespace' => 'CodeCommit', 'versions' => [ 'latest' => '2015-04-13', '2015-04-13' => '2015-04-13', ], ], 'codedeploy' => [ 'namespace' => 'CodeDeploy', 'versions' => [ 'latest' => '2014-10-06', '2014-10-06' => '2014-10-06', ], ], 'codepipeline' => [ 'namespace' => 'CodePipeline', 'versions' => [ 'latest' => '2015-07-09', '2015-07-09' => '2015-07-09', ], ], 'codestar' => [ 'namespace' => 'CodeStar', 'versions' => [ 'latest' => '2017-04-19', '2017-04-19' => '2017-04-19', ], ], 'cognito-identity' => [ 'namespace' => 'CognitoIdentity', 'versions' => [ 'latest' => '2014-06-30', '2014-06-30' => '2014-06-30', ], ], 'cognito-idp' => [ 'namespace' => 'CognitoIdentityProvider', 'versions' => [ 'latest' => '2016-04-18', '2016-04-18' => '2016-04-18', ], ], 'cognito-sync' => [ 'namespace' => 'CognitoSync', 'versions' => [ 'latest' => '2014-06-30', '2014-06-30' => '2014-06-30', ], ], 'comprehend' => [ 'namespace' => 'Comprehend', 'versions' => [ 'latest' => '2017-11-27', '2017-11-27' => '2017-11-27', ], ], 'comprehendmedical' => [ 'namespace' => 'ComprehendMedical', 'versions' => [ 'latest' => '2018-10-30', '2018-10-30' => '2018-10-30', ], ], 'config' => [ 'namespace' => 'ConfigService', 'versions' => [ 'latest' => '2014-11-12', '2014-11-12' => '2014-11-12', ], ], 'connect' => [ 'namespace' => 'Connect', 'versions' => [ 'latest' => '2017-08-08', '2017-08-08' => '2017-08-08', ], ], 'cur' => [ 'namespace' => 'CostandUsageReportService', 'versions' => [ 'latest' => '2017-01-06', '2017-01-06' => '2017-01-06', ], ], 'data.iot' => [ 'namespace' => 'IotDataPlane', 'versions' => [ 'latest' => '2015-05-28', '2015-05-28' => '2015-05-28', ], ], 'datapipeline' => [ 'namespace' => 'DataPipeline', 'versions' => [ 'latest' => '2012-10-29', '2012-10-29' => '2012-10-29', ], ], 'datasync' => [ 'namespace' => 'DataSync', 'versions' => [ 'latest' => '2018-11-09', '2018-11-09' => '2018-11-09', ], ], 'dax' => [ 'namespace' => 'DAX', 'versions' => [ 'latest' => '2017-04-19', '2017-04-19' => '2017-04-19', ], ], 'devicefarm' => [ 'namespace' => 'DeviceFarm', 'versions' => [ 'latest' => '2015-06-23', '2015-06-23' => '2015-06-23', ], ], 'directconnect' => [ 'namespace' => 'DirectConnect', 'versions' => [ 'latest' => '2012-10-25', '2012-10-25' => '2012-10-25', ], ], 'discovery' => [ 'namespace' => 'ApplicationDiscoveryService', 'versions' => [ 'latest' => '2015-11-01', '2015-11-01' => '2015-11-01', ], ], 'dlm' => [ 'namespace' => 'DLM', 'versions' => [ 'latest' => '2018-01-12', '2018-01-12' => '2018-01-12', ], ], 'dms' => [ 'namespace' => 'DatabaseMigrationService', 'versions' => [ 'latest' => '2016-01-01', '2016-01-01' => '2016-01-01', ], ], 'docdb' => [ 'namespace' => 'DocDB', 'versions' => [ 'latest' => '2014-10-31', '2014-10-31' => '2014-10-31', ], ], 'ds' => [ 'namespace' => 'DirectoryService', 'versions' => [ 'latest' => '2015-04-16', '2015-04-16' => '2015-04-16', ], ], 'dynamodb' => [ 'namespace' => 'DynamoDb', 'versions' => [ 'latest' => '2012-08-10', '2012-08-10' => '2012-08-10', '2011-12-05' => '2011-12-05', ], ], 'ec2' => [ 'namespace' => 'Ec2', 'versions' => [ 'latest' => '2016-11-15', '2016-11-15' => '2016-11-15', '2016-09-15' => '2016-09-15', '2016-04-01' => '2016-04-01', '2015-10-01' => '2015-10-01', '2015-04-15' => '2016-11-15', ], ], 'ecr' => [ 'namespace' => 'Ecr', 'versions' => [ 'latest' => '2015-09-21', '2015-09-21' => '2015-09-21', ], ], 'ecs' => [ 'namespace' => 'Ecs', 'versions' => [ 'latest' => '2014-11-13', '2014-11-13' => '2014-11-13', ], ], 'eks' => [ 'namespace' => 'EKS', 'versions' => [ 'latest' => '2017-11-01', '2017-11-01' => '2017-11-01', ], ], 'elasticache' => [ 'namespace' => 'ElastiCache', 'versions' => [ 'latest' => '2015-02-02', '2015-02-02' => '2015-02-02', ], ], 'elasticbeanstalk' => [ 'namespace' => 'ElasticBeanstalk', 'versions' => [ 'latest' => '2010-12-01', '2010-12-01' => '2010-12-01', ], ], 'elasticfilesystem' => [ 'namespace' => 'Efs', 'versions' => [ 'latest' => '2015-02-01', '2015-02-01' => '2015-02-01', ], ], 'elasticloadbalancing' => [ 'namespace' => 'ElasticLoadBalancing', 'versions' => [ 'latest' => '2012-06-01', '2012-06-01' => '2012-06-01', ], ], 'elasticloadbalancingv2' => [ 'namespace' => 'ElasticLoadBalancingV2', 'versions' => [ 'latest' => '2015-12-01', '2015-12-01' => '2015-12-01', ], ], 'elasticmapreduce' => [ 'namespace' => 'Emr', 'versions' => [ 'latest' => '2009-03-31', '2009-03-31' => '2009-03-31', ], ], 'elastictranscoder' => [ 'namespace' => 'ElasticTranscoder', 'versions' => [ 'latest' => '2012-09-25', '2012-09-25' => '2012-09-25', ], ], 'email' => [ 'namespace' => 'Ses', 'versions' => [ 'latest' => '2010-12-01', '2010-12-01' => '2010-12-01', ], ], 'entitlement.marketplace' => [ 'namespace' => 'MarketplaceEntitlementService', 'versions' => [ 'latest' => '2017-01-11', '2017-01-11' => '2017-01-11', ], ], 'es' => [ 'namespace' => 'ElasticsearchService', 'versions' => [ 'latest' => '2015-01-01', '2015-01-01' => '2015-01-01', ], ], 'events' => [ 'namespace' => 'CloudWatchEvents', 'versions' => [ 'latest' => '2015-10-07', '2015-10-07' => '2015-10-07', '2014-02-03' => '2015-10-07', ], ], 'firehose' => [ 'namespace' => 'Firehose', 'versions' => [ 'latest' => '2015-08-04', '2015-08-04' => '2015-08-04', ], ], 'fms' => [ 'namespace' => 'FMS', 'versions' => [ 'latest' => '2018-01-01', '2018-01-01' => '2018-01-01', ], ], 'fsx' => [ 'namespace' => 'FSx', 'versions' => [ 'latest' => '2018-03-01', '2018-03-01' => '2018-03-01', ], ], 'gamelift' => [ 'namespace' => 'GameLift', 'versions' => [ 'latest' => '2015-10-01', '2015-10-01' => '2015-10-01', ], ], 'glacier' => [ 'namespace' => 'Glacier', 'versions' => [ 'latest' => '2012-06-01', '2012-06-01' => '2012-06-01', ], ], 'globalaccelerator' => [ 'namespace' => 'GlobalAccelerator', 'versions' => [ 'latest' => '2018-08-08', '2018-08-08' => '2018-08-08', ], ], 'glue' => [ 'namespace' => 'Glue', 'versions' => [ 'latest' => '2017-03-31', '2017-03-31' => '2017-03-31', ], ], 'greengrass' => [ 'namespace' => 'Greengrass', 'versions' => [ 'latest' => '2017-06-07', '2017-06-07' => '2017-06-07', ], ], 'guardduty' => [ 'namespace' => 'GuardDuty', 'versions' => [ 'latest' => '2017-11-28', '2017-11-28' => '2017-11-28', ], ], 'health' => [ 'namespace' => 'Health', 'versions' => [ 'latest' => '2016-08-04', '2016-08-04' => '2016-08-04', ], ], 'iam' => [ 'namespace' => 'Iam', 'versions' => [ 'latest' => '2010-05-08', '2010-05-08' => '2010-05-08', ], ], 'importexport' => [ 'namespace' => 'ImportExport', 'versions' => [ 'latest' => '2010-06-01', '2010-06-01' => '2010-06-01', ], ], 'inspector' => [ 'namespace' => 'Inspector', 'versions' => [ 'latest' => '2016-02-16', '2016-02-16' => '2016-02-16', '2015-08-18' => '2016-02-16', ], ], 'iot-jobs-data' => [ 'namespace' => 'IoTJobsDataPlane', 'versions' => [ 'latest' => '2017-09-29', '2017-09-29' => '2017-09-29', ], ], 'iot' => [ 'namespace' => 'Iot', 'versions' => [ 'latest' => '2015-05-28', '2015-05-28' => '2015-05-28', ], ], 'iot1click-devices' => [ 'namespace' => 'IoT1ClickDevicesService', 'versions' => [ 'latest' => '2018-05-14', '2018-05-14' => '2018-05-14', ], ], 'iot1click-projects' => [ 'namespace' => 'IoT1ClickProjects', 'versions' => [ 'latest' => '2018-05-14', '2018-05-14' => '2018-05-14', ], ], 'iotanalytics' => [ 'namespace' => 'IoTAnalytics', 'versions' => [ 'latest' => '2017-11-27', '2017-11-27' => '2017-11-27', ], ], 'kafka' => [ 'namespace' => 'Kafka', 'versions' => [ 'latest' => '2018-11-14', '2018-11-14' => '2018-11-14', ], ], 'kinesis-video-archived-media' => [ 'namespace' => 'KinesisVideoArchivedMedia', 'versions' => [ 'latest' => '2017-09-30', '2017-09-30' => '2017-09-30', ], ], 'kinesis-video-media' => [ 'namespace' => 'KinesisVideoMedia', 'versions' => [ 'latest' => '2017-09-30', '2017-09-30' => '2017-09-30', ], ], 'kinesis' => [ 'namespace' => 'Kinesis', 'versions' => [ 'latest' => '2013-12-02', '2013-12-02' => '2013-12-02', ], ], 'kinesisanalytics' => [ 'namespace' => 'KinesisAnalytics', 'versions' => [ 'latest' => '2015-08-14', '2015-08-14' => '2015-08-14', ], ], 'kinesisanalyticsv2' => [ 'namespace' => 'KinesisAnalyticsV2', 'versions' => [ 'latest' => '2018-05-23', '2018-05-23' => '2018-05-23', ], ], 'kinesisvideo' => [ 'namespace' => 'KinesisVideo', 'versions' => [ 'latest' => '2017-09-30', '2017-09-30' => '2017-09-30', ], ], 'kms' => [ 'namespace' => 'Kms', 'versions' => [ 'latest' => '2014-11-01', '2014-11-01' => '2014-11-01', ], ], 'lambda' => [ 'namespace' => 'Lambda', 'versions' => [ 'latest' => '2015-03-31', '2015-03-31' => '2015-03-31', ], ], 'lex-models' => [ 'namespace' => 'LexModelBuildingService', 'versions' => [ 'latest' => '2017-04-19', '2017-04-19' => '2017-04-19', ], ], 'license-manager' => [ 'namespace' => 'LicenseManager', 'versions' => [ 'latest' => '2018-08-01', '2018-08-01' => '2018-08-01', ], ], 'lightsail' => [ 'namespace' => 'Lightsail', 'versions' => [ 'latest' => '2016-11-28', '2016-11-28' => '2016-11-28', ], ], 'logs' => [ 'namespace' => 'CloudWatchLogs', 'versions' => [ 'latest' => '2014-03-28', '2014-03-28' => '2014-03-28', ], ], 'machinelearning' => [ 'namespace' => 'MachineLearning', 'versions' => [ 'latest' => '2014-12-12', '2014-12-12' => '2014-12-12', ], ], 'macie' => [ 'namespace' => 'Macie', 'versions' => [ 'latest' => '2017-12-19', '2017-12-19' => '2017-12-19', ], ], 'managedblockchain' => [ 'namespace' => 'ManagedBlockchain', 'versions' => [ 'latest' => '2018-09-24', '2018-09-24' => '2018-09-24', ], ], 'marketplacecommerceanalytics' => [ 'namespace' => 'MarketplaceCommerceAnalytics', 'versions' => [ 'latest' => '2015-07-01', '2015-07-01' => '2015-07-01', ], ], 'mediaconnect' => [ 'namespace' => 'MediaConnect', 'versions' => [ 'latest' => '2018-11-14', '2018-11-14' => '2018-11-14', ], ], 'mediaconvert' => [ 'namespace' => 'MediaConvert', 'versions' => [ 'latest' => '2017-08-29', '2017-08-29' => '2017-08-29', ], ], 'medialive' => [ 'namespace' => 'MediaLive', 'versions' => [ 'latest' => '2017-10-14', '2017-10-14' => '2017-10-14', ], ], 'mediapackage' => [ 'namespace' => 'MediaPackage', 'versions' => [ 'latest' => '2017-10-12', '2017-10-12' => '2017-10-12', ], ], 'mediastore-data' => [ 'namespace' => 'MediaStoreData', 'versions' => [ 'latest' => '2017-09-01', '2017-09-01' => '2017-09-01', ], ], 'mediastore' => [ 'namespace' => 'MediaStore', 'versions' => [ 'latest' => '2017-09-01', '2017-09-01' => '2017-09-01', ], ], 'mediatailor' => [ 'namespace' => 'MediaTailor', 'versions' => [ 'latest' => '2018-04-23', '2018-04-23' => '2018-04-23', ], ], 'metering.marketplace' => [ 'namespace' => 'MarketplaceMetering', 'versions' => [ 'latest' => '2016-01-14', '2016-01-14' => '2016-01-14', ], ], 'mgh' => [ 'namespace' => 'MigrationHub', 'versions' => [ 'latest' => '2017-05-31', '2017-05-31' => '2017-05-31', ], ], 'mobile' => [ 'namespace' => 'Mobile', 'versions' => [ 'latest' => '2017-07-01', '2017-07-01' => '2017-07-01', ], ], 'monitoring' => [ 'namespace' => 'CloudWatch', 'versions' => [ 'latest' => '2010-08-01', '2010-08-01' => '2010-08-01', ], ], 'mq' => [ 'namespace' => 'MQ', 'versions' => [ 'latest' => '2017-11-27', '2017-11-27' => '2017-11-27', ], ], 'mturk-requester' => [ 'namespace' => 'MTurk', 'versions' => [ 'latest' => '2017-01-17', '2017-01-17' => '2017-01-17', ], ], 'neptune' => [ 'namespace' => 'Neptune', 'versions' => [ 'latest' => '2014-10-31', '2014-10-31' => '2014-10-31', ], ], 'opsworks' => [ 'namespace' => 'OpsWorks', 'versions' => [ 'latest' => '2013-02-18', '2013-02-18' => '2013-02-18', ], ], 'opsworkscm' => [ 'namespace' => 'OpsWorksCM', 'versions' => [ 'latest' => '2016-11-01', '2016-11-01' => '2016-11-01', ], ], 'organizations' => [ 'namespace' => 'Organizations', 'versions' => [ 'latest' => '2016-11-28', '2016-11-28' => '2016-11-28', ], ], 'pi' => [ 'namespace' => 'PI', 'versions' => [ 'latest' => '2018-02-27', '2018-02-27' => '2018-02-27', ], ], 'pinpoint-email' => [ 'namespace' => 'PinpointEmail', 'versions' => [ 'latest' => '2018-07-26', '2018-07-26' => '2018-07-26', ], ], 'pinpoint' => [ 'namespace' => 'Pinpoint', 'versions' => [ 'latest' => '2016-12-01', '2016-12-01' => '2016-12-01', ], ], 'polly' => [ 'namespace' => 'Polly', 'versions' => [ 'latest' => '2016-06-10', '2016-06-10' => '2016-06-10', ], ], 'pricing' => [ 'namespace' => 'Pricing', 'versions' => [ 'latest' => '2017-10-15', '2017-10-15' => '2017-10-15', ], ], 'quicksight' => [ 'namespace' => 'QuickSight', 'versions' => [ 'latest' => '2018-04-01', '2018-04-01' => '2018-04-01', ], ], 'ram' => [ 'namespace' => 'RAM', 'versions' => [ 'latest' => '2018-01-04', '2018-01-04' => '2018-01-04', ], ], 'rds-data' => [ 'namespace' => 'RDSDataService', 'versions' => [ 'latest' => '2018-08-01', '2018-08-01' => '2018-08-01', ], ], 'rds' => [ 'namespace' => 'Rds', 'versions' => [ 'latest' => '2014-10-31', '2014-10-31' => '2014-10-31', '2014-09-01' => '2014-09-01', ], ], 'redshift' => [ 'namespace' => 'Redshift', 'versions' => [ 'latest' => '2012-12-01', '2012-12-01' => '2012-12-01', ], ], 'rekognition' => [ 'namespace' => 'Rekognition', 'versions' => [ 'latest' => '2016-06-27', '2016-06-27' => '2016-06-27', ], ], 'resource-groups' => [ 'namespace' => 'ResourceGroups', 'versions' => [ 'latest' => '2017-11-27', '2017-11-27' => '2017-11-27', ], ], 'resourcegroupstaggingapi' => [ 'namespace' => 'ResourceGroupsTaggingAPI', 'versions' => [ 'latest' => '2017-01-26', '2017-01-26' => '2017-01-26', ], ], 'robomaker' => [ 'namespace' => 'RoboMaker', 'versions' => [ 'latest' => '2018-06-29', '2018-06-29' => '2018-06-29', ], ], 'route53' => [ 'namespace' => 'Route53', 'versions' => [ 'latest' => '2013-04-01', '2013-04-01' => '2013-04-01', ], ], 'route53domains' => [ 'namespace' => 'Route53Domains', 'versions' => [ 'latest' => '2014-05-15', '2014-05-15' => '2014-05-15', ], ], 'route53resolver' => [ 'namespace' => 'Route53Resolver', 'versions' => [ 'latest' => '2018-04-01', '2018-04-01' => '2018-04-01', ], ], 'runtime.lex' => [ 'namespace' => 'LexRuntimeService', 'versions' => [ 'latest' => '2016-11-28', '2016-11-28' => '2016-11-28', ], ], 'runtime.sagemaker' => [ 'namespace' => 'SageMakerRuntime', 'versions' => [ 'latest' => '2017-05-13', '2017-05-13' => '2017-05-13', ], ], 's3' => [ 'namespace' => 'S3', 'versions' => [ 'latest' => '2006-03-01', '2006-03-01' => '2006-03-01', ], ], 's3control' => [ 'namespace' => 'S3Control', 'versions' => [ 'latest' => '2018-08-20', '2018-08-20' => '2018-08-20', ], ], 'sagemaker' => [ 'namespace' => 'SageMaker', 'versions' => [ 'latest' => '2017-07-24', '2017-07-24' => '2017-07-24', ], ], 'secretsmanager' => [ 'namespace' => 'SecretsManager', 'versions' => [ 'latest' => '2017-10-17', '2017-10-17' => '2017-10-17', ], ], 'securityhub' => [ 'namespace' => 'SecurityHub', 'versions' => [ 'latest' => '2018-10-26', '2018-10-26' => '2018-10-26', ], ], 'serverlessrepo' => [ 'namespace' => 'ServerlessApplicationRepository', 'versions' => [ 'latest' => '2017-09-08', '2017-09-08' => '2017-09-08', ], ], 'servicecatalog' => [ 'namespace' => 'ServiceCatalog', 'versions' => [ 'latest' => '2015-12-10', '2015-12-10' => '2015-12-10', ], ], 'servicediscovery' => [ 'namespace' => 'ServiceDiscovery', 'versions' => [ 'latest' => '2017-03-14', '2017-03-14' => '2017-03-14', ], ], 'shield' => [ 'namespace' => 'Shield', 'versions' => [ 'latest' => '2016-06-02', '2016-06-02' => '2016-06-02', ], ], 'signer' => [ 'namespace' => 'signer', 'versions' => [ 'latest' => '2017-08-25', '2017-08-25' => '2017-08-25', ], ], 'sms-voice' => [ 'namespace' => 'PinpointSMSVoice', 'versions' => [ 'latest' => '2018-09-05', '2018-09-05' => '2018-09-05', ], ], 'sms' => [ 'namespace' => 'Sms', 'versions' => [ 'latest' => '2016-10-24', '2016-10-24' => '2016-10-24', ], ], 'snowball' => [ 'namespace' => 'SnowBall', 'versions' => [ 'latest' => '2016-06-30', '2016-06-30' => '2016-06-30', ], ], 'sns' => [ 'namespace' => 'Sns', 'versions' => [ 'latest' => '2010-03-31', '2010-03-31' => '2010-03-31', ], ], 'sqs' => [ 'namespace' => 'Sqs', 'versions' => [ 'latest' => '2012-11-05', '2012-11-05' => '2012-11-05', ], ], 'ssm' => [ 'namespace' => 'Ssm', 'versions' => [ 'latest' => '2014-11-06', '2014-11-06' => '2014-11-06', ], ], 'states' => [ 'namespace' => 'Sfn', 'versions' => [ 'latest' => '2016-11-23', '2016-11-23' => '2016-11-23', ], ], 'storagegateway' => [ 'namespace' => 'StorageGateway', 'versions' => [ 'latest' => '2013-06-30', '2013-06-30' => '2013-06-30', ], ], 'streams.dynamodb' => [ 'namespace' => 'DynamoDbStreams', 'versions' => [ 'latest' => '2012-08-10', '2012-08-10' => '2012-08-10', ], ], 'sts' => [ 'namespace' => 'Sts', 'versions' => [ 'latest' => '2011-06-15', '2011-06-15' => '2011-06-15', ], ], 'support' => [ 'namespace' => 'Support', 'versions' => [ 'latest' => '2013-04-15', '2013-04-15' => '2013-04-15', ], ], 'swf' => [ 'namespace' => 'Swf', 'versions' => [ 'latest' => '2012-01-25', '2012-01-25' => '2012-01-25', ], ], 'textract' => [ 'namespace' => 'Textract', 'versions' => [ 'latest' => '2018-06-27', '2018-06-27' => '2018-06-27', ], ], 'transcribe' => [ 'namespace' => 'TranscribeService', 'versions' => [ 'latest' => '2017-10-26', '2017-10-26' => '2017-10-26', ], ], 'transfer' => [ 'namespace' => 'Transfer', 'versions' => [ 'latest' => '2018-11-05', '2018-11-05' => '2018-11-05', ], ], 'translate' => [ 'namespace' => 'Translate', 'versions' => [ 'latest' => '2017-07-01', '2017-07-01' => '2017-07-01', ], ], 'waf-regional' => [ 'namespace' => 'WafRegional', 'versions' => [ 'latest' => '2016-11-28', '2016-11-28' => '2016-11-28', ], ], 'waf' => [ 'namespace' => 'Waf', 'versions' => [ 'latest' => '2015-08-24', '2015-08-24' => '2015-08-24', ], ], 'workdocs' => [ 'namespace' => 'WorkDocs', 'versions' => [ 'latest' => '2016-05-01', '2016-05-01' => '2016-05-01', ], ], 'worklink' => [ 'namespace' => 'WorkLink', 'versions' => [ 'latest' => '2018-09-25', '2018-09-25' => '2018-09-25', ], ], 'workmail' => [ 'namespace' => 'WorkMail', 'versions' => [ 'latest' => '2017-10-01', '2017-10-01' => '2017-10-01', ], ], 'workspaces' => [ 'namespace' => 'WorkSpaces', 'versions' => [ 'latest' => '2015-04-08', '2015-04-08' => '2015-04-08', ], ], 'xray' => [ 'namespace' => 'XRay', 'versions' => [ 'latest' => '2016-04-12', '2016-04-12' => '2016-04-12', ], ],];
|
|
|
|
|
|
lib/Aws/Aws/data/s3/2006-03-01/api-2.json.php
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// This file was auto-generated from sdk-root/src/data/s3/2006-03-01/api-2.json
|
3 |
-
return [ 'version' => '2.0', 'metadata' => [ 'apiVersion' => '2006-03-01', 'checksumFormat' => 'md5', 'endpointPrefix' => 's3', 'globalEndpoint' => 's3.amazonaws.com', 'protocol' => 'rest-xml', 'serviceAbbreviation' => 'Amazon S3', 'serviceFullName' => 'Amazon Simple Storage Service', 'serviceId' => 'S3', 'signatureVersion' => 's3', 'uid' => 's3-2006-03-01', ], 'operations' => [ 'AbortMultipartUpload' => [ 'name' => 'AbortMultipartUpload', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}/{Key+}', 'responseCode' => 204, ], 'input' => [ 'shape' => 'AbortMultipartUploadRequest', ], 'output' => [ 'shape' => 'AbortMultipartUploadOutput', ], 'errors' => [ [ 'shape' => 'NoSuchUpload', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadAbort.html', ], 'CompleteMultipartUpload' => [ 'name' => 'CompleteMultipartUpload', 'http' => [ 'method' => 'POST', 'requestUri' => '/{Bucket}/{Key+}', ], 'input' => [ 'shape' => 'CompleteMultipartUploadRequest', ], 'output' => [ 'shape' => 'CompleteMultipartUploadOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadComplete.html', ], 'CopyObject' => [ 'name' => 'CopyObject', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}/{Key+}', ], 'input' => [ 'shape' => 'CopyObjectRequest', ], 'output' => [ 'shape' => 'CopyObjectOutput', ], 'errors' => [ [ 'shape' => 'ObjectNotInActiveTierError', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectCOPY.html', 'alias' => 'PutObjectCopy', ], 'CreateBucket' => [ 'name' => 'CreateBucket', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}', ], 'input' => [ 'shape' => 'CreateBucketRequest', ], 'output' => [ 'shape' => 'CreateBucketOutput', ], 'errors' => [ [ 'shape' => 'BucketAlreadyExists', ], [ 'shape' => 'BucketAlreadyOwnedByYou', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html', 'alias' => 'PutBucket', ], 'CreateMultipartUpload' => [ 'name' => 'CreateMultipartUpload', 'http' => [ 'method' => 'POST', 'requestUri' => '/{Bucket}/{Key+}?uploads', ], 'input' => [ 'shape' => 'CreateMultipartUploadRequest', ], 'output' => [ 'shape' => 'CreateMultipartUploadOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadInitiate.html', 'alias' => 'InitiateMultipartUpload', ], 'DeleteBucket' => [ 'name' => 'DeleteBucket', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETE.html', ], 'DeleteBucketAnalyticsConfiguration' => [ 'name' => 'DeleteBucketAnalyticsConfiguration', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?analytics', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketAnalyticsConfigurationRequest', ], ], 'DeleteBucketCors' => [ 'name' => 'DeleteBucketCors', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?cors', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketCorsRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEcors.html', ], 'DeleteBucketEncryption' => [ 'name' => 'DeleteBucketEncryption', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?encryption', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketEncryptionRequest', ], ], 'DeleteBucketInventoryConfiguration' => [ 'name' => 'DeleteBucketInventoryConfiguration', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?inventory', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketInventoryConfigurationRequest', ], ], 'DeleteBucketLifecycle' => [ 'name' => 'DeleteBucketLifecycle', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?lifecycle', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketLifecycleRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETElifecycle.html', ], 'DeleteBucketMetricsConfiguration' => [ 'name' => 'DeleteBucketMetricsConfiguration', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?metrics', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketMetricsConfigurationRequest', ], ], 'DeleteBucketPolicy' => [ 'name' => 'DeleteBucketPolicy', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?policy', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketPolicyRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEpolicy.html', ], 'DeleteBucketReplication' => [ 'name' => 'DeleteBucketReplication', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?replication', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketReplicationRequest', ], ], 'DeleteBucketTagging' => [ 'name' => 'DeleteBucketTagging', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?tagging', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketTaggingRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEtagging.html', ], 'DeleteBucketWebsite' => [ 'name' => 'DeleteBucketWebsite', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?website', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteBucketWebsiteRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEwebsite.html', ], 'DeleteObject' => [ 'name' => 'DeleteObject', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}/{Key+}', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteObjectRequest', ], 'output' => [ 'shape' => 'DeleteObjectOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectDELETE.html', ], 'DeleteObjectTagging' => [ 'name' => 'DeleteObjectTagging', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}/{Key+}?tagging', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeleteObjectTaggingRequest', ], 'output' => [ 'shape' => 'DeleteObjectTaggingOutput', ], ], 'DeleteObjects' => [ 'name' => 'DeleteObjects', 'http' => [ 'method' => 'POST', 'requestUri' => '/{Bucket}?delete', ], 'input' => [ 'shape' => 'DeleteObjectsRequest', ], 'output' => [ 'shape' => 'DeleteObjectsOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/multiobjectdeleteapi.html', 'alias' => 'DeleteMultipleObjects', ], 'DeletePublicAccessBlock' => [ 'name' => 'DeletePublicAccessBlock', 'http' => [ 'method' => 'DELETE', 'requestUri' => '/{Bucket}?publicAccessBlock', 'responseCode' => 204, ], 'input' => [ 'shape' => 'DeletePublicAccessBlockRequest', ], ], 'GetBucketAccelerateConfiguration' => [ 'name' => 'GetBucketAccelerateConfiguration', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?accelerate', ], 'input' => [ 'shape' => 'GetBucketAccelerateConfigurationRequest', ], 'output' => [ 'shape' => 'GetBucketAccelerateConfigurationOutput', ], ], 'GetBucketAcl' => [ 'name' => 'GetBucketAcl', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?acl', ], 'input' => [ 'shape' => 'GetBucketAclRequest', ], 'output' => [ 'shape' => 'GetBucketAclOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETacl.html', ], 'GetBucketAnalyticsConfiguration' => [ 'name' => 'GetBucketAnalyticsConfiguration', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?analytics', ], 'input' => [ 'shape' => 'GetBucketAnalyticsConfigurationRequest', ], 'output' => [ 'shape' => 'GetBucketAnalyticsConfigurationOutput', ], ], 'GetBucketCors' => [ 'name' => 'GetBucketCors', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?cors', ], 'input' => [ 'shape' => 'GetBucketCorsRequest', ], 'output' => [ 'shape' => 'GetBucketCorsOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETcors.html', ], 'GetBucketEncryption' => [ 'name' => 'GetBucketEncryption', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?encryption', ], 'input' => [ 'shape' => 'GetBucketEncryptionRequest', ], 'output' => [ 'shape' => 'GetBucketEncryptionOutput', ], ], 'GetBucketInventoryConfiguration' => [ 'name' => 'GetBucketInventoryConfiguration', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?inventory', ], 'input' => [ 'shape' => 'GetBucketInventoryConfigurationRequest', ], 'output' => [ 'shape' => 'GetBucketInventoryConfigurationOutput', ], ], 'GetBucketLifecycle' => [ 'name' => 'GetBucketLifecycle', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?lifecycle', ], 'input' => [ 'shape' => 'GetBucketLifecycleRequest', ], 'output' => [ 'shape' => 'GetBucketLifecycleOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETlifecycle.html', 'deprecated' => true, ], 'GetBucketLifecycleConfiguration' => [ 'name' => 'GetBucketLifecycleConfiguration', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?lifecycle', ], 'input' => [ 'shape' => 'GetBucketLifecycleConfigurationRequest', ], 'output' => [ 'shape' => 'GetBucketLifecycleConfigurationOutput', ], ], 'GetBucketLocation' => [ 'name' => 'GetBucketLocation', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?location', ], 'input' => [ 'shape' => 'GetBucketLocationRequest', ], 'output' => [ 'shape' => 'GetBucketLocationOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETlocation.html', ], 'GetBucketLogging' => [ 'name' => 'GetBucketLogging', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?logging', ], 'input' => [ 'shape' => 'GetBucketLoggingRequest', ], 'output' => [ 'shape' => 'GetBucketLoggingOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETlogging.html', ], 'GetBucketMetricsConfiguration' => [ 'name' => 'GetBucketMetricsConfiguration', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?metrics', ], 'input' => [ 'shape' => 'GetBucketMetricsConfigurationRequest', ], 'output' => [ 'shape' => 'GetBucketMetricsConfigurationOutput', ], ], 'GetBucketNotification' => [ 'name' => 'GetBucketNotification', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?notification', ], 'input' => [ 'shape' => 'GetBucketNotificationConfigurationRequest', ], 'output' => [ 'shape' => 'NotificationConfigurationDeprecated', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETnotification.html', 'deprecated' => true, ], 'GetBucketNotificationConfiguration' => [ 'name' => 'GetBucketNotificationConfiguration', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?notification', ], 'input' => [ 'shape' => 'GetBucketNotificationConfigurationRequest', ], 'output' => [ 'shape' => 'NotificationConfiguration', ], ], 'GetBucketPolicy' => [ 'name' => 'GetBucketPolicy', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?policy', ], 'input' => [ 'shape' => 'GetBucketPolicyRequest', ], 'output' => [ 'shape' => 'GetBucketPolicyOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETpolicy.html', ], 'GetBucketPolicyStatus' => [ 'name' => 'GetBucketPolicyStatus', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?policyStatus', ], 'input' => [ 'shape' => 'GetBucketPolicyStatusRequest', ], 'output' => [ 'shape' => 'GetBucketPolicyStatusOutput', ], ], 'GetBucketReplication' => [ 'name' => 'GetBucketReplication', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?replication', ], 'input' => [ 'shape' => 'GetBucketReplicationRequest', ], 'output' => [ 'shape' => 'GetBucketReplicationOutput', ], ], 'GetBucketRequestPayment' => [ 'name' => 'GetBucketRequestPayment', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?requestPayment', ], 'input' => [ 'shape' => 'GetBucketRequestPaymentRequest', ], 'output' => [ 'shape' => 'GetBucketRequestPaymentOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTrequestPaymentGET.html', ], 'GetBucketTagging' => [ 'name' => 'GetBucketTagging', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?tagging', ], 'input' => [ 'shape' => 'GetBucketTaggingRequest', ], 'output' => [ 'shape' => 'GetBucketTaggingOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETtagging.html', ], 'GetBucketVersioning' => [ 'name' => 'GetBucketVersioning', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?versioning', ], 'input' => [ 'shape' => 'GetBucketVersioningRequest', ], 'output' => [ 'shape' => 'GetBucketVersioningOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETversioningStatus.html', ], 'GetBucketWebsite' => [ 'name' => 'GetBucketWebsite', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?website', ], 'input' => [ 'shape' => 'GetBucketWebsiteRequest', ], 'output' => [ 'shape' => 'GetBucketWebsiteOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETwebsite.html', ], 'GetObject' => [ 'name' => 'GetObject', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}/{Key+}', ], 'input' => [ 'shape' => 'GetObjectRequest', ], 'output' => [ 'shape' => 'GetObjectOutput', ], 'errors' => [ [ 'shape' => 'NoSuchKey', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html', ], 'GetObjectAcl' => [ 'name' => 'GetObjectAcl', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}/{Key+}?acl', ], 'input' => [ 'shape' => 'GetObjectAclRequest', ], 'output' => [ 'shape' => 'GetObjectAclOutput', ], 'errors' => [ [ 'shape' => 'NoSuchKey', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGETacl.html', ], 'GetObjectLegalHold' => [ 'name' => 'GetObjectLegalHold', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}/{Key+}?legal-hold', ], 'input' => [ 'shape' => 'GetObjectLegalHoldRequest', ], 'output' => [ 'shape' => 'GetObjectLegalHoldOutput', ], ], 'GetObjectLockConfiguration' => [ 'name' => 'GetObjectLockConfiguration', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?object-lock', ], 'input' => [ 'shape' => 'GetObjectLockConfigurationRequest', ], 'output' => [ 'shape' => 'GetObjectLockConfigurationOutput', ], ], 'GetObjectRetention' => [ 'name' => 'GetObjectRetention', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}/{Key+}?retention', ], 'input' => [ 'shape' => 'GetObjectRetentionRequest', ], 'output' => [ 'shape' => 'GetObjectRetentionOutput', ], ], 'GetObjectTagging' => [ 'name' => 'GetObjectTagging', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}/{Key+}?tagging', ], 'input' => [ 'shape' => 'GetObjectTaggingRequest', ], 'output' => [ 'shape' => 'GetObjectTaggingOutput', ], ], 'GetObjectTorrent' => [ 'name' => 'GetObjectTorrent', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}/{Key+}?torrent', ], 'input' => [ 'shape' => 'GetObjectTorrentRequest', ], 'output' => [ 'shape' => 'GetObjectTorrentOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGETtorrent.html', ], 'GetPublicAccessBlock' => [ 'name' => 'GetPublicAccessBlock', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?publicAccessBlock', ], 'input' => [ 'shape' => 'GetPublicAccessBlockRequest', ], 'output' => [ 'shape' => 'GetPublicAccessBlockOutput', ], ], 'HeadBucket' => [ 'name' => 'HeadBucket', 'http' => [ 'method' => 'HEAD', 'requestUri' => '/{Bucket}', ], 'input' => [ 'shape' => 'HeadBucketRequest', ], 'errors' => [ [ 'shape' => 'NoSuchBucket', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketHEAD.html', ], 'HeadObject' => [ 'name' => 'HeadObject', 'http' => [ 'method' => 'HEAD', 'requestUri' => '/{Bucket}/{Key+}', ], 'input' => [ 'shape' => 'HeadObjectRequest', ], 'output' => [ 'shape' => 'HeadObjectOutput', ], 'errors' => [ [ 'shape' => 'NoSuchKey', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectHEAD.html', ], 'ListBucketAnalyticsConfigurations' => [ 'name' => 'ListBucketAnalyticsConfigurations', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?analytics', ], 'input' => [ 'shape' => 'ListBucketAnalyticsConfigurationsRequest', ], 'output' => [ 'shape' => 'ListBucketAnalyticsConfigurationsOutput', ], ], 'ListBucketInventoryConfigurations' => [ 'name' => 'ListBucketInventoryConfigurations', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?inventory', ], 'input' => [ 'shape' => 'ListBucketInventoryConfigurationsRequest', ], 'output' => [ 'shape' => 'ListBucketInventoryConfigurationsOutput', ], ], 'ListBucketMetricsConfigurations' => [ 'name' => 'ListBucketMetricsConfigurations', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?metrics', ], 'input' => [ 'shape' => 'ListBucketMetricsConfigurationsRequest', ], 'output' => [ 'shape' => 'ListBucketMetricsConfigurationsOutput', ], ], 'ListBuckets' => [ 'name' => 'ListBuckets', 'http' => [ 'method' => 'GET', 'requestUri' => '/', ], 'output' => [ 'shape' => 'ListBucketsOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTServiceGET.html', 'alias' => 'GetService', ], 'ListMultipartUploads' => [ 'name' => 'ListMultipartUploads', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?uploads', ], 'input' => [ 'shape' => 'ListMultipartUploadsRequest', ], 'output' => [ 'shape' => 'ListMultipartUploadsOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListMPUpload.html', ], 'ListObjectVersions' => [ 'name' => 'ListObjectVersions', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?versions', ], 'input' => [ 'shape' => 'ListObjectVersionsRequest', ], 'output' => [ 'shape' => 'ListObjectVersionsOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETVersion.html', 'alias' => 'GetBucketObjectVersions', ], 'ListObjects' => [ 'name' => 'ListObjects', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}', ], 'input' => [ 'shape' => 'ListObjectsRequest', ], 'output' => [ 'shape' => 'ListObjectsOutput', ], 'errors' => [ [ 'shape' => 'NoSuchBucket', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGET.html', 'alias' => 'GetBucket', ], 'ListObjectsV2' => [ 'name' => 'ListObjectsV2', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}?list-type=2', ], 'input' => [ 'shape' => 'ListObjectsV2Request', ], 'output' => [ 'shape' => 'ListObjectsV2Output', ], 'errors' => [ [ 'shape' => 'NoSuchBucket', ], ], ], 'ListParts' => [ 'name' => 'ListParts', 'http' => [ 'method' => 'GET', 'requestUri' => '/{Bucket}/{Key+}', ], 'input' => [ 'shape' => 'ListPartsRequest', ], 'output' => [ 'shape' => 'ListPartsOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListParts.html', ], 'PutBucketAccelerateConfiguration' => [ 'name' => 'PutBucketAccelerateConfiguration', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?accelerate', ], 'input' => [ 'shape' => 'PutBucketAccelerateConfigurationRequest', ], ], 'PutBucketAcl' => [ 'name' => 'PutBucketAcl', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?acl', ], 'input' => [ 'shape' => 'PutBucketAclRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTacl.html', ], 'PutBucketAnalyticsConfiguration' => [ 'name' => 'PutBucketAnalyticsConfiguration', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?analytics', ], 'input' => [ 'shape' => 'PutBucketAnalyticsConfigurationRequest', ], ], 'PutBucketCors' => [ 'name' => 'PutBucketCors', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?cors', ], 'input' => [ 'shape' => 'PutBucketCorsRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTcors.html', ], 'PutBucketEncryption' => [ 'name' => 'PutBucketEncryption', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?encryption', ], 'input' => [ 'shape' => 'PutBucketEncryptionRequest', ], ], 'PutBucketInventoryConfiguration' => [ 'name' => 'PutBucketInventoryConfiguration', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?inventory', ], 'input' => [ 'shape' => 'PutBucketInventoryConfigurationRequest', ], ], 'PutBucketLifecycle' => [ 'name' => 'PutBucketLifecycle', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?lifecycle', ], 'input' => [ 'shape' => 'PutBucketLifecycleRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html', 'deprecated' => true, ], 'PutBucketLifecycleConfiguration' => [ 'name' => 'PutBucketLifecycleConfiguration', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?lifecycle', ], 'input' => [ 'shape' => 'PutBucketLifecycleConfigurationRequest', ], ], 'PutBucketLogging' => [ 'name' => 'PutBucketLogging', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?logging', ], 'input' => [ 'shape' => 'PutBucketLoggingRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTlogging.html', ], 'PutBucketMetricsConfiguration' => [ 'name' => 'PutBucketMetricsConfiguration', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?metrics', ], 'input' => [ 'shape' => 'PutBucketMetricsConfigurationRequest', ], ], 'PutBucketNotification' => [ 'name' => 'PutBucketNotification', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?notification', ], 'input' => [ 'shape' => 'PutBucketNotificationRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTnotification.html', 'deprecated' => true, ], 'PutBucketNotificationConfiguration' => [ 'name' => 'PutBucketNotificationConfiguration', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?notification', ], 'input' => [ 'shape' => 'PutBucketNotificationConfigurationRequest', ], ], 'PutBucketPolicy' => [ 'name' => 'PutBucketPolicy', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?policy', ], 'input' => [ 'shape' => 'PutBucketPolicyRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTpolicy.html', ], 'PutBucketReplication' => [ 'name' => 'PutBucketReplication', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?replication', ], 'input' => [ 'shape' => 'PutBucketReplicationRequest', ], ], 'PutBucketRequestPayment' => [ 'name' => 'PutBucketRequestPayment', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?requestPayment', ], 'input' => [ 'shape' => 'PutBucketRequestPaymentRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTrequestPaymentPUT.html', ], 'PutBucketTagging' => [ 'name' => 'PutBucketTagging', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?tagging', ], 'input' => [ 'shape' => 'PutBucketTaggingRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTtagging.html', ], 'PutBucketVersioning' => [ 'name' => 'PutBucketVersioning', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?versioning', ], 'input' => [ 'shape' => 'PutBucketVersioningRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTVersioningStatus.html', ], 'PutBucketWebsite' => [ 'name' => 'PutBucketWebsite', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?website', ], 'input' => [ 'shape' => 'PutBucketWebsiteRequest', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTwebsite.html', ], 'PutObject' => [ 'name' => 'PutObject', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}/{Key+}', ], 'input' => [ 'shape' => 'PutObjectRequest', ], 'output' => [ 'shape' => 'PutObjectOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPUT.html', ], 'PutObjectAcl' => [ 'name' => 'PutObjectAcl', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}/{Key+}?acl', ], 'input' => [ 'shape' => 'PutObjectAclRequest', ], 'output' => [ 'shape' => 'PutObjectAclOutput', ], 'errors' => [ [ 'shape' => 'NoSuchKey', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPUTacl.html', ], 'PutObjectLegalHold' => [ 'name' => 'PutObjectLegalHold', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}/{Key+}?legal-hold', ], 'input' => [ 'shape' => 'PutObjectLegalHoldRequest', ], 'output' => [ 'shape' => 'PutObjectLegalHoldOutput', ], ], 'PutObjectLockConfiguration' => [ 'name' => 'PutObjectLockConfiguration', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?object-lock', ], 'input' => [ 'shape' => 'PutObjectLockConfigurationRequest', ], 'output' => [ 'shape' => 'PutObjectLockConfigurationOutput', ], ], 'PutObjectRetention' => [ 'name' => 'PutObjectRetention', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}/{Key+}?retention', ], 'input' => [ 'shape' => 'PutObjectRetentionRequest', ], 'output' => [ 'shape' => 'PutObjectRetentionOutput', ], ], 'PutObjectTagging' => [ 'name' => 'PutObjectTagging', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}/{Key+}?tagging', ], 'input' => [ 'shape' => 'PutObjectTaggingRequest', ], 'output' => [ 'shape' => 'PutObjectTaggingOutput', ], ], 'PutPublicAccessBlock' => [ 'name' => 'PutPublicAccessBlock', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}?publicAccessBlock', ], 'input' => [ 'shape' => 'PutPublicAccessBlockRequest', ], ], 'RestoreObject' => [ 'name' => 'RestoreObject', 'http' => [ 'method' => 'POST', 'requestUri' => '/{Bucket}/{Key+}?restore', ], 'input' => [ 'shape' => 'RestoreObjectRequest', ], 'output' => [ 'shape' => 'RestoreObjectOutput', ], 'errors' => [ [ 'shape' => 'ObjectAlreadyInActiveTierError', ], ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectRestore.html', 'alias' => 'PostObjectRestore', ], 'SelectObjectContent' => [ 'name' => 'SelectObjectContent', 'http' => [ 'method' => 'POST', 'requestUri' => '/{Bucket}/{Key+}?select&select-type=2', ], 'input' => [ 'shape' => 'SelectObjectContentRequest', 'locationName' => 'SelectObjectContentRequest', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'output' => [ 'shape' => 'SelectObjectContentOutput', ], ], 'UploadPart' => [ 'name' => 'UploadPart', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}/{Key+}', ], 'input' => [ 'shape' => 'UploadPartRequest', ], 'output' => [ 'shape' => 'UploadPartOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPart.html', ], 'UploadPartCopy' => [ 'name' => 'UploadPartCopy', 'http' => [ 'method' => 'PUT', 'requestUri' => '/{Bucket}/{Key+}', ], 'input' => [ 'shape' => 'UploadPartCopyRequest', ], 'output' => [ 'shape' => 'UploadPartCopyOutput', ], 'documentationUrl' => 'http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html', ], ], 'shapes' => [ 'AbortDate' => [ 'type' => 'timestamp', ], 'AbortIncompleteMultipartUpload' => [ 'type' => 'structure', 'members' => [ 'DaysAfterInitiation' => [ 'shape' => 'DaysAfterInitiation', ], ], ], 'AbortMultipartUploadOutput' => [ 'type' => 'structure', 'members' => [ 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'AbortMultipartUploadRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', 'UploadId', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'UploadId' => [ 'shape' => 'MultipartUploadId', 'location' => 'querystring', 'locationName' => 'uploadId', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'AbortRuleId' => [ 'type' => 'string', ], 'AccelerateConfiguration' => [ 'type' => 'structure', 'members' => [ 'Status' => [ 'shape' => 'BucketAccelerateStatus', ], ], ], 'AcceptRanges' => [ 'type' => 'string', ], 'AccessControlPolicy' => [ 'type' => 'structure', 'members' => [ 'Grants' => [ 'shape' => 'Grants', 'locationName' => 'AccessControlList', ], 'Owner' => [ 'shape' => 'Owner', ], ], ], 'AccessControlTranslation' => [ 'type' => 'structure', 'required' => [ 'Owner', ], 'members' => [ 'Owner' => [ 'shape' => 'OwnerOverride', ], ], ], 'AccountId' => [ 'type' => 'string', ], 'AllowQuotedRecordDelimiter' => [ 'type' => 'boolean', ], 'AllowedHeader' => [ 'type' => 'string', ], 'AllowedHeaders' => [ 'type' => 'list', 'member' => [ 'shape' => 'AllowedHeader', ], 'flattened' => true, ], 'AllowedMethod' => [ 'type' => 'string', ], 'AllowedMethods' => [ 'type' => 'list', 'member' => [ 'shape' => 'AllowedMethod', ], 'flattened' => true, ], 'AllowedOrigin' => [ 'type' => 'string', ], 'AllowedOrigins' => [ 'type' => 'list', 'member' => [ 'shape' => 'AllowedOrigin', ], 'flattened' => true, ], 'AnalyticsAndOperator' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], 'Tags' => [ 'shape' => 'TagSet', 'flattened' => true, 'locationName' => 'Tag', ], ], ], 'AnalyticsConfiguration' => [ 'type' => 'structure', 'required' => [ 'Id', 'StorageClassAnalysis', ], 'members' => [ 'Id' => [ 'shape' => 'AnalyticsId', ], 'Filter' => [ 'shape' => 'AnalyticsFilter', ], 'StorageClassAnalysis' => [ 'shape' => 'StorageClassAnalysis', ], ], ], 'AnalyticsConfigurationList' => [ 'type' => 'list', 'member' => [ 'shape' => 'AnalyticsConfiguration', ], 'flattened' => true, ], 'AnalyticsExportDestination' => [ 'type' => 'structure', 'required' => [ 'S3BucketDestination', ], 'members' => [ 'S3BucketDestination' => [ 'shape' => 'AnalyticsS3BucketDestination', ], ], ], 'AnalyticsFilter' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], 'Tag' => [ 'shape' => 'Tag', ], 'And' => [ 'shape' => 'AnalyticsAndOperator', ], ], ], 'AnalyticsId' => [ 'type' => 'string', ], 'AnalyticsS3BucketDestination' => [ 'type' => 'structure', 'required' => [ 'Format', 'Bucket', ], 'members' => [ 'Format' => [ 'shape' => 'AnalyticsS3ExportFileFormat', ], 'BucketAccountId' => [ 'shape' => 'AccountId', ], 'Bucket' => [ 'shape' => 'BucketName', ], 'Prefix' => [ 'shape' => 'Prefix', ], ], ], 'AnalyticsS3ExportFileFormat' => [ 'type' => 'string', 'enum' => [ 'CSV', ], ], 'Body' => [ 'type' => 'blob', ], 'Bucket' => [ 'type' => 'structure', 'members' => [ 'Name' => [ 'shape' => 'BucketName', ], 'CreationDate' => [ 'shape' => 'CreationDate', ], ], ], 'BucketAccelerateStatus' => [ 'type' => 'string', 'enum' => [ 'Enabled', 'Suspended', ], ], 'BucketAlreadyExists' => [ 'type' => 'structure', 'members' => [], 'exception' => true, ], 'BucketAlreadyOwnedByYou' => [ 'type' => 'structure', 'members' => [], 'exception' => true, ], 'BucketCannedACL' => [ 'type' => 'string', 'enum' => [ 'private', 'public-read', 'public-read-write', 'authenticated-read', ], ], 'BucketLifecycleConfiguration' => [ 'type' => 'structure', 'required' => [ 'Rules', ], 'members' => [ 'Rules' => [ 'shape' => 'LifecycleRules', 'locationName' => 'Rule', ], ], ], 'BucketLocationConstraint' => [ 'type' => 'string', 'enum' => [ 'EU', 'eu-west-1', 'us-west-1', 'us-west-2', 'ap-south-1', 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'sa-east-1', 'cn-north-1', 'eu-central-1', ], ], 'BucketLoggingStatus' => [ 'type' => 'structure', 'members' => [ 'LoggingEnabled' => [ 'shape' => 'LoggingEnabled', ], ], ], 'BucketLogsPermission' => [ 'type' => 'string', 'enum' => [ 'FULL_CONTROL', 'READ', 'WRITE', ], ], 'BucketName' => [ 'type' => 'string', ], 'BucketVersioningStatus' => [ 'type' => 'string', 'enum' => [ 'Enabled', 'Suspended', ], ], 'Buckets' => [ 'type' => 'list', 'member' => [ 'shape' => 'Bucket', 'locationName' => 'Bucket', ], ], 'BypassGovernanceRetention' => [ 'type' => 'boolean', ], 'BytesProcessed' => [ 'type' => 'long', ], 'BytesReturned' => [ 'type' => 'long', ], 'BytesScanned' => [ 'type' => 'long', ], 'CORSConfiguration' => [ 'type' => 'structure', 'required' => [ 'CORSRules', ], 'members' => [ 'CORSRules' => [ 'shape' => 'CORSRules', 'locationName' => 'CORSRule', ], ], ], 'CORSRule' => [ 'type' => 'structure', 'required' => [ 'AllowedMethods', 'AllowedOrigins', ], 'members' => [ 'AllowedHeaders' => [ 'shape' => 'AllowedHeaders', 'locationName' => 'AllowedHeader', ], 'AllowedMethods' => [ 'shape' => 'AllowedMethods', 'locationName' => 'AllowedMethod', ], 'AllowedOrigins' => [ 'shape' => 'AllowedOrigins', 'locationName' => 'AllowedOrigin', ], 'ExposeHeaders' => [ 'shape' => 'ExposeHeaders', 'locationName' => 'ExposeHeader', ], 'MaxAgeSeconds' => [ 'shape' => 'MaxAgeSeconds', ], ], ], 'CORSRules' => [ 'type' => 'list', 'member' => [ 'shape' => 'CORSRule', ], 'flattened' => true, ], 'CSVInput' => [ 'type' => 'structure', 'members' => [ 'FileHeaderInfo' => [ 'shape' => 'FileHeaderInfo', ], 'Comments' => [ 'shape' => 'Comments', ], 'QuoteEscapeCharacter' => [ 'shape' => 'QuoteEscapeCharacter', ], 'RecordDelimiter' => [ 'shape' => 'RecordDelimiter', ], 'FieldDelimiter' => [ 'shape' => 'FieldDelimiter', ], 'QuoteCharacter' => [ 'shape' => 'QuoteCharacter', ], 'AllowQuotedRecordDelimiter' => [ 'shape' => 'AllowQuotedRecordDelimiter', ], ], ], 'CSVOutput' => [ 'type' => 'structure', 'members' => [ 'QuoteFields' => [ 'shape' => 'QuoteFields', ], 'QuoteEscapeCharacter' => [ 'shape' => 'QuoteEscapeCharacter', ], 'RecordDelimiter' => [ 'shape' => 'RecordDelimiter', ], 'FieldDelimiter' => [ 'shape' => 'FieldDelimiter', ], 'QuoteCharacter' => [ 'shape' => 'QuoteCharacter', ], ], ], 'CacheControl' => [ 'type' => 'string', ], 'CloudFunction' => [ 'type' => 'string', ], 'CloudFunctionConfiguration' => [ 'type' => 'structure', 'members' => [ 'Id' => [ 'shape' => 'NotificationId', ], 'Event' => [ 'shape' => 'Event', 'deprecated' => true, ], 'Events' => [ 'shape' => 'EventList', 'locationName' => 'Event', ], 'CloudFunction' => [ 'shape' => 'CloudFunction', ], 'InvocationRole' => [ 'shape' => 'CloudFunctionInvocationRole', ], ], ], 'CloudFunctionInvocationRole' => [ 'type' => 'string', ], 'Code' => [ 'type' => 'string', ], 'Comments' => [ 'type' => 'string', ], 'CommonPrefix' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], ], ], 'CommonPrefixList' => [ 'type' => 'list', 'member' => [ 'shape' => 'CommonPrefix', ], 'flattened' => true, ], 'CompleteMultipartUploadOutput' => [ 'type' => 'structure', 'members' => [ 'Location' => [ 'shape' => 'Location', ], 'Bucket' => [ 'shape' => 'BucketName', ], 'Key' => [ 'shape' => 'ObjectKey', ], 'Expiration' => [ 'shape' => 'Expiration', 'location' => 'header', 'locationName' => 'x-amz-expiration', ], 'ETag' => [ 'shape' => 'ETag', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'CompleteMultipartUploadRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', 'UploadId', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'MultipartUpload' => [ 'shape' => 'CompletedMultipartUpload', 'locationName' => 'CompleteMultipartUpload', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'UploadId' => [ 'shape' => 'MultipartUploadId', 'location' => 'querystring', 'locationName' => 'uploadId', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], 'payload' => 'MultipartUpload', ], 'CompletedMultipartUpload' => [ 'type' => 'structure', 'members' => [ 'Parts' => [ 'shape' => 'CompletedPartList', 'locationName' => 'Part', ], ], ], 'CompletedPart' => [ 'type' => 'structure', 'members' => [ 'ETag' => [ 'shape' => 'ETag', ], 'PartNumber' => [ 'shape' => 'PartNumber', ], ], ], 'CompletedPartList' => [ 'type' => 'list', 'member' => [ 'shape' => 'CompletedPart', ], 'flattened' => true, ], 'CompressionType' => [ 'type' => 'string', 'enum' => [ 'NONE', 'GZIP', 'BZIP2', ], ], 'Condition' => [ 'type' => 'structure', 'members' => [ 'HttpErrorCodeReturnedEquals' => [ 'shape' => 'HttpErrorCodeReturnedEquals', ], 'KeyPrefixEquals' => [ 'shape' => 'KeyPrefixEquals', ], ], ], 'ConfirmRemoveSelfBucketAccess' => [ 'type' => 'boolean', ], 'ContentDisposition' => [ 'type' => 'string', ], 'ContentEncoding' => [ 'type' => 'string', ], 'ContentLanguage' => [ 'type' => 'string', ], 'ContentLength' => [ 'type' => 'long', ], 'ContentMD5' => [ 'type' => 'string', ], 'ContentRange' => [ 'type' => 'string', ], 'ContentType' => [ 'type' => 'string', ], 'ContinuationEvent' => [ 'type' => 'structure', 'members' => [], 'event' => true, ], 'CopyObjectOutput' => [ 'type' => 'structure', 'members' => [ 'CopyObjectResult' => [ 'shape' => 'CopyObjectResult', ], 'Expiration' => [ 'shape' => 'Expiration', 'location' => 'header', 'locationName' => 'x-amz-expiration', ], 'CopySourceVersionId' => [ 'shape' => 'CopySourceVersionId', 'location' => 'header', 'locationName' => 'x-amz-copy-source-version-id', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], 'payload' => 'CopyObjectResult', ], 'CopyObjectRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'CopySource', 'Key', ], 'members' => [ 'ACL' => [ 'shape' => 'ObjectCannedACL', 'location' => 'header', 'locationName' => 'x-amz-acl', ], 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'CacheControl' => [ 'shape' => 'CacheControl', 'location' => 'header', 'locationName' => 'Cache-Control', ], 'ContentDisposition' => [ 'shape' => 'ContentDisposition', 'location' => 'header', 'locationName' => 'Content-Disposition', ], 'ContentEncoding' => [ 'shape' => 'ContentEncoding', 'location' => 'header', 'locationName' => 'Content-Encoding', ], 'ContentLanguage' => [ 'shape' => 'ContentLanguage', 'location' => 'header', 'locationName' => 'Content-Language', ], 'ContentType' => [ 'shape' => 'ContentType', 'location' => 'header', 'locationName' => 'Content-Type', ], 'CopySource' => [ 'shape' => 'CopySource', 'location' => 'header', 'locationName' => 'x-amz-copy-source', ], 'CopySourceIfMatch' => [ 'shape' => 'CopySourceIfMatch', 'location' => 'header', 'locationName' => 'x-amz-copy-source-if-match', ], 'CopySourceIfModifiedSince' => [ 'shape' => 'CopySourceIfModifiedSince', 'location' => 'header', 'locationName' => 'x-amz-copy-source-if-modified-since', ], 'CopySourceIfNoneMatch' => [ 'shape' => 'CopySourceIfNoneMatch', 'location' => 'header', 'locationName' => 'x-amz-copy-source-if-none-match', ], 'CopySourceIfUnmodifiedSince' => [ 'shape' => 'CopySourceIfUnmodifiedSince', 'location' => 'header', 'locationName' => 'x-amz-copy-source-if-unmodified-since', ], 'Expires' => [ 'shape' => 'Expires', 'location' => 'header', 'locationName' => 'Expires', ], 'GrantFullControl' => [ 'shape' => 'GrantFullControl', 'location' => 'header', 'locationName' => 'x-amz-grant-full-control', ], 'GrantRead' => [ 'shape' => 'GrantRead', 'location' => 'header', 'locationName' => 'x-amz-grant-read', ], 'GrantReadACP' => [ 'shape' => 'GrantReadACP', 'location' => 'header', 'locationName' => 'x-amz-grant-read-acp', ], 'GrantWriteACP' => [ 'shape' => 'GrantWriteACP', 'location' => 'header', 'locationName' => 'x-amz-grant-write-acp', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'Metadata' => [ 'shape' => 'Metadata', 'location' => 'headers', 'locationName' => 'x-amz-meta-', ], 'MetadataDirective' => [ 'shape' => 'MetadataDirective', 'location' => 'header', 'locationName' => 'x-amz-metadata-directive', ], 'TaggingDirective' => [ 'shape' => 'TaggingDirective', 'location' => 'header', 'locationName' => 'x-amz-tagging-directive', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'StorageClass' => [ 'shape' => 'StorageClass', 'location' => 'header', 'locationName' => 'x-amz-storage-class', ], 'WebsiteRedirectLocation' => [ 'shape' => 'WebsiteRedirectLocation', 'location' => 'header', 'locationName' => 'x-amz-website-redirect-location', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKey' => [ 'shape' => 'SSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'CopySourceSSECustomerAlgorithm' => [ 'shape' => 'CopySourceSSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-copy-source-server-side-encryption-customer-algorithm', ], 'CopySourceSSECustomerKey' => [ 'shape' => 'CopySourceSSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-copy-source-server-side-encryption-customer-key', ], 'CopySourceSSECustomerKeyMD5' => [ 'shape' => 'CopySourceSSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-copy-source-server-side-encryption-customer-key-MD5', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'Tagging' => [ 'shape' => 'TaggingHeader', 'location' => 'header', 'locationName' => 'x-amz-tagging', ], 'ObjectLockMode' => [ 'shape' => 'ObjectLockMode', 'location' => 'header', 'locationName' => 'x-amz-object-lock-mode', ], 'ObjectLockRetainUntilDate' => [ 'shape' => 'ObjectLockRetainUntilDate', 'location' => 'header', 'locationName' => 'x-amz-object-lock-retain-until-date', ], 'ObjectLockLegalHoldStatus' => [ 'shape' => 'ObjectLockLegalHoldStatus', 'location' => 'header', 'locationName' => 'x-amz-object-lock-legal-hold', ], ], ], 'CopyObjectResult' => [ 'type' => 'structure', 'members' => [ 'ETag' => [ 'shape' => 'ETag', ], 'LastModified' => [ 'shape' => 'LastModified', ], ], ], 'CopyPartResult' => [ 'type' => 'structure', 'members' => [ 'ETag' => [ 'shape' => 'ETag', ], 'LastModified' => [ 'shape' => 'LastModified', ], ], ], 'CopySource' => [ 'type' => 'string', 'pattern' => '\\/.+\\/.+', ], 'CopySourceIfMatch' => [ 'type' => 'string', ], 'CopySourceIfModifiedSince' => [ 'type' => 'timestamp', ], 'CopySourceIfNoneMatch' => [ 'type' => 'string', ], 'CopySourceIfUnmodifiedSince' => [ 'type' => 'timestamp', ], 'CopySourceRange' => [ 'type' => 'string', ], 'CopySourceSSECustomerAlgorithm' => [ 'type' => 'string', ], 'CopySourceSSECustomerKey' => [ 'type' => 'string', 'sensitive' => true, ], 'CopySourceSSECustomerKeyMD5' => [ 'type' => 'string', ], 'CopySourceVersionId' => [ 'type' => 'string', ], 'CreateBucketConfiguration' => [ 'type' => 'structure', 'members' => [ 'LocationConstraint' => [ 'shape' => 'BucketLocationConstraint', ], ], ], 'CreateBucketOutput' => [ 'type' => 'structure', 'members' => [ 'Location' => [ 'shape' => 'Location', 'location' => 'header', 'locationName' => 'Location', ], ], ], 'CreateBucketRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'ACL' => [ 'shape' => 'BucketCannedACL', 'location' => 'header', 'locationName' => 'x-amz-acl', ], 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'CreateBucketConfiguration' => [ 'shape' => 'CreateBucketConfiguration', 'locationName' => 'CreateBucketConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'GrantFullControl' => [ 'shape' => 'GrantFullControl', 'location' => 'header', 'locationName' => 'x-amz-grant-full-control', ], 'GrantRead' => [ 'shape' => 'GrantRead', 'location' => 'header', 'locationName' => 'x-amz-grant-read', ], 'GrantReadACP' => [ 'shape' => 'GrantReadACP', 'location' => 'header', 'locationName' => 'x-amz-grant-read-acp', ], 'GrantWrite' => [ 'shape' => 'GrantWrite', 'location' => 'header', 'locationName' => 'x-amz-grant-write', ], 'GrantWriteACP' => [ 'shape' => 'GrantWriteACP', 'location' => 'header', 'locationName' => 'x-amz-grant-write-acp', ], 'ObjectLockEnabledForBucket' => [ 'shape' => 'ObjectLockEnabledForBucket', 'location' => 'header', 'locationName' => 'x-amz-bucket-object-lock-enabled', ], ], 'payload' => 'CreateBucketConfiguration', ], 'CreateMultipartUploadOutput' => [ 'type' => 'structure', 'members' => [ 'AbortDate' => [ 'shape' => 'AbortDate', 'location' => 'header', 'locationName' => 'x-amz-abort-date', ], 'AbortRuleId' => [ 'shape' => 'AbortRuleId', 'location' => 'header', 'locationName' => 'x-amz-abort-rule-id', ], 'Bucket' => [ 'shape' => 'BucketName', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', ], 'UploadId' => [ 'shape' => 'MultipartUploadId', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'CreateMultipartUploadRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'ACL' => [ 'shape' => 'ObjectCannedACL', 'location' => 'header', 'locationName' => 'x-amz-acl', ], 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'CacheControl' => [ 'shape' => 'CacheControl', 'location' => 'header', 'locationName' => 'Cache-Control', ], 'ContentDisposition' => [ 'shape' => 'ContentDisposition', 'location' => 'header', 'locationName' => 'Content-Disposition', ], 'ContentEncoding' => [ 'shape' => 'ContentEncoding', 'location' => 'header', 'locationName' => 'Content-Encoding', ], 'ContentLanguage' => [ 'shape' => 'ContentLanguage', 'location' => 'header', 'locationName' => 'Content-Language', ], 'ContentType' => [ 'shape' => 'ContentType', 'location' => 'header', 'locationName' => 'Content-Type', ], 'Expires' => [ 'shape' => 'Expires', 'location' => 'header', 'locationName' => 'Expires', ], 'GrantFullControl' => [ 'shape' => 'GrantFullControl', 'location' => 'header', 'locationName' => 'x-amz-grant-full-control', ], 'GrantRead' => [ 'shape' => 'GrantRead', 'location' => 'header', 'locationName' => 'x-amz-grant-read', ], 'GrantReadACP' => [ 'shape' => 'GrantReadACP', 'location' => 'header', 'locationName' => 'x-amz-grant-read-acp', ], 'GrantWriteACP' => [ 'shape' => 'GrantWriteACP', 'location' => 'header', 'locationName' => 'x-amz-grant-write-acp', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'Metadata' => [ 'shape' => 'Metadata', 'location' => 'headers', 'locationName' => 'x-amz-meta-', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'StorageClass' => [ 'shape' => 'StorageClass', 'location' => 'header', 'locationName' => 'x-amz-storage-class', ], 'WebsiteRedirectLocation' => [ 'shape' => 'WebsiteRedirectLocation', 'location' => 'header', 'locationName' => 'x-amz-website-redirect-location', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKey' => [ 'shape' => 'SSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'Tagging' => [ 'shape' => 'TaggingHeader', 'location' => 'header', 'locationName' => 'x-amz-tagging', ], 'ObjectLockMode' => [ 'shape' => 'ObjectLockMode', 'location' => 'header', 'locationName' => 'x-amz-object-lock-mode', ], 'ObjectLockRetainUntilDate' => [ 'shape' => 'ObjectLockRetainUntilDate', 'location' => 'header', 'locationName' => 'x-amz-object-lock-retain-until-date', ], 'ObjectLockLegalHoldStatus' => [ 'shape' => 'ObjectLockLegalHoldStatus', 'location' => 'header', 'locationName' => 'x-amz-object-lock-legal-hold', ], ], ], 'CreationDate' => [ 'type' => 'timestamp', ], 'Date' => [ 'type' => 'timestamp', 'timestampFormat' => 'iso8601', ], 'Days' => [ 'type' => 'integer', ], 'DaysAfterInitiation' => [ 'type' => 'integer', ], 'DefaultRetention' => [ 'type' => 'structure', 'members' => [ 'Mode' => [ 'shape' => 'ObjectLockRetentionMode', ], 'Days' => [ 'shape' => 'Days', ], 'Years' => [ 'shape' => 'Years', ], ], ], 'Delete' => [ 'type' => 'structure', 'required' => [ 'Objects', ], 'members' => [ 'Objects' => [ 'shape' => 'ObjectIdentifierList', 'locationName' => 'Object', ], 'Quiet' => [ 'shape' => 'Quiet', ], ], ], 'DeleteBucketAnalyticsConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'AnalyticsId', 'location' => 'querystring', 'locationName' => 'id', ], ], ], 'DeleteBucketCorsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeleteBucketEncryptionRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeleteBucketInventoryConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'InventoryId', 'location' => 'querystring', 'locationName' => 'id', ], ], ], 'DeleteBucketLifecycleRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeleteBucketMetricsConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'MetricsId', 'location' => 'querystring', 'locationName' => 'id', ], ], ], 'DeleteBucketPolicyRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeleteBucketReplicationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeleteBucketRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeleteBucketTaggingRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeleteBucketWebsiteRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeleteMarker' => [ 'type' => 'boolean', ], 'DeleteMarkerEntry' => [ 'type' => 'structure', 'members' => [ 'Owner' => [ 'shape' => 'Owner', ], 'Key' => [ 'shape' => 'ObjectKey', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', ], 'IsLatest' => [ 'shape' => 'IsLatest', ], 'LastModified' => [ 'shape' => 'LastModified', ], ], ], 'DeleteMarkerReplication' => [ 'type' => 'structure', 'members' => [ 'Status' => [ 'shape' => 'DeleteMarkerReplicationStatus', ], ], ], 'DeleteMarkerReplicationStatus' => [ 'type' => 'string', 'enum' => [ 'Enabled', 'Disabled', ], ], 'DeleteMarkerVersionId' => [ 'type' => 'string', ], 'DeleteMarkers' => [ 'type' => 'list', 'member' => [ 'shape' => 'DeleteMarkerEntry', ], 'flattened' => true, ], 'DeleteObjectOutput' => [ 'type' => 'structure', 'members' => [ 'DeleteMarker' => [ 'shape' => 'DeleteMarker', 'location' => 'header', 'locationName' => 'x-amz-delete-marker', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'DeleteObjectRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'MFA' => [ 'shape' => 'MFA', 'location' => 'header', 'locationName' => 'x-amz-mfa', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'BypassGovernanceRetention' => [ 'shape' => 'BypassGovernanceRetention', 'location' => 'header', 'locationName' => 'x-amz-bypass-governance-retention', ], ], ], 'DeleteObjectTaggingOutput' => [ 'type' => 'structure', 'members' => [ 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], ], ], 'DeleteObjectTaggingRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], ], ], 'DeleteObjectsOutput' => [ 'type' => 'structure', 'members' => [ 'Deleted' => [ 'shape' => 'DeletedObjects', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], 'Errors' => [ 'shape' => 'Errors', 'locationName' => 'Error', ], ], ], 'DeleteObjectsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Delete', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Delete' => [ 'shape' => 'Delete', 'locationName' => 'Delete', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'MFA' => [ 'shape' => 'MFA', 'location' => 'header', 'locationName' => 'x-amz-mfa', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'BypassGovernanceRetention' => [ 'shape' => 'BypassGovernanceRetention', 'location' => 'header', 'locationName' => 'x-amz-bypass-governance-retention', ], ], 'payload' => 'Delete', ], 'DeletePublicAccessBlockRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'DeletedObject' => [ 'type' => 'structure', 'members' => [ 'Key' => [ 'shape' => 'ObjectKey', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', ], 'DeleteMarker' => [ 'shape' => 'DeleteMarker', ], 'DeleteMarkerVersionId' => [ 'shape' => 'DeleteMarkerVersionId', ], ], ], 'DeletedObjects' => [ 'type' => 'list', 'member' => [ 'shape' => 'DeletedObject', ], 'flattened' => true, ], 'Delimiter' => [ 'type' => 'string', ], 'Description' => [ 'type' => 'string', ], 'Destination' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', ], 'Account' => [ 'shape' => 'AccountId', ], 'StorageClass' => [ 'shape' => 'StorageClass', ], 'AccessControlTranslation' => [ 'shape' => 'AccessControlTranslation', ], 'EncryptionConfiguration' => [ 'shape' => 'EncryptionConfiguration', ], ], ], 'DisplayName' => [ 'type' => 'string', ], 'ETag' => [ 'type' => 'string', ], 'EmailAddress' => [ 'type' => 'string', ], 'EnableRequestProgress' => [ 'type' => 'boolean', ], 'EncodingType' => [ 'type' => 'string', 'enum' => [ 'url', ], ], 'Encryption' => [ 'type' => 'structure', 'required' => [ 'EncryptionType', ], 'members' => [ 'EncryptionType' => [ 'shape' => 'ServerSideEncryption', ], 'KMSKeyId' => [ 'shape' => 'SSEKMSKeyId', ], 'KMSContext' => [ 'shape' => 'KMSContext', ], ], ], 'EncryptionConfiguration' => [ 'type' => 'structure', 'members' => [ 'ReplicaKmsKeyID' => [ 'shape' => 'ReplicaKmsKeyID', ], ], ], 'EndEvent' => [ 'type' => 'structure', 'members' => [], 'event' => true, ], 'Error' => [ 'type' => 'structure', 'members' => [ 'Key' => [ 'shape' => 'ObjectKey', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', ], 'Code' => [ 'shape' => 'Code', ], 'Message' => [ 'shape' => 'Message', ], ], ], 'ErrorDocument' => [ 'type' => 'structure', 'required' => [ 'Key', ], 'members' => [ 'Key' => [ 'shape' => 'ObjectKey', ], ], ], 'Errors' => [ 'type' => 'list', 'member' => [ 'shape' => 'Error', ], 'flattened' => true, ], 'Event' => [ 'type' => 'string', 'enum' => [ 's3:ReducedRedundancyLostObject', 's3:ObjectCreated:*', 's3:ObjectCreated:Put', 's3:ObjectCreated:Post', 's3:ObjectCreated:Copy', 's3:ObjectCreated:CompleteMultipartUpload', 's3:ObjectRemoved:*', 's3:ObjectRemoved:Delete', 's3:ObjectRemoved:DeleteMarkerCreated', 's3:ObjectRestore:Post', 's3:ObjectRestore:Completed', ], ], 'EventList' => [ 'type' => 'list', 'member' => [ 'shape' => 'Event', ], 'flattened' => true, ], 'Expiration' => [ 'type' => 'string', ], 'ExpirationStatus' => [ 'type' => 'string', 'enum' => [ 'Enabled', 'Disabled', ], ], 'ExpiredObjectDeleteMarker' => [ 'type' => 'boolean', ], 'Expires' => [ 'type' => 'timestamp', ], 'ExposeHeader' => [ 'type' => 'string', ], 'ExposeHeaders' => [ 'type' => 'list', 'member' => [ 'shape' => 'ExposeHeader', ], 'flattened' => true, ], 'Expression' => [ 'type' => 'string', ], 'ExpressionType' => [ 'type' => 'string', 'enum' => [ 'SQL', ], ], 'FetchOwner' => [ 'type' => 'boolean', ], 'FieldDelimiter' => [ 'type' => 'string', ], 'FileHeaderInfo' => [ 'type' => 'string', 'enum' => [ 'USE', 'IGNORE', 'NONE', ], ], 'FilterRule' => [ 'type' => 'structure', 'members' => [ 'Name' => [ 'shape' => 'FilterRuleName', ], 'Value' => [ 'shape' => 'FilterRuleValue', ], ], ], 'FilterRuleList' => [ 'type' => 'list', 'member' => [ 'shape' => 'FilterRule', ], 'flattened' => true, ], 'FilterRuleName' => [ 'type' => 'string', 'enum' => [ 'prefix', 'suffix', ], ], 'FilterRuleValue' => [ 'type' => 'string', ], 'GetBucketAccelerateConfigurationOutput' => [ 'type' => 'structure', 'members' => [ 'Status' => [ 'shape' => 'BucketAccelerateStatus', ], ], ], 'GetBucketAccelerateConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketAclOutput' => [ 'type' => 'structure', 'members' => [ 'Owner' => [ 'shape' => 'Owner', ], 'Grants' => [ 'shape' => 'Grants', 'locationName' => 'AccessControlList', ], ], ], 'GetBucketAclRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketAnalyticsConfigurationOutput' => [ 'type' => 'structure', 'members' => [ 'AnalyticsConfiguration' => [ 'shape' => 'AnalyticsConfiguration', ], ], 'payload' => 'AnalyticsConfiguration', ], 'GetBucketAnalyticsConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'AnalyticsId', 'location' => 'querystring', 'locationName' => 'id', ], ], ], 'GetBucketCorsOutput' => [ 'type' => 'structure', 'members' => [ 'CORSRules' => [ 'shape' => 'CORSRules', 'locationName' => 'CORSRule', ], ], ], 'GetBucketCorsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketEncryptionOutput' => [ 'type' => 'structure', 'members' => [ 'ServerSideEncryptionConfiguration' => [ 'shape' => 'ServerSideEncryptionConfiguration', ], ], 'payload' => 'ServerSideEncryptionConfiguration', ], 'GetBucketEncryptionRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketInventoryConfigurationOutput' => [ 'type' => 'structure', 'members' => [ 'InventoryConfiguration' => [ 'shape' => 'InventoryConfiguration', ], ], 'payload' => 'InventoryConfiguration', ], 'GetBucketInventoryConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'InventoryId', 'location' => 'querystring', 'locationName' => 'id', ], ], ], 'GetBucketLifecycleConfigurationOutput' => [ 'type' => 'structure', 'members' => [ 'Rules' => [ 'shape' => 'LifecycleRules', 'locationName' => 'Rule', ], ], ], 'GetBucketLifecycleConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketLifecycleOutput' => [ 'type' => 'structure', 'members' => [ 'Rules' => [ 'shape' => 'Rules', 'locationName' => 'Rule', ], ], ], 'GetBucketLifecycleRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketLocationOutput' => [ 'type' => 'structure', 'members' => [ 'LocationConstraint' => [ 'shape' => 'BucketLocationConstraint', ], ], ], 'GetBucketLocationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketLoggingOutput' => [ 'type' => 'structure', 'members' => [ 'LoggingEnabled' => [ 'shape' => 'LoggingEnabled', ], ], ], 'GetBucketLoggingRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketMetricsConfigurationOutput' => [ 'type' => 'structure', 'members' => [ 'MetricsConfiguration' => [ 'shape' => 'MetricsConfiguration', ], ], 'payload' => 'MetricsConfiguration', ], 'GetBucketMetricsConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'MetricsId', 'location' => 'querystring', 'locationName' => 'id', ], ], ], 'GetBucketNotificationConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketPolicyOutput' => [ 'type' => 'structure', 'members' => [ 'Policy' => [ 'shape' => 'Policy', ], ], 'payload' => 'Policy', ], 'GetBucketPolicyRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketPolicyStatusOutput' => [ 'type' => 'structure', 'members' => [ 'PolicyStatus' => [ 'shape' => 'PolicyStatus', ], ], 'payload' => 'PolicyStatus', ], 'GetBucketPolicyStatusRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketReplicationOutput' => [ 'type' => 'structure', 'members' => [ 'ReplicationConfiguration' => [ 'shape' => 'ReplicationConfiguration', ], ], 'payload' => 'ReplicationConfiguration', ], 'GetBucketReplicationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketRequestPaymentOutput' => [ 'type' => 'structure', 'members' => [ 'Payer' => [ 'shape' => 'Payer', ], ], ], 'GetBucketRequestPaymentRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketTaggingOutput' => [ 'type' => 'structure', 'required' => [ 'TagSet', ], 'members' => [ 'TagSet' => [ 'shape' => 'TagSet', ], ], ], 'GetBucketTaggingRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketVersioningOutput' => [ 'type' => 'structure', 'members' => [ 'Status' => [ 'shape' => 'BucketVersioningStatus', ], 'MFADelete' => [ 'shape' => 'MFADeleteStatus', 'locationName' => 'MfaDelete', ], ], ], 'GetBucketVersioningRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetBucketWebsiteOutput' => [ 'type' => 'structure', 'members' => [ 'RedirectAllRequestsTo' => [ 'shape' => 'RedirectAllRequestsTo', ], 'IndexDocument' => [ 'shape' => 'IndexDocument', ], 'ErrorDocument' => [ 'shape' => 'ErrorDocument', ], 'RoutingRules' => [ 'shape' => 'RoutingRules', ], ], ], 'GetBucketWebsiteRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetObjectAclOutput' => [ 'type' => 'structure', 'members' => [ 'Owner' => [ 'shape' => 'Owner', ], 'Grants' => [ 'shape' => 'Grants', 'locationName' => 'AccessControlList', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'GetObjectAclRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'GetObjectLegalHoldOutput' => [ 'type' => 'structure', 'members' => [ 'LegalHold' => [ 'shape' => 'ObjectLockLegalHold', ], ], 'payload' => 'LegalHold', ], 'GetObjectLegalHoldRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'GetObjectLockConfigurationOutput' => [ 'type' => 'structure', 'members' => [ 'ObjectLockConfiguration' => [ 'shape' => 'ObjectLockConfiguration', ], ], 'payload' => 'ObjectLockConfiguration', ], 'GetObjectLockConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GetObjectOutput' => [ 'type' => 'structure', 'members' => [ 'Body' => [ 'shape' => 'Body', 'streaming' => true, ], 'DeleteMarker' => [ 'shape' => 'DeleteMarker', 'location' => 'header', 'locationName' => 'x-amz-delete-marker', ], 'AcceptRanges' => [ 'shape' => 'AcceptRanges', 'location' => 'header', 'locationName' => 'accept-ranges', ], 'Expiration' => [ 'shape' => 'Expiration', 'location' => 'header', 'locationName' => 'x-amz-expiration', ], 'Restore' => [ 'shape' => 'Restore', 'location' => 'header', 'locationName' => 'x-amz-restore', ], 'LastModified' => [ 'shape' => 'LastModified', 'location' => 'header', 'locationName' => 'Last-Modified', ], 'ContentLength' => [ 'shape' => 'ContentLength', 'location' => 'header', 'locationName' => 'Content-Length', ], 'ETag' => [ 'shape' => 'ETag', 'location' => 'header', 'locationName' => 'ETag', ], 'MissingMeta' => [ 'shape' => 'MissingMeta', 'location' => 'header', 'locationName' => 'x-amz-missing-meta', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], 'CacheControl' => [ 'shape' => 'CacheControl', 'location' => 'header', 'locationName' => 'Cache-Control', ], 'ContentDisposition' => [ 'shape' => 'ContentDisposition', 'location' => 'header', 'locationName' => 'Content-Disposition', ], 'ContentEncoding' => [ 'shape' => 'ContentEncoding', 'location' => 'header', 'locationName' => 'Content-Encoding', ], 'ContentLanguage' => [ 'shape' => 'ContentLanguage', 'location' => 'header', 'locationName' => 'Content-Language', ], 'ContentRange' => [ 'shape' => 'ContentRange', 'location' => 'header', 'locationName' => 'Content-Range', ], 'ContentType' => [ 'shape' => 'ContentType', 'location' => 'header', 'locationName' => 'Content-Type', ], 'Expires' => [ 'shape' => 'Expires', 'location' => 'header', 'locationName' => 'Expires', ], 'WebsiteRedirectLocation' => [ 'shape' => 'WebsiteRedirectLocation', 'location' => 'header', 'locationName' => 'x-amz-website-redirect-location', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'Metadata' => [ 'shape' => 'Metadata', 'location' => 'headers', 'locationName' => 'x-amz-meta-', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'StorageClass' => [ 'shape' => 'StorageClass', 'location' => 'header', 'locationName' => 'x-amz-storage-class', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], 'ReplicationStatus' => [ 'shape' => 'ReplicationStatus', 'location' => 'header', 'locationName' => 'x-amz-replication-status', ], 'PartsCount' => [ 'shape' => 'PartsCount', 'location' => 'header', 'locationName' => 'x-amz-mp-parts-count', ], 'TagCount' => [ 'shape' => 'TagCount', 'location' => 'header', 'locationName' => 'x-amz-tagging-count', ], 'ObjectLockMode' => [ 'shape' => 'ObjectLockMode', 'location' => 'header', 'locationName' => 'x-amz-object-lock-mode', ], 'ObjectLockRetainUntilDate' => [ 'shape' => 'ObjectLockRetainUntilDate', 'location' => 'header', 'locationName' => 'x-amz-object-lock-retain-until-date', ], 'ObjectLockLegalHoldStatus' => [ 'shape' => 'ObjectLockLegalHoldStatus', 'location' => 'header', 'locationName' => 'x-amz-object-lock-legal-hold', ], ], 'payload' => 'Body', ], 'GetObjectRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'IfMatch' => [ 'shape' => 'IfMatch', 'location' => 'header', 'locationName' => 'If-Match', ], 'IfModifiedSince' => [ 'shape' => 'IfModifiedSince', 'location' => 'header', 'locationName' => 'If-Modified-Since', ], 'IfNoneMatch' => [ 'shape' => 'IfNoneMatch', 'location' => 'header', 'locationName' => 'If-None-Match', ], 'IfUnmodifiedSince' => [ 'shape' => 'IfUnmodifiedSince', 'location' => 'header', 'locationName' => 'If-Unmodified-Since', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'Range' => [ 'shape' => 'Range', 'location' => 'header', 'locationName' => 'Range', ], 'ResponseCacheControl' => [ 'shape' => 'ResponseCacheControl', 'location' => 'querystring', 'locationName' => 'response-cache-control', ], 'ResponseContentDisposition' => [ 'shape' => 'ResponseContentDisposition', 'location' => 'querystring', 'locationName' => 'response-content-disposition', ], 'ResponseContentEncoding' => [ 'shape' => 'ResponseContentEncoding', 'location' => 'querystring', 'locationName' => 'response-content-encoding', ], 'ResponseContentLanguage' => [ 'shape' => 'ResponseContentLanguage', 'location' => 'querystring', 'locationName' => 'response-content-language', ], 'ResponseContentType' => [ 'shape' => 'ResponseContentType', 'location' => 'querystring', 'locationName' => 'response-content-type', ], 'ResponseExpires' => [ 'shape' => 'ResponseExpires', 'location' => 'querystring', 'locationName' => 'response-expires', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKey' => [ 'shape' => 'SSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'PartNumber' => [ 'shape' => 'PartNumber', 'location' => 'querystring', 'locationName' => 'partNumber', ], ], ], 'GetObjectRetentionOutput' => [ 'type' => 'structure', 'members' => [ 'Retention' => [ 'shape' => 'ObjectLockRetention', ], ], 'payload' => 'Retention', ], 'GetObjectRetentionRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'GetObjectTaggingOutput' => [ 'type' => 'structure', 'required' => [ 'TagSet', ], 'members' => [ 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], 'TagSet' => [ 'shape' => 'TagSet', ], ], ], 'GetObjectTaggingRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], ], ], 'GetObjectTorrentOutput' => [ 'type' => 'structure', 'members' => [ 'Body' => [ 'shape' => 'Body', 'streaming' => true, ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], 'payload' => 'Body', ], 'GetObjectTorrentRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'GetPublicAccessBlockOutput' => [ 'type' => 'structure', 'members' => [ 'PublicAccessBlockConfiguration' => [ 'shape' => 'PublicAccessBlockConfiguration', ], ], 'payload' => 'PublicAccessBlockConfiguration', ], 'GetPublicAccessBlockRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'GlacierJobParameters' => [ 'type' => 'structure', 'required' => [ 'Tier', ], 'members' => [ 'Tier' => [ 'shape' => 'Tier', ], ], ], 'Grant' => [ 'type' => 'structure', 'members' => [ 'Grantee' => [ 'shape' => 'Grantee', ], 'Permission' => [ 'shape' => 'Permission', ], ], ], 'GrantFullControl' => [ 'type' => 'string', ], 'GrantRead' => [ 'type' => 'string', ], 'GrantReadACP' => [ 'type' => 'string', ], 'GrantWrite' => [ 'type' => 'string', ], 'GrantWriteACP' => [ 'type' => 'string', ], 'Grantee' => [ 'type' => 'structure', 'required' => [ 'Type', ], 'members' => [ 'DisplayName' => [ 'shape' => 'DisplayName', ], 'EmailAddress' => [ 'shape' => 'EmailAddress', ], 'ID' => [ 'shape' => 'ID', ], 'Type' => [ 'shape' => 'Type', 'locationName' => 'xsi:type', 'xmlAttribute' => true, ], 'URI' => [ 'shape' => 'URI', ], ], 'xmlNamespace' => [ 'prefix' => 'xsi', 'uri' => 'http://www.w3.org/2001/XMLSchema-instance', ], ], 'Grants' => [ 'type' => 'list', 'member' => [ 'shape' => 'Grant', 'locationName' => 'Grant', ], ], 'HeadBucketRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], ], ], 'HeadObjectOutput' => [ 'type' => 'structure', 'members' => [ 'DeleteMarker' => [ 'shape' => 'DeleteMarker', 'location' => 'header', 'locationName' => 'x-amz-delete-marker', ], 'AcceptRanges' => [ 'shape' => 'AcceptRanges', 'location' => 'header', 'locationName' => 'accept-ranges', ], 'Expiration' => [ 'shape' => 'Expiration', 'location' => 'header', 'locationName' => 'x-amz-expiration', ], 'Restore' => [ 'shape' => 'Restore', 'location' => 'header', 'locationName' => 'x-amz-restore', ], 'LastModified' => [ 'shape' => 'LastModified', 'location' => 'header', 'locationName' => 'Last-Modified', ], 'ContentLength' => [ 'shape' => 'ContentLength', 'location' => 'header', 'locationName' => 'Content-Length', ], 'ETag' => [ 'shape' => 'ETag', 'location' => 'header', 'locationName' => 'ETag', ], 'MissingMeta' => [ 'shape' => 'MissingMeta', 'location' => 'header', 'locationName' => 'x-amz-missing-meta', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], 'CacheControl' => [ 'shape' => 'CacheControl', 'location' => 'header', 'locationName' => 'Cache-Control', ], 'ContentDisposition' => [ 'shape' => 'ContentDisposition', 'location' => 'header', 'locationName' => 'Content-Disposition', ], 'ContentEncoding' => [ 'shape' => 'ContentEncoding', 'location' => 'header', 'locationName' => 'Content-Encoding', ], 'ContentLanguage' => [ 'shape' => 'ContentLanguage', 'location' => 'header', 'locationName' => 'Content-Language', ], 'ContentType' => [ 'shape' => 'ContentType', 'location' => 'header', 'locationName' => 'Content-Type', ], 'Expires' => [ 'shape' => 'Expires', 'location' => 'header', 'locationName' => 'Expires', ], 'WebsiteRedirectLocation' => [ 'shape' => 'WebsiteRedirectLocation', 'location' => 'header', 'locationName' => 'x-amz-website-redirect-location', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'Metadata' => [ 'shape' => 'Metadata', 'location' => 'headers', 'locationName' => 'x-amz-meta-', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'StorageClass' => [ 'shape' => 'StorageClass', 'location' => 'header', 'locationName' => 'x-amz-storage-class', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], 'ReplicationStatus' => [ 'shape' => 'ReplicationStatus', 'location' => 'header', 'locationName' => 'x-amz-replication-status', ], 'PartsCount' => [ 'shape' => 'PartsCount', 'location' => 'header', 'locationName' => 'x-amz-mp-parts-count', ], 'ObjectLockMode' => [ 'shape' => 'ObjectLockMode', 'location' => 'header', 'locationName' => 'x-amz-object-lock-mode', ], 'ObjectLockRetainUntilDate' => [ 'shape' => 'ObjectLockRetainUntilDate', 'location' => 'header', 'locationName' => 'x-amz-object-lock-retain-until-date', ], 'ObjectLockLegalHoldStatus' => [ 'shape' => 'ObjectLockLegalHoldStatus', 'location' => 'header', 'locationName' => 'x-amz-object-lock-legal-hold', ], ], ], 'HeadObjectRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'IfMatch' => [ 'shape' => 'IfMatch', 'location' => 'header', 'locationName' => 'If-Match', ], 'IfModifiedSince' => [ 'shape' => 'IfModifiedSince', 'location' => 'header', 'locationName' => 'If-Modified-Since', ], 'IfNoneMatch' => [ 'shape' => 'IfNoneMatch', 'location' => 'header', 'locationName' => 'If-None-Match', ], 'IfUnmodifiedSince' => [ 'shape' => 'IfUnmodifiedSince', 'location' => 'header', 'locationName' => 'If-Unmodified-Since', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'Range' => [ 'shape' => 'Range', 'location' => 'header', 'locationName' => 'Range', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKey' => [ 'shape' => 'SSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'PartNumber' => [ 'shape' => 'PartNumber', 'location' => 'querystring', 'locationName' => 'partNumber', ], ], ], 'HostName' => [ 'type' => 'string', ], 'HttpErrorCodeReturnedEquals' => [ 'type' => 'string', ], 'HttpRedirectCode' => [ 'type' => 'string', ], 'ID' => [ 'type' => 'string', ], 'IfMatch' => [ 'type' => 'string', ], 'IfModifiedSince' => [ 'type' => 'timestamp', ], 'IfNoneMatch' => [ 'type' => 'string', ], 'IfUnmodifiedSince' => [ 'type' => 'timestamp', ], 'IndexDocument' => [ 'type' => 'structure', 'required' => [ 'Suffix', ], 'members' => [ 'Suffix' => [ 'shape' => 'Suffix', ], ], ], 'Initiated' => [ 'type' => 'timestamp', ], 'Initiator' => [ 'type' => 'structure', 'members' => [ 'ID' => [ 'shape' => 'ID', ], 'DisplayName' => [ 'shape' => 'DisplayName', ], ], ], 'InputSerialization' => [ 'type' => 'structure', 'members' => [ 'CSV' => [ 'shape' => 'CSVInput', ], 'CompressionType' => [ 'shape' => 'CompressionType', ], 'JSON' => [ 'shape' => 'JSONInput', ], 'Parquet' => [ 'shape' => 'ParquetInput', ], ], ], 'InventoryConfiguration' => [ 'type' => 'structure', 'required' => [ 'Destination', 'IsEnabled', 'Id', 'IncludedObjectVersions', 'Schedule', ], 'members' => [ 'Destination' => [ 'shape' => 'InventoryDestination', ], 'IsEnabled' => [ 'shape' => 'IsEnabled', ], 'Filter' => [ 'shape' => 'InventoryFilter', ], 'Id' => [ 'shape' => 'InventoryId', ], 'IncludedObjectVersions' => [ 'shape' => 'InventoryIncludedObjectVersions', ], 'OptionalFields' => [ 'shape' => 'InventoryOptionalFields', ], 'Schedule' => [ 'shape' => 'InventorySchedule', ], ], ], 'InventoryConfigurationList' => [ 'type' => 'list', 'member' => [ 'shape' => 'InventoryConfiguration', ], 'flattened' => true, ], 'InventoryDestination' => [ 'type' => 'structure', 'required' => [ 'S3BucketDestination', ], 'members' => [ 'S3BucketDestination' => [ 'shape' => 'InventoryS3BucketDestination', ], ], ], 'InventoryEncryption' => [ 'type' => 'structure', 'members' => [ 'SSES3' => [ 'shape' => 'SSES3', 'locationName' => 'SSE-S3', ], 'SSEKMS' => [ 'shape' => 'SSEKMS', 'locationName' => 'SSE-KMS', ], ], ], 'InventoryFilter' => [ 'type' => 'structure', 'required' => [ 'Prefix', ], 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], ], ], 'InventoryFormat' => [ 'type' => 'string', 'enum' => [ 'CSV', 'ORC', 'Parquet', ], ], 'InventoryFrequency' => [ 'type' => 'string', 'enum' => [ 'Daily', 'Weekly', ], ], 'InventoryId' => [ 'type' => 'string', ], 'InventoryIncludedObjectVersions' => [ 'type' => 'string', 'enum' => [ 'All', 'Current', ], ], 'InventoryOptionalField' => [ 'type' => 'string', 'enum' => [ 'Size', 'LastModifiedDate', 'StorageClass', 'ETag', 'IsMultipartUploaded', 'ReplicationStatus', 'EncryptionStatus', 'ObjectLockRetainUntilDate', 'ObjectLockMode', 'ObjectLockLegalHoldStatus', ], ], 'InventoryOptionalFields' => [ 'type' => 'list', 'member' => [ 'shape' => 'InventoryOptionalField', 'locationName' => 'Field', ], ], 'InventoryS3BucketDestination' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Format', ], 'members' => [ 'AccountId' => [ 'shape' => 'AccountId', ], 'Bucket' => [ 'shape' => 'BucketName', ], 'Format' => [ 'shape' => 'InventoryFormat', ], 'Prefix' => [ 'shape' => 'Prefix', ], 'Encryption' => [ 'shape' => 'InventoryEncryption', ], ], ], 'InventorySchedule' => [ 'type' => 'structure', 'required' => [ 'Frequency', ], 'members' => [ 'Frequency' => [ 'shape' => 'InventoryFrequency', ], ], ], 'IsEnabled' => [ 'type' => 'boolean', ], 'IsLatest' => [ 'type' => 'boolean', ], 'IsPublic' => [ 'type' => 'boolean', ], 'IsTruncated' => [ 'type' => 'boolean', ], 'JSONInput' => [ 'type' => 'structure', 'members' => [ 'Type' => [ 'shape' => 'JSONType', ], ], ], 'JSONOutput' => [ 'type' => 'structure', 'members' => [ 'RecordDelimiter' => [ 'shape' => 'RecordDelimiter', ], ], ], 'JSONType' => [ 'type' => 'string', 'enum' => [ 'DOCUMENT', 'LINES', ], ], 'KMSContext' => [ 'type' => 'string', ], 'KeyCount' => [ 'type' => 'integer', ], 'KeyMarker' => [ 'type' => 'string', ], 'KeyPrefixEquals' => [ 'type' => 'string', ], 'LambdaFunctionArn' => [ 'type' => 'string', ], 'LambdaFunctionConfiguration' => [ 'type' => 'structure', 'required' => [ 'LambdaFunctionArn', 'Events', ], 'members' => [ 'Id' => [ 'shape' => 'NotificationId', ], 'LambdaFunctionArn' => [ 'shape' => 'LambdaFunctionArn', 'locationName' => 'CloudFunction', ], 'Events' => [ 'shape' => 'EventList', 'locationName' => 'Event', ], 'Filter' => [ 'shape' => 'NotificationConfigurationFilter', ], ], ], 'LambdaFunctionConfigurationList' => [ 'type' => 'list', 'member' => [ 'shape' => 'LambdaFunctionConfiguration', ], 'flattened' => true, ], 'LastModified' => [ 'type' => 'timestamp', ], 'LifecycleConfiguration' => [ 'type' => 'structure', 'required' => [ 'Rules', ], 'members' => [ 'Rules' => [ 'shape' => 'Rules', 'locationName' => 'Rule', ], ], ], 'LifecycleExpiration' => [ 'type' => 'structure', 'members' => [ 'Date' => [ 'shape' => 'Date', ], 'Days' => [ 'shape' => 'Days', ], 'ExpiredObjectDeleteMarker' => [ 'shape' => 'ExpiredObjectDeleteMarker', ], ], ], 'LifecycleRule' => [ 'type' => 'structure', 'required' => [ 'Status', ], 'members' => [ 'Expiration' => [ 'shape' => 'LifecycleExpiration', ], 'ID' => [ 'shape' => 'ID', ], 'Prefix' => [ 'shape' => 'Prefix', 'deprecated' => true, ], 'Filter' => [ 'shape' => 'LifecycleRuleFilter', ], 'Status' => [ 'shape' => 'ExpirationStatus', ], 'Transitions' => [ 'shape' => 'TransitionList', 'locationName' => 'Transition', ], 'NoncurrentVersionTransitions' => [ 'shape' => 'NoncurrentVersionTransitionList', 'locationName' => 'NoncurrentVersionTransition', ], 'NoncurrentVersionExpiration' => [ 'shape' => 'NoncurrentVersionExpiration', ], 'AbortIncompleteMultipartUpload' => [ 'shape' => 'AbortIncompleteMultipartUpload', ], ], ], 'LifecycleRuleAndOperator' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], 'Tags' => [ 'shape' => 'TagSet', 'flattened' => true, 'locationName' => 'Tag', ], ], ], 'LifecycleRuleFilter' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], 'Tag' => [ 'shape' => 'Tag', ], 'And' => [ 'shape' => 'LifecycleRuleAndOperator', ], ], ], 'LifecycleRules' => [ 'type' => 'list', 'member' => [ 'shape' => 'LifecycleRule', ], 'flattened' => true, ], 'ListBucketAnalyticsConfigurationsOutput' => [ 'type' => 'structure', 'members' => [ 'IsTruncated' => [ 'shape' => 'IsTruncated', ], 'ContinuationToken' => [ 'shape' => 'Token', ], 'NextContinuationToken' => [ 'shape' => 'NextToken', ], 'AnalyticsConfigurationList' => [ 'shape' => 'AnalyticsConfigurationList', 'locationName' => 'AnalyticsConfiguration', ], ], ], 'ListBucketAnalyticsConfigurationsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContinuationToken' => [ 'shape' => 'Token', 'location' => 'querystring', 'locationName' => 'continuation-token', ], ], ], 'ListBucketInventoryConfigurationsOutput' => [ 'type' => 'structure', 'members' => [ 'ContinuationToken' => [ 'shape' => 'Token', ], 'InventoryConfigurationList' => [ 'shape' => 'InventoryConfigurationList', 'locationName' => 'InventoryConfiguration', ], 'IsTruncated' => [ 'shape' => 'IsTruncated', ], 'NextContinuationToken' => [ 'shape' => 'NextToken', ], ], ], 'ListBucketInventoryConfigurationsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContinuationToken' => [ 'shape' => 'Token', 'location' => 'querystring', 'locationName' => 'continuation-token', ], ], ], 'ListBucketMetricsConfigurationsOutput' => [ 'type' => 'structure', 'members' => [ 'IsTruncated' => [ 'shape' => 'IsTruncated', ], 'ContinuationToken' => [ 'shape' => 'Token', ], 'NextContinuationToken' => [ 'shape' => 'NextToken', ], 'MetricsConfigurationList' => [ 'shape' => 'MetricsConfigurationList', 'locationName' => 'MetricsConfiguration', ], ], ], 'ListBucketMetricsConfigurationsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContinuationToken' => [ 'shape' => 'Token', 'location' => 'querystring', 'locationName' => 'continuation-token', ], ], ], 'ListBucketsOutput' => [ 'type' => 'structure', 'members' => [ 'Buckets' => [ 'shape' => 'Buckets', ], 'Owner' => [ 'shape' => 'Owner', ], ], ], 'ListMultipartUploadsOutput' => [ 'type' => 'structure', 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', ], 'KeyMarker' => [ 'shape' => 'KeyMarker', ], 'UploadIdMarker' => [ 'shape' => 'UploadIdMarker', ], 'NextKeyMarker' => [ 'shape' => 'NextKeyMarker', ], 'Prefix' => [ 'shape' => 'Prefix', ], 'Delimiter' => [ 'shape' => 'Delimiter', ], 'NextUploadIdMarker' => [ 'shape' => 'NextUploadIdMarker', ], 'MaxUploads' => [ 'shape' => 'MaxUploads', ], 'IsTruncated' => [ 'shape' => 'IsTruncated', ], 'Uploads' => [ 'shape' => 'MultipartUploadList', 'locationName' => 'Upload', ], 'CommonPrefixes' => [ 'shape' => 'CommonPrefixList', ], 'EncodingType' => [ 'shape' => 'EncodingType', ], ], ], 'ListMultipartUploadsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Delimiter' => [ 'shape' => 'Delimiter', 'location' => 'querystring', 'locationName' => 'delimiter', ], 'EncodingType' => [ 'shape' => 'EncodingType', 'location' => 'querystring', 'locationName' => 'encoding-type', ], 'KeyMarker' => [ 'shape' => 'KeyMarker', 'location' => 'querystring', 'locationName' => 'key-marker', ], 'MaxUploads' => [ 'shape' => 'MaxUploads', 'location' => 'querystring', 'locationName' => 'max-uploads', ], 'Prefix' => [ 'shape' => 'Prefix', 'location' => 'querystring', 'locationName' => 'prefix', ], 'UploadIdMarker' => [ 'shape' => 'UploadIdMarker', 'location' => 'querystring', 'locationName' => 'upload-id-marker', ], ], ], 'ListObjectVersionsOutput' => [ 'type' => 'structure', 'members' => [ 'IsTruncated' => [ 'shape' => 'IsTruncated', ], 'KeyMarker' => [ 'shape' => 'KeyMarker', ], 'VersionIdMarker' => [ 'shape' => 'VersionIdMarker', ], 'NextKeyMarker' => [ 'shape' => 'NextKeyMarker', ], 'NextVersionIdMarker' => [ 'shape' => 'NextVersionIdMarker', ], 'Versions' => [ 'shape' => 'ObjectVersionList', 'locationName' => 'Version', ], 'DeleteMarkers' => [ 'shape' => 'DeleteMarkers', 'locationName' => 'DeleteMarker', ], 'Name' => [ 'shape' => 'BucketName', ], 'Prefix' => [ 'shape' => 'Prefix', ], 'Delimiter' => [ 'shape' => 'Delimiter', ], 'MaxKeys' => [ 'shape' => 'MaxKeys', ], 'CommonPrefixes' => [ 'shape' => 'CommonPrefixList', ], 'EncodingType' => [ 'shape' => 'EncodingType', ], ], ], 'ListObjectVersionsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Delimiter' => [ 'shape' => 'Delimiter', 'location' => 'querystring', 'locationName' => 'delimiter', ], 'EncodingType' => [ 'shape' => 'EncodingType', 'location' => 'querystring', 'locationName' => 'encoding-type', ], 'KeyMarker' => [ 'shape' => 'KeyMarker', 'location' => 'querystring', 'locationName' => 'key-marker', ], 'MaxKeys' => [ 'shape' => 'MaxKeys', 'location' => 'querystring', 'locationName' => 'max-keys', ], 'Prefix' => [ 'shape' => 'Prefix', 'location' => 'querystring', 'locationName' => 'prefix', ], 'VersionIdMarker' => [ 'shape' => 'VersionIdMarker', 'location' => 'querystring', 'locationName' => 'version-id-marker', ], ], ], 'ListObjectsOutput' => [ 'type' => 'structure', 'members' => [ 'IsTruncated' => [ 'shape' => 'IsTruncated', ], 'Marker' => [ 'shape' => 'Marker', ], 'NextMarker' => [ 'shape' => 'NextMarker', ], 'Contents' => [ 'shape' => 'ObjectList', ], 'Name' => [ 'shape' => 'BucketName', ], 'Prefix' => [ 'shape' => 'Prefix', ], 'Delimiter' => [ 'shape' => 'Delimiter', ], 'MaxKeys' => [ 'shape' => 'MaxKeys', ], 'CommonPrefixes' => [ 'shape' => 'CommonPrefixList', ], 'EncodingType' => [ 'shape' => 'EncodingType', ], ], ], 'ListObjectsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Delimiter' => [ 'shape' => 'Delimiter', 'location' => 'querystring', 'locationName' => 'delimiter', ], 'EncodingType' => [ 'shape' => 'EncodingType', 'location' => 'querystring', 'locationName' => 'encoding-type', ], 'Marker' => [ 'shape' => 'Marker', 'location' => 'querystring', 'locationName' => 'marker', ], 'MaxKeys' => [ 'shape' => 'MaxKeys', 'location' => 'querystring', 'locationName' => 'max-keys', ], 'Prefix' => [ 'shape' => 'Prefix', 'location' => 'querystring', 'locationName' => 'prefix', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'ListObjectsV2Output' => [ 'type' => 'structure', 'members' => [ 'IsTruncated' => [ 'shape' => 'IsTruncated', ], 'Contents' => [ 'shape' => 'ObjectList', ], 'Name' => [ 'shape' => 'BucketName', ], 'Prefix' => [ 'shape' => 'Prefix', ], 'Delimiter' => [ 'shape' => 'Delimiter', ], 'MaxKeys' => [ 'shape' => 'MaxKeys', ], 'CommonPrefixes' => [ 'shape' => 'CommonPrefixList', ], 'EncodingType' => [ 'shape' => 'EncodingType', ], 'KeyCount' => [ 'shape' => 'KeyCount', ], 'ContinuationToken' => [ 'shape' => 'Token', ], 'NextContinuationToken' => [ 'shape' => 'NextToken', ], 'StartAfter' => [ 'shape' => 'StartAfter', ], ], ], 'ListObjectsV2Request' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Delimiter' => [ 'shape' => 'Delimiter', 'location' => 'querystring', 'locationName' => 'delimiter', ], 'EncodingType' => [ 'shape' => 'EncodingType', 'location' => 'querystring', 'locationName' => 'encoding-type', ], 'MaxKeys' => [ 'shape' => 'MaxKeys', 'location' => 'querystring', 'locationName' => 'max-keys', ], 'Prefix' => [ 'shape' => 'Prefix', 'location' => 'querystring', 'locationName' => 'prefix', ], 'ContinuationToken' => [ 'shape' => 'Token', 'location' => 'querystring', 'locationName' => 'continuation-token', ], 'FetchOwner' => [ 'shape' => 'FetchOwner', 'location' => 'querystring', 'locationName' => 'fetch-owner', ], 'StartAfter' => [ 'shape' => 'StartAfter', 'location' => 'querystring', 'locationName' => 'start-after', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'ListPartsOutput' => [ 'type' => 'structure', 'members' => [ 'AbortDate' => [ 'shape' => 'AbortDate', 'location' => 'header', 'locationName' => 'x-amz-abort-date', ], 'AbortRuleId' => [ 'shape' => 'AbortRuleId', 'location' => 'header', 'locationName' => 'x-amz-abort-rule-id', ], 'Bucket' => [ 'shape' => 'BucketName', ], 'Key' => [ 'shape' => 'ObjectKey', ], 'UploadId' => [ 'shape' => 'MultipartUploadId', ], 'PartNumberMarker' => [ 'shape' => 'PartNumberMarker', ], 'NextPartNumberMarker' => [ 'shape' => 'NextPartNumberMarker', ], 'MaxParts' => [ 'shape' => 'MaxParts', ], 'IsTruncated' => [ 'shape' => 'IsTruncated', ], 'Parts' => [ 'shape' => 'Parts', 'locationName' => 'Part', ], 'Initiator' => [ 'shape' => 'Initiator', ], 'Owner' => [ 'shape' => 'Owner', ], 'StorageClass' => [ 'shape' => 'StorageClass', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'ListPartsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', 'UploadId', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'MaxParts' => [ 'shape' => 'MaxParts', 'location' => 'querystring', 'locationName' => 'max-parts', ], 'PartNumberMarker' => [ 'shape' => 'PartNumberMarker', 'location' => 'querystring', 'locationName' => 'part-number-marker', ], 'UploadId' => [ 'shape' => 'MultipartUploadId', 'location' => 'querystring', 'locationName' => 'uploadId', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'Location' => [ 'type' => 'string', ], 'LocationPrefix' => [ 'type' => 'string', ], 'LoggingEnabled' => [ 'type' => 'structure', 'required' => [ 'TargetBucket', 'TargetPrefix', ], 'members' => [ 'TargetBucket' => [ 'shape' => 'TargetBucket', ], 'TargetGrants' => [ 'shape' => 'TargetGrants', ], 'TargetPrefix' => [ 'shape' => 'TargetPrefix', ], ], ], 'MFA' => [ 'type' => 'string', ], 'MFADelete' => [ 'type' => 'string', 'enum' => [ 'Enabled', 'Disabled', ], ], 'MFADeleteStatus' => [ 'type' => 'string', 'enum' => [ 'Enabled', 'Disabled', ], ], 'Marker' => [ 'type' => 'string', ], 'MaxAgeSeconds' => [ 'type' => 'integer', ], 'MaxKeys' => [ 'type' => 'integer', ], 'MaxParts' => [ 'type' => 'integer', ], 'MaxUploads' => [ 'type' => 'integer', ], 'Message' => [ 'type' => 'string', ], 'Metadata' => [ 'type' => 'map', 'key' => [ 'shape' => 'MetadataKey', ], 'value' => [ 'shape' => 'MetadataValue', ], ], 'MetadataDirective' => [ 'type' => 'string', 'enum' => [ 'COPY', 'REPLACE', ], ], 'MetadataEntry' => [ 'type' => 'structure', 'members' => [ 'Name' => [ 'shape' => 'MetadataKey', ], 'Value' => [ 'shape' => 'MetadataValue', ], ], ], 'MetadataKey' => [ 'type' => 'string', ], 'MetadataValue' => [ 'type' => 'string', ], 'MetricsAndOperator' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], 'Tags' => [ 'shape' => 'TagSet', 'flattened' => true, 'locationName' => 'Tag', ], ], ], 'MetricsConfiguration' => [ 'type' => 'structure', 'required' => [ 'Id', ], 'members' => [ 'Id' => [ 'shape' => 'MetricsId', ], 'Filter' => [ 'shape' => 'MetricsFilter', ], ], ], 'MetricsConfigurationList' => [ 'type' => 'list', 'member' => [ 'shape' => 'MetricsConfiguration', ], 'flattened' => true, ], 'MetricsFilter' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], 'Tag' => [ 'shape' => 'Tag', ], 'And' => [ 'shape' => 'MetricsAndOperator', ], ], ], 'MetricsId' => [ 'type' => 'string', ], 'MissingMeta' => [ 'type' => 'integer', ], 'MultipartUpload' => [ 'type' => 'structure', 'members' => [ 'UploadId' => [ 'shape' => 'MultipartUploadId', ], 'Key' => [ 'shape' => 'ObjectKey', ], 'Initiated' => [ 'shape' => 'Initiated', ], 'StorageClass' => [ 'shape' => 'StorageClass', ], 'Owner' => [ 'shape' => 'Owner', ], 'Initiator' => [ 'shape' => 'Initiator', ], ], ], 'MultipartUploadId' => [ 'type' => 'string', ], 'MultipartUploadList' => [ 'type' => 'list', 'member' => [ 'shape' => 'MultipartUpload', ], 'flattened' => true, ], 'NextKeyMarker' => [ 'type' => 'string', ], 'NextMarker' => [ 'type' => 'string', ], 'NextPartNumberMarker' => [ 'type' => 'integer', ], 'NextToken' => [ 'type' => 'string', ], 'NextUploadIdMarker' => [ 'type' => 'string', ], 'NextVersionIdMarker' => [ 'type' => 'string', ], 'NoSuchBucket' => [ 'type' => 'structure', 'members' => [], 'exception' => true, ], 'NoSuchKey' => [ 'type' => 'structure', 'members' => [], 'exception' => true, ], 'NoSuchUpload' => [ 'type' => 'structure', 'members' => [], 'exception' => true, ], 'NoncurrentVersionExpiration' => [ 'type' => 'structure', 'members' => [ 'NoncurrentDays' => [ 'shape' => 'Days', ], ], ], 'NoncurrentVersionTransition' => [ 'type' => 'structure', 'members' => [ 'NoncurrentDays' => [ 'shape' => 'Days', ], 'StorageClass' => [ 'shape' => 'TransitionStorageClass', ], ], ], 'NoncurrentVersionTransitionList' => [ 'type' => 'list', 'member' => [ 'shape' => 'NoncurrentVersionTransition', ], 'flattened' => true, ], 'NotificationConfiguration' => [ 'type' => 'structure', 'members' => [ 'TopicConfigurations' => [ 'shape' => 'TopicConfigurationList', 'locationName' => 'TopicConfiguration', ], 'QueueConfigurations' => [ 'shape' => 'QueueConfigurationList', 'locationName' => 'QueueConfiguration', ], 'LambdaFunctionConfigurations' => [ 'shape' => 'LambdaFunctionConfigurationList', 'locationName' => 'CloudFunctionConfiguration', ], ], ], 'NotificationConfigurationDeprecated' => [ 'type' => 'structure', 'members' => [ 'TopicConfiguration' => [ 'shape' => 'TopicConfigurationDeprecated', ], 'QueueConfiguration' => [ 'shape' => 'QueueConfigurationDeprecated', ], 'CloudFunctionConfiguration' => [ 'shape' => 'CloudFunctionConfiguration', ], ], ], 'NotificationConfigurationFilter' => [ 'type' => 'structure', 'members' => [ 'Key' => [ 'shape' => 'S3KeyFilter', 'locationName' => 'S3Key', ], ], ], 'NotificationId' => [ 'type' => 'string', ], 'Object' => [ 'type' => 'structure', 'members' => [ 'Key' => [ 'shape' => 'ObjectKey', ], 'LastModified' => [ 'shape' => 'LastModified', ], 'ETag' => [ 'shape' => 'ETag', ], 'Size' => [ 'shape' => 'Size', ], 'StorageClass' => [ 'shape' => 'ObjectStorageClass', ], 'Owner' => [ 'shape' => 'Owner', ], ], ], 'ObjectAlreadyInActiveTierError' => [ 'type' => 'structure', 'members' => [], 'exception' => true, ], 'ObjectCannedACL' => [ 'type' => 'string', 'enum' => [ 'private', 'public-read', 'public-read-write', 'authenticated-read', 'aws-exec-read', 'bucket-owner-read', 'bucket-owner-full-control', ], ], 'ObjectIdentifier' => [ 'type' => 'structure', 'required' => [ 'Key', ], 'members' => [ 'Key' => [ 'shape' => 'ObjectKey', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', ], ], ], 'ObjectIdentifierList' => [ 'type' => 'list', 'member' => [ 'shape' => 'ObjectIdentifier', ], 'flattened' => true, ], 'ObjectKey' => [ 'type' => 'string', 'min' => 1, ], 'ObjectList' => [ 'type' => 'list', 'member' => [ 'shape' => 'Object', ], 'flattened' => true, ], 'ObjectLockConfiguration' => [ 'type' => 'structure', 'members' => [ 'ObjectLockEnabled' => [ 'shape' => 'ObjectLockEnabled', ], 'Rule' => [ 'shape' => 'ObjectLockRule', ], ], ], 'ObjectLockEnabled' => [ 'type' => 'string', 'enum' => [ 'Enabled', ], ], 'ObjectLockEnabledForBucket' => [ 'type' => 'boolean', ], 'ObjectLockLegalHold' => [ 'type' => 'structure', 'members' => [ 'Status' => [ 'shape' => 'ObjectLockLegalHoldStatus', ], ], ], 'ObjectLockLegalHoldStatus' => [ 'type' => 'string', 'enum' => [ 'ON', 'OFF', ], ], 'ObjectLockMode' => [ 'type' => 'string', 'enum' => [ 'GOVERNANCE', 'COMPLIANCE', ], ], 'ObjectLockRetainUntilDate' => [ 'type' => 'timestamp', 'timestampFormat' => 'iso8601', ], 'ObjectLockRetention' => [ 'type' => 'structure', 'members' => [ 'Mode' => [ 'shape' => 'ObjectLockRetentionMode', ], 'RetainUntilDate' => [ 'shape' => 'Date', ], ], ], 'ObjectLockRetentionMode' => [ 'type' => 'string', 'enum' => [ 'GOVERNANCE', 'COMPLIANCE', ], ], 'ObjectLockRule' => [ 'type' => 'structure', 'members' => [ 'DefaultRetention' => [ 'shape' => 'DefaultRetention', ], ], ], 'ObjectLockToken' => [ 'type' => 'string', ], 'ObjectNotInActiveTierError' => [ 'type' => 'structure', 'members' => [], 'exception' => true, ], 'ObjectStorageClass' => [ 'type' => 'string', 'enum' => [ 'STANDARD', 'REDUCED_REDUNDANCY', 'GLACIER', 'STANDARD_IA', 'ONEZONE_IA', 'INTELLIGENT_TIERING', 'DEEP_ARCHIVE', ], ], 'ObjectVersion' => [ 'type' => 'structure', 'members' => [ 'ETag' => [ 'shape' => 'ETag', ], 'Size' => [ 'shape' => 'Size', ], 'StorageClass' => [ 'shape' => 'ObjectVersionStorageClass', ], 'Key' => [ 'shape' => 'ObjectKey', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', ], 'IsLatest' => [ 'shape' => 'IsLatest', ], 'LastModified' => [ 'shape' => 'LastModified', ], 'Owner' => [ 'shape' => 'Owner', ], ], ], 'ObjectVersionId' => [ 'type' => 'string', ], 'ObjectVersionList' => [ 'type' => 'list', 'member' => [ 'shape' => 'ObjectVersion', ], 'flattened' => true, ], 'ObjectVersionStorageClass' => [ 'type' => 'string', 'enum' => [ 'STANDARD', ], ], 'OutputLocation' => [ 'type' => 'structure', 'members' => [ 'S3' => [ 'shape' => 'S3Location', ], ], ], 'OutputSerialization' => [ 'type' => 'structure', 'members' => [ 'CSV' => [ 'shape' => 'CSVOutput', ], 'JSON' => [ 'shape' => 'JSONOutput', ], ], ], 'Owner' => [ 'type' => 'structure', 'members' => [ 'DisplayName' => [ 'shape' => 'DisplayName', ], 'ID' => [ 'shape' => 'ID', ], ], ], 'OwnerOverride' => [ 'type' => 'string', 'enum' => [ 'Destination', ], ], 'ParquetInput' => [ 'type' => 'structure', 'members' => [], ], 'Part' => [ 'type' => 'structure', 'members' => [ 'PartNumber' => [ 'shape' => 'PartNumber', ], 'LastModified' => [ 'shape' => 'LastModified', ], 'ETag' => [ 'shape' => 'ETag', ], 'Size' => [ 'shape' => 'Size', ], ], ], 'PartNumber' => [ 'type' => 'integer', ], 'PartNumberMarker' => [ 'type' => 'integer', ], 'Parts' => [ 'type' => 'list', 'member' => [ 'shape' => 'Part', ], 'flattened' => true, ], 'PartsCount' => [ 'type' => 'integer', ], 'Payer' => [ 'type' => 'string', 'enum' => [ 'Requester', 'BucketOwner', ], ], 'Permission' => [ 'type' => 'string', 'enum' => [ 'FULL_CONTROL', 'WRITE', 'WRITE_ACP', 'READ', 'READ_ACP', ], ], 'Policy' => [ 'type' => 'string', ], 'PolicyStatus' => [ 'type' => 'structure', 'members' => [ 'IsPublic' => [ 'shape' => 'IsPublic', 'locationName' => 'IsPublic', ], ], ], 'Prefix' => [ 'type' => 'string', ], 'Priority' => [ 'type' => 'integer', ], 'Progress' => [ 'type' => 'structure', 'members' => [ 'BytesScanned' => [ 'shape' => 'BytesScanned', ], 'BytesProcessed' => [ 'shape' => 'BytesProcessed', ], 'BytesReturned' => [ 'shape' => 'BytesReturned', ], ], ], 'ProgressEvent' => [ 'type' => 'structure', 'members' => [ 'Details' => [ 'shape' => 'Progress', 'eventpayload' => true, ], ], 'event' => true, ], 'Protocol' => [ 'type' => 'string', 'enum' => [ 'http', 'https', ], ], 'PublicAccessBlockConfiguration' => [ 'type' => 'structure', 'members' => [ 'BlockPublicAcls' => [ 'shape' => 'Setting', 'locationName' => 'BlockPublicAcls', ], 'IgnorePublicAcls' => [ 'shape' => 'Setting', 'locationName' => 'IgnorePublicAcls', ], 'BlockPublicPolicy' => [ 'shape' => 'Setting', 'locationName' => 'BlockPublicPolicy', ], 'RestrictPublicBuckets' => [ 'shape' => 'Setting', 'locationName' => 'RestrictPublicBuckets', ], ], ], 'PutBucketAccelerateConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'AccelerateConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'AccelerateConfiguration' => [ 'shape' => 'AccelerateConfiguration', 'locationName' => 'AccelerateConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'AccelerateConfiguration', ], 'PutBucketAclRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'ACL' => [ 'shape' => 'BucketCannedACL', 'location' => 'header', 'locationName' => 'x-amz-acl', ], 'AccessControlPolicy' => [ 'shape' => 'AccessControlPolicy', 'locationName' => 'AccessControlPolicy', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'GrantFullControl' => [ 'shape' => 'GrantFullControl', 'location' => 'header', 'locationName' => 'x-amz-grant-full-control', ], 'GrantRead' => [ 'shape' => 'GrantRead', 'location' => 'header', 'locationName' => 'x-amz-grant-read', ], 'GrantReadACP' => [ 'shape' => 'GrantReadACP', 'location' => 'header', 'locationName' => 'x-amz-grant-read-acp', ], 'GrantWrite' => [ 'shape' => 'GrantWrite', 'location' => 'header', 'locationName' => 'x-amz-grant-write', ], 'GrantWriteACP' => [ 'shape' => 'GrantWriteACP', 'location' => 'header', 'locationName' => 'x-amz-grant-write-acp', ], ], 'payload' => 'AccessControlPolicy', ], 'PutBucketAnalyticsConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', 'AnalyticsConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'AnalyticsId', 'location' => 'querystring', 'locationName' => 'id', ], 'AnalyticsConfiguration' => [ 'shape' => 'AnalyticsConfiguration', 'locationName' => 'AnalyticsConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'AnalyticsConfiguration', ], 'PutBucketCorsRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'CORSConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'CORSConfiguration' => [ 'shape' => 'CORSConfiguration', 'locationName' => 'CORSConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], ], 'payload' => 'CORSConfiguration', ], 'PutBucketEncryptionRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'ServerSideEncryptionConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'ServerSideEncryptionConfiguration' => [ 'shape' => 'ServerSideEncryptionConfiguration', 'locationName' => 'ServerSideEncryptionConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'ServerSideEncryptionConfiguration', ], 'PutBucketInventoryConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', 'InventoryConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'InventoryId', 'location' => 'querystring', 'locationName' => 'id', ], 'InventoryConfiguration' => [ 'shape' => 'InventoryConfiguration', 'locationName' => 'InventoryConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'InventoryConfiguration', ], 'PutBucketLifecycleConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'LifecycleConfiguration' => [ 'shape' => 'BucketLifecycleConfiguration', 'locationName' => 'LifecycleConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'LifecycleConfiguration', ], 'PutBucketLifecycleRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'LifecycleConfiguration' => [ 'shape' => 'LifecycleConfiguration', 'locationName' => 'LifecycleConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'LifecycleConfiguration', ], 'PutBucketLoggingRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'BucketLoggingStatus', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'BucketLoggingStatus' => [ 'shape' => 'BucketLoggingStatus', 'locationName' => 'BucketLoggingStatus', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], ], 'payload' => 'BucketLoggingStatus', ], 'PutBucketMetricsConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Id', 'MetricsConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Id' => [ 'shape' => 'MetricsId', 'location' => 'querystring', 'locationName' => 'id', ], 'MetricsConfiguration' => [ 'shape' => 'MetricsConfiguration', 'locationName' => 'MetricsConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'MetricsConfiguration', ], 'PutBucketNotificationConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'NotificationConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'NotificationConfiguration' => [ 'shape' => 'NotificationConfiguration', 'locationName' => 'NotificationConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'NotificationConfiguration', ], 'PutBucketNotificationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'NotificationConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'NotificationConfiguration' => [ 'shape' => 'NotificationConfigurationDeprecated', 'locationName' => 'NotificationConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'NotificationConfiguration', ], 'PutBucketPolicyRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Policy', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'ConfirmRemoveSelfBucketAccess' => [ 'shape' => 'ConfirmRemoveSelfBucketAccess', 'location' => 'header', 'locationName' => 'x-amz-confirm-remove-self-bucket-access', ], 'Policy' => [ 'shape' => 'Policy', ], ], 'payload' => 'Policy', ], 'PutBucketReplicationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'ReplicationConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'ReplicationConfiguration' => [ 'shape' => 'ReplicationConfiguration', 'locationName' => 'ReplicationConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'ReplicationConfiguration', ], 'PutBucketRequestPaymentRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'RequestPaymentConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'RequestPaymentConfiguration' => [ 'shape' => 'RequestPaymentConfiguration', 'locationName' => 'RequestPaymentConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'RequestPaymentConfiguration', ], 'PutBucketTaggingRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Tagging', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'Tagging' => [ 'shape' => 'Tagging', 'locationName' => 'Tagging', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'Tagging', ], 'PutBucketVersioningRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'VersioningConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'MFA' => [ 'shape' => 'MFA', 'location' => 'header', 'locationName' => 'x-amz-mfa', ], 'VersioningConfiguration' => [ 'shape' => 'VersioningConfiguration', 'locationName' => 'VersioningConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'VersioningConfiguration', ], 'PutBucketWebsiteRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'WebsiteConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'WebsiteConfiguration' => [ 'shape' => 'WebsiteConfiguration', 'locationName' => 'WebsiteConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'WebsiteConfiguration', ], 'PutObjectAclOutput' => [ 'type' => 'structure', 'members' => [ 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'PutObjectAclRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'ACL' => [ 'shape' => 'ObjectCannedACL', 'location' => 'header', 'locationName' => 'x-amz-acl', ], 'AccessControlPolicy' => [ 'shape' => 'AccessControlPolicy', 'locationName' => 'AccessControlPolicy', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'GrantFullControl' => [ 'shape' => 'GrantFullControl', 'location' => 'header', 'locationName' => 'x-amz-grant-full-control', ], 'GrantRead' => [ 'shape' => 'GrantRead', 'location' => 'header', 'locationName' => 'x-amz-grant-read', ], 'GrantReadACP' => [ 'shape' => 'GrantReadACP', 'location' => 'header', 'locationName' => 'x-amz-grant-read-acp', ], 'GrantWrite' => [ 'shape' => 'GrantWrite', 'location' => 'header', 'locationName' => 'x-amz-grant-write', ], 'GrantWriteACP' => [ 'shape' => 'GrantWriteACP', 'location' => 'header', 'locationName' => 'x-amz-grant-write-acp', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], ], 'payload' => 'AccessControlPolicy', ], 'PutObjectLegalHoldOutput' => [ 'type' => 'structure', 'members' => [ 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'PutObjectLegalHoldRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'LegalHold' => [ 'shape' => 'ObjectLockLegalHold', 'locationName' => 'LegalHold', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], ], 'payload' => 'LegalHold', ], 'PutObjectLockConfigurationOutput' => [ 'type' => 'structure', 'members' => [ 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'PutObjectLockConfigurationRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ObjectLockConfiguration' => [ 'shape' => 'ObjectLockConfiguration', 'locationName' => 'ObjectLockConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'Token' => [ 'shape' => 'ObjectLockToken', 'location' => 'header', 'locationName' => 'x-amz-bucket-object-lock-token', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], ], 'payload' => 'ObjectLockConfiguration', ], 'PutObjectOutput' => [ 'type' => 'structure', 'members' => [ 'Expiration' => [ 'shape' => 'Expiration', 'location' => 'header', 'locationName' => 'x-amz-expiration', ], 'ETag' => [ 'shape' => 'ETag', 'location' => 'header', 'locationName' => 'ETag', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'PutObjectRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'ACL' => [ 'shape' => 'ObjectCannedACL', 'location' => 'header', 'locationName' => 'x-amz-acl', ], 'Body' => [ 'shape' => 'Body', 'streaming' => true, ], 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'CacheControl' => [ 'shape' => 'CacheControl', 'location' => 'header', 'locationName' => 'Cache-Control', ], 'ContentDisposition' => [ 'shape' => 'ContentDisposition', 'location' => 'header', 'locationName' => 'Content-Disposition', ], 'ContentEncoding' => [ 'shape' => 'ContentEncoding', 'location' => 'header', 'locationName' => 'Content-Encoding', ], 'ContentLanguage' => [ 'shape' => 'ContentLanguage', 'location' => 'header', 'locationName' => 'Content-Language', ], 'ContentLength' => [ 'shape' => 'ContentLength', 'location' => 'header', 'locationName' => 'Content-Length', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'ContentType' => [ 'shape' => 'ContentType', 'location' => 'header', 'locationName' => 'Content-Type', ], 'Expires' => [ 'shape' => 'Expires', 'location' => 'header', 'locationName' => 'Expires', ], 'GrantFullControl' => [ 'shape' => 'GrantFullControl', 'location' => 'header', 'locationName' => 'x-amz-grant-full-control', ], 'GrantRead' => [ 'shape' => 'GrantRead', 'location' => 'header', 'locationName' => 'x-amz-grant-read', ], 'GrantReadACP' => [ 'shape' => 'GrantReadACP', 'location' => 'header', 'locationName' => 'x-amz-grant-read-acp', ], 'GrantWriteACP' => [ 'shape' => 'GrantWriteACP', 'location' => 'header', 'locationName' => 'x-amz-grant-write-acp', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'Metadata' => [ 'shape' => 'Metadata', 'location' => 'headers', 'locationName' => 'x-amz-meta-', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'StorageClass' => [ 'shape' => 'StorageClass', 'location' => 'header', 'locationName' => 'x-amz-storage-class', ], 'WebsiteRedirectLocation' => [ 'shape' => 'WebsiteRedirectLocation', 'location' => 'header', 'locationName' => 'x-amz-website-redirect-location', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKey' => [ 'shape' => 'SSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'Tagging' => [ 'shape' => 'TaggingHeader', 'location' => 'header', 'locationName' => 'x-amz-tagging', ], 'ObjectLockMode' => [ 'shape' => 'ObjectLockMode', 'location' => 'header', 'locationName' => 'x-amz-object-lock-mode', ], 'ObjectLockRetainUntilDate' => [ 'shape' => 'ObjectLockRetainUntilDate', 'location' => 'header', 'locationName' => 'x-amz-object-lock-retain-until-date', ], 'ObjectLockLegalHoldStatus' => [ 'shape' => 'ObjectLockLegalHoldStatus', 'location' => 'header', 'locationName' => 'x-amz-object-lock-legal-hold', ], ], 'payload' => 'Body', ], 'PutObjectRetentionOutput' => [ 'type' => 'structure', 'members' => [ 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'PutObjectRetentionRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'Retention' => [ 'shape' => 'ObjectLockRetention', 'locationName' => 'Retention', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'BypassGovernanceRetention' => [ 'shape' => 'BypassGovernanceRetention', 'location' => 'header', 'locationName' => 'x-amz-bypass-governance-retention', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], ], 'payload' => 'Retention', ], 'PutObjectTaggingOutput' => [ 'type' => 'structure', 'members' => [ 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'header', 'locationName' => 'x-amz-version-id', ], ], ], 'PutObjectTaggingRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', 'Tagging', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'Tagging' => [ 'shape' => 'Tagging', 'locationName' => 'Tagging', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'Tagging', ], 'PutPublicAccessBlockRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'PublicAccessBlockConfiguration', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'PublicAccessBlockConfiguration' => [ 'shape' => 'PublicAccessBlockConfiguration', 'locationName' => 'PublicAccessBlockConfiguration', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], ], 'payload' => 'PublicAccessBlockConfiguration', ], 'QueueArn' => [ 'type' => 'string', ], 'QueueConfiguration' => [ 'type' => 'structure', 'required' => [ 'QueueArn', 'Events', ], 'members' => [ 'Id' => [ 'shape' => 'NotificationId', ], 'QueueArn' => [ 'shape' => 'QueueArn', 'locationName' => 'Queue', ], 'Events' => [ 'shape' => 'EventList', 'locationName' => 'Event', ], 'Filter' => [ 'shape' => 'NotificationConfigurationFilter', ], ], ], 'QueueConfigurationDeprecated' => [ 'type' => 'structure', 'members' => [ 'Id' => [ 'shape' => 'NotificationId', ], 'Event' => [ 'shape' => 'Event', 'deprecated' => true, ], 'Events' => [ 'shape' => 'EventList', 'locationName' => 'Event', ], 'Queue' => [ 'shape' => 'QueueArn', ], ], ], 'QueueConfigurationList' => [ 'type' => 'list', 'member' => [ 'shape' => 'QueueConfiguration', ], 'flattened' => true, ], 'Quiet' => [ 'type' => 'boolean', ], 'QuoteCharacter' => [ 'type' => 'string', ], 'QuoteEscapeCharacter' => [ 'type' => 'string', ], 'QuoteFields' => [ 'type' => 'string', 'enum' => [ 'ALWAYS', 'ASNEEDED', ], ], 'Range' => [ 'type' => 'string', ], 'RecordDelimiter' => [ 'type' => 'string', ], 'RecordsEvent' => [ 'type' => 'structure', 'members' => [ 'Payload' => [ 'shape' => 'Body', 'eventpayload' => true, ], ], 'event' => true, ], 'Redirect' => [ 'type' => 'structure', 'members' => [ 'HostName' => [ 'shape' => 'HostName', ], 'HttpRedirectCode' => [ 'shape' => 'HttpRedirectCode', ], 'Protocol' => [ 'shape' => 'Protocol', ], 'ReplaceKeyPrefixWith' => [ 'shape' => 'ReplaceKeyPrefixWith', ], 'ReplaceKeyWith' => [ 'shape' => 'ReplaceKeyWith', ], ], ], 'RedirectAllRequestsTo' => [ 'type' => 'structure', 'required' => [ 'HostName', ], 'members' => [ 'HostName' => [ 'shape' => 'HostName', ], 'Protocol' => [ 'shape' => 'Protocol', ], ], ], 'ReplaceKeyPrefixWith' => [ 'type' => 'string', ], 'ReplaceKeyWith' => [ 'type' => 'string', ], 'ReplicaKmsKeyID' => [ 'type' => 'string', ], 'ReplicationConfiguration' => [ 'type' => 'structure', 'required' => [ 'Role', 'Rules', ], 'members' => [ 'Role' => [ 'shape' => 'Role', ], 'Rules' => [ 'shape' => 'ReplicationRules', 'locationName' => 'Rule', ], ], ], 'ReplicationRule' => [ 'type' => 'structure', 'required' => [ 'Status', 'Destination', ], 'members' => [ 'ID' => [ 'shape' => 'ID', ], 'Priority' => [ 'shape' => 'Priority', ], 'Prefix' => [ 'shape' => 'Prefix', 'deprecated' => true, ], 'Filter' => [ 'shape' => 'ReplicationRuleFilter', ], 'Status' => [ 'shape' => 'ReplicationRuleStatus', ], 'SourceSelectionCriteria' => [ 'shape' => 'SourceSelectionCriteria', ], 'Destination' => [ 'shape' => 'Destination', ], 'DeleteMarkerReplication' => [ 'shape' => 'DeleteMarkerReplication', ], ], ], 'ReplicationRuleAndOperator' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], 'Tags' => [ 'shape' => 'TagSet', 'flattened' => true, 'locationName' => 'Tag', ], ], ], 'ReplicationRuleFilter' => [ 'type' => 'structure', 'members' => [ 'Prefix' => [ 'shape' => 'Prefix', ], 'Tag' => [ 'shape' => 'Tag', ], 'And' => [ 'shape' => 'ReplicationRuleAndOperator', ], ], ], 'ReplicationRuleStatus' => [ 'type' => 'string', 'enum' => [ 'Enabled', 'Disabled', ], ], 'ReplicationRules' => [ 'type' => 'list', 'member' => [ 'shape' => 'ReplicationRule', ], 'flattened' => true, ], 'ReplicationStatus' => [ 'type' => 'string', 'enum' => [ 'COMPLETE', 'PENDING', 'FAILED', 'REPLICA', ], ], 'RequestCharged' => [ 'type' => 'string', 'enum' => [ 'requester', ], ], 'RequestPayer' => [ 'type' => 'string', 'enum' => [ 'requester', ], ], 'RequestPaymentConfiguration' => [ 'type' => 'structure', 'required' => [ 'Payer', ], 'members' => [ 'Payer' => [ 'shape' => 'Payer', ], ], ], 'RequestProgress' => [ 'type' => 'structure', 'members' => [ 'Enabled' => [ 'shape' => 'EnableRequestProgress', ], ], ], 'ResponseCacheControl' => [ 'type' => 'string', ], 'ResponseContentDisposition' => [ 'type' => 'string', ], 'ResponseContentEncoding' => [ 'type' => 'string', ], 'ResponseContentLanguage' => [ 'type' => 'string', ], 'ResponseContentType' => [ 'type' => 'string', ], 'ResponseExpires' => [ 'type' => 'timestamp', ], 'Restore' => [ 'type' => 'string', ], 'RestoreObjectOutput' => [ 'type' => 'structure', 'members' => [ 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], 'RestoreOutputPath' => [ 'shape' => 'RestoreOutputPath', 'location' => 'header', 'locationName' => 'x-amz-restore-output-path', ], ], ], 'RestoreObjectRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'VersionId' => [ 'shape' => 'ObjectVersionId', 'location' => 'querystring', 'locationName' => 'versionId', ], 'RestoreRequest' => [ 'shape' => 'RestoreRequest', 'locationName' => 'RestoreRequest', 'xmlNamespace' => [ 'uri' => 'http://s3.amazonaws.com/doc/2006-03-01/', ], ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], 'payload' => 'RestoreRequest', ], 'RestoreOutputPath' => [ 'type' => 'string', ], 'RestoreRequest' => [ 'type' => 'structure', 'members' => [ 'Days' => [ 'shape' => 'Days', ], 'GlacierJobParameters' => [ 'shape' => 'GlacierJobParameters', ], 'Type' => [ 'shape' => 'RestoreRequestType', ], 'Tier' => [ 'shape' => 'Tier', ], 'Description' => [ 'shape' => 'Description', ], 'SelectParameters' => [ 'shape' => 'SelectParameters', ], 'OutputLocation' => [ 'shape' => 'OutputLocation', ], ], ], 'RestoreRequestType' => [ 'type' => 'string', 'enum' => [ 'SELECT', ], ], 'Role' => [ 'type' => 'string', ], 'RoutingRule' => [ 'type' => 'structure', 'required' => [ 'Redirect', ], 'members' => [ 'Condition' => [ 'shape' => 'Condition', ], 'Redirect' => [ 'shape' => 'Redirect', ], ], ], 'RoutingRules' => [ 'type' => 'list', 'member' => [ 'shape' => 'RoutingRule', 'locationName' => 'RoutingRule', ], ], 'Rule' => [ 'type' => 'structure', 'required' => [ 'Prefix', 'Status', ], 'members' => [ 'Expiration' => [ 'shape' => 'LifecycleExpiration', ], 'ID' => [ 'shape' => 'ID', ], 'Prefix' => [ 'shape' => 'Prefix', ], 'Status' => [ 'shape' => 'ExpirationStatus', ], 'Transition' => [ 'shape' => 'Transition', ], 'NoncurrentVersionTransition' => [ 'shape' => 'NoncurrentVersionTransition', ], 'NoncurrentVersionExpiration' => [ 'shape' => 'NoncurrentVersionExpiration', ], 'AbortIncompleteMultipartUpload' => [ 'shape' => 'AbortIncompleteMultipartUpload', ], ], ], 'Rules' => [ 'type' => 'list', 'member' => [ 'shape' => 'Rule', ], 'flattened' => true, ], 'S3KeyFilter' => [ 'type' => 'structure', 'members' => [ 'FilterRules' => [ 'shape' => 'FilterRuleList', 'locationName' => 'FilterRule', ], ], ], 'S3Location' => [ 'type' => 'structure', 'required' => [ 'BucketName', 'Prefix', ], 'members' => [ 'BucketName' => [ 'shape' => 'BucketName', ], 'Prefix' => [ 'shape' => 'LocationPrefix', ], 'Encryption' => [ 'shape' => 'Encryption', ], 'CannedACL' => [ 'shape' => 'ObjectCannedACL', ], 'AccessControlList' => [ 'shape' => 'Grants', ], 'Tagging' => [ 'shape' => 'Tagging', ], 'UserMetadata' => [ 'shape' => 'UserMetadata', ], 'StorageClass' => [ 'shape' => 'StorageClass', ], ], ], 'SSECustomerAlgorithm' => [ 'type' => 'string', ], 'SSECustomerKey' => [ 'type' => 'string', 'sensitive' => true, ], 'SSECustomerKeyMD5' => [ 'type' => 'string', ], 'SSEKMS' => [ 'type' => 'structure', 'required' => [ 'KeyId', ], 'members' => [ 'KeyId' => [ 'shape' => 'SSEKMSKeyId', ], ], 'locationName' => 'SSE-KMS', ], 'SSEKMSKeyId' => [ 'type' => 'string', 'sensitive' => true, ], 'SSES3' => [ 'type' => 'structure', 'members' => [], 'locationName' => 'SSE-S3', ], 'SelectObjectContentEventStream' => [ 'type' => 'structure', 'members' => [ 'Records' => [ 'shape' => 'RecordsEvent', ], 'Stats' => [ 'shape' => 'StatsEvent', ], 'Progress' => [ 'shape' => 'ProgressEvent', ], 'Cont' => [ 'shape' => 'ContinuationEvent', ], 'End' => [ 'shape' => 'EndEvent', ], ], 'eventstream' => true, ], 'SelectObjectContentOutput' => [ 'type' => 'structure', 'members' => [ 'Payload' => [ 'shape' => 'SelectObjectContentEventStream', ], ], 'payload' => 'Payload', ], 'SelectObjectContentRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', 'Expression', 'ExpressionType', 'InputSerialization', 'OutputSerialization', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKey' => [ 'shape' => 'SSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'Expression' => [ 'shape' => 'Expression', ], 'ExpressionType' => [ 'shape' => 'ExpressionType', ], 'RequestProgress' => [ 'shape' => 'RequestProgress', ], 'InputSerialization' => [ 'shape' => 'InputSerialization', ], 'OutputSerialization' => [ 'shape' => 'OutputSerialization', ], ], ], 'SelectParameters' => [ 'type' => 'structure', 'required' => [ 'InputSerialization', 'ExpressionType', 'Expression', 'OutputSerialization', ], 'members' => [ 'InputSerialization' => [ 'shape' => 'InputSerialization', ], 'ExpressionType' => [ 'shape' => 'ExpressionType', ], 'Expression' => [ 'shape' => 'Expression', ], 'OutputSerialization' => [ 'shape' => 'OutputSerialization', ], ], ], 'ServerSideEncryption' => [ 'type' => 'string', 'enum' => [ 'AES256', 'aws:kms', ], ], 'ServerSideEncryptionByDefault' => [ 'type' => 'structure', 'required' => [ 'SSEAlgorithm', ], 'members' => [ 'SSEAlgorithm' => [ 'shape' => 'ServerSideEncryption', ], 'KMSMasterKeyID' => [ 'shape' => 'SSEKMSKeyId', ], ], ], 'ServerSideEncryptionConfiguration' => [ 'type' => 'structure', 'required' => [ 'Rules', ], 'members' => [ 'Rules' => [ 'shape' => 'ServerSideEncryptionRules', 'locationName' => 'Rule', ], ], ], 'ServerSideEncryptionRule' => [ 'type' => 'structure', 'members' => [ 'ApplyServerSideEncryptionByDefault' => [ 'shape' => 'ServerSideEncryptionByDefault', ], ], ], 'ServerSideEncryptionRules' => [ 'type' => 'list', 'member' => [ 'shape' => 'ServerSideEncryptionRule', ], 'flattened' => true, ], 'Setting' => [ 'type' => 'boolean', ], 'Size' => [ 'type' => 'long', ], 'SourceSelectionCriteria' => [ 'type' => 'structure', 'members' => [ 'SseKmsEncryptedObjects' => [ 'shape' => 'SseKmsEncryptedObjects', ], ], ], 'SseKmsEncryptedObjects' => [ 'type' => 'structure', 'required' => [ 'Status', ], 'members' => [ 'Status' => [ 'shape' => 'SseKmsEncryptedObjectsStatus', ], ], ], 'SseKmsEncryptedObjectsStatus' => [ 'type' => 'string', 'enum' => [ 'Enabled', 'Disabled', ], ], 'StartAfter' => [ 'type' => 'string', ], 'Stats' => [ 'type' => 'structure', 'members' => [ 'BytesScanned' => [ 'shape' => 'BytesScanned', ], 'BytesProcessed' => [ 'shape' => 'BytesProcessed', ], 'BytesReturned' => [ 'shape' => 'BytesReturned', ], ], ], 'StatsEvent' => [ 'type' => 'structure', 'members' => [ 'Details' => [ 'shape' => 'Stats', 'eventpayload' => true, ], ], 'event' => true, ], 'StorageClass' => [ 'type' => 'string', 'enum' => [ 'STANDARD', 'REDUCED_REDUNDANCY', 'STANDARD_IA', 'ONEZONE_IA', 'INTELLIGENT_TIERING', 'GLACIER', 'DEEP_ARCHIVE', ], ], 'StorageClassAnalysis' => [ 'type' => 'structure', 'members' => [ 'DataExport' => [ 'shape' => 'StorageClassAnalysisDataExport', ], ], ], 'StorageClassAnalysisDataExport' => [ 'type' => 'structure', 'required' => [ 'OutputSchemaVersion', 'Destination', ], 'members' => [ 'OutputSchemaVersion' => [ 'shape' => 'StorageClassAnalysisSchemaVersion', ], 'Destination' => [ 'shape' => 'AnalyticsExportDestination', ], ], ], 'StorageClassAnalysisSchemaVersion' => [ 'type' => 'string', 'enum' => [ 'V_1', ], ], 'Suffix' => [ 'type' => 'string', ], 'Tag' => [ 'type' => 'structure', 'required' => [ 'Key', 'Value', ], 'members' => [ 'Key' => [ 'shape' => 'ObjectKey', ], 'Value' => [ 'shape' => 'Value', ], ], ], 'TagCount' => [ 'type' => 'integer', ], 'TagSet' => [ 'type' => 'list', 'member' => [ 'shape' => 'Tag', 'locationName' => 'Tag', ], ], 'Tagging' => [ 'type' => 'structure', 'required' => [ 'TagSet', ], 'members' => [ 'TagSet' => [ 'shape' => 'TagSet', ], ], ], 'TaggingDirective' => [ 'type' => 'string', 'enum' => [ 'COPY', 'REPLACE', ], ], 'TaggingHeader' => [ 'type' => 'string', ], 'TargetBucket' => [ 'type' => 'string', ], 'TargetGrant' => [ 'type' => 'structure', 'members' => [ 'Grantee' => [ 'shape' => 'Grantee', ], 'Permission' => [ 'shape' => 'BucketLogsPermission', ], ], ], 'TargetGrants' => [ 'type' => 'list', 'member' => [ 'shape' => 'TargetGrant', 'locationName' => 'Grant', ], ], 'TargetPrefix' => [ 'type' => 'string', ], 'Tier' => [ 'type' => 'string', 'enum' => [ 'Standard', 'Bulk', 'Expedited', ], ], 'Token' => [ 'type' => 'string', ], 'TopicArn' => [ 'type' => 'string', ], 'TopicConfiguration' => [ 'type' => 'structure', 'required' => [ 'TopicArn', 'Events', ], 'members' => [ 'Id' => [ 'shape' => 'NotificationId', ], 'TopicArn' => [ 'shape' => 'TopicArn', 'locationName' => 'Topic', ], 'Events' => [ 'shape' => 'EventList', 'locationName' => 'Event', ], 'Filter' => [ 'shape' => 'NotificationConfigurationFilter', ], ], ], 'TopicConfigurationDeprecated' => [ 'type' => 'structure', 'members' => [ 'Id' => [ 'shape' => 'NotificationId', ], 'Events' => [ 'shape' => 'EventList', 'locationName' => 'Event', ], 'Event' => [ 'shape' => 'Event', 'deprecated' => true, ], 'Topic' => [ 'shape' => 'TopicArn', ], ], ], 'TopicConfigurationList' => [ 'type' => 'list', 'member' => [ 'shape' => 'TopicConfiguration', ], 'flattened' => true, ], 'Transition' => [ 'type' => 'structure', 'members' => [ 'Date' => [ 'shape' => 'Date', ], 'Days' => [ 'shape' => 'Days', ], 'StorageClass' => [ 'shape' => 'TransitionStorageClass', ], ], ], 'TransitionList' => [ 'type' => 'list', 'member' => [ 'shape' => 'Transition', ], 'flattened' => true, ], 'TransitionStorageClass' => [ 'type' => 'string', 'enum' => [ 'GLACIER', 'STANDARD_IA', 'ONEZONE_IA', 'INTELLIGENT_TIERING', 'DEEP_ARCHIVE', ], ], 'Type' => [ 'type' => 'string', 'enum' => [ 'CanonicalUser', 'AmazonCustomerByEmail', 'Group', ], ], 'URI' => [ 'type' => 'string', ], 'UploadIdMarker' => [ 'type' => 'string', ], 'UploadPartCopyOutput' => [ 'type' => 'structure', 'members' => [ 'CopySourceVersionId' => [ 'shape' => 'CopySourceVersionId', 'location' => 'header', 'locationName' => 'x-amz-copy-source-version-id', ], 'CopyPartResult' => [ 'shape' => 'CopyPartResult', ], 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], 'payload' => 'CopyPartResult', ], 'UploadPartCopyRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'CopySource', 'Key', 'PartNumber', 'UploadId', ], 'members' => [ 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'CopySource' => [ 'shape' => 'CopySource', 'location' => 'header', 'locationName' => 'x-amz-copy-source', ], 'CopySourceIfMatch' => [ 'shape' => 'CopySourceIfMatch', 'location' => 'header', 'locationName' => 'x-amz-copy-source-if-match', ], 'CopySourceIfModifiedSince' => [ 'shape' => 'CopySourceIfModifiedSince', 'location' => 'header', 'locationName' => 'x-amz-copy-source-if-modified-since', ], 'CopySourceIfNoneMatch' => [ 'shape' => 'CopySourceIfNoneMatch', 'location' => 'header', 'locationName' => 'x-amz-copy-source-if-none-match', ], 'CopySourceIfUnmodifiedSince' => [ 'shape' => 'CopySourceIfUnmodifiedSince', 'location' => 'header', 'locationName' => 'x-amz-copy-source-if-unmodified-since', ], 'CopySourceRange' => [ 'shape' => 'CopySourceRange', 'location' => 'header', 'locationName' => 'x-amz-copy-source-range', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'PartNumber' => [ 'shape' => 'PartNumber', 'location' => 'querystring', 'locationName' => 'partNumber', ], 'UploadId' => [ 'shape' => 'MultipartUploadId', 'location' => 'querystring', 'locationName' => 'uploadId', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKey' => [ 'shape' => 'SSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'CopySourceSSECustomerAlgorithm' => [ 'shape' => 'CopySourceSSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-copy-source-server-side-encryption-customer-algorithm', ], 'CopySourceSSECustomerKey' => [ 'shape' => 'CopySourceSSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-copy-source-server-side-encryption-customer-key', ], 'CopySourceSSECustomerKeyMD5' => [ 'shape' => 'CopySourceSSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-copy-source-server-side-encryption-customer-key-MD5', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], ], 'UploadPartOutput' => [ 'type' => 'structure', 'members' => [ 'ServerSideEncryption' => [ 'shape' => 'ServerSideEncryption', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption', ], 'ETag' => [ 'shape' => 'ETag', 'location' => 'header', 'locationName' => 'ETag', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'SSEKMSKeyId' => [ 'shape' => 'SSEKMSKeyId', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-aws-kms-key-id', ], 'RequestCharged' => [ 'shape' => 'RequestCharged', 'location' => 'header', 'locationName' => 'x-amz-request-charged', ], ], ], 'UploadPartRequest' => [ 'type' => 'structure', 'required' => [ 'Bucket', 'Key', 'PartNumber', 'UploadId', ], 'members' => [ 'Body' => [ 'shape' => 'Body', 'streaming' => true, ], 'Bucket' => [ 'shape' => 'BucketName', 'location' => 'uri', 'locationName' => 'Bucket', ], 'ContentLength' => [ 'shape' => 'ContentLength', 'location' => 'header', 'locationName' => 'Content-Length', ], 'ContentMD5' => [ 'shape' => 'ContentMD5', 'location' => 'header', 'locationName' => 'Content-MD5', ], 'Key' => [ 'shape' => 'ObjectKey', 'location' => 'uri', 'locationName' => 'Key', ], 'PartNumber' => [ 'shape' => 'PartNumber', 'location' => 'querystring', 'locationName' => 'partNumber', ], 'UploadId' => [ 'shape' => 'MultipartUploadId', 'location' => 'querystring', 'locationName' => 'uploadId', ], 'SSECustomerAlgorithm' => [ 'shape' => 'SSECustomerAlgorithm', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-algorithm', ], 'SSECustomerKey' => [ 'shape' => 'SSECustomerKey', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key', ], 'SSECustomerKeyMD5' => [ 'shape' => 'SSECustomerKeyMD5', 'location' => 'header', 'locationName' => 'x-amz-server-side-encryption-customer-key-MD5', ], 'RequestPayer' => [ 'shape' => 'RequestPayer', 'location' => 'header', 'locationName' => 'x-amz-request-payer', ], ], 'payload' => 'Body', ], 'UserMetadata' => [ 'type' => 'list', 'member' => [ 'shape' => 'MetadataEntry', 'locationName' => 'MetadataEntry', ], ], 'Value' => [ 'type' => 'string', ], 'VersionIdMarker' => [ 'type' => 'string', ], 'VersioningConfiguration' => [ 'type' => 'structure', 'members' => [ 'MFADelete' => [ 'shape' => 'MFADelete', 'locationName' => 'MfaDelete', ], 'Status' => [ 'shape' => 'BucketVersioningStatus', ], ], ], 'WebsiteConfiguration' => [ 'type' => 'structure', 'members' => [ 'ErrorDocument' => [ 'shape' => 'ErrorDocument', ], 'IndexDocument' => [ 'shape' => 'IndexDocument', ], 'RedirectAllRequestsTo' => [ 'shape' => 'RedirectAllRequestsTo', ], 'RoutingRules' => [ 'shape' => 'RoutingRules', ], ], ], 'WebsiteRedirectLocation' => [ 'type' => 'string', ], 'Years' => [ 'type' => 'integer', ], ],];
|
|
|
|
|
|
lib/Aws/Aws/data/sns/2010-03-31/api-2.json.php
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// This file was auto-generated from sdk-root/src/data/sns/2010-03-31/api-2.json
|
3 |
-
return [ 'version' => '2.0', 'metadata' => [ 'apiVersion' => '2010-03-31', 'endpointPrefix' => 'sns', 'protocol' => 'query', 'serviceAbbreviation' => 'Amazon SNS', 'serviceFullName' => 'Amazon Simple Notification Service', 'serviceId' => 'SNS', 'signatureVersion' => 'v4', 'uid' => 'sns-2010-03-31', 'xmlNamespace' => 'http://sns.amazonaws.com/doc/2010-03-31/', ], 'operations' => [ 'AddPermission' => [ 'name' => 'AddPermission', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'AddPermissionInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], ], ], 'CheckIfPhoneNumberIsOptedOut' => [ 'name' => 'CheckIfPhoneNumberIsOptedOut', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'CheckIfPhoneNumberIsOptedOutInput', ], 'output' => [ 'shape' => 'CheckIfPhoneNumberIsOptedOutResponse', 'resultWrapper' => 'CheckIfPhoneNumberIsOptedOutResult', ], 'errors' => [ [ 'shape' => 'ThrottledException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'InvalidParameterException', ], ], ], 'ConfirmSubscription' => [ 'name' => 'ConfirmSubscription', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'ConfirmSubscriptionInput', ], 'output' => [ 'shape' => 'ConfirmSubscriptionResponse', 'resultWrapper' => 'ConfirmSubscriptionResult', ], 'errors' => [ [ 'shape' => 'SubscriptionLimitExceededException', ], [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'FilterPolicyLimitExceededException', ], ], ], 'CreatePlatformApplication' => [ 'name' => 'CreatePlatformApplication', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'CreatePlatformApplicationInput', ], 'output' => [ 'shape' => 'CreatePlatformApplicationResponse', 'resultWrapper' => 'CreatePlatformApplicationResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'CreatePlatformEndpoint' => [ 'name' => 'CreatePlatformEndpoint', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'CreatePlatformEndpointInput', ], 'output' => [ 'shape' => 'CreateEndpointResponse', 'resultWrapper' => 'CreatePlatformEndpointResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], ], ], 'CreateTopic' => [ 'name' => 'CreateTopic', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'CreateTopicInput', ], 'output' => [ 'shape' => 'CreateTopicResponse', 'resultWrapper' => 'CreateTopicResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'TopicLimitExceededException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'InvalidSecurityException', ], [ 'shape' => 'TagLimitExceededException', ], [ 'shape' => 'StaleTagException', ], [ 'shape' => 'TagPolicyException', ], [ 'shape' => 'ConcurrentAccessException', ], ], ], 'DeleteEndpoint' => [ 'name' => 'DeleteEndpoint', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'DeleteEndpointInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'DeletePlatformApplication' => [ 'name' => 'DeletePlatformApplication', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'DeletePlatformApplicationInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'DeleteTopic' => [ 'name' => 'DeleteTopic', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'DeleteTopicInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'StaleTagException', ], [ 'shape' => 'TagPolicyException', ], [ 'shape' => 'ConcurrentAccessException', ], ], ], 'GetEndpointAttributes' => [ 'name' => 'GetEndpointAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'GetEndpointAttributesInput', ], 'output' => [ 'shape' => 'GetEndpointAttributesResponse', 'resultWrapper' => 'GetEndpointAttributesResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], ], ], 'GetPlatformApplicationAttributes' => [ 'name' => 'GetPlatformApplicationAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'GetPlatformApplicationAttributesInput', ], 'output' => [ 'shape' => 'GetPlatformApplicationAttributesResponse', 'resultWrapper' => 'GetPlatformApplicationAttributesResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], ], ], 'GetSMSAttributes' => [ 'name' => 'GetSMSAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'GetSMSAttributesInput', ], 'output' => [ 'shape' => 'GetSMSAttributesResponse', 'resultWrapper' => 'GetSMSAttributesResult', ], 'errors' => [ [ 'shape' => 'ThrottledException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'InvalidParameterException', ], ], ], 'GetSubscriptionAttributes' => [ 'name' => 'GetSubscriptionAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'GetSubscriptionAttributesInput', ], 'output' => [ 'shape' => 'GetSubscriptionAttributesResponse', 'resultWrapper' => 'GetSubscriptionAttributesResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'GetTopicAttributes' => [ 'name' => 'GetTopicAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'GetTopicAttributesInput', ], 'output' => [ 'shape' => 'GetTopicAttributesResponse', 'resultWrapper' => 'GetTopicAttributesResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'InvalidSecurityException', ], ], ], 'ListEndpointsByPlatformApplication' => [ 'name' => 'ListEndpointsByPlatformApplication', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'ListEndpointsByPlatformApplicationInput', ], 'output' => [ 'shape' => 'ListEndpointsByPlatformApplicationResponse', 'resultWrapper' => 'ListEndpointsByPlatformApplicationResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], ], ], 'ListPhoneNumbersOptedOut' => [ 'name' => 'ListPhoneNumbersOptedOut', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'ListPhoneNumbersOptedOutInput', ], 'output' => [ 'shape' => 'ListPhoneNumbersOptedOutResponse', 'resultWrapper' => 'ListPhoneNumbersOptedOutResult', ], 'errors' => [ [ 'shape' => 'ThrottledException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'InvalidParameterException', ], ], ], 'ListPlatformApplications' => [ 'name' => 'ListPlatformApplications', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'ListPlatformApplicationsInput', ], 'output' => [ 'shape' => 'ListPlatformApplicationsResponse', 'resultWrapper' => 'ListPlatformApplicationsResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'ListSubscriptions' => [ 'name' => 'ListSubscriptions', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'ListSubscriptionsInput', ], 'output' => [ 'shape' => 'ListSubscriptionsResponse', 'resultWrapper' => 'ListSubscriptionsResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'ListSubscriptionsByTopic' => [ 'name' => 'ListSubscriptionsByTopic', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'ListSubscriptionsByTopicInput', ], 'output' => [ 'shape' => 'ListSubscriptionsByTopicResponse', 'resultWrapper' => 'ListSubscriptionsByTopicResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'ListTagsForResource' => [ 'name' => 'ListTagsForResource', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'ListTagsForResourceRequest', ], 'output' => [ 'shape' => 'ListTagsForResourceResponse', 'resultWrapper' => 'ListTagsForResourceResult', ], 'errors' => [ [ 'shape' => 'ResourceNotFoundException', ], [ 'shape' => 'TagPolicyException', ], [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'ConcurrentAccessException', ], ], ], 'ListTopics' => [ 'name' => 'ListTopics', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'ListTopicsInput', ], 'output' => [ 'shape' => 'ListTopicsResponse', 'resultWrapper' => 'ListTopicsResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'OptInPhoneNumber' => [ 'name' => 'OptInPhoneNumber', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'OptInPhoneNumberInput', ], 'output' => [ 'shape' => 'OptInPhoneNumberResponse', 'resultWrapper' => 'OptInPhoneNumberResult', ], 'errors' => [ [ 'shape' => 'ThrottledException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'InvalidParameterException', ], ], ], 'Publish' => [ 'name' => 'Publish', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'PublishInput', ], 'output' => [ 'shape' => 'PublishResponse', 'resultWrapper' => 'PublishResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InvalidParameterValueException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'EndpointDisabledException', ], [ 'shape' => 'PlatformApplicationDisabledException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'KMSDisabledException', ], [ 'shape' => 'KMSInvalidStateException', ], [ 'shape' => 'KMSNotFoundException', ], [ 'shape' => 'KMSOptInRequired', ], [ 'shape' => 'KMSThrottlingException', ], [ 'shape' => 'KMSAccessDeniedException', ], [ 'shape' => 'InvalidSecurityException', ], ], ], 'RemovePermission' => [ 'name' => 'RemovePermission', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'RemovePermissionInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], ], ], 'SetEndpointAttributes' => [ 'name' => 'SetEndpointAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'SetEndpointAttributesInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], ], ], 'SetPlatformApplicationAttributes' => [ 'name' => 'SetPlatformApplicationAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'SetPlatformApplicationAttributesInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], ], ], 'SetSMSAttributes' => [ 'name' => 'SetSMSAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'SetSMSAttributesInput', ], 'output' => [ 'shape' => 'SetSMSAttributesResponse', 'resultWrapper' => 'SetSMSAttributesResult', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'ThrottledException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'SetSubscriptionAttributes' => [ 'name' => 'SetSubscriptionAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'SetSubscriptionAttributesInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'FilterPolicyLimitExceededException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'AuthorizationErrorException', ], ], ], 'SetTopicAttributes' => [ 'name' => 'SetTopicAttributes', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'SetTopicAttributesInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'InvalidSecurityException', ], ], ], 'Subscribe' => [ 'name' => 'Subscribe', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'SubscribeInput', ], 'output' => [ 'shape' => 'SubscribeResponse', 'resultWrapper' => 'SubscribeResult', ], 'errors' => [ [ 'shape' => 'SubscriptionLimitExceededException', ], [ 'shape' => 'FilterPolicyLimitExceededException', ], [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'InvalidSecurityException', ], ], ], 'TagResource' => [ 'name' => 'TagResource', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'TagResourceRequest', ], 'output' => [ 'shape' => 'TagResourceResponse', 'resultWrapper' => 'TagResourceResult', ], 'errors' => [ [ 'shape' => 'ResourceNotFoundException', ], [ 'shape' => 'TagLimitExceededException', ], [ 'shape' => 'StaleTagException', ], [ 'shape' => 'TagPolicyException', ], [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'ConcurrentAccessException', ], ], ], 'Unsubscribe' => [ 'name' => 'Unsubscribe', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'UnsubscribeInput', ], 'errors' => [ [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'InternalErrorException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'NotFoundException', ], [ 'shape' => 'InvalidSecurityException', ], ], ], 'UntagResource' => [ 'name' => 'UntagResource', 'http' => [ 'method' => 'POST', 'requestUri' => '/', ], 'input' => [ 'shape' => 'UntagResourceRequest', ], 'output' => [ 'shape' => 'UntagResourceResponse', 'resultWrapper' => 'UntagResourceResult', ], 'errors' => [ [ 'shape' => 'ResourceNotFoundException', ], [ 'shape' => 'TagLimitExceededException', ], [ 'shape' => 'StaleTagException', ], [ 'shape' => 'TagPolicyException', ], [ 'shape' => 'InvalidParameterException', ], [ 'shape' => 'AuthorizationErrorException', ], [ 'shape' => 'ConcurrentAccessException', ], ], ], ], 'shapes' => [ 'ActionsList' => [ 'type' => 'list', 'member' => [ 'shape' => 'action', ], ], 'AddPermissionInput' => [ 'type' => 'structure', 'required' => [ 'TopicArn', 'Label', 'AWSAccountId', 'ActionName', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], 'Label' => [ 'shape' => 'label', ], 'AWSAccountId' => [ 'shape' => 'DelegatesList', ], 'ActionName' => [ 'shape' => 'ActionsList', ], ], ], 'AmazonResourceName' => [ 'type' => 'string', 'max' => 1011, 'min' => 1, ], 'AuthorizationErrorException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'AuthorizationError', 'httpStatusCode' => 403, 'senderFault' => true, ], 'exception' => true, ], 'Binary' => [ 'type' => 'blob', ], 'CheckIfPhoneNumberIsOptedOutInput' => [ 'type' => 'structure', 'required' => [ 'phoneNumber', ], 'members' => [ 'phoneNumber' => [ 'shape' => 'PhoneNumber', ], ], ], 'CheckIfPhoneNumberIsOptedOutResponse' => [ 'type' => 'structure', 'members' => [ 'isOptedOut' => [ 'shape' => 'boolean', ], ], ], 'ConcurrentAccessException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'ConcurrentAccess', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'ConfirmSubscriptionInput' => [ 'type' => 'structure', 'required' => [ 'TopicArn', 'Token', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], 'Token' => [ 'shape' => 'token', ], 'AuthenticateOnUnsubscribe' => [ 'shape' => 'authenticateOnUnsubscribe', ], ], ], 'ConfirmSubscriptionResponse' => [ 'type' => 'structure', 'members' => [ 'SubscriptionArn' => [ 'shape' => 'subscriptionARN', ], ], ], 'CreateEndpointResponse' => [ 'type' => 'structure', 'members' => [ 'EndpointArn' => [ 'shape' => 'String', ], ], ], 'CreatePlatformApplicationInput' => [ 'type' => 'structure', 'required' => [ 'Name', 'Platform', 'Attributes', ], 'members' => [ 'Name' => [ 'shape' => 'String', ], 'Platform' => [ 'shape' => 'String', ], 'Attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'CreatePlatformApplicationResponse' => [ 'type' => 'structure', 'members' => [ 'PlatformApplicationArn' => [ 'shape' => 'String', ], ], ], 'CreatePlatformEndpointInput' => [ 'type' => 'structure', 'required' => [ 'PlatformApplicationArn', 'Token', ], 'members' => [ 'PlatformApplicationArn' => [ 'shape' => 'String', ], 'Token' => [ 'shape' => 'String', ], 'CustomUserData' => [ 'shape' => 'String', ], 'Attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'CreateTopicInput' => [ 'type' => 'structure', 'required' => [ 'Name', ], 'members' => [ 'Name' => [ 'shape' => 'topicName', ], 'Attributes' => [ 'shape' => 'TopicAttributesMap', ], 'Tags' => [ 'shape' => 'TagList', ], ], ], 'CreateTopicResponse' => [ 'type' => 'structure', 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], ], ], 'DelegatesList' => [ 'type' => 'list', 'member' => [ 'shape' => 'delegate', ], ], 'DeleteEndpointInput' => [ 'type' => 'structure', 'required' => [ 'EndpointArn', ], 'members' => [ 'EndpointArn' => [ 'shape' => 'String', ], ], ], 'DeletePlatformApplicationInput' => [ 'type' => 'structure', 'required' => [ 'PlatformApplicationArn', ], 'members' => [ 'PlatformApplicationArn' => [ 'shape' => 'String', ], ], ], 'DeleteTopicInput' => [ 'type' => 'structure', 'required' => [ 'TopicArn', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], ], ], 'Endpoint' => [ 'type' => 'structure', 'members' => [ 'EndpointArn' => [ 'shape' => 'String', ], 'Attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'EndpointDisabledException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'EndpointDisabled', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'FilterPolicyLimitExceededException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'FilterPolicyLimitExceeded', 'httpStatusCode' => 403, 'senderFault' => true, ], 'exception' => true, ], 'GetEndpointAttributesInput' => [ 'type' => 'structure', 'required' => [ 'EndpointArn', ], 'members' => [ 'EndpointArn' => [ 'shape' => 'String', ], ], ], 'GetEndpointAttributesResponse' => [ 'type' => 'structure', 'members' => [ 'Attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'GetPlatformApplicationAttributesInput' => [ 'type' => 'structure', 'required' => [ 'PlatformApplicationArn', ], 'members' => [ 'PlatformApplicationArn' => [ 'shape' => 'String', ], ], ], 'GetPlatformApplicationAttributesResponse' => [ 'type' => 'structure', 'members' => [ 'Attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'GetSMSAttributesInput' => [ 'type' => 'structure', 'members' => [ 'attributes' => [ 'shape' => 'ListString', ], ], ], 'GetSMSAttributesResponse' => [ 'type' => 'structure', 'members' => [ 'attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'GetSubscriptionAttributesInput' => [ 'type' => 'structure', 'required' => [ 'SubscriptionArn', ], 'members' => [ 'SubscriptionArn' => [ 'shape' => 'subscriptionARN', ], ], ], 'GetSubscriptionAttributesResponse' => [ 'type' => 'structure', 'members' => [ 'Attributes' => [ 'shape' => 'SubscriptionAttributesMap', ], ], ], 'GetTopicAttributesInput' => [ 'type' => 'structure', 'required' => [ 'TopicArn', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], ], ], 'GetTopicAttributesResponse' => [ 'type' => 'structure', 'members' => [ 'Attributes' => [ 'shape' => 'TopicAttributesMap', ], ], ], 'InternalErrorException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'InternalError', 'httpStatusCode' => 500, ], 'exception' => true, 'fault' => true, ], 'InvalidParameterException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'InvalidParameter', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'InvalidParameterValueException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'ParameterValueInvalid', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'InvalidSecurityException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'InvalidSecurity', 'httpStatusCode' => 403, 'senderFault' => true, ], 'exception' => true, ], 'KMSAccessDeniedException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'KMSAccessDenied', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'KMSDisabledException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'KMSDisabled', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'KMSInvalidStateException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'KMSInvalidState', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'KMSNotFoundException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'KMSNotFound', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'KMSOptInRequired' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'KMSOptInRequired', 'httpStatusCode' => 403, 'senderFault' => true, ], 'exception' => true, ], 'KMSThrottlingException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'KMSThrottling', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'ListEndpointsByPlatformApplicationInput' => [ 'type' => 'structure', 'required' => [ 'PlatformApplicationArn', ], 'members' => [ 'PlatformApplicationArn' => [ 'shape' => 'String', ], 'NextToken' => [ 'shape' => 'String', ], ], ], 'ListEndpointsByPlatformApplicationResponse' => [ 'type' => 'structure', 'members' => [ 'Endpoints' => [ 'shape' => 'ListOfEndpoints', ], 'NextToken' => [ 'shape' => 'String', ], ], ], 'ListOfEndpoints' => [ 'type' => 'list', 'member' => [ 'shape' => 'Endpoint', ], ], 'ListOfPlatformApplications' => [ 'type' => 'list', 'member' => [ 'shape' => 'PlatformApplication', ], ], 'ListPhoneNumbersOptedOutInput' => [ 'type' => 'structure', 'members' => [ 'nextToken' => [ 'shape' => 'string', ], ], ], 'ListPhoneNumbersOptedOutResponse' => [ 'type' => 'structure', 'members' => [ 'phoneNumbers' => [ 'shape' => 'PhoneNumberList', ], 'nextToken' => [ 'shape' => 'string', ], ], ], 'ListPlatformApplicationsInput' => [ 'type' => 'structure', 'members' => [ 'NextToken' => [ 'shape' => 'String', ], ], ], 'ListPlatformApplicationsResponse' => [ 'type' => 'structure', 'members' => [ 'PlatformApplications' => [ 'shape' => 'ListOfPlatformApplications', ], 'NextToken' => [ 'shape' => 'String', ], ], ], 'ListString' => [ 'type' => 'list', 'member' => [ 'shape' => 'String', ], ], 'ListSubscriptionsByTopicInput' => [ 'type' => 'structure', 'required' => [ 'TopicArn', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], 'NextToken' => [ 'shape' => 'nextToken', ], ], ], 'ListSubscriptionsByTopicResponse' => [ 'type' => 'structure', 'members' => [ 'Subscriptions' => [ 'shape' => 'SubscriptionsList', ], 'NextToken' => [ 'shape' => 'nextToken', ], ], ], 'ListSubscriptionsInput' => [ 'type' => 'structure', 'members' => [ 'NextToken' => [ 'shape' => 'nextToken', ], ], ], 'ListSubscriptionsResponse' => [ 'type' => 'structure', 'members' => [ 'Subscriptions' => [ 'shape' => 'SubscriptionsList', ], 'NextToken' => [ 'shape' => 'nextToken', ], ], ], 'ListTagsForResourceRequest' => [ 'type' => 'structure', 'required' => [ 'ResourceArn', ], 'members' => [ 'ResourceArn' => [ 'shape' => 'AmazonResourceName', ], ], ], 'ListTagsForResourceResponse' => [ 'type' => 'structure', 'members' => [ 'Tags' => [ 'shape' => 'TagList', ], ], ], 'ListTopicsInput' => [ 'type' => 'structure', 'members' => [ 'NextToken' => [ 'shape' => 'nextToken', ], ], ], 'ListTopicsResponse' => [ 'type' => 'structure', 'members' => [ 'Topics' => [ 'shape' => 'TopicsList', ], 'NextToken' => [ 'shape' => 'nextToken', ], ], ], 'MapStringToString' => [ 'type' => 'map', 'key' => [ 'shape' => 'String', ], 'value' => [ 'shape' => 'String', ], ], 'MessageAttributeMap' => [ 'type' => 'map', 'key' => [ 'shape' => 'String', 'locationName' => 'Name', ], 'value' => [ 'shape' => 'MessageAttributeValue', 'locationName' => 'Value', ], ], 'MessageAttributeValue' => [ 'type' => 'structure', 'required' => [ 'DataType', ], 'members' => [ 'DataType' => [ 'shape' => 'String', ], 'StringValue' => [ 'shape' => 'String', ], 'BinaryValue' => [ 'shape' => 'Binary', ], ], ], 'NotFoundException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'NotFound', 'httpStatusCode' => 404, 'senderFault' => true, ], 'exception' => true, ], 'OptInPhoneNumberInput' => [ 'type' => 'structure', 'required' => [ 'phoneNumber', ], 'members' => [ 'phoneNumber' => [ 'shape' => 'PhoneNumber', ], ], ], 'OptInPhoneNumberResponse' => [ 'type' => 'structure', 'members' => [], ], 'PhoneNumber' => [ 'type' => 'string', ], 'PhoneNumberList' => [ 'type' => 'list', 'member' => [ 'shape' => 'PhoneNumber', ], ], 'PlatformApplication' => [ 'type' => 'structure', 'members' => [ 'PlatformApplicationArn' => [ 'shape' => 'String', ], 'Attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'PlatformApplicationDisabledException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'PlatformApplicationDisabled', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'PublishInput' => [ 'type' => 'structure', 'required' => [ 'Message', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], 'TargetArn' => [ 'shape' => 'String', ], 'PhoneNumber' => [ 'shape' => 'String', ], 'Message' => [ 'shape' => 'message', ], 'Subject' => [ 'shape' => 'subject', ], 'MessageStructure' => [ 'shape' => 'messageStructure', ], 'MessageAttributes' => [ 'shape' => 'MessageAttributeMap', ], ], ], 'PublishResponse' => [ 'type' => 'structure', 'members' => [ 'MessageId' => [ 'shape' => 'messageId', ], ], ], 'RemovePermissionInput' => [ 'type' => 'structure', 'required' => [ 'TopicArn', 'Label', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], 'Label' => [ 'shape' => 'label', ], ], ], 'ResourceNotFoundException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'ResourceNotFound', 'httpStatusCode' => 404, 'senderFault' => true, ], 'exception' => true, ], 'SetEndpointAttributesInput' => [ 'type' => 'structure', 'required' => [ 'EndpointArn', 'Attributes', ], 'members' => [ 'EndpointArn' => [ 'shape' => 'String', ], 'Attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'SetPlatformApplicationAttributesInput' => [ 'type' => 'structure', 'required' => [ 'PlatformApplicationArn', 'Attributes', ], 'members' => [ 'PlatformApplicationArn' => [ 'shape' => 'String', ], 'Attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'SetSMSAttributesInput' => [ 'type' => 'structure', 'required' => [ 'attributes', ], 'members' => [ 'attributes' => [ 'shape' => 'MapStringToString', ], ], ], 'SetSMSAttributesResponse' => [ 'type' => 'structure', 'members' => [], ], 'SetSubscriptionAttributesInput' => [ 'type' => 'structure', 'required' => [ 'SubscriptionArn', 'AttributeName', ], 'members' => [ 'SubscriptionArn' => [ 'shape' => 'subscriptionARN', ], 'AttributeName' => [ 'shape' => 'attributeName', ], 'AttributeValue' => [ 'shape' => 'attributeValue', ], ], ], 'SetTopicAttributesInput' => [ 'type' => 'structure', 'required' => [ 'TopicArn', 'AttributeName', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], 'AttributeName' => [ 'shape' => 'attributeName', ], 'AttributeValue' => [ 'shape' => 'attributeValue', ], ], ], 'StaleTagException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'StaleTag', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'String' => [ 'type' => 'string', ], 'SubscribeInput' => [ 'type' => 'structure', 'required' => [ 'TopicArn', 'Protocol', ], 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], 'Protocol' => [ 'shape' => 'protocol', ], 'Endpoint' => [ 'shape' => 'endpoint', ], 'Attributes' => [ 'shape' => 'SubscriptionAttributesMap', ], 'ReturnSubscriptionArn' => [ 'shape' => 'boolean', ], ], ], 'SubscribeResponse' => [ 'type' => 'structure', 'members' => [ 'SubscriptionArn' => [ 'shape' => 'subscriptionARN', ], ], ], 'Subscription' => [ 'type' => 'structure', 'members' => [ 'SubscriptionArn' => [ 'shape' => 'subscriptionARN', ], 'Owner' => [ 'shape' => 'account', ], 'Protocol' => [ 'shape' => 'protocol', ], 'Endpoint' => [ 'shape' => 'endpoint', ], 'TopicArn' => [ 'shape' => 'topicARN', ], ], ], 'SubscriptionAttributesMap' => [ 'type' => 'map', 'key' => [ 'shape' => 'attributeName', ], 'value' => [ 'shape' => 'attributeValue', ], ], 'SubscriptionLimitExceededException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'SubscriptionLimitExceeded', 'httpStatusCode' => 403, 'senderFault' => true, ], 'exception' => true, ], 'SubscriptionsList' => [ 'type' => 'list', 'member' => [ 'shape' => 'Subscription', ], ], 'Tag' => [ 'type' => 'structure', 'required' => [ 'Key', 'Value', ], 'members' => [ 'Key' => [ 'shape' => 'TagKey', ], 'Value' => [ 'shape' => 'TagValue', ], ], ], 'TagKey' => [ 'type' => 'string', 'max' => 128, 'min' => 1, ], 'TagKeyList' => [ 'type' => 'list', 'member' => [ 'shape' => 'TagKey', ], ], 'TagLimitExceededException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'TagLimitExceeded', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'TagList' => [ 'type' => 'list', 'member' => [ 'shape' => 'Tag', ], ], 'TagPolicyException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'TagPolicy', 'httpStatusCode' => 400, 'senderFault' => true, ], 'exception' => true, ], 'TagResourceRequest' => [ 'type' => 'structure', 'required' => [ 'ResourceArn', 'Tags', ], 'members' => [ 'ResourceArn' => [ 'shape' => 'AmazonResourceName', ], 'Tags' => [ 'shape' => 'TagList', ], ], ], 'TagResourceResponse' => [ 'type' => 'structure', 'members' => [], ], 'TagValue' => [ 'type' => 'string', 'max' => 256, 'min' => 0, ], 'ThrottledException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'Throttled', 'httpStatusCode' => 429, 'senderFault' => true, ], 'exception' => true, ], 'Topic' => [ 'type' => 'structure', 'members' => [ 'TopicArn' => [ 'shape' => 'topicARN', ], ], ], 'TopicAttributesMap' => [ 'type' => 'map', 'key' => [ 'shape' => 'attributeName', ], 'value' => [ 'shape' => 'attributeValue', ], ], 'TopicLimitExceededException' => [ 'type' => 'structure', 'members' => [ 'message' => [ 'shape' => 'string', ], ], 'error' => [ 'code' => 'TopicLimitExceeded', 'httpStatusCode' => 403, 'senderFault' => true, ], 'exception' => true, ], 'TopicsList' => [ 'type' => 'list', 'member' => [ 'shape' => 'Topic', ], ], 'UnsubscribeInput' => [ 'type' => 'structure', 'required' => [ 'SubscriptionArn', ], 'members' => [ 'SubscriptionArn' => [ 'shape' => 'subscriptionARN', ], ], ], 'UntagResourceRequest' => [ 'type' => 'structure', 'required' => [ 'ResourceArn', 'TagKeys', ], 'members' => [ 'ResourceArn' => [ 'shape' => 'AmazonResourceName', ], 'TagKeys' => [ 'shape' => 'TagKeyList', ], ], ], 'UntagResourceResponse' => [ 'type' => 'structure', 'members' => [], ], 'account' => [ 'type' => 'string', ], 'action' => [ 'type' => 'string', ], 'attributeName' => [ 'type' => 'string', ], 'attributeValue' => [ 'type' => 'string', ], 'authenticateOnUnsubscribe' => [ 'type' => 'string', ], 'boolean' => [ 'type' => 'boolean', ], 'delegate' => [ 'type' => 'string', ], 'endpoint' => [ 'type' => 'string', ], 'label' => [ 'type' => 'string', ], 'message' => [ 'type' => 'string', ], 'messageId' => [ 'type' => 'string', ], 'messageStructure' => [ 'type' => 'string', ], 'nextToken' => [ 'type' => 'string', ], 'protocol' => [ 'type' => 'string', ], 'string' => [ 'type' => 'string', ], 'subject' => [ 'type' => 'string', ], 'subscriptionARN' => [ 'type' => 'string', ], 'token' => [ 'type' => 'string', ], 'topicARN' => [ 'type' => 'string', ], 'topicName' => [ 'type' => 'string', ], ],];
|
|
|
|
|
|
lib/Aws/Aws/functions.php
DELETED
@@ -1,411 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws;
|
3 |
-
|
4 |
-
use Psr\Http\Message\RequestInterface;
|
5 |
-
use GuzzleHttp\ClientInterface;
|
6 |
-
use GuzzleHttp\Promise\FulfilledPromise;
|
7 |
-
|
8 |
-
//-----------------------------------------------------------------------------
|
9 |
-
// Functional functions
|
10 |
-
//-----------------------------------------------------------------------------
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Returns a function that always returns the same value;
|
14 |
-
*
|
15 |
-
* @param mixed $value Value to return.
|
16 |
-
*
|
17 |
-
* @return callable
|
18 |
-
*/
|
19 |
-
function constantly($value)
|
20 |
-
{
|
21 |
-
return function () use ($value) { return $value; };
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Filters values that do not satisfy the predicate function $pred.
|
26 |
-
*
|
27 |
-
* @param mixed $iterable Iterable sequence of data.
|
28 |
-
* @param callable $pred Function that accepts a value and returns true/false
|
29 |
-
*
|
30 |
-
* @return \Generator
|
31 |
-
*/
|
32 |
-
function filter($iterable, callable $pred)
|
33 |
-
{
|
34 |
-
foreach ($iterable as $value) {
|
35 |
-
if ($pred($value)) {
|
36 |
-
yield $value;
|
37 |
-
}
|
38 |
-
}
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Applies a map function $f to each value in a collection.
|
43 |
-
*
|
44 |
-
* @param mixed $iterable Iterable sequence of data.
|
45 |
-
* @param callable $f Map function to apply.
|
46 |
-
*
|
47 |
-
* @return \Generator
|
48 |
-
*/
|
49 |
-
function map($iterable, callable $f)
|
50 |
-
{
|
51 |
-
foreach ($iterable as $value) {
|
52 |
-
yield $f($value);
|
53 |
-
}
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Creates a generator that iterates over a sequence, then iterates over each
|
58 |
-
* value in the sequence and yields the application of the map function to each
|
59 |
-
* value.
|
60 |
-
*
|
61 |
-
* @param mixed $iterable Iterable sequence of data.
|
62 |
-
* @param callable $f Map function to apply.
|
63 |
-
*
|
64 |
-
* @return \Generator
|
65 |
-
*/
|
66 |
-
function flatmap($iterable, callable $f)
|
67 |
-
{
|
68 |
-
foreach (map($iterable, $f) as $outer) {
|
69 |
-
foreach ($outer as $inner) {
|
70 |
-
yield $inner;
|
71 |
-
}
|
72 |
-
}
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Partitions the input sequence into partitions of the specified size.
|
77 |
-
*
|
78 |
-
* @param mixed $iterable Iterable sequence of data.
|
79 |
-
* @param int $size Size to make each partition (except possibly the last chunk)
|
80 |
-
*
|
81 |
-
* @return \Generator
|
82 |
-
*/
|
83 |
-
function partition($iterable, $size)
|
84 |
-
{
|
85 |
-
$buffer = [];
|
86 |
-
foreach ($iterable as $value) {
|
87 |
-
$buffer[] = $value;
|
88 |
-
if (count($buffer) === $size) {
|
89 |
-
yield $buffer;
|
90 |
-
$buffer = [];
|
91 |
-
}
|
92 |
-
}
|
93 |
-
|
94 |
-
if ($buffer) {
|
95 |
-
yield $buffer;
|
96 |
-
}
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Returns a function that invokes the provided variadic functions one
|
101 |
-
* after the other until one of the functions returns a non-null value.
|
102 |
-
* The return function will call each passed function with any arguments it
|
103 |
-
* is provided.
|
104 |
-
*
|
105 |
-
* $a = function ($x, $y) { return null; };
|
106 |
-
* $b = function ($x, $y) { return $x + $y; };
|
107 |
-
* $fn = \Aws\or_chain($a, $b);
|
108 |
-
* echo $fn(1, 2); // 3
|
109 |
-
*
|
110 |
-
* @return callable
|
111 |
-
*/
|
112 |
-
function or_chain()
|
113 |
-
{
|
114 |
-
$fns = func_get_args();
|
115 |
-
return function () use ($fns) {
|
116 |
-
$args = func_get_args();
|
117 |
-
foreach ($fns as $fn) {
|
118 |
-
$result = $args ? call_user_func_array($fn, $args) : $fn();
|
119 |
-
if ($result) {
|
120 |
-
return $result;
|
121 |
-
}
|
122 |
-
}
|
123 |
-
return null;
|
124 |
-
};
|
125 |
-
}
|
126 |
-
|
127 |
-
//-----------------------------------------------------------------------------
|
128 |
-
// JSON compiler and loading functions
|
129 |
-
//-----------------------------------------------------------------------------
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Loads a compiled JSON file from a PHP file.
|
133 |
-
*
|
134 |
-
* If the JSON file has not been cached to disk as a PHP file, it will be loaded
|
135 |
-
* from the JSON source file and returned.
|
136 |
-
*
|
137 |
-
* @param string $path Path to the JSON file on disk
|
138 |
-
*
|
139 |
-
* @return mixed Returns the JSON decoded data. Note that JSON objects are
|
140 |
-
* decoded as associative arrays.
|
141 |
-
*/
|
142 |
-
function load_compiled_json($path)
|
143 |
-
{
|
144 |
-
$compiledFilepath = "{$path}.php";
|
145 |
-
if (is_readable($compiledFilepath)) {
|
146 |
-
return include($compiledFilepath);
|
147 |
-
}
|
148 |
-
|
149 |
-
if (!file_exists($path)) {
|
150 |
-
throw new \InvalidArgumentException(
|
151 |
-
sprintf("File not found: %s", $path)
|
152 |
-
);
|
153 |
-
}
|
154 |
-
|
155 |
-
return json_decode(file_get_contents($path), true);
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* No-op
|
160 |
-
*/
|
161 |
-
function clear_compiled_json()
|
162 |
-
{
|
163 |
-
// pass
|
164 |
-
}
|
165 |
-
|
166 |
-
//-----------------------------------------------------------------------------
|
167 |
-
// Directory iterator functions.
|
168 |
-
//-----------------------------------------------------------------------------
|
169 |
-
|
170 |
-
/**
|
171 |
-
* Iterates over the files in a directory and works with custom wrappers.
|
172 |
-
*
|
173 |
-
* @param string $path Path to open (e.g., "s3://foo/bar").
|
174 |
-
* @param resource $context Stream wrapper context.
|
175 |
-
*
|
176 |
-
* @return \Generator Yields relative filename strings.
|
177 |
-
*/
|
178 |
-
function dir_iterator($path, $context = null)
|
179 |
-
{
|
180 |
-
$dh = $context ? opendir($path, $context) : opendir($path);
|
181 |
-
if (!$dh) {
|
182 |
-
throw new \InvalidArgumentException('File not found: ' . $path);
|
183 |
-
}
|
184 |
-
while (($file = readdir($dh)) !== false) {
|
185 |
-
yield $file;
|
186 |
-
}
|
187 |
-
closedir($dh);
|
188 |
-
}
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Returns a recursive directory iterator that yields absolute filenames.
|
192 |
-
*
|
193 |
-
* This iterator is not broken like PHP's built-in DirectoryIterator (which
|
194 |
-
* will read the first file from a stream wrapper, then rewind, then read
|
195 |
-
* it again).
|
196 |
-
*
|
197 |
-
* @param string $path Path to traverse (e.g., s3://bucket/key, /tmp)
|
198 |
-
* @param resource $context Stream context options.
|
199 |
-
*
|
200 |
-
* @return \Generator Yields absolute filenames.
|
201 |
-
*/
|
202 |
-
function recursive_dir_iterator($path, $context = null)
|
203 |
-
{
|
204 |
-
$invalid = ['.' => true, '..' => true];
|
205 |
-
$pathLen = strlen($path) + 1;
|
206 |
-
$iterator = dir_iterator($path, $context);
|
207 |
-
$queue = [];
|
208 |
-
do {
|
209 |
-
while ($iterator->valid()) {
|
210 |
-
$file = $iterator->current();
|
211 |
-
$iterator->next();
|
212 |
-
if (isset($invalid[basename($file)])) {
|
213 |
-
continue;
|
214 |
-
}
|
215 |
-
$fullPath = "{$path}/{$file}";
|
216 |
-
yield $fullPath;
|
217 |
-
if (is_dir($fullPath)) {
|
218 |
-
$queue[] = $iterator;
|
219 |
-
$iterator = map(
|
220 |
-
dir_iterator($fullPath, $context),
|
221 |
-
function ($file) use ($fullPath, $pathLen) {
|
222 |
-
return substr("{$fullPath}/{$file}", $pathLen);
|
223 |
-
}
|
224 |
-
);
|
225 |
-
continue;
|
226 |
-
}
|
227 |
-
}
|
228 |
-
$iterator = array_pop($queue);
|
229 |
-
} while ($iterator);
|
230 |
-
}
|
231 |
-
|
232 |
-
//-----------------------------------------------------------------------------
|
233 |
-
// Misc. functions.
|
234 |
-
//-----------------------------------------------------------------------------
|
235 |
-
|
236 |
-
/**
|
237 |
-
* Debug function used to describe the provided value type and class.
|
238 |
-
*
|
239 |
-
* @param mixed $input
|
240 |
-
*
|
241 |
-
* @return string Returns a string containing the type of the variable and
|
242 |
-
* if a class is provided, the class name.
|
243 |
-
*/
|
244 |
-
function describe_type($input)
|
245 |
-
{
|
246 |
-
switch (gettype($input)) {
|
247 |
-
case 'object':
|
248 |
-
return 'object(' . get_class($input) . ')';
|
249 |
-
case 'array':
|
250 |
-
return 'array(' . count($input) . ')';
|
251 |
-
default:
|
252 |
-
ob_start();
|
253 |
-
var_dump($input);
|
254 |
-
// normalize float vs double
|
255 |
-
return str_replace('double(', 'float(', rtrim(ob_get_clean()));
|
256 |
-
}
|
257 |
-
}
|
258 |
-
|
259 |
-
/**
|
260 |
-
* Creates a default HTTP handler based on the available clients.
|
261 |
-
*
|
262 |
-
* @return callable
|
263 |
-
*/
|
264 |
-
function default_http_handler()
|
265 |
-
{
|
266 |
-
$version = (string) ClientInterface::VERSION;
|
267 |
-
if ($version[0] === '5') {
|
268 |
-
return new \Aws\Handler\GuzzleV5\GuzzleHandler();
|
269 |
-
}
|
270 |
-
|
271 |
-
if ($version[0] === '6') {
|
272 |
-
return new \Aws\Handler\GuzzleV6\GuzzleHandler();
|
273 |
-
}
|
274 |
-
|
275 |
-
throw new \RuntimeException('Unknown Guzzle version: ' . $version);
|
276 |
-
}
|
277 |
-
|
278 |
-
/**
|
279 |
-
* Gets the default user agent string depending on the Guzzle version
|
280 |
-
*
|
281 |
-
* @return string
|
282 |
-
*/
|
283 |
-
function default_user_agent()
|
284 |
-
{
|
285 |
-
$version = (string) ClientInterface::VERSION;
|
286 |
-
if ($version[0] === '5') {
|
287 |
-
return \GuzzleHttp\Client::getDefaultUserAgent();
|
288 |
-
}
|
289 |
-
|
290 |
-
if ($version[0] === '6') {
|
291 |
-
return \GuzzleHttp\default_user_agent();
|
292 |
-
}
|
293 |
-
|
294 |
-
throw new \RuntimeException('Unknown Guzzle version: ' . $version);
|
295 |
-
}
|
296 |
-
|
297 |
-
/**
|
298 |
-
* Serialize a request for a command but do not send it.
|
299 |
-
*
|
300 |
-
* Returns a promise that is fulfilled with the serialized request.
|
301 |
-
*
|
302 |
-
* @param CommandInterface $command Command to serialize.
|
303 |
-
*
|
304 |
-
* @return RequestInterface
|
305 |
-
* @throws \RuntimeException
|
306 |
-
*/
|
307 |
-
function serialize(CommandInterface $command)
|
308 |
-
{
|
309 |
-
$request = null;
|
310 |
-
$handlerList = $command->getHandlerList();
|
311 |
-
|
312 |
-
// Return a mock result.
|
313 |
-
$handlerList->setHandler(
|
314 |
-
function (CommandInterface $_, RequestInterface $r) use (&$request) {
|
315 |
-
$request = $r;
|
316 |
-
return new FulfilledPromise(new Result([]));
|
317 |
-
}
|
318 |
-
);
|
319 |
-
|
320 |
-
call_user_func($handlerList->resolve(), $command)->wait();
|
321 |
-
if (!$request instanceof RequestInterface) {
|
322 |
-
throw new \RuntimeException(
|
323 |
-
'Calling handler did not serialize request'
|
324 |
-
);
|
325 |
-
}
|
326 |
-
|
327 |
-
return $request;
|
328 |
-
}
|
329 |
-
|
330 |
-
/**
|
331 |
-
* Retrieves data for a service from the SDK's service manifest file.
|
332 |
-
*
|
333 |
-
* Manifest data is stored statically, so it does not need to be loaded more
|
334 |
-
* than once per process. The JSON data is also cached in opcache.
|
335 |
-
*
|
336 |
-
* @param string $service Case-insensitive namespace or endpoint prefix of the
|
337 |
-
* service for which you are retrieving manifest data.
|
338 |
-
*
|
339 |
-
* @return array
|
340 |
-
* @throws \InvalidArgumentException if the service is not supported.
|
341 |
-
*/
|
342 |
-
function manifest($service = null)
|
343 |
-
{
|
344 |
-
// Load the manifest and create aliases for lowercased namespaces
|
345 |
-
static $manifest = [];
|
346 |
-
static $aliases = [];
|
347 |
-
if (empty($manifest)) {
|
348 |
-
$manifest = load_compiled_json(__DIR__ . '/data/manifest.json');
|
349 |
-
foreach ($manifest as $endpoint => $info) {
|
350 |
-
$alias = strtolower($info['namespace']);
|
351 |
-
if ($alias !== $endpoint) {
|
352 |
-
$aliases[$alias] = $endpoint;
|
353 |
-
}
|
354 |
-
}
|
355 |
-
}
|
356 |
-
|
357 |
-
// If no service specified, then return the whole manifest.
|
358 |
-
if ($service === null) {
|
359 |
-
return $manifest;
|
360 |
-
}
|
361 |
-
|
362 |
-
// Look up the service's info in the manifest data.
|
363 |
-
$service = strtolower($service);
|
364 |
-
if (isset($manifest[$service])) {
|
365 |
-
return $manifest[$service] + ['endpoint' => $service];
|
366 |
-
}
|
367 |
-
|
368 |
-
if (isset($aliases[$service])) {
|
369 |
-
return manifest($aliases[$service]);
|
370 |
-
}
|
371 |
-
|
372 |
-
throw new \InvalidArgumentException(
|
373 |
-
"The service \"{$service}\" is not provided by the AWS SDK for PHP."
|
374 |
-
);
|
375 |
-
}
|
376 |
-
|
377 |
-
/**
|
378 |
-
* Checks if supplied parameter is a valid hostname
|
379 |
-
*
|
380 |
-
* @param string $hostname
|
381 |
-
* @return bool
|
382 |
-
*/
|
383 |
-
function is_valid_hostname($hostname)
|
384 |
-
{
|
385 |
-
return (
|
386 |
-
preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*\.?$/i", $hostname)
|
387 |
-
&& preg_match("/^.{1,253}$/", $hostname)
|
388 |
-
&& preg_match("/^[^\.]{1,63}(\.[^\.]{0,63})*$/", $hostname)
|
389 |
-
);
|
390 |
-
}
|
391 |
-
|
392 |
-
/**
|
393 |
-
* Ignores '#' full line comments, which parse_ini_file no longer does
|
394 |
-
* in PHP 7+.
|
395 |
-
*
|
396 |
-
* @param $filename
|
397 |
-
* @param bool $process_sections
|
398 |
-
* @param int $scanner_mode
|
399 |
-
* @return array|bool
|
400 |
-
*/
|
401 |
-
function parse_ini_file(
|
402 |
-
$filename,
|
403 |
-
$process_sections = false,
|
404 |
-
$scanner_mode = INI_SCANNER_NORMAL)
|
405 |
-
{
|
406 |
-
return parse_ini_string(
|
407 |
-
preg_replace('/^#.*\\n/m', "", file_get_contents($filename)),
|
408 |
-
$process_sections,
|
409 |
-
$scanner_mode
|
410 |
-
);
|
411 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/Aws/signer/signerClient.php
DELETED
@@ -1,27 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Aws\signer;
|
3 |
-
|
4 |
-
use Aws\AwsClient;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* This client is used to interact with the **AWS Signer** service.
|
8 |
-
* @method \Aws\Result cancelSigningProfile(array $args = [])
|
9 |
-
* @method \GuzzleHttp\Promise\Promise cancelSigningProfileAsync(array $args = [])
|
10 |
-
* @method \Aws\Result describeSigningJob(array $args = [])
|
11 |
-
* @method \GuzzleHttp\Promise\Promise describeSigningJobAsync(array $args = [])
|
12 |
-
* @method \Aws\Result getSigningPlatform(array $args = [])
|
13 |
-
* @method \GuzzleHttp\Promise\Promise getSigningPlatformAsync(array $args = [])
|
14 |
-
* @method \Aws\Result getSigningProfile(array $args = [])
|
15 |
-
* @method \GuzzleHttp\Promise\Promise getSigningProfileAsync(array $args = [])
|
16 |
-
* @method \Aws\Result listSigningJobs(array $args = [])
|
17 |
-
* @method \GuzzleHttp\Promise\Promise listSigningJobsAsync(array $args = [])
|
18 |
-
* @method \Aws\Result listSigningPlatforms(array $args = [])
|
19 |
-
* @method \GuzzleHttp\Promise\Promise listSigningPlatformsAsync(array $args = [])
|
20 |
-
* @method \Aws\Result listSigningProfiles(array $args = [])
|
21 |
-
* @method \GuzzleHttp\Promise\Promise listSigningProfilesAsync(array $args = [])
|
22 |
-
* @method \Aws\Result putSigningProfile(array $args = [])
|
23 |
-
* @method \GuzzleHttp\Promise\Promise putSigningProfileAsync(array $args = [])
|
24 |
-
* @method \Aws\Result startSigningJob(array $args = [])
|
25 |
-
* @method \GuzzleHttp\Promise\Promise startSigningJobAsync(array $args = [])
|
26 |
-
*/
|
27 |
-
class signerClient extends AwsClient {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Client.php
DELETED
@@ -1,422 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp;
|
3 |
-
|
4 |
-
use GuzzleHttp\Cookie\CookieJar;
|
5 |
-
use GuzzleHttp\Promise;
|
6 |
-
use GuzzleHttp\Psr7;
|
7 |
-
use Psr\Http\Message\UriInterface;
|
8 |
-
use Psr\Http\Message\RequestInterface;
|
9 |
-
use Psr\Http\Message\ResponseInterface;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @method ResponseInterface get(string|UriInterface $uri, array $options = [])
|
13 |
-
* @method ResponseInterface head(string|UriInterface $uri, array $options = [])
|
14 |
-
* @method ResponseInterface put(string|UriInterface $uri, array $options = [])
|
15 |
-
* @method ResponseInterface post(string|UriInterface $uri, array $options = [])
|
16 |
-
* @method ResponseInterface patch(string|UriInterface $uri, array $options = [])
|
17 |
-
* @method ResponseInterface delete(string|UriInterface $uri, array $options = [])
|
18 |
-
* @method Promise\PromiseInterface getAsync(string|UriInterface $uri, array $options = [])
|
19 |
-
* @method Promise\PromiseInterface headAsync(string|UriInterface $uri, array $options = [])
|
20 |
-
* @method Promise\PromiseInterface putAsync(string|UriInterface $uri, array $options = [])
|
21 |
-
* @method Promise\PromiseInterface postAsync(string|UriInterface $uri, array $options = [])
|
22 |
-
* @method Promise\PromiseInterface patchAsync(string|UriInterface $uri, array $options = [])
|
23 |
-
* @method Promise\PromiseInterface deleteAsync(string|UriInterface $uri, array $options = [])
|
24 |
-
*/
|
25 |
-
class Client implements ClientInterface
|
26 |
-
{
|
27 |
-
/** @var array Default request options */
|
28 |
-
private $config;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Clients accept an array of constructor parameters.
|
32 |
-
*
|
33 |
-
* Here's an example of creating a client using a base_uri and an array of
|
34 |
-
* default request options to apply to each request:
|
35 |
-
*
|
36 |
-
* $client = new Client([
|
37 |
-
* 'base_uri' => 'http://www.foo.com/1.0/',
|
38 |
-
* 'timeout' => 0,
|
39 |
-
* 'allow_redirects' => false,
|
40 |
-
* 'proxy' => '192.168.16.1:10'
|
41 |
-
* ]);
|
42 |
-
*
|
43 |
-
* Client configuration settings include the following options:
|
44 |
-
*
|
45 |
-
* - handler: (callable) Function that transfers HTTP requests over the
|
46 |
-
* wire. The function is called with a Psr7\Http\Message\RequestInterface
|
47 |
-
* and array of transfer options, and must return a
|
48 |
-
* GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
|
49 |
-
* Psr7\Http\Message\ResponseInterface on success. "handler" is a
|
50 |
-
* constructor only option that cannot be overridden in per/request
|
51 |
-
* options. If no handler is provided, a default handler will be created
|
52 |
-
* that enables all of the request options below by attaching all of the
|
53 |
-
* default middleware to the handler.
|
54 |
-
* - base_uri: (string|UriInterface) Base URI of the client that is merged
|
55 |
-
* into relative URIs. Can be a string or instance of UriInterface.
|
56 |
-
* - **: any request option
|
57 |
-
*
|
58 |
-
* @param array $config Client configuration settings.
|
59 |
-
*
|
60 |
-
* @see \GuzzleHttp\RequestOptions for a list of available request options.
|
61 |
-
*/
|
62 |
-
public function __construct(array $config = [])
|
63 |
-
{
|
64 |
-
if (!isset($config['handler'])) {
|
65 |
-
$config['handler'] = HandlerStack::create();
|
66 |
-
} elseif (!is_callable($config['handler'])) {
|
67 |
-
throw new \InvalidArgumentException('handler must be a callable');
|
68 |
-
}
|
69 |
-
|
70 |
-
// Convert the base_uri to a UriInterface
|
71 |
-
if (isset($config['base_uri'])) {
|
72 |
-
$config['base_uri'] = Psr7\uri_for($config['base_uri']);
|
73 |
-
}
|
74 |
-
|
75 |
-
$this->configureDefaults($config);
|
76 |
-
}
|
77 |
-
|
78 |
-
public function __call($method, $args)
|
79 |
-
{
|
80 |
-
if (count($args) < 1) {
|
81 |
-
throw new \InvalidArgumentException('Magic request methods require a URI and optional options array');
|
82 |
-
}
|
83 |
-
|
84 |
-
$uri = $args[0];
|
85 |
-
$opts = isset($args[1]) ? $args[1] : [];
|
86 |
-
|
87 |
-
return substr($method, -5) === 'Async'
|
88 |
-
? $this->requestAsync(substr($method, 0, -5), $uri, $opts)
|
89 |
-
: $this->request($method, $uri, $opts);
|
90 |
-
}
|
91 |
-
|
92 |
-
public function sendAsync(RequestInterface $request, array $options = [])
|
93 |
-
{
|
94 |
-
// Merge the base URI into the request URI if needed.
|
95 |
-
$options = $this->prepareDefaults($options);
|
96 |
-
|
97 |
-
return $this->transfer(
|
98 |
-
$request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
|
99 |
-
$options
|
100 |
-
);
|
101 |
-
}
|
102 |
-
|
103 |
-
public function send(RequestInterface $request, array $options = [])
|
104 |
-
{
|
105 |
-
$options[RequestOptions::SYNCHRONOUS] = true;
|
106 |
-
return $this->sendAsync($request, $options)->wait();
|
107 |
-
}
|
108 |
-
|
109 |
-
public function requestAsync($method, $uri = '', array $options = [])
|
110 |
-
{
|
111 |
-
$options = $this->prepareDefaults($options);
|
112 |
-
// Remove request modifying parameter because it can be done up-front.
|
113 |
-
$headers = isset($options['headers']) ? $options['headers'] : [];
|
114 |
-
$body = isset($options['body']) ? $options['body'] : null;
|
115 |
-
$version = isset($options['version']) ? $options['version'] : '1.1';
|
116 |
-
// Merge the URI into the base URI.
|
117 |
-
$uri = $this->buildUri($uri, $options);
|
118 |
-
if (is_array($body)) {
|
119 |
-
$this->invalidBody();
|
120 |
-
}
|
121 |
-
$request = new Psr7\Request($method, $uri, $headers, $body, $version);
|
122 |
-
// Remove the option so that they are not doubly-applied.
|
123 |
-
unset($options['headers'], $options['body'], $options['version']);
|
124 |
-
|
125 |
-
return $this->transfer($request, $options);
|
126 |
-
}
|
127 |
-
|
128 |
-
public function request($method, $uri = '', array $options = [])
|
129 |
-
{
|
130 |
-
$options[RequestOptions::SYNCHRONOUS] = true;
|
131 |
-
return $this->requestAsync($method, $uri, $options)->wait();
|
132 |
-
}
|
133 |
-
|
134 |
-
public function getConfig($option = null)
|
135 |
-
{
|
136 |
-
return $option === null
|
137 |
-
? $this->config
|
138 |
-
: (isset($this->config[$option]) ? $this->config[$option] : null);
|
139 |
-
}
|
140 |
-
|
141 |
-
private function buildUri($uri, array $config)
|
142 |
-
{
|
143 |
-
// for BC we accept null which would otherwise fail in uri_for
|
144 |
-
$uri = Psr7\uri_for($uri === null ? '' : $uri);
|
145 |
-
|
146 |
-
if (isset($config['base_uri'])) {
|
147 |
-
$uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
|
148 |
-
}
|
149 |
-
|
150 |
-
return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* Configures the default options for a client.
|
155 |
-
*
|
156 |
-
* @param array $config
|
157 |
-
*/
|
158 |
-
private function configureDefaults(array $config)
|
159 |
-
{
|
160 |
-
$defaults = [
|
161 |
-
'allow_redirects' => RedirectMiddleware::$defaultSettings,
|
162 |
-
'http_errors' => true,
|
163 |
-
'decode_content' => true,
|
164 |
-
'verify' => true,
|
165 |
-
'cookies' => false
|
166 |
-
];
|
167 |
-
|
168 |
-
// Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
|
169 |
-
|
170 |
-
// We can only trust the HTTP_PROXY environment variable in a CLI
|
171 |
-
// process due to the fact that PHP has no reliable mechanism to
|
172 |
-
// get environment variables that start with "HTTP_".
|
173 |
-
if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) {
|
174 |
-
$defaults['proxy']['http'] = getenv('HTTP_PROXY');
|
175 |
-
}
|
176 |
-
|
177 |
-
if ($proxy = getenv('HTTPS_PROXY')) {
|
178 |
-
$defaults['proxy']['https'] = $proxy;
|
179 |
-
}
|
180 |
-
|
181 |
-
if ($noProxy = getenv('NO_PROXY')) {
|
182 |
-
$cleanedNoProxy = str_replace(' ', '', $noProxy);
|
183 |
-
$defaults['proxy']['no'] = explode(',', $cleanedNoProxy);
|
184 |
-
}
|
185 |
-
|
186 |
-
$this->config = $config + $defaults;
|
187 |
-
|
188 |
-
if (!empty($config['cookies']) && $config['cookies'] === true) {
|
189 |
-
$this->config['cookies'] = new CookieJar();
|
190 |
-
}
|
191 |
-
|
192 |
-
// Add the default user-agent header.
|
193 |
-
if (!isset($this->config['headers'])) {
|
194 |
-
$this->config['headers'] = ['User-Agent' => default_user_agent()];
|
195 |
-
} else {
|
196 |
-
// Add the User-Agent header if one was not already set.
|
197 |
-
foreach (array_keys($this->config['headers']) as $name) {
|
198 |
-
if (strtolower($name) === 'user-agent') {
|
199 |
-
return;
|
200 |
-
}
|
201 |
-
}
|
202 |
-
$this->config['headers']['User-Agent'] = default_user_agent();
|
203 |
-
}
|
204 |
-
}
|
205 |
-
|
206 |
-
/**
|
207 |
-
* Merges default options into the array.
|
208 |
-
*
|
209 |
-
* @param array $options Options to modify by reference
|
210 |
-
*
|
211 |
-
* @return array
|
212 |
-
*/
|
213 |
-
private function prepareDefaults($options)
|
214 |
-
{
|
215 |
-
$defaults = $this->config;
|
216 |
-
|
217 |
-
if (!empty($defaults['headers'])) {
|
218 |
-
// Default headers are only added if they are not present.
|
219 |
-
$defaults['_conditional'] = $defaults['headers'];
|
220 |
-
unset($defaults['headers']);
|
221 |
-
}
|
222 |
-
|
223 |
-
// Special handling for headers is required as they are added as
|
224 |
-
// conditional headers and as headers passed to a request ctor.
|
225 |
-
if (array_key_exists('headers', $options)) {
|
226 |
-
// Allows default headers to be unset.
|
227 |
-
if ($options['headers'] === null) {
|
228 |
-
$defaults['_conditional'] = null;
|
229 |
-
unset($options['headers']);
|
230 |
-
} elseif (!is_array($options['headers'])) {
|
231 |
-
throw new \InvalidArgumentException('headers must be an array');
|
232 |
-
}
|
233 |
-
}
|
234 |
-
|
235 |
-
// Shallow merge defaults underneath options.
|
236 |
-
$result = $options + $defaults;
|
237 |
-
|
238 |
-
// Remove null values.
|
239 |
-
foreach ($result as $k => $v) {
|
240 |
-
if ($v === null) {
|
241 |
-
unset($result[$k]);
|
242 |
-
}
|
243 |
-
}
|
244 |
-
|
245 |
-
return $result;
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Transfers the given request and applies request options.
|
250 |
-
*
|
251 |
-
* The URI of the request is not modified and the request options are used
|
252 |
-
* as-is without merging in default options.
|
253 |
-
*
|
254 |
-
* @param RequestInterface $request
|
255 |
-
* @param array $options
|
256 |
-
*
|
257 |
-
* @return Promise\PromiseInterface
|
258 |
-
*/
|
259 |
-
private function transfer(RequestInterface $request, array $options)
|
260 |
-
{
|
261 |
-
// save_to -> sink
|
262 |
-
if (isset($options['save_to'])) {
|
263 |
-
$options['sink'] = $options['save_to'];
|
264 |
-
unset($options['save_to']);
|
265 |
-
}
|
266 |
-
|
267 |
-
// exceptions -> http_errors
|
268 |
-
if (isset($options['exceptions'])) {
|
269 |
-
$options['http_errors'] = $options['exceptions'];
|
270 |
-
unset($options['exceptions']);
|
271 |
-
}
|
272 |
-
|
273 |
-
$request = $this->applyOptions($request, $options);
|
274 |
-
$handler = $options['handler'];
|
275 |
-
|
276 |
-
try {
|
277 |
-
return Promise\promise_for($handler($request, $options));
|
278 |
-
} catch (\Exception $e) {
|
279 |
-
return Promise\rejection_for($e);
|
280 |
-
}
|
281 |
-
}
|
282 |
-
|
283 |
-
/**
|
284 |
-
* Applies the array of request options to a request.
|
285 |
-
*
|
286 |
-
* @param RequestInterface $request
|
287 |
-
* @param array $options
|
288 |
-
*
|
289 |
-
* @return RequestInterface
|
290 |
-
*/
|
291 |
-
private function applyOptions(RequestInterface $request, array &$options)
|
292 |
-
{
|
293 |
-
$modify = [
|
294 |
-
'set_headers' => [],
|
295 |
-
];
|
296 |
-
|
297 |
-
if (isset($options['headers'])) {
|
298 |
-
$modify['set_headers'] = $options['headers'];
|
299 |
-
unset($options['headers']);
|
300 |
-
}
|
301 |
-
|
302 |
-
if (isset($options['form_params'])) {
|
303 |
-
if (isset($options['multipart'])) {
|
304 |
-
throw new \InvalidArgumentException('You cannot use '
|
305 |
-
. 'form_params and multipart at the same time. Use the '
|
306 |
-
. 'form_params option if you want to send application/'
|
307 |
-
. 'x-www-form-urlencoded requests, and the multipart '
|
308 |
-
. 'option to send multipart/form-data requests.');
|
309 |
-
}
|
310 |
-
$options['body'] = http_build_query($options['form_params'], '', '&');
|
311 |
-
unset($options['form_params']);
|
312 |
-
// Ensure that we don't have the header in different case and set the new value.
|
313 |
-
$options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
|
314 |
-
$options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
|
315 |
-
}
|
316 |
-
|
317 |
-
if (isset($options['multipart'])) {
|
318 |
-
$options['body'] = new Psr7\MultipartStream($options['multipart']);
|
319 |
-
unset($options['multipart']);
|
320 |
-
}
|
321 |
-
|
322 |
-
if (isset($options['json'])) {
|
323 |
-
$options['body'] = \GuzzleHttp\json_encode($options['json']);
|
324 |
-
unset($options['json']);
|
325 |
-
// Ensure that we don't have the header in different case and set the new value.
|
326 |
-
$options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
|
327 |
-
$options['_conditional']['Content-Type'] = 'application/json';
|
328 |
-
}
|
329 |
-
|
330 |
-
if (!empty($options['decode_content'])
|
331 |
-
&& $options['decode_content'] !== true
|
332 |
-
) {
|
333 |
-
// Ensure that we don't have the header in different case and set the new value.
|
334 |
-
$options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']);
|
335 |
-
$modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
|
336 |
-
}
|
337 |
-
|
338 |
-
if (isset($options['body'])) {
|
339 |
-
if (is_array($options['body'])) {
|
340 |
-
$this->invalidBody();
|
341 |
-
}
|
342 |
-
$modify['body'] = Psr7\stream_for($options['body']);
|
343 |
-
unset($options['body']);
|
344 |
-
}
|
345 |
-
|
346 |
-
if (!empty($options['auth']) && is_array($options['auth'])) {
|
347 |
-
$value = $options['auth'];
|
348 |
-
$type = isset($value[2]) ? strtolower($value[2]) : 'basic';
|
349 |
-
switch ($type) {
|
350 |
-
case 'basic':
|
351 |
-
// Ensure that we don't have the header in different case and set the new value.
|
352 |
-
$modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']);
|
353 |
-
$modify['set_headers']['Authorization'] = 'Basic '
|
354 |
-
. base64_encode("$value[0]:$value[1]");
|
355 |
-
break;
|
356 |
-
case 'digest':
|
357 |
-
// @todo: Do not rely on curl
|
358 |
-
$options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
|
359 |
-
$options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
|
360 |
-
break;
|
361 |
-
case 'ntlm':
|
362 |
-
$options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM;
|
363 |
-
$options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
|
364 |
-
break;
|
365 |
-
}
|
366 |
-
}
|
367 |
-
|
368 |
-
if (isset($options['query'])) {
|
369 |
-
$value = $options['query'];
|
370 |
-
if (is_array($value)) {
|
371 |
-
$value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);
|
372 |
-
}
|
373 |
-
if (!is_string($value)) {
|
374 |
-
throw new \InvalidArgumentException('query must be a string or array');
|
375 |
-
}
|
376 |
-
$modify['query'] = $value;
|
377 |
-
unset($options['query']);
|
378 |
-
}
|
379 |
-
|
380 |
-
// Ensure that sink is not an invalid value.
|
381 |
-
if (isset($options['sink'])) {
|
382 |
-
// TODO: Add more sink validation?
|
383 |
-
if (is_bool($options['sink'])) {
|
384 |
-
throw new \InvalidArgumentException('sink must not be a boolean');
|
385 |
-
}
|
386 |
-
}
|
387 |
-
|
388 |
-
$request = Psr7\modify_request($request, $modify);
|
389 |
-
if ($request->getBody() instanceof Psr7\MultipartStream) {
|
390 |
-
// Use a multipart/form-data POST if a Content-Type is not set.
|
391 |
-
// Ensure that we don't have the header in different case and set the new value.
|
392 |
-
$options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
|
393 |
-
$options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
|
394 |
-
. $request->getBody()->getBoundary();
|
395 |
-
}
|
396 |
-
|
397 |
-
// Merge in conditional headers if they are not present.
|
398 |
-
if (isset($options['_conditional'])) {
|
399 |
-
// Build up the changes so it's in a single clone of the message.
|
400 |
-
$modify = [];
|
401 |
-
foreach ($options['_conditional'] as $k => $v) {
|
402 |
-
if (!$request->hasHeader($k)) {
|
403 |
-
$modify['set_headers'][$k] = $v;
|
404 |
-
}
|
405 |
-
}
|
406 |
-
$request = Psr7\modify_request($request, $modify);
|
407 |
-
// Don't pass this internal value along to middleware/handlers.
|
408 |
-
unset($options['_conditional']);
|
409 |
-
}
|
410 |
-
|
411 |
-
return $request;
|
412 |
-
}
|
413 |
-
|
414 |
-
private function invalidBody()
|
415 |
-
{
|
416 |
-
throw new \InvalidArgumentException('Passing in the "body" request '
|
417 |
-
. 'option as an array to send a POST request has been deprecated. '
|
418 |
-
. 'Please use the "form_params" request option to send a '
|
419 |
-
. 'application/x-www-form-urlencoded request, or the "multipart" '
|
420 |
-
. 'request option to send a multipart/form-data request.');
|
421 |
-
}
|
422 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/ClientInterface.php
DELETED
@@ -1,84 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp;
|
3 |
-
|
4 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
5 |
-
use GuzzleHttp\Exception\GuzzleException;
|
6 |
-
use Psr\Http\Message\RequestInterface;
|
7 |
-
use Psr\Http\Message\ResponseInterface;
|
8 |
-
use Psr\Http\Message\UriInterface;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Client interface for sending HTTP requests.
|
12 |
-
*/
|
13 |
-
interface ClientInterface
|
14 |
-
{
|
15 |
-
const VERSION = '6.3.3';
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Send an HTTP request.
|
19 |
-
*
|
20 |
-
* @param RequestInterface $request Request to send
|
21 |
-
* @param array $options Request options to apply to the given
|
22 |
-
* request and to the transfer.
|
23 |
-
*
|
24 |
-
* @return ResponseInterface
|
25 |
-
* @throws GuzzleException
|
26 |
-
*/
|
27 |
-
public function send(RequestInterface $request, array $options = []);
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Asynchronously send an HTTP request.
|
31 |
-
*
|
32 |
-
* @param RequestInterface $request Request to send
|
33 |
-
* @param array $options Request options to apply to the given
|
34 |
-
* request and to the transfer.
|
35 |
-
*
|
36 |
-
* @return PromiseInterface
|
37 |
-
*/
|
38 |
-
public function sendAsync(RequestInterface $request, array $options = []);
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Create and send an HTTP request.
|
42 |
-
*
|
43 |
-
* Use an absolute path to override the base path of the client, or a
|
44 |
-
* relative path to append to the base path of the client. The URL can
|
45 |
-
* contain the query string as well.
|
46 |
-
*
|
47 |
-
* @param string $method HTTP method.
|
48 |
-
* @param string|UriInterface $uri URI object or string.
|
49 |
-
* @param array $options Request options to apply.
|
50 |
-
*
|
51 |
-
* @return ResponseInterface
|
52 |
-
* @throws GuzzleException
|
53 |
-
*/
|
54 |
-
public function request($method, $uri, array $options = []);
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Create and send an asynchronous HTTP request.
|
58 |
-
*
|
59 |
-
* Use an absolute path to override the base path of the client, or a
|
60 |
-
* relative path to append to the base path of the client. The URL can
|
61 |
-
* contain the query string as well. Use an array to provide a URL
|
62 |
-
* template and additional variables to use in the URL template expansion.
|
63 |
-
*
|
64 |
-
* @param string $method HTTP method
|
65 |
-
* @param string|UriInterface $uri URI object or string.
|
66 |
-
* @param array $options Request options to apply.
|
67 |
-
*
|
68 |
-
* @return PromiseInterface
|
69 |
-
*/
|
70 |
-
public function requestAsync($method, $uri, array $options = []);
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Get a client configuration option.
|
74 |
-
*
|
75 |
-
* These options include default request options of the client, a "handler"
|
76 |
-
* (if utilized by the concrete client), and a "base_uri" if utilized by
|
77 |
-
* the concrete client.
|
78 |
-
*
|
79 |
-
* @param string|null $option The config option to retrieve.
|
80 |
-
*
|
81 |
-
* @return mixed
|
82 |
-
*/
|
83 |
-
public function getConfig($option = null);
|
84 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Cookie/CookieJar.php
DELETED
@@ -1,314 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Cookie;
|
3 |
-
|
4 |
-
use Psr\Http\Message\RequestInterface;
|
5 |
-
use Psr\Http\Message\ResponseInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Cookie jar that stores cookies as an array
|
9 |
-
*/
|
10 |
-
class CookieJar implements CookieJarInterface
|
11 |
-
{
|
12 |
-
/** @var SetCookie[] Loaded cookie data */
|
13 |
-
private $cookies = [];
|
14 |
-
|
15 |
-
/** @var bool */
|
16 |
-
private $strictMode;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @param bool $strictMode Set to true to throw exceptions when invalid
|
20 |
-
* cookies are added to the cookie jar.
|
21 |
-
* @param array $cookieArray Array of SetCookie objects or a hash of
|
22 |
-
* arrays that can be used with the SetCookie
|
23 |
-
* constructor
|
24 |
-
*/
|
25 |
-
public function __construct($strictMode = false, $cookieArray = [])
|
26 |
-
{
|
27 |
-
$this->strictMode = $strictMode;
|
28 |
-
|
29 |
-
foreach ($cookieArray as $cookie) {
|
30 |
-
if (!($cookie instanceof SetCookie)) {
|
31 |
-
$cookie = new SetCookie($cookie);
|
32 |
-
}
|
33 |
-
$this->setCookie($cookie);
|
34 |
-
}
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Create a new Cookie jar from an associative array and domain.
|
39 |
-
*
|
40 |
-
* @param array $cookies Cookies to create the jar from
|
41 |
-
* @param string $domain Domain to set the cookies to
|
42 |
-
*
|
43 |
-
* @return self
|
44 |
-
*/
|
45 |
-
public static function fromArray(array $cookies, $domain)
|
46 |
-
{
|
47 |
-
$cookieJar = new self();
|
48 |
-
foreach ($cookies as $name => $value) {
|
49 |
-
$cookieJar->setCookie(new SetCookie([
|
50 |
-
'Domain' => $domain,
|
51 |
-
'Name' => $name,
|
52 |
-
'Value' => $value,
|
53 |
-
'Discard' => true
|
54 |
-
]));
|
55 |
-
}
|
56 |
-
|
57 |
-
return $cookieJar;
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* @deprecated
|
62 |
-
*/
|
63 |
-
public static function getCookieValue($value)
|
64 |
-
{
|
65 |
-
return $value;
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Evaluate if this cookie should be persisted to storage
|
70 |
-
* that survives between requests.
|
71 |
-
*
|
72 |
-
* @param SetCookie $cookie Being evaluated.
|
73 |
-
* @param bool $allowSessionCookies If we should persist session cookies
|
74 |
-
* @return bool
|
75 |
-
*/
|
76 |
-
public static function shouldPersist(
|
77 |
-
SetCookie $cookie,
|
78 |
-
$allowSessionCookies = false
|
79 |
-
) {
|
80 |
-
if ($cookie->getExpires() || $allowSessionCookies) {
|
81 |
-
if (!$cookie->getDiscard()) {
|
82 |
-
return true;
|
83 |
-
}
|
84 |
-
}
|
85 |
-
|
86 |
-
return false;
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Finds and returns the cookie based on the name
|
91 |
-
*
|
92 |
-
* @param string $name cookie name to search for
|
93 |
-
* @return SetCookie|null cookie that was found or null if not found
|
94 |
-
*/
|
95 |
-
public function getCookieByName($name)
|
96 |
-
{
|
97 |
-
// don't allow a null name
|
98 |
-
if ($name === null) {
|
99 |
-
return null;
|
100 |
-
}
|
101 |
-
foreach ($this->cookies as $cookie) {
|
102 |
-
if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) {
|
103 |
-
return $cookie;
|
104 |
-
}
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
public function toArray()
|
109 |
-
{
|
110 |
-
return array_map(function (SetCookie $cookie) {
|
111 |
-
return $cookie->toArray();
|
112 |
-
}, $this->getIterator()->getArrayCopy());
|
113 |
-
}
|
114 |
-
|
115 |
-
public function clear($domain = null, $path = null, $name = null)
|
116 |
-
{
|
117 |
-
if (!$domain) {
|
118 |
-
$this->cookies = [];
|
119 |
-
return;
|
120 |
-
} elseif (!$path) {
|
121 |
-
$this->cookies = array_filter(
|
122 |
-
$this->cookies,
|
123 |
-
function (SetCookie $cookie) use ($path, $domain) {
|
124 |
-
return !$cookie->matchesDomain($domain);
|
125 |
-
}
|
126 |
-
);
|
127 |
-
} elseif (!$name) {
|
128 |
-
$this->cookies = array_filter(
|
129 |
-
$this->cookies,
|
130 |
-
function (SetCookie $cookie) use ($path, $domain) {
|
131 |
-
return !($cookie->matchesPath($path) &&
|
132 |
-
$cookie->matchesDomain($domain));
|
133 |
-
}
|
134 |
-
);
|
135 |
-
} else {
|
136 |
-
$this->cookies = array_filter(
|
137 |
-
$this->cookies,
|
138 |
-
function (SetCookie $cookie) use ($path, $domain, $name) {
|
139 |
-
return !($cookie->getName() == $name &&
|
140 |
-
$cookie->matchesPath($path) &&
|
141 |
-
$cookie->matchesDomain($domain));
|
142 |
-
}
|
143 |
-
);
|
144 |
-
}
|
145 |
-
}
|
146 |
-
|
147 |
-
public function clearSessionCookies()
|
148 |
-
{
|
149 |
-
$this->cookies = array_filter(
|
150 |
-
$this->cookies,
|
151 |
-
function (SetCookie $cookie) {
|
152 |
-
return !$cookie->getDiscard() && $cookie->getExpires();
|
153 |
-
}
|
154 |
-
);
|
155 |
-
}
|
156 |
-
|
157 |
-
public function setCookie(SetCookie $cookie)
|
158 |
-
{
|
159 |
-
// If the name string is empty (but not 0), ignore the set-cookie
|
160 |
-
// string entirely.
|
161 |
-
$name = $cookie->getName();
|
162 |
-
if (!$name && $name !== '0') {
|
163 |
-
return false;
|
164 |
-
}
|
165 |
-
|
166 |
-
// Only allow cookies with set and valid domain, name, value
|
167 |
-
$result = $cookie->validate();
|
168 |
-
if ($result !== true) {
|
169 |
-
if ($this->strictMode) {
|
170 |
-
throw new \RuntimeException('Invalid cookie: ' . $result);
|
171 |
-
} else {
|
172 |
-
$this->removeCookieIfEmpty($cookie);
|
173 |
-
return false;
|
174 |
-
}
|
175 |
-
}
|
176 |
-
|
177 |
-
// Resolve conflicts with previously set cookies
|
178 |
-
foreach ($this->cookies as $i => $c) {
|
179 |
-
|
180 |
-
// Two cookies are identical, when their path, and domain are
|
181 |
-
// identical.
|
182 |
-
if ($c->getPath() != $cookie->getPath() ||
|
183 |
-
$c->getDomain() != $cookie->getDomain() ||
|
184 |
-
$c->getName() != $cookie->getName()
|
185 |
-
) {
|
186 |
-
continue;
|
187 |
-
}
|
188 |
-
|
189 |
-
// The previously set cookie is a discard cookie and this one is
|
190 |
-
// not so allow the new cookie to be set
|
191 |
-
if (!$cookie->getDiscard() && $c->getDiscard()) {
|
192 |
-
unset($this->cookies[$i]);
|
193 |
-
continue;
|
194 |
-
}
|
195 |
-
|
196 |
-
// If the new cookie's expiration is further into the future, then
|
197 |
-
// replace the old cookie
|
198 |
-
if ($cookie->getExpires() > $c->getExpires()) {
|
199 |
-
unset($this->cookies[$i]);
|
200 |
-
continue;
|
201 |
-
}
|
202 |
-
|
203 |
-
// If the value has changed, we better change it
|
204 |
-
if ($cookie->getValue() !== $c->getValue()) {
|
205 |
-
unset($this->cookies[$i]);
|
206 |
-
continue;
|
207 |
-
}
|
208 |
-
|
209 |
-
// The cookie exists, so no need to continue
|
210 |
-
return false;
|
211 |
-
}
|
212 |
-
|
213 |
-
$this->cookies[] = $cookie;
|
214 |
-
|
215 |
-
return true;
|
216 |
-
}
|
217 |
-
|
218 |
-
public function count()
|
219 |
-
{
|
220 |
-
return count($this->cookies);
|
221 |
-
}
|
222 |
-
|
223 |
-
public function getIterator()
|
224 |
-
{
|
225 |
-
return new \ArrayIterator(array_values($this->cookies));
|
226 |
-
}
|
227 |
-
|
228 |
-
public function extractCookies(
|
229 |
-
RequestInterface $request,
|
230 |
-
ResponseInterface $response
|
231 |
-
) {
|
232 |
-
if ($cookieHeader = $response->getHeader('Set-Cookie')) {
|
233 |
-
foreach ($cookieHeader as $cookie) {
|
234 |
-
$sc = SetCookie::fromString($cookie);
|
235 |
-
if (!$sc->getDomain()) {
|
236 |
-
$sc->setDomain($request->getUri()->getHost());
|
237 |
-
}
|
238 |
-
if (0 !== strpos($sc->getPath(), '/')) {
|
239 |
-
$sc->setPath($this->getCookiePathFromRequest($request));
|
240 |
-
}
|
241 |
-
$this->setCookie($sc);
|
242 |
-
}
|
243 |
-
}
|
244 |
-
}
|
245 |
-
|
246 |
-
/**
|
247 |
-
* Computes cookie path following RFC 6265 section 5.1.4
|
248 |
-
*
|
249 |
-
* @link https://tools.ietf.org/html/rfc6265#section-5.1.4
|
250 |
-
*
|
251 |
-
* @param RequestInterface $request
|
252 |
-
* @return string
|
253 |
-
*/
|
254 |
-
private function getCookiePathFromRequest(RequestInterface $request)
|
255 |
-
{
|
256 |
-
$uriPath = $request->getUri()->getPath();
|
257 |
-
if ('' === $uriPath) {
|
258 |
-
return '/';
|
259 |
-
}
|
260 |
-
if (0 !== strpos($uriPath, '/')) {
|
261 |
-
return '/';
|
262 |
-
}
|
263 |
-
if ('/' === $uriPath) {
|
264 |
-
return '/';
|
265 |
-
}
|
266 |
-
if (0 === $lastSlashPos = strrpos($uriPath, '/')) {
|
267 |
-
return '/';
|
268 |
-
}
|
269 |
-
|
270 |
-
return substr($uriPath, 0, $lastSlashPos);
|
271 |
-
}
|
272 |
-
|
273 |
-
public function withCookieHeader(RequestInterface $request)
|
274 |
-
{
|
275 |
-
$values = [];
|
276 |
-
$uri = $request->getUri();
|
277 |
-
$scheme = $uri->getScheme();
|
278 |
-
$host = $uri->getHost();
|
279 |
-
$path = $uri->getPath() ?: '/';
|
280 |
-
|
281 |
-
foreach ($this->cookies as $cookie) {
|
282 |
-
if ($cookie->matchesPath($path) &&
|
283 |
-
$cookie->matchesDomain($host) &&
|
284 |
-
!$cookie->isExpired() &&
|
285 |
-
(!$cookie->getSecure() || $scheme === 'https')
|
286 |
-
) {
|
287 |
-
$values[] = $cookie->getName() . '='
|
288 |
-
. $cookie->getValue();
|
289 |
-
}
|
290 |
-
}
|
291 |
-
|
292 |
-
return $values
|
293 |
-
? $request->withHeader('Cookie', implode('; ', $values))
|
294 |
-
: $request;
|
295 |
-
}
|
296 |
-
|
297 |
-
/**
|
298 |
-
* If a cookie already exists and the server asks to set it again with a
|
299 |
-
* null value, the cookie must be deleted.
|
300 |
-
*
|
301 |
-
* @param SetCookie $cookie
|
302 |
-
*/
|
303 |
-
private function removeCookieIfEmpty(SetCookie $cookie)
|
304 |
-
{
|
305 |
-
$cookieValue = $cookie->getValue();
|
306 |
-
if ($cookieValue === null || $cookieValue === '') {
|
307 |
-
$this->clear(
|
308 |
-
$cookie->getDomain(),
|
309 |
-
$cookie->getPath(),
|
310 |
-
$cookie->getName()
|
311 |
-
);
|
312 |
-
}
|
313 |
-
}
|
314 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Cookie/CookieJarInterface.php
DELETED
@@ -1,84 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Cookie;
|
3 |
-
|
4 |
-
use Psr\Http\Message\RequestInterface;
|
5 |
-
use Psr\Http\Message\ResponseInterface;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Stores HTTP cookies.
|
9 |
-
*
|
10 |
-
* It extracts cookies from HTTP requests, and returns them in HTTP responses.
|
11 |
-
* CookieJarInterface instances automatically expire contained cookies when
|
12 |
-
* necessary. Subclasses are also responsible for storing and retrieving
|
13 |
-
* cookies from a file, database, etc.
|
14 |
-
*
|
15 |
-
* @link http://docs.python.org/2/library/cookielib.html Inspiration
|
16 |
-
*/
|
17 |
-
interface CookieJarInterface extends \Countable, \IteratorAggregate
|
18 |
-
{
|
19 |
-
/**
|
20 |
-
* Create a request with added cookie headers.
|
21 |
-
*
|
22 |
-
* If no matching cookies are found in the cookie jar, then no Cookie
|
23 |
-
* header is added to the request and the same request is returned.
|
24 |
-
*
|
25 |
-
* @param RequestInterface $request Request object to modify.
|
26 |
-
*
|
27 |
-
* @return RequestInterface returns the modified request.
|
28 |
-
*/
|
29 |
-
public function withCookieHeader(RequestInterface $request);
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Extract cookies from an HTTP response and store them in the CookieJar.
|
33 |
-
*
|
34 |
-
* @param RequestInterface $request Request that was sent
|
35 |
-
* @param ResponseInterface $response Response that was received
|
36 |
-
*/
|
37 |
-
public function extractCookies(
|
38 |
-
RequestInterface $request,
|
39 |
-
ResponseInterface $response
|
40 |
-
);
|
41 |
-
|
42 |
-
/**
|
43 |
-
* Sets a cookie in the cookie jar.
|
44 |
-
*
|
45 |
-
* @param SetCookie $cookie Cookie to set.
|
46 |
-
*
|
47 |
-
* @return bool Returns true on success or false on failure
|
48 |
-
*/
|
49 |
-
public function setCookie(SetCookie $cookie);
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Remove cookies currently held in the cookie jar.
|
53 |
-
*
|
54 |
-
* Invoking this method without arguments will empty the whole cookie jar.
|
55 |
-
* If given a $domain argument only cookies belonging to that domain will
|
56 |
-
* be removed. If given a $domain and $path argument, cookies belonging to
|
57 |
-
* the specified path within that domain are removed. If given all three
|
58 |
-
* arguments, then the cookie with the specified name, path and domain is
|
59 |
-
* removed.
|
60 |
-
*
|
61 |
-
* @param string $domain Clears cookies matching a domain
|
62 |
-
* @param string $path Clears cookies matching a domain and path
|
63 |
-
* @param string $name Clears cookies matching a domain, path, and name
|
64 |
-
*
|
65 |
-
* @return CookieJarInterface
|
66 |
-
*/
|
67 |
-
public function clear($domain = null, $path = null, $name = null);
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Discard all sessions cookies.
|
71 |
-
*
|
72 |
-
* Removes cookies that don't have an expire field or a have a discard
|
73 |
-
* field set to true. To be called when the user agent shuts down according
|
74 |
-
* to RFC 2965.
|
75 |
-
*/
|
76 |
-
public function clearSessionCookies();
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Converts the cookie jar to an array.
|
80 |
-
*
|
81 |
-
* @return array
|
82 |
-
*/
|
83 |
-
public function toArray();
|
84 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Cookie/FileCookieJar.php
DELETED
@@ -1,90 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Cookie;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Persists non-session cookies using a JSON formatted file
|
6 |
-
*/
|
7 |
-
class FileCookieJar extends CookieJar
|
8 |
-
{
|
9 |
-
/** @var string filename */
|
10 |
-
private $filename;
|
11 |
-
|
12 |
-
/** @var bool Control whether to persist session cookies or not. */
|
13 |
-
private $storeSessionCookies;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Create a new FileCookieJar object
|
17 |
-
*
|
18 |
-
* @param string $cookieFile File to store the cookie data
|
19 |
-
* @param bool $storeSessionCookies Set to true to store session cookies
|
20 |
-
* in the cookie jar.
|
21 |
-
*
|
22 |
-
* @throws \RuntimeException if the file cannot be found or created
|
23 |
-
*/
|
24 |
-
public function __construct($cookieFile, $storeSessionCookies = false)
|
25 |
-
{
|
26 |
-
$this->filename = $cookieFile;
|
27 |
-
$this->storeSessionCookies = $storeSessionCookies;
|
28 |
-
|
29 |
-
if (file_exists($cookieFile)) {
|
30 |
-
$this->load($cookieFile);
|
31 |
-
}
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Saves the file when shutting down
|
36 |
-
*/
|
37 |
-
public function __destruct()
|
38 |
-
{
|
39 |
-
$this->save($this->filename);
|
40 |
-
}
|
41 |
-
|
42 |
-
/**
|
43 |
-
* Saves the cookies to a file.
|
44 |
-
*
|
45 |
-
* @param string $filename File to save
|
46 |
-
* @throws \RuntimeException if the file cannot be found or created
|
47 |
-
*/
|
48 |
-
public function save($filename)
|
49 |
-
{
|
50 |
-
$json = [];
|
51 |
-
foreach ($this as $cookie) {
|
52 |
-
/** @var SetCookie $cookie */
|
53 |
-
if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
|
54 |
-
$json[] = $cookie->toArray();
|
55 |
-
}
|
56 |
-
}
|
57 |
-
|
58 |
-
$jsonStr = \GuzzleHttp\json_encode($json);
|
59 |
-
if (false === file_put_contents($filename, $jsonStr)) {
|
60 |
-
throw new \RuntimeException("Unable to save file {$filename}");
|
61 |
-
}
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Load cookies from a JSON formatted file.
|
66 |
-
*
|
67 |
-
* Old cookies are kept unless overwritten by newly loaded ones.
|
68 |
-
*
|
69 |
-
* @param string $filename Cookie file to load.
|
70 |
-
* @throws \RuntimeException if the file cannot be loaded.
|
71 |
-
*/
|
72 |
-
public function load($filename)
|
73 |
-
{
|
74 |
-
$json = file_get_contents($filename);
|
75 |
-
if (false === $json) {
|
76 |
-
throw new \RuntimeException("Unable to load file {$filename}");
|
77 |
-
} elseif ($json === '') {
|
78 |
-
return;
|
79 |
-
}
|
80 |
-
|
81 |
-
$data = \GuzzleHttp\json_decode($json, true);
|
82 |
-
if (is_array($data)) {
|
83 |
-
foreach (json_decode($json, true) as $cookie) {
|
84 |
-
$this->setCookie(new SetCookie($cookie));
|
85 |
-
}
|
86 |
-
} elseif (strlen($data)) {
|
87 |
-
throw new \RuntimeException("Invalid cookie file: {$filename}");
|
88 |
-
}
|
89 |
-
}
|
90 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Cookie/SessionCookieJar.php
DELETED
@@ -1,71 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Cookie;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Persists cookies in the client session
|
6 |
-
*/
|
7 |
-
class SessionCookieJar extends CookieJar
|
8 |
-
{
|
9 |
-
/** @var string session key */
|
10 |
-
private $sessionKey;
|
11 |
-
|
12 |
-
/** @var bool Control whether to persist session cookies or not. */
|
13 |
-
private $storeSessionCookies;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Create a new SessionCookieJar object
|
17 |
-
*
|
18 |
-
* @param string $sessionKey Session key name to store the cookie
|
19 |
-
* data in session
|
20 |
-
* @param bool $storeSessionCookies Set to true to store session cookies
|
21 |
-
* in the cookie jar.
|
22 |
-
*/
|
23 |
-
public function __construct($sessionKey, $storeSessionCookies = false)
|
24 |
-
{
|
25 |
-
$this->sessionKey = $sessionKey;
|
26 |
-
$this->storeSessionCookies = $storeSessionCookies;
|
27 |
-
$this->load();
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Saves cookies to session when shutting down
|
32 |
-
*/
|
33 |
-
public function __destruct()
|
34 |
-
{
|
35 |
-
$this->save();
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Save cookies to the client session
|
40 |
-
*/
|
41 |
-
public function save()
|
42 |
-
{
|
43 |
-
$json = [];
|
44 |
-
foreach ($this as $cookie) {
|
45 |
-
/** @var SetCookie $cookie */
|
46 |
-
if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
|
47 |
-
$json[] = $cookie->toArray();
|
48 |
-
}
|
49 |
-
}
|
50 |
-
|
51 |
-
$_SESSION[$this->sessionKey] = json_encode($json);
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Load the contents of the client session into the data array
|
56 |
-
*/
|
57 |
-
protected function load()
|
58 |
-
{
|
59 |
-
if (!isset($_SESSION[$this->sessionKey])) {
|
60 |
-
return;
|
61 |
-
}
|
62 |
-
$data = json_decode($_SESSION[$this->sessionKey], true);
|
63 |
-
if (is_array($data)) {
|
64 |
-
foreach ($data as $cookie) {
|
65 |
-
$this->setCookie(new SetCookie($cookie));
|
66 |
-
}
|
67 |
-
} elseif (strlen($data)) {
|
68 |
-
throw new \RuntimeException("Invalid cookie data");
|
69 |
-
}
|
70 |
-
}
|
71 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Cookie/SetCookie.php
DELETED
@@ -1,403 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Cookie;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Set-Cookie object
|
6 |
-
*/
|
7 |
-
class SetCookie
|
8 |
-
{
|
9 |
-
/** @var array */
|
10 |
-
private static $defaults = [
|
11 |
-
'Name' => null,
|
12 |
-
'Value' => null,
|
13 |
-
'Domain' => null,
|
14 |
-
'Path' => '/',
|
15 |
-
'Max-Age' => null,
|
16 |
-
'Expires' => null,
|
17 |
-
'Secure' => false,
|
18 |
-
'Discard' => false,
|
19 |
-
'HttpOnly' => false
|
20 |
-
];
|
21 |
-
|
22 |
-
/** @var array Cookie data */
|
23 |
-
private $data;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Create a new SetCookie object from a string
|
27 |
-
*
|
28 |
-
* @param string $cookie Set-Cookie header string
|
29 |
-
*
|
30 |
-
* @return self
|
31 |
-
*/
|
32 |
-
public static function fromString($cookie)
|
33 |
-
{
|
34 |
-
// Create the default return array
|
35 |
-
$data = self::$defaults;
|
36 |
-
// Explode the cookie string using a series of semicolons
|
37 |
-
$pieces = array_filter(array_map('trim', explode(';', $cookie)));
|
38 |
-
// The name of the cookie (first kvp) must exist and include an equal sign.
|
39 |
-
if (empty($pieces[0]) || !strpos($pieces[0], '=')) {
|
40 |
-
return new self($data);
|
41 |
-
}
|
42 |
-
|
43 |
-
// Add the cookie pieces into the parsed data array
|
44 |
-
foreach ($pieces as $part) {
|
45 |
-
$cookieParts = explode('=', $part, 2);
|
46 |
-
$key = trim($cookieParts[0]);
|
47 |
-
$value = isset($cookieParts[1])
|
48 |
-
? trim($cookieParts[1], " \n\r\t\0\x0B")
|
49 |
-
: true;
|
50 |
-
|
51 |
-
// Only check for non-cookies when cookies have been found
|
52 |
-
if (empty($data['Name'])) {
|
53 |
-
$data['Name'] = $key;
|
54 |
-
$data['Value'] = $value;
|
55 |
-
} else {
|
56 |
-
foreach (array_keys(self::$defaults) as $search) {
|
57 |
-
if (!strcasecmp($search, $key)) {
|
58 |
-
$data[$search] = $value;
|
59 |
-
continue 2;
|
60 |
-
}
|
61 |
-
}
|
62 |
-
$data[$key] = $value;
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
return new self($data);
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* @param array $data Array of cookie data provided by a Cookie parser
|
71 |
-
*/
|
72 |
-
public function __construct(array $data = [])
|
73 |
-
{
|
74 |
-
$this->data = array_replace(self::$defaults, $data);
|
75 |
-
// Extract the Expires value and turn it into a UNIX timestamp if needed
|
76 |
-
if (!$this->getExpires() && $this->getMaxAge()) {
|
77 |
-
// Calculate the Expires date
|
78 |
-
$this->setExpires(time() + $this->getMaxAge());
|
79 |
-
} elseif ($this->getExpires() && !is_numeric($this->getExpires())) {
|
80 |
-
$this->setExpires($this->getExpires());
|
81 |
-
}
|
82 |
-
}
|
83 |
-
|
84 |
-
public function __toString()
|
85 |
-
{
|
86 |
-
$str = $this->data['Name'] . '=' . $this->data['Value'] . '; ';
|
87 |
-
foreach ($this->data as $k => $v) {
|
88 |
-
if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) {
|
89 |
-
if ($k === 'Expires') {
|
90 |
-
$str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; ';
|
91 |
-
} else {
|
92 |
-
$str .= ($v === true ? $k : "{$k}={$v}") . '; ';
|
93 |
-
}
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
return rtrim($str, '; ');
|
98 |
-
}
|
99 |
-
|
100 |
-
public function toArray()
|
101 |
-
{
|
102 |
-
return $this->data;
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Get the cookie name
|
107 |
-
*
|
108 |
-
* @return string
|
109 |
-
*/
|
110 |
-
public function getName()
|
111 |
-
{
|
112 |
-
return $this->data['Name'];
|
113 |
-
}
|
114 |
-
|
115 |
-
/**
|
116 |
-
* Set the cookie name
|
117 |
-
*
|
118 |
-
* @param string $name Cookie name
|
119 |
-
*/
|
120 |
-
public function setName($name)
|
121 |
-
{
|
122 |
-
$this->data['Name'] = $name;
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Get the cookie value
|
127 |
-
*
|
128 |
-
* @return string
|
129 |
-
*/
|
130 |
-
public function getValue()
|
131 |
-
{
|
132 |
-
return $this->data['Value'];
|
133 |
-
}
|
134 |
-
|
135 |
-
/**
|
136 |
-
* Set the cookie value
|
137 |
-
*
|
138 |
-
* @param string $value Cookie value
|
139 |
-
*/
|
140 |
-
public function setValue($value)
|
141 |
-
{
|
142 |
-
$this->data['Value'] = $value;
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
-
* Get the domain
|
147 |
-
*
|
148 |
-
* @return string|null
|
149 |
-
*/
|
150 |
-
public function getDomain()
|
151 |
-
{
|
152 |
-
return $this->data['Domain'];
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Set the domain of the cookie
|
157 |
-
*
|
158 |
-
* @param string $domain
|
159 |
-
*/
|
160 |
-
public function setDomain($domain)
|
161 |
-
{
|
162 |
-
$this->data['Domain'] = $domain;
|
163 |
-
}
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Get the path
|
167 |
-
*
|
168 |
-
* @return string
|
169 |
-
*/
|
170 |
-
public function getPath()
|
171 |
-
{
|
172 |
-
return $this->data['Path'];
|
173 |
-
}
|
174 |
-
|
175 |
-
/**
|
176 |
-
* Set the path of the cookie
|
177 |
-
*
|
178 |
-
* @param string $path Path of the cookie
|
179 |
-
*/
|
180 |
-
public function setPath($path)
|
181 |
-
{
|
182 |
-
$this->data['Path'] = $path;
|
183 |
-
}
|
184 |
-
|
185 |
-
/**
|
186 |
-
* Maximum lifetime of the cookie in seconds
|
187 |
-
*
|
188 |
-
* @return int|null
|
189 |
-
*/
|
190 |
-
public function getMaxAge()
|
191 |
-
{
|
192 |
-
return $this->data['Max-Age'];
|
193 |
-
}
|
194 |
-
|
195 |
-
/**
|
196 |
-
* Set the max-age of the cookie
|
197 |
-
*
|
198 |
-
* @param int $maxAge Max age of the cookie in seconds
|
199 |
-
*/
|
200 |
-
public function setMaxAge($maxAge)
|
201 |
-
{
|
202 |
-
$this->data['Max-Age'] = $maxAge;
|
203 |
-
}
|
204 |
-
|
205 |
-
/**
|
206 |
-
* The UNIX timestamp when the cookie Expires
|
207 |
-
*
|
208 |
-
* @return mixed
|
209 |
-
*/
|
210 |
-
public function getExpires()
|
211 |
-
{
|
212 |
-
return $this->data['Expires'];
|
213 |
-
}
|
214 |
-
|
215 |
-
/**
|
216 |
-
* Set the unix timestamp for which the cookie will expire
|
217 |
-
*
|
218 |
-
* @param int $timestamp Unix timestamp
|
219 |
-
*/
|
220 |
-
public function setExpires($timestamp)
|
221 |
-
{
|
222 |
-
$this->data['Expires'] = is_numeric($timestamp)
|
223 |
-
? (int) $timestamp
|
224 |
-
: strtotime($timestamp);
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* Get whether or not this is a secure cookie
|
229 |
-
*
|
230 |
-
* @return null|bool
|
231 |
-
*/
|
232 |
-
public function getSecure()
|
233 |
-
{
|
234 |
-
return $this->data['Secure'];
|
235 |
-
}
|
236 |
-
|
237 |
-
/**
|
238 |
-
* Set whether or not the cookie is secure
|
239 |
-
*
|
240 |
-
* @param bool $secure Set to true or false if secure
|
241 |
-
*/
|
242 |
-
public function setSecure($secure)
|
243 |
-
{
|
244 |
-
$this->data['Secure'] = $secure;
|
245 |
-
}
|
246 |
-
|
247 |
-
/**
|
248 |
-
* Get whether or not this is a session cookie
|
249 |
-
*
|
250 |
-
* @return null|bool
|
251 |
-
*/
|
252 |
-
public function getDiscard()
|
253 |
-
{
|
254 |
-
return $this->data['Discard'];
|
255 |
-
}
|
256 |
-
|
257 |
-
/**
|
258 |
-
* Set whether or not this is a session cookie
|
259 |
-
*
|
260 |
-
* @param bool $discard Set to true or false if this is a session cookie
|
261 |
-
*/
|
262 |
-
public function setDiscard($discard)
|
263 |
-
{
|
264 |
-
$this->data['Discard'] = $discard;
|
265 |
-
}
|
266 |
-
|
267 |
-
/**
|
268 |
-
* Get whether or not this is an HTTP only cookie
|
269 |
-
*
|
270 |
-
* @return bool
|
271 |
-
*/
|
272 |
-
public function getHttpOnly()
|
273 |
-
{
|
274 |
-
return $this->data['HttpOnly'];
|
275 |
-
}
|
276 |
-
|
277 |
-
/**
|
278 |
-
* Set whether or not this is an HTTP only cookie
|
279 |
-
*
|
280 |
-
* @param bool $httpOnly Set to true or false if this is HTTP only
|
281 |
-
*/
|
282 |
-
public function setHttpOnly($httpOnly)
|
283 |
-
{
|
284 |
-
$this->data['HttpOnly'] = $httpOnly;
|
285 |
-
}
|
286 |
-
|
287 |
-
/**
|
288 |
-
* Check if the cookie matches a path value.
|
289 |
-
*
|
290 |
-
* A request-path path-matches a given cookie-path if at least one of
|
291 |
-
* the following conditions holds:
|
292 |
-
*
|
293 |
-
* - The cookie-path and the request-path are identical.
|
294 |
-
* - The cookie-path is a prefix of the request-path, and the last
|
295 |
-
* character of the cookie-path is %x2F ("/").
|
296 |
-
* - The cookie-path is a prefix of the request-path, and the first
|
297 |
-
* character of the request-path that is not included in the cookie-
|
298 |
-
* path is a %x2F ("/") character.
|
299 |
-
*
|
300 |
-
* @param string $requestPath Path to check against
|
301 |
-
*
|
302 |
-
* @return bool
|
303 |
-
*/
|
304 |
-
public function matchesPath($requestPath)
|
305 |
-
{
|
306 |
-
$cookiePath = $this->getPath();
|
307 |
-
|
308 |
-
// Match on exact matches or when path is the default empty "/"
|
309 |
-
if ($cookiePath === '/' || $cookiePath == $requestPath) {
|
310 |
-
return true;
|
311 |
-
}
|
312 |
-
|
313 |
-
// Ensure that the cookie-path is a prefix of the request path.
|
314 |
-
if (0 !== strpos($requestPath, $cookiePath)) {
|
315 |
-
return false;
|
316 |
-
}
|
317 |
-
|
318 |
-
// Match if the last character of the cookie-path is "/"
|
319 |
-
if (substr($cookiePath, -1, 1) === '/') {
|
320 |
-
return true;
|
321 |
-
}
|
322 |
-
|
323 |
-
// Match if the first character not included in cookie path is "/"
|
324 |
-
return substr($requestPath, strlen($cookiePath), 1) === '/';
|
325 |
-
}
|
326 |
-
|
327 |
-
/**
|
328 |
-
* Check if the cookie matches a domain value
|
329 |
-
*
|
330 |
-
* @param string $domain Domain to check against
|
331 |
-
*
|
332 |
-
* @return bool
|
333 |
-
*/
|
334 |
-
public function matchesDomain($domain)
|
335 |
-
{
|
336 |
-
// Remove the leading '.' as per spec in RFC 6265.
|
337 |
-
// http://tools.ietf.org/html/rfc6265#section-5.2.3
|
338 |
-
$cookieDomain = ltrim($this->getDomain(), '.');
|
339 |
-
|
340 |
-
// Domain not set or exact match.
|
341 |
-
if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) {
|
342 |
-
return true;
|
343 |
-
}
|
344 |
-
|
345 |
-
// Matching the subdomain according to RFC 6265.
|
346 |
-
// http://tools.ietf.org/html/rfc6265#section-5.1.3
|
347 |
-
if (filter_var($domain, FILTER_VALIDATE_IP)) {
|
348 |
-
return false;
|
349 |
-
}
|
350 |
-
|
351 |
-
return (bool) preg_match('/\.' . preg_quote($cookieDomain, '/') . '$/', $domain);
|
352 |
-
}
|
353 |
-
|
354 |
-
/**
|
355 |
-
* Check if the cookie is expired
|
356 |
-
*
|
357 |
-
* @return bool
|
358 |
-
*/
|
359 |
-
public function isExpired()
|
360 |
-
{
|
361 |
-
return $this->getExpires() !== null && time() > $this->getExpires();
|
362 |
-
}
|
363 |
-
|
364 |
-
/**
|
365 |
-
* Check if the cookie is valid according to RFC 6265
|
366 |
-
*
|
367 |
-
* @return bool|string Returns true if valid or an error message if invalid
|
368 |
-
*/
|
369 |
-
public function validate()
|
370 |
-
{
|
371 |
-
// Names must not be empty, but can be 0
|
372 |
-
$name = $this->getName();
|
373 |
-
if (empty($name) && !is_numeric($name)) {
|
374 |
-
return 'The cookie name must not be empty';
|
375 |
-
}
|
376 |
-
|
377 |
-
// Check if any of the invalid characters are present in the cookie name
|
378 |
-
if (preg_match(
|
379 |
-
'/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/',
|
380 |
-
$name
|
381 |
-
)) {
|
382 |
-
return 'Cookie name must not contain invalid characters: ASCII '
|
383 |
-
. 'Control characters (0-31;127), space, tab and the '
|
384 |
-
. 'following characters: ()<>@,;:\"/?={}';
|
385 |
-
}
|
386 |
-
|
387 |
-
// Value must not be empty, but can be 0
|
388 |
-
$value = $this->getValue();
|
389 |
-
if (empty($value) && !is_numeric($value)) {
|
390 |
-
return 'The cookie value must not be empty';
|
391 |
-
}
|
392 |
-
|
393 |
-
// Domains must not be empty, but can be 0
|
394 |
-
// A "0" is not a valid internet domain, but may be used as server name
|
395 |
-
// in a private network.
|
396 |
-
$domain = $this->getDomain();
|
397 |
-
if (empty($domain) && !is_numeric($domain)) {
|
398 |
-
return 'The cookie domain must not be empty';
|
399 |
-
}
|
400 |
-
|
401 |
-
return true;
|
402 |
-
}
|
403 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Exception/ClientException.php
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Exception;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Exception when a client error is encountered (4xx codes)
|
6 |
-
*/
|
7 |
-
class ClientException extends BadResponseException {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Exception/GuzzleException.php
DELETED
@@ -1,13 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Exception;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* @method string getMessage()
|
6 |
-
* @method \Throwable|null getPrevious()
|
7 |
-
* @method mixed getCode()
|
8 |
-
* @method string getFile()
|
9 |
-
* @method int getLine()
|
10 |
-
* @method array getTrace()
|
11 |
-
* @method string getTraceAsString()
|
12 |
-
*/
|
13 |
-
interface GuzzleException {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Exception/RequestException.php
DELETED
@@ -1,217 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Exception;
|
3 |
-
|
4 |
-
use Psr\Http\Message\RequestInterface;
|
5 |
-
use Psr\Http\Message\ResponseInterface;
|
6 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
7 |
-
use Psr\Http\Message\UriInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* HTTP Request exception
|
11 |
-
*/
|
12 |
-
class RequestException extends TransferException
|
13 |
-
{
|
14 |
-
/** @var RequestInterface */
|
15 |
-
private $request;
|
16 |
-
|
17 |
-
/** @var ResponseInterface */
|
18 |
-
private $response;
|
19 |
-
|
20 |
-
/** @var array */
|
21 |
-
private $handlerContext;
|
22 |
-
|
23 |
-
public function __construct(
|
24 |
-
$message,
|
25 |
-
RequestInterface $request,
|
26 |
-
ResponseInterface $response = null,
|
27 |
-
\Exception $previous = null,
|
28 |
-
array $handlerContext = []
|
29 |
-
) {
|
30 |
-
// Set the code of the exception if the response is set and not future.
|
31 |
-
$code = $response && !($response instanceof PromiseInterface)
|
32 |
-
? $response->getStatusCode()
|
33 |
-
: 0;
|
34 |
-
parent::__construct($message, $code, $previous);
|
35 |
-
$this->request = $request;
|
36 |
-
$this->response = $response;
|
37 |
-
$this->handlerContext = $handlerContext;
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Wrap non-RequestExceptions with a RequestException
|
42 |
-
*
|
43 |
-
* @param RequestInterface $request
|
44 |
-
* @param \Exception $e
|
45 |
-
*
|
46 |
-
* @return RequestException
|
47 |
-
*/
|
48 |
-
public static function wrapException(RequestInterface $request, \Exception $e)
|
49 |
-
{
|
50 |
-
return $e instanceof RequestException
|
51 |
-
? $e
|
52 |
-
: new RequestException($e->getMessage(), $request, null, $e);
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Factory method to create a new exception with a normalized error message
|
57 |
-
*
|
58 |
-
* @param RequestInterface $request Request
|
59 |
-
* @param ResponseInterface $response Response received
|
60 |
-
* @param \Exception $previous Previous exception
|
61 |
-
* @param array $ctx Optional handler context.
|
62 |
-
*
|
63 |
-
* @return self
|
64 |
-
*/
|
65 |
-
public static function create(
|
66 |
-
RequestInterface $request,
|
67 |
-
ResponseInterface $response = null,
|
68 |
-
\Exception $previous = null,
|
69 |
-
array $ctx = []
|
70 |
-
) {
|
71 |
-
if (!$response) {
|
72 |
-
return new self(
|
73 |
-
'Error completing request',
|
74 |
-
$request,
|
75 |
-
null,
|
76 |
-
$previous,
|
77 |
-
$ctx
|
78 |
-
);
|
79 |
-
}
|
80 |
-
|
81 |
-
$level = (int) floor($response->getStatusCode() / 100);
|
82 |
-
if ($level === 4) {
|
83 |
-
$label = 'Client error';
|
84 |
-
$className = ClientException::class;
|
85 |
-
} elseif ($level === 5) {
|
86 |
-
$label = 'Server error';
|
87 |
-
$className = ServerException::class;
|
88 |
-
} else {
|
89 |
-
$label = 'Unsuccessful request';
|
90 |
-
$className = __CLASS__;
|
91 |
-
}
|
92 |
-
|
93 |
-
$uri = $request->getUri();
|
94 |
-
$uri = static::obfuscateUri($uri);
|
95 |
-
|
96 |
-
// Client Error: `GET /` resulted in a `404 Not Found` response:
|
97 |
-
// <html> ... (truncated)
|
98 |
-
$message = sprintf(
|
99 |
-
'%s: `%s %s` resulted in a `%s %s` response',
|
100 |
-
$label,
|
101 |
-
$request->getMethod(),
|
102 |
-
$uri,
|
103 |
-
$response->getStatusCode(),
|
104 |
-
$response->getReasonPhrase()
|
105 |
-
);
|
106 |
-
|
107 |
-
$summary = static::getResponseBodySummary($response);
|
108 |
-
|
109 |
-
if ($summary !== null) {
|
110 |
-
$message .= ":\n{$summary}\n";
|
111 |
-
}
|
112 |
-
|
113 |
-
return new $className($message, $request, $response, $previous, $ctx);
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Get a short summary of the response
|
118 |
-
*
|
119 |
-
* Will return `null` if the response is not printable.
|
120 |
-
*
|
121 |
-
* @param ResponseInterface $response
|
122 |
-
*
|
123 |
-
* @return string|null
|
124 |
-
*/
|
125 |
-
public static function getResponseBodySummary(ResponseInterface $response)
|
126 |
-
{
|
127 |
-
$body = $response->getBody();
|
128 |
-
|
129 |
-
if (!$body->isSeekable()) {
|
130 |
-
return null;
|
131 |
-
}
|
132 |
-
|
133 |
-
$size = $body->getSize();
|
134 |
-
|
135 |
-
if ($size === 0) {
|
136 |
-
return null;
|
137 |
-
}
|
138 |
-
|
139 |
-
$summary = $body->read(120);
|
140 |
-
$body->rewind();
|
141 |
-
|
142 |
-
if ($size > 120) {
|
143 |
-
$summary .= ' (truncated...)';
|
144 |
-
}
|
145 |
-
|
146 |
-
// Matches any printable character, including unicode characters:
|
147 |
-
// letters, marks, numbers, punctuation, spacing, and separators.
|
148 |
-
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
|
149 |
-
return null;
|
150 |
-
}
|
151 |
-
|
152 |
-
return $summary;
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Obfuscates URI if there is an username and a password present
|
157 |
-
*
|
158 |
-
* @param UriInterface $uri
|
159 |
-
*
|
160 |
-
* @return UriInterface
|
161 |
-
*/
|
162 |
-
private static function obfuscateUri($uri)
|
163 |
-
{
|
164 |
-
$userInfo = $uri->getUserInfo();
|
165 |
-
|
166 |
-
if (false !== ($pos = strpos($userInfo, ':'))) {
|
167 |
-
return $uri->withUserInfo(substr($userInfo, 0, $pos), '***');
|
168 |
-
}
|
169 |
-
|
170 |
-
return $uri;
|
171 |
-
}
|
172 |
-
|
173 |
-
/**
|
174 |
-
* Get the request that caused the exception
|
175 |
-
*
|
176 |
-
* @return RequestInterface
|
177 |
-
*/
|
178 |
-
public function getRequest()
|
179 |
-
{
|
180 |
-
return $this->request;
|
181 |
-
}
|
182 |
-
|
183 |
-
/**
|
184 |
-
* Get the associated response
|
185 |
-
*
|
186 |
-
* @return ResponseInterface|null
|
187 |
-
*/
|
188 |
-
public function getResponse()
|
189 |
-
{
|
190 |
-
return $this->response;
|
191 |
-
}
|
192 |
-
|
193 |
-
/**
|
194 |
-
* Check if a response was received
|
195 |
-
*
|
196 |
-
* @return bool
|
197 |
-
*/
|
198 |
-
public function hasResponse()
|
199 |
-
{
|
200 |
-
return $this->response !== null;
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* Get contextual information about the error from the underlying handler.
|
205 |
-
*
|
206 |
-
* The contents of this array will vary depending on which handler you are
|
207 |
-
* using. It may also be just an empty array. Relying on this data will
|
208 |
-
* couple you to a specific handler, but can give more debug information
|
209 |
-
* when needed.
|
210 |
-
*
|
211 |
-
* @return array
|
212 |
-
*/
|
213 |
-
public function getHandlerContext()
|
214 |
-
{
|
215 |
-
return $this->handlerContext;
|
216 |
-
}
|
217 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Exception/ServerException.php
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Exception;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Exception when a server error is encountered (5xx codes)
|
6 |
-
*/
|
7 |
-
class ServerException extends BadResponseException {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Exception/TooManyRedirectsException.php
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Exception;
|
3 |
-
|
4 |
-
class TooManyRedirectsException extends RequestException {}
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Exception/TransferException.php
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Exception;
|
3 |
-
|
4 |
-
class TransferException extends \RuntimeException implements GuzzleException {}
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Handler/CurlFactory.php
DELETED
@@ -1,565 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Handler;
|
3 |
-
|
4 |
-
use GuzzleHttp\Exception\RequestException;
|
5 |
-
use GuzzleHttp\Exception\ConnectException;
|
6 |
-
use GuzzleHttp\Promise\FulfilledPromise;
|
7 |
-
use GuzzleHttp\Psr7;
|
8 |
-
use GuzzleHttp\Psr7\LazyOpenStream;
|
9 |
-
use GuzzleHttp\TransferStats;
|
10 |
-
use Psr\Http\Message\RequestInterface;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Creates curl resources from a request
|
14 |
-
*/
|
15 |
-
class CurlFactory implements CurlFactoryInterface
|
16 |
-
{
|
17 |
-
/** @var array */
|
18 |
-
private $handles = [];
|
19 |
-
|
20 |
-
/** @var int Total number of idle handles to keep in cache */
|
21 |
-
private $maxHandles;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @param int $maxHandles Maximum number of idle handles.
|
25 |
-
*/
|
26 |
-
public function __construct($maxHandles)
|
27 |
-
{
|
28 |
-
$this->maxHandles = $maxHandles;
|
29 |
-
}
|
30 |
-
|
31 |
-
public function create(RequestInterface $request, array $options)
|
32 |
-
{
|
33 |
-
if (isset($options['curl']['body_as_string'])) {
|
34 |
-
$options['_body_as_string'] = $options['curl']['body_as_string'];
|
35 |
-
unset($options['curl']['body_as_string']);
|
36 |
-
}
|
37 |
-
|
38 |
-
$easy = new EasyHandle;
|
39 |
-
$easy->request = $request;
|
40 |
-
$easy->options = $options;
|
41 |
-
$conf = $this->getDefaultConf($easy);
|
42 |
-
$this->applyMethod($easy, $conf);
|
43 |
-
$this->applyHandlerOptions($easy, $conf);
|
44 |
-
$this->applyHeaders($easy, $conf);
|
45 |
-
unset($conf['_headers']);
|
46 |
-
|
47 |
-
// Add handler options from the request configuration options
|
48 |
-
if (isset($options['curl'])) {
|
49 |
-
$conf = array_replace($conf, $options['curl']);
|
50 |
-
}
|
51 |
-
|
52 |
-
$conf[CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy);
|
53 |
-
$easy->handle = $this->handles
|
54 |
-
? array_pop($this->handles)
|
55 |
-
: curl_init();
|
56 |
-
curl_setopt_array($easy->handle, $conf);
|
57 |
-
|
58 |
-
return $easy;
|
59 |
-
}
|
60 |
-
|
61 |
-
public function release(EasyHandle $easy)
|
62 |
-
{
|
63 |
-
$resource = $easy->handle;
|
64 |
-
unset($easy->handle);
|
65 |
-
|
66 |
-
if (count($this->handles) >= $this->maxHandles) {
|
67 |
-
curl_close($resource);
|
68 |
-
} else {
|
69 |
-
// Remove all callback functions as they can hold onto references
|
70 |
-
// and are not cleaned up by curl_reset. Using curl_setopt_array
|
71 |
-
// does not work for some reason, so removing each one
|
72 |
-
// individually.
|
73 |
-
curl_setopt($resource, CURLOPT_HEADERFUNCTION, null);
|
74 |
-
curl_setopt($resource, CURLOPT_READFUNCTION, null);
|
75 |
-
curl_setopt($resource, CURLOPT_WRITEFUNCTION, null);
|
76 |
-
curl_setopt($resource, CURLOPT_PROGRESSFUNCTION, null);
|
77 |
-
curl_reset($resource);
|
78 |
-
$this->handles[] = $resource;
|
79 |
-
}
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Completes a cURL transaction, either returning a response promise or a
|
84 |
-
* rejected promise.
|
85 |
-
*
|
86 |
-
* @param callable $handler
|
87 |
-
* @param EasyHandle $easy
|
88 |
-
* @param CurlFactoryInterface $factory Dictates how the handle is released
|
89 |
-
*
|
90 |
-
* @return \GuzzleHttp\Promise\PromiseInterface
|
91 |
-
*/
|
92 |
-
public static function finish(
|
93 |
-
callable $handler,
|
94 |
-
EasyHandle $easy,
|
95 |
-
CurlFactoryInterface $factory
|
96 |
-
) {
|
97 |
-
if (isset($easy->options['on_stats'])) {
|
98 |
-
self::invokeStats($easy);
|
99 |
-
}
|
100 |
-
|
101 |
-
if (!$easy->response || $easy->errno) {
|
102 |
-
return self::finishError($handler, $easy, $factory);
|
103 |
-
}
|
104 |
-
|
105 |
-
// Return the response if it is present and there is no error.
|
106 |
-
$factory->release($easy);
|
107 |
-
|
108 |
-
// Rewind the body of the response if possible.
|
109 |
-
$body = $easy->response->getBody();
|
110 |
-
if ($body->isSeekable()) {
|
111 |
-
$body->rewind();
|
112 |
-
}
|
113 |
-
|
114 |
-
return new FulfilledPromise($easy->response);
|
115 |
-
}
|
116 |
-
|
117 |
-
private static function invokeStats(EasyHandle $easy)
|
118 |
-
{
|
119 |
-
$curlStats = curl_getinfo($easy->handle);
|
120 |
-
$stats = new TransferStats(
|
121 |
-
$easy->request,
|
122 |
-
$easy->response,
|
123 |
-
$curlStats['total_time'],
|
124 |
-
$easy->errno,
|
125 |
-
$curlStats
|
126 |
-
);
|
127 |
-
call_user_func($easy->options['on_stats'], $stats);
|
128 |
-
}
|
129 |
-
|
130 |
-
private static function finishError(
|
131 |
-
callable $handler,
|
132 |
-
EasyHandle $easy,
|
133 |
-
CurlFactoryInterface $factory
|
134 |
-
) {
|
135 |
-
// Get error information and release the handle to the factory.
|
136 |
-
$ctx = [
|
137 |
-
'errno' => $easy->errno,
|
138 |
-
'error' => curl_error($easy->handle),
|
139 |
-
] + curl_getinfo($easy->handle);
|
140 |
-
$factory->release($easy);
|
141 |
-
|
142 |
-
// Retry when nothing is present or when curl failed to rewind.
|
143 |
-
if (empty($easy->options['_err_message'])
|
144 |
-
&& (!$easy->errno || $easy->errno == 65)
|
145 |
-
) {
|
146 |
-
return self::retryFailedRewind($handler, $easy, $ctx);
|
147 |
-
}
|
148 |
-
|
149 |
-
return self::createRejection($easy, $ctx);
|
150 |
-
}
|
151 |
-
|
152 |
-
private static function createRejection(EasyHandle $easy, array $ctx)
|
153 |
-
{
|
154 |
-
static $connectionErrors = [
|
155 |
-
CURLE_OPERATION_TIMEOUTED => true,
|
156 |
-
CURLE_COULDNT_RESOLVE_HOST => true,
|
157 |
-
CURLE_COULDNT_CONNECT => true,
|
158 |
-
CURLE_SSL_CONNECT_ERROR => true,
|
159 |
-
CURLE_GOT_NOTHING => true,
|
160 |
-
];
|
161 |
-
|
162 |
-
// If an exception was encountered during the onHeaders event, then
|
163 |
-
// return a rejected promise that wraps that exception.
|
164 |
-
if ($easy->onHeadersException) {
|
165 |
-
return \GuzzleHttp\Promise\rejection_for(
|
166 |
-
new RequestException(
|
167 |
-
'An error was encountered during the on_headers event',
|
168 |
-
$easy->request,
|
169 |
-
$easy->response,
|
170 |
-
$easy->onHeadersException,
|
171 |
-
$ctx
|
172 |
-
)
|
173 |
-
);
|
174 |
-
}
|
175 |
-
|
176 |
-
$message = sprintf(
|
177 |
-
'cURL error %s: %s (%s)',
|
178 |
-
$ctx['errno'],
|
179 |
-
$ctx['error'],
|
180 |
-
'see http://curl.haxx.se/libcurl/c/libcurl-errors.html'
|
181 |
-
);
|
182 |
-
|
183 |
-
// Create a connection exception if it was a specific error code.
|
184 |
-
$error = isset($connectionErrors[$easy->errno])
|
185 |
-
? new ConnectException($message, $easy->request, null, $ctx)
|
186 |
-
: new RequestException($message, $easy->request, $easy->response, null, $ctx);
|
187 |
-
|
188 |
-
return \GuzzleHttp\Promise\rejection_for($error);
|
189 |
-
}
|
190 |
-
|
191 |
-
private function getDefaultConf(EasyHandle $easy)
|
192 |
-
{
|
193 |
-
$conf = [
|
194 |
-
'_headers' => $easy->request->getHeaders(),
|
195 |
-
CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
|
196 |
-
CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
|
197 |
-
CURLOPT_RETURNTRANSFER => false,
|
198 |
-
CURLOPT_HEADER => false,
|
199 |
-
CURLOPT_CONNECTTIMEOUT => 150,
|
200 |
-
];
|
201 |
-
|
202 |
-
if (defined('CURLOPT_PROTOCOLS')) {
|
203 |
-
$conf[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS;
|
204 |
-
}
|
205 |
-
|
206 |
-
$version = $easy->request->getProtocolVersion();
|
207 |
-
if ($version == 1.1) {
|
208 |
-
$conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
|
209 |
-
} elseif ($version == 2.0) {
|
210 |
-
$conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0;
|
211 |
-
} else {
|
212 |
-
$conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
|
213 |
-
}
|
214 |
-
|
215 |
-
return $conf;
|
216 |
-
}
|
217 |
-
|
218 |
-
private function applyMethod(EasyHandle $easy, array &$conf)
|
219 |
-
{
|
220 |
-
$body = $easy->request->getBody();
|
221 |
-
$size = $body->getSize();
|
222 |
-
|
223 |
-
if ($size === null || $size > 0) {
|
224 |
-
$this->applyBody($easy->request, $easy->options, $conf);
|
225 |
-
return;
|
226 |
-
}
|
227 |
-
|
228 |
-
$method = $easy->request->getMethod();
|
229 |
-
if ($method === 'PUT' || $method === 'POST') {
|
230 |
-
// See http://tools.ietf.org/html/rfc7230#section-3.3.2
|
231 |
-
if (!$easy->request->hasHeader('Content-Length')) {
|
232 |
-
$conf[CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
|
233 |
-
}
|
234 |
-
} elseif ($method === 'HEAD') {
|
235 |
-
$conf[CURLOPT_NOBODY] = true;
|
236 |
-
unset(
|
237 |
-
$conf[CURLOPT_WRITEFUNCTION],
|
238 |
-
$conf[CURLOPT_READFUNCTION],
|
239 |
-
$conf[CURLOPT_FILE],
|
240 |
-
$conf[CURLOPT_INFILE]
|
241 |
-
);
|
242 |
-
}
|
243 |
-
}
|
244 |
-
|
245 |
-
private function applyBody(RequestInterface $request, array $options, array &$conf)
|
246 |
-
{
|
247 |
-
$size = $request->hasHeader('Content-Length')
|
248 |
-
? (int) $request->getHeaderLine('Content-Length')
|
249 |
-
: null;
|
250 |
-
|
251 |
-
// Send the body as a string if the size is less than 1MB OR if the
|
252 |
-
// [curl][body_as_string] request value is set.
|
253 |
-
if (($size !== null && $size < 1000000) ||
|
254 |
-
!empty($options['_body_as_string'])
|
255 |
-
) {
|
256 |
-
$conf[CURLOPT_POSTFIELDS] = (string) $request->getBody();
|
257 |
-
// Don't duplicate the Content-Length header
|
258 |
-
$this->removeHeader('Content-Length', $conf);
|
259 |
-
$this->removeHeader('Transfer-Encoding', $conf);
|
260 |
-
} else {
|
261 |
-
$conf[CURLOPT_UPLOAD] = true;
|
262 |
-
if ($size !== null) {
|
263 |
-
$conf[CURLOPT_INFILESIZE] = $size;
|
264 |
-
$this->removeHeader('Content-Length', $conf);
|
265 |
-
}
|
266 |
-
$body = $request->getBody();
|
267 |
-
if ($body->isSeekable()) {
|
268 |
-
$body->rewind();
|
269 |
-
}
|
270 |
-
$conf[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) {
|
271 |
-
return $body->read($length);
|
272 |
-
};
|
273 |
-
}
|
274 |
-
|
275 |
-
// If the Expect header is not present, prevent curl from adding it
|
276 |
-
if (!$request->hasHeader('Expect')) {
|
277 |
-
$conf[CURLOPT_HTTPHEADER][] = 'Expect:';
|
278 |
-
}
|
279 |
-
|
280 |
-
// cURL sometimes adds a content-type by default. Prevent this.
|
281 |
-
if (!$request->hasHeader('Content-Type')) {
|
282 |
-
$conf[CURLOPT_HTTPHEADER][] = 'Content-Type:';
|
283 |
-
}
|
284 |
-
}
|
285 |
-
|
286 |
-
private function applyHeaders(EasyHandle $easy, array &$conf)
|
287 |
-
{
|
288 |
-
foreach ($conf['_headers'] as $name => $values) {
|
289 |
-
foreach ($values as $value) {
|
290 |
-
$value = (string) $value;
|
291 |
-
if ($value === '') {
|
292 |
-
// cURL requires a special format for empty headers.
|
293 |
-
// See https://github.com/guzzle/guzzle/issues/1882 for more details.
|
294 |
-
$conf[CURLOPT_HTTPHEADER][] = "$name;";
|
295 |
-
} else {
|
296 |
-
$conf[CURLOPT_HTTPHEADER][] = "$name: $value";
|
297 |
-
}
|
298 |
-
}
|
299 |
-
}
|
300 |
-
|
301 |
-
// Remove the Accept header if one was not set
|
302 |
-
if (!$easy->request->hasHeader('Accept')) {
|
303 |
-
$conf[CURLOPT_HTTPHEADER][] = 'Accept:';
|
304 |
-
}
|
305 |
-
}
|
306 |
-
|
307 |
-
/**
|
308 |
-
* Remove a header from the options array.
|
309 |
-
*
|
310 |
-
* @param string $name Case-insensitive header to remove
|
311 |
-
* @param array $options Array of options to modify
|
312 |
-
*/
|
313 |
-
private function removeHeader($name, array &$options)
|
314 |
-
{
|
315 |
-
foreach (array_keys($options['_headers']) as $key) {
|
316 |
-
if (!strcasecmp($key, $name)) {
|
317 |
-
unset($options['_headers'][$key]);
|
318 |
-
return;
|
319 |
-
}
|
320 |
-
}
|
321 |
-
}
|
322 |
-
|
323 |
-
private function applyHandlerOptions(EasyHandle $easy, array &$conf)
|
324 |
-
{
|
325 |
-
$options = $easy->options;
|
326 |
-
if (isset($options['verify'])) {
|
327 |
-
if ($options['verify'] === false) {
|
328 |
-
unset($conf[CURLOPT_CAINFO]);
|
329 |
-
$conf[CURLOPT_SSL_VERIFYHOST] = 0;
|
330 |
-
$conf[CURLOPT_SSL_VERIFYPEER] = false;
|
331 |
-
} else {
|
332 |
-
$conf[CURLOPT_SSL_VERIFYHOST] = 2;
|
333 |
-
$conf[CURLOPT_SSL_VERIFYPEER] = true;
|
334 |
-
if (is_string($options['verify'])) {
|
335 |
-
// Throw an error if the file/folder/link path is not valid or doesn't exist.
|
336 |
-
if (!file_exists($options['verify'])) {
|
337 |
-
throw new \InvalidArgumentException(
|
338 |
-
"SSL CA bundle not found: {$options['verify']}"
|
339 |
-
);
|
340 |
-
}
|
341 |
-
// If it's a directory or a link to a directory use CURLOPT_CAPATH.
|
342 |
-
// If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
|
343 |
-
if (is_dir($options['verify']) ||
|
344 |
-
(is_link($options['verify']) && is_dir(readlink($options['verify'])))) {
|
345 |
-
$conf[CURLOPT_CAPATH] = $options['verify'];
|
346 |
-
} else {
|
347 |
-
$conf[CURLOPT_CAINFO] = $options['verify'];
|
348 |
-
}
|
349 |
-
}
|
350 |
-
}
|
351 |
-
}
|
352 |
-
|
353 |
-
if (!empty($options['decode_content'])) {
|
354 |
-
$accept = $easy->request->getHeaderLine('Accept-Encoding');
|
355 |
-
if ($accept) {
|
356 |
-
$conf[CURLOPT_ENCODING] = $accept;
|
357 |
-
} else {
|
358 |
-
$conf[CURLOPT_ENCODING] = '';
|
359 |
-
// Don't let curl send the header over the wire
|
360 |
-
$conf[CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
|
361 |
-
}
|
362 |
-
}
|
363 |
-
|
364 |
-
if (isset($options['sink'])) {
|
365 |
-
$sink = $options['sink'];
|
366 |
-
if (!is_string($sink)) {
|
367 |
-
$sink = \GuzzleHttp\Psr7\stream_for($sink);
|
368 |
-
} elseif (!is_dir(dirname($sink))) {
|
369 |
-
// Ensure that the directory exists before failing in curl.
|
370 |
-
throw new \RuntimeException(sprintf(
|
371 |
-
'Directory %s does not exist for sink value of %s',
|
372 |
-
dirname($sink),
|
373 |
-
$sink
|
374 |
-
));
|
375 |
-
} else {
|
376 |
-
$sink = new LazyOpenStream($sink, 'w+');
|
377 |
-
}
|
378 |
-
$easy->sink = $sink;
|
379 |
-
$conf[CURLOPT_WRITEFUNCTION] = function ($ch, $write) use ($sink) {
|
380 |
-
return $sink->write($write);
|
381 |
-
};
|
382 |
-
} else {
|
383 |
-
// Use a default temp stream if no sink was set.
|
384 |
-
$conf[CURLOPT_FILE] = fopen('php://temp', 'w+');
|
385 |
-
$easy->sink = Psr7\stream_for($conf[CURLOPT_FILE]);
|
386 |
-
}
|
387 |
-
$timeoutRequiresNoSignal = false;
|
388 |
-
if (isset($options['timeout'])) {
|
389 |
-
$timeoutRequiresNoSignal |= $options['timeout'] < 1;
|
390 |
-
$conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
|
391 |
-
}
|
392 |
-
|
393 |
-
// CURL default value is CURL_IPRESOLVE_WHATEVER
|
394 |
-
if (isset($options['force_ip_resolve'])) {
|
395 |
-
if ('v4' === $options['force_ip_resolve']) {
|
396 |
-
$conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4;
|
397 |
-
} elseif ('v6' === $options['force_ip_resolve']) {
|
398 |
-
$conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V6;
|
399 |
-
}
|
400 |
-
}
|
401 |
-
|
402 |
-
if (isset($options['connect_timeout'])) {
|
403 |
-
$timeoutRequiresNoSignal |= $options['connect_timeout'] < 1;
|
404 |
-
$conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
|
405 |
-
}
|
406 |
-
|
407 |
-
if ($timeoutRequiresNoSignal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
408 |
-
$conf[CURLOPT_NOSIGNAL] = true;
|
409 |
-
}
|
410 |
-
|
411 |
-
if (isset($options['proxy'])) {
|
412 |
-
if (!is_array($options['proxy'])) {
|
413 |
-
$conf[CURLOPT_PROXY] = $options['proxy'];
|
414 |
-
} else {
|
415 |
-
$scheme = $easy->request->getUri()->getScheme();
|
416 |
-
if (isset($options['proxy'][$scheme])) {
|
417 |
-
$host = $easy->request->getUri()->getHost();
|
418 |
-
if (!isset($options['proxy']['no']) ||
|
419 |
-
!\GuzzleHttp\is_host_in_noproxy($host, $options['proxy']['no'])
|
420 |
-
) {
|
421 |
-
$conf[CURLOPT_PROXY] = $options['proxy'][$scheme];
|
422 |
-
}
|
423 |
-
}
|
424 |
-
}
|
425 |
-
}
|
426 |
-
|
427 |
-
if (isset($options['cert'])) {
|
428 |
-
$cert = $options['cert'];
|
429 |
-
if (is_array($cert)) {
|
430 |
-
$conf[CURLOPT_SSLCERTPASSWD] = $cert[1];
|
431 |
-
$cert = $cert[0];
|
432 |
-
}
|
433 |
-
if (!file_exists($cert)) {
|
434 |
-
throw new \InvalidArgumentException(
|
435 |
-
"SSL certificate not found: {$cert}"
|
436 |
-
);
|
437 |
-
}
|
438 |
-
$conf[CURLOPT_SSLCERT] = $cert;
|
439 |
-
}
|
440 |
-
|
441 |
-
if (isset($options['ssl_key'])) {
|
442 |
-
$sslKey = $options['ssl_key'];
|
443 |
-
if (is_array($sslKey)) {
|
444 |
-
$conf[CURLOPT_SSLKEYPASSWD] = $sslKey[1];
|
445 |
-
$sslKey = $sslKey[0];
|
446 |
-
}
|
447 |
-
if (!file_exists($sslKey)) {
|
448 |
-
throw new \InvalidArgumentException(
|
449 |
-
"SSL private key not found: {$sslKey}"
|
450 |
-
);
|
451 |
-
}
|
452 |
-
$conf[CURLOPT_SSLKEY] = $sslKey;
|
453 |
-
}
|
454 |
-
|
455 |
-
if (isset($options['progress'])) {
|
456 |
-
$progress = $options['progress'];
|
457 |
-
if (!is_callable($progress)) {
|
458 |
-
throw new \InvalidArgumentException(
|
459 |
-
'progress client option must be callable'
|
460 |
-
);
|
461 |
-
}
|
462 |
-
$conf[CURLOPT_NOPROGRESS] = false;
|
463 |
-
$conf[CURLOPT_PROGRESSFUNCTION] = function () use ($progress) {
|
464 |
-
$args = func_get_args();
|
465 |
-
// PHP 5.5 pushed the handle onto the start of the args
|
466 |
-
if (is_resource($args[0])) {
|
467 |
-
array_shift($args);
|
468 |
-
}
|
469 |
-
call_user_func_array($progress, $args);
|
470 |
-
};
|
471 |
-
}
|
472 |
-
|
473 |
-
if (!empty($options['debug'])) {
|
474 |
-
$conf[CURLOPT_STDERR] = \GuzzleHttp\debug_resource($options['debug']);
|
475 |
-
$conf[CURLOPT_VERBOSE] = true;
|
476 |
-
}
|
477 |
-
}
|
478 |
-
|
479 |
-
/**
|
480 |
-
* This function ensures that a response was set on a transaction. If one
|
481 |
-
* was not set, then the request is retried if possible. This error
|
482 |
-
* typically means you are sending a payload, curl encountered a
|
483 |
-
* "Connection died, retrying a fresh connect" error, tried to rewind the
|
484 |
-
* stream, and then encountered a "necessary data rewind wasn't possible"
|
485 |
-
* error, causing the request to be sent through curl_multi_info_read()
|
486 |
-
* without an error status.
|
487 |
-
*/
|
488 |
-
private static function retryFailedRewind(
|
489 |
-
callable $handler,
|
490 |
-
EasyHandle $easy,
|
491 |
-
array $ctx
|
492 |
-
) {
|
493 |
-
try {
|
494 |
-
// Only rewind if the body has been read from.
|
495 |
-
$body = $easy->request->getBody();
|
496 |
-
if ($body->tell() > 0) {
|
497 |
-
$body->rewind();
|
498 |
-
}
|
499 |
-
} catch (\RuntimeException $e) {
|
500 |
-
$ctx['error'] = 'The connection unexpectedly failed without '
|
501 |
-
. 'providing an error. The request would have been retried, '
|
502 |
-
. 'but attempting to rewind the request body failed. '
|
503 |
-
. 'Exception: ' . $e;
|
504 |
-
return self::createRejection($easy, $ctx);
|
505 |
-
}
|
506 |
-
|
507 |
-
// Retry no more than 3 times before giving up.
|
508 |
-
if (!isset($easy->options['_curl_retries'])) {
|
509 |
-
$easy->options['_curl_retries'] = 1;
|
510 |
-
} elseif ($easy->options['_curl_retries'] == 2) {
|
511 |
-
$ctx['error'] = 'The cURL request was retried 3 times '
|
512 |
-
. 'and did not succeed. The most likely reason for the failure '
|
513 |
-
. 'is that cURL was unable to rewind the body of the request '
|
514 |
-
. 'and subsequent retries resulted in the same error. Turn on '
|
515 |
-
. 'the debug option to see what went wrong. See '
|
516 |
-
. 'https://bugs.php.net/bug.php?id=47204 for more information.';
|
517 |
-
return self::createRejection($easy, $ctx);
|
518 |
-
} else {
|
519 |
-
$easy->options['_curl_retries']++;
|
520 |
-
}
|
521 |
-
|
522 |
-
return $handler($easy->request, $easy->options);
|
523 |
-
}
|
524 |
-
|
525 |
-
private function createHeaderFn(EasyHandle $easy)
|
526 |
-
{
|
527 |
-
if (isset($easy->options['on_headers'])) {
|
528 |
-
$onHeaders = $easy->options['on_headers'];
|
529 |
-
|
530 |
-
if (!is_callable($onHeaders)) {
|
531 |
-
throw new \InvalidArgumentException('on_headers must be callable');
|
532 |
-
}
|
533 |
-
} else {
|
534 |
-
$onHeaders = null;
|
535 |
-
}
|
536 |
-
|
537 |
-
return function ($ch, $h) use (
|
538 |
-
$onHeaders,
|
539 |
-
$easy,
|
540 |
-
&$startingResponse
|
541 |
-
) {
|
542 |
-
$value = trim($h);
|
543 |
-
if ($value === '') {
|
544 |
-
$startingResponse = true;
|
545 |
-
$easy->createResponse();
|
546 |
-
if ($onHeaders !== null) {
|
547 |
-
try {
|
548 |
-
$onHeaders($easy->response);
|
549 |
-
} catch (\Exception $e) {
|
550 |
-
// Associate the exception with the handle and trigger
|
551 |
-
// a curl header write error by returning 0.
|
552 |
-
$easy->onHeadersException = $e;
|
553 |
-
return -1;
|
554 |
-
}
|
555 |
-
}
|
556 |
-
} elseif ($startingResponse) {
|
557 |
-
$startingResponse = false;
|
558 |
-
$easy->headers = [$value];
|
559 |
-
} else {
|
560 |
-
$easy->headers[] = $value;
|
561 |
-
}
|
562 |
-
return strlen($h);
|
563 |
-
};
|
564 |
-
}
|
565 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Handler/CurlMultiHandler.php
DELETED
@@ -1,199 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Handler;
|
3 |
-
|
4 |
-
use GuzzleHttp\Promise as P;
|
5 |
-
use GuzzleHttp\Promise\Promise;
|
6 |
-
use GuzzleHttp\Psr7;
|
7 |
-
use Psr\Http\Message\RequestInterface;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Returns an asynchronous response using curl_multi_* functions.
|
11 |
-
*
|
12 |
-
* When using the CurlMultiHandler, custom curl options can be specified as an
|
13 |
-
* associative array of curl option constants mapping to values in the
|
14 |
-
* **curl** key of the provided request options.
|
15 |
-
*
|
16 |
-
* @property resource $_mh Internal use only. Lazy loaded multi-handle.
|
17 |
-
*/
|
18 |
-
class CurlMultiHandler
|
19 |
-
{
|
20 |
-
/** @var CurlFactoryInterface */
|
21 |
-
private $factory;
|
22 |
-
private $selectTimeout;
|
23 |
-
private $active;
|
24 |
-
private $handles = [];
|
25 |
-
private $delays = [];
|
26 |
-
|
27 |
-
/**
|
28 |
-
* This handler accepts the following options:
|
29 |
-
*
|
30 |
-
* - handle_factory: An optional factory used to create curl handles
|
31 |
-
* - select_timeout: Optional timeout (in seconds) to block before timing
|
32 |
-
* out while selecting curl handles. Defaults to 1 second.
|
33 |
-
*
|
34 |
-
* @param array $options
|
35 |
-
*/
|
36 |
-
public function __construct(array $options = [])
|
37 |
-
{
|
38 |
-
$this->factory = isset($options['handle_factory'])
|
39 |
-
? $options['handle_factory'] : new CurlFactory(50);
|
40 |
-
$this->selectTimeout = isset($options['select_timeout'])
|
41 |
-
? $options['select_timeout'] : 1;
|
42 |
-
}
|
43 |
-
|
44 |
-
public function __get($name)
|
45 |
-
{
|
46 |
-
if ($name === '_mh') {
|
47 |
-
return $this->_mh = curl_multi_init();
|
48 |
-
}
|
49 |
-
|
50 |
-
throw new \BadMethodCallException();
|
51 |
-
}
|
52 |
-
|
53 |
-
public function __destruct()
|
54 |
-
{
|
55 |
-
if (isset($this->_mh)) {
|
56 |
-
curl_multi_close($this->_mh);
|
57 |
-
unset($this->_mh);
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
public function __invoke(RequestInterface $request, array $options)
|
62 |
-
{
|
63 |
-
$easy = $this->factory->create($request, $options);
|
64 |
-
$id = (int) $easy->handle;
|
65 |
-
|
66 |
-
$promise = new Promise(
|
67 |
-
[$this, 'execute'],
|
68 |
-
function () use ($id) {
|
69 |
-
return $this->cancel($id);
|
70 |
-
}
|
71 |
-
);
|
72 |
-
|
73 |
-
$this->addRequest(['easy' => $easy, 'deferred' => $promise]);
|
74 |
-
|
75 |
-
return $promise;
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Ticks the curl event loop.
|
80 |
-
*/
|
81 |
-
public function tick()
|
82 |
-
{
|
83 |
-
// Add any delayed handles if needed.
|
84 |
-
if ($this->delays) {
|
85 |
-
$currentTime = microtime(true);
|
86 |
-
foreach ($this->delays as $id => $delay) {
|
87 |
-
if ($currentTime >= $delay) {
|
88 |
-
unset($this->delays[$id]);
|
89 |
-
curl_multi_add_handle(
|
90 |
-
$this->_mh,
|
91 |
-
$this->handles[$id]['easy']->handle
|
92 |
-
);
|
93 |
-
}
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
// Step through the task queue which may add additional requests.
|
98 |
-
P\queue()->run();
|
99 |
-
|
100 |
-
if ($this->active &&
|
101 |
-
curl_multi_select($this->_mh, $this->selectTimeout) === -1
|
102 |
-
) {
|
103 |
-
// Perform a usleep if a select returns -1.
|
104 |
-
// See: https://bugs.php.net/bug.php?id=61141
|
105 |
-
usleep(250);
|
106 |
-
}
|
107 |
-
|
108 |
-
while (curl_multi_exec($this->_mh, $this->active) === CURLM_CALL_MULTI_PERFORM);
|
109 |
-
|
110 |
-
$this->processMessages();
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Runs until all outstanding connections have completed.
|
115 |
-
*/
|
116 |
-
public function execute()
|
117 |
-
{
|
118 |
-
$queue = P\queue();
|
119 |
-
|
120 |
-
while ($this->handles || !$queue->isEmpty()) {
|
121 |
-
// If there are no transfers, then sleep for the next delay
|
122 |
-
if (!$this->active && $this->delays) {
|
123 |
-
usleep($this->timeToNext());
|
124 |
-
}
|
125 |
-
$this->tick();
|
126 |
-
}
|
127 |
-
}
|
128 |
-
|
129 |
-
private function addRequest(array $entry)
|
130 |
-
{
|
131 |
-
$easy = $entry['easy'];
|
132 |
-
$id = (int) $easy->handle;
|
133 |
-
$this->handles[$id] = $entry;
|
134 |
-
if (empty($easy->options['delay'])) {
|
135 |
-
curl_multi_add_handle($this->_mh, $easy->handle);
|
136 |
-
} else {
|
137 |
-
$this->delays[$id] = microtime(true) + ($easy->options['delay'] / 1000);
|
138 |
-
}
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Cancels a handle from sending and removes references to it.
|
143 |
-
*
|
144 |
-
* @param int $id Handle ID to cancel and remove.
|
145 |
-
*
|
146 |
-
* @return bool True on success, false on failure.
|
147 |
-
*/
|
148 |
-
private function cancel($id)
|
149 |
-
{
|
150 |
-
// Cannot cancel if it has been processed.
|
151 |
-
if (!isset($this->handles[$id])) {
|
152 |
-
return false;
|
153 |
-
}
|
154 |
-
|
155 |
-
$handle = $this->handles[$id]['easy']->handle;
|
156 |
-
unset($this->delays[$id], $this->handles[$id]);
|
157 |
-
curl_multi_remove_handle($this->_mh, $handle);
|
158 |
-
curl_close($handle);
|
159 |
-
|
160 |
-
return true;
|
161 |
-
}
|
162 |
-
|
163 |
-
private function processMessages()
|
164 |
-
{
|
165 |
-
while ($done = curl_multi_info_read($this->_mh)) {
|
166 |
-
$id = (int) $done['handle'];
|
167 |
-
curl_multi_remove_handle($this->_mh, $done['handle']);
|
168 |
-
|
169 |
-
if (!isset($this->handles[$id])) {
|
170 |
-
// Probably was cancelled.
|
171 |
-
continue;
|
172 |
-
}
|
173 |
-
|
174 |
-
$entry = $this->handles[$id];
|
175 |
-
unset($this->handles[$id], $this->delays[$id]);
|
176 |
-
$entry['easy']->errno = $done['result'];
|
177 |
-
$entry['deferred']->resolve(
|
178 |
-
CurlFactory::finish(
|
179 |
-
$this,
|
180 |
-
$entry['easy'],
|
181 |
-
$this->factory
|
182 |
-
)
|
183 |
-
);
|
184 |
-
}
|
185 |
-
}
|
186 |
-
|
187 |
-
private function timeToNext()
|
188 |
-
{
|
189 |
-
$currentTime = microtime(true);
|
190 |
-
$nextTime = PHP_INT_MAX;
|
191 |
-
foreach ($this->delays as $time) {
|
192 |
-
if ($time < $nextTime) {
|
193 |
-
$nextTime = $time;
|
194 |
-
}
|
195 |
-
}
|
196 |
-
|
197 |
-
return max(0, $nextTime - $currentTime) * 1000000;
|
198 |
-
}
|
199 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Handler/MockHandler.php
DELETED
@@ -1,189 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Handler;
|
3 |
-
|
4 |
-
use GuzzleHttp\Exception\RequestException;
|
5 |
-
use GuzzleHttp\HandlerStack;
|
6 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
7 |
-
use GuzzleHttp\Promise\RejectedPromise;
|
8 |
-
use GuzzleHttp\TransferStats;
|
9 |
-
use Psr\Http\Message\RequestInterface;
|
10 |
-
use Psr\Http\Message\ResponseInterface;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Handler that returns responses or throw exceptions from a queue.
|
14 |
-
*/
|
15 |
-
class MockHandler implements \Countable
|
16 |
-
{
|
17 |
-
private $queue = [];
|
18 |
-
private $lastRequest;
|
19 |
-
private $lastOptions;
|
20 |
-
private $onFulfilled;
|
21 |
-
private $onRejected;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Creates a new MockHandler that uses the default handler stack list of
|
25 |
-
* middlewares.
|
26 |
-
*
|
27 |
-
* @param array $queue Array of responses, callables, or exceptions.
|
28 |
-
* @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
|
29 |
-
* @param callable $onRejected Callback to invoke when the return value is rejected.
|
30 |
-
*
|
31 |
-
* @return HandlerStack
|
32 |
-
*/
|
33 |
-
public static function createWithMiddleware(
|
34 |
-
array $queue = null,
|
35 |
-
callable $onFulfilled = null,
|
36 |
-
callable $onRejected = null
|
37 |
-
) {
|
38 |
-
return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* The passed in value must be an array of
|
43 |
-
* {@see Psr7\Http\Message\ResponseInterface} objects, Exceptions,
|
44 |
-
* callables, or Promises.
|
45 |
-
*
|
46 |
-
* @param array $queue
|
47 |
-
* @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
|
48 |
-
* @param callable $onRejected Callback to invoke when the return value is rejected.
|
49 |
-
*/
|
50 |
-
public function __construct(
|
51 |
-
array $queue = null,
|
52 |
-
callable $onFulfilled = null,
|
53 |
-
callable $onRejected = null
|
54 |
-
) {
|
55 |
-
$this->onFulfilled = $onFulfilled;
|
56 |
-
$this->onRejected = $onRejected;
|
57 |
-
|
58 |
-
if ($queue) {
|
59 |
-
call_user_func_array([$this, 'append'], $queue);
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
public function __invoke(RequestInterface $request, array $options)
|
64 |
-
{
|
65 |
-
if (!$this->queue) {
|
66 |
-
throw new \OutOfBoundsException('Mock queue is empty');
|
67 |
-
}
|
68 |
-
|
69 |
-
if (isset($options['delay'])) {
|
70 |
-
usleep($options['delay'] * 1000);
|
71 |
-
}
|
72 |
-
|
73 |
-
$this->lastRequest = $request;
|
74 |
-
$this->lastOptions = $options;
|
75 |
-
$response = array_shift($this->queue);
|
76 |
-
|
77 |
-
if (isset($options['on_headers'])) {
|
78 |
-
if (!is_callable($options['on_headers'])) {
|
79 |
-
throw new \InvalidArgumentException('on_headers must be callable');
|
80 |
-
}
|
81 |
-
try {
|
82 |
-
$options['on_headers']($response);
|
83 |
-
} catch (\Exception $e) {
|
84 |
-
$msg = 'An error was encountered during the on_headers event';
|
85 |
-
$response = new RequestException($msg, $request, $response, $e);
|
86 |
-
}
|
87 |
-
}
|
88 |
-
|
89 |
-
if (is_callable($response)) {
|
90 |
-
$response = call_user_func($response, $request, $options);
|
91 |
-
}
|
92 |
-
|
93 |
-
$response = $response instanceof \Exception
|
94 |
-
? \GuzzleHttp\Promise\rejection_for($response)
|
95 |
-
: \GuzzleHttp\Promise\promise_for($response);
|
96 |
-
|
97 |
-
return $response->then(
|
98 |
-
function ($value) use ($request, $options) {
|
99 |
-
$this->invokeStats($request, $options, $value);
|
100 |
-
if ($this->onFulfilled) {
|
101 |
-
call_user_func($this->onFulfilled, $value);
|
102 |
-
}
|
103 |
-
if (isset($options['sink'])) {
|
104 |
-
$contents = (string) $value->getBody();
|
105 |
-
$sink = $options['sink'];
|
106 |
-
|
107 |
-
if (is_resource($sink)) {
|
108 |
-
fwrite($sink, $contents);
|
109 |
-
} elseif (is_string($sink)) {
|
110 |
-
file_put_contents($sink, $contents);
|
111 |
-
} elseif ($sink instanceof \Psr\Http\Message\StreamInterface) {
|
112 |
-
$sink->write($contents);
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
return $value;
|
117 |
-
},
|
118 |
-
function ($reason) use ($request, $options) {
|
119 |
-
$this->invokeStats($request, $options, null, $reason);
|
120 |
-
if ($this->onRejected) {
|
121 |
-
call_user_func($this->onRejected, $reason);
|
122 |
-
}
|
123 |
-
return \GuzzleHttp\Promise\rejection_for($reason);
|
124 |
-
}
|
125 |
-
);
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Adds one or more variadic requests, exceptions, callables, or promises
|
130 |
-
* to the queue.
|
131 |
-
*/
|
132 |
-
public function append()
|
133 |
-
{
|
134 |
-
foreach (func_get_args() as $value) {
|
135 |
-
if ($value instanceof ResponseInterface
|
136 |
-
|| $value instanceof \Exception
|
137 |
-
|| $value instanceof PromiseInterface
|
138 |
-
|| is_callable($value)
|
139 |
-
) {
|
140 |
-
$this->queue[] = $value;
|
141 |
-
} else {
|
142 |
-
throw new \InvalidArgumentException('Expected a response or '
|
143 |
-
. 'exception. Found ' . \GuzzleHttp\describe_type($value));
|
144 |
-
}
|
145 |
-
}
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* Get the last received request.
|
150 |
-
*
|
151 |
-
* @return RequestInterface
|
152 |
-
*/
|
153 |
-
public function getLastRequest()
|
154 |
-
{
|
155 |
-
return $this->lastRequest;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Get the last received request options.
|
160 |
-
*
|
161 |
-
* @return array
|
162 |
-
*/
|
163 |
-
public function getLastOptions()
|
164 |
-
{
|
165 |
-
return $this->lastOptions;
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* Returns the number of remaining items in the queue.
|
170 |
-
*
|
171 |
-
* @return int
|
172 |
-
*/
|
173 |
-
public function count()
|
174 |
-
{
|
175 |
-
return count($this->queue);
|
176 |
-
}
|
177 |
-
|
178 |
-
private function invokeStats(
|
179 |
-
RequestInterface $request,
|
180 |
-
array $options,
|
181 |
-
ResponseInterface $response = null,
|
182 |
-
$reason = null
|
183 |
-
) {
|
184 |
-
if (isset($options['on_stats'])) {
|
185 |
-
$stats = new TransferStats($request, $response, 0, $reason);
|
186 |
-
call_user_func($options['on_stats'], $stats);
|
187 |
-
}
|
188 |
-
}
|
189 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Handler/StreamHandler.php
DELETED
@@ -1,532 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Handler;
|
3 |
-
|
4 |
-
use GuzzleHttp\Exception\RequestException;
|
5 |
-
use GuzzleHttp\Exception\ConnectException;
|
6 |
-
use GuzzleHttp\Promise\FulfilledPromise;
|
7 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
8 |
-
use GuzzleHttp\Psr7;
|
9 |
-
use GuzzleHttp\TransferStats;
|
10 |
-
use Psr\Http\Message\RequestInterface;
|
11 |
-
use Psr\Http\Message\ResponseInterface;
|
12 |
-
use Psr\Http\Message\StreamInterface;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* HTTP handler that uses PHP's HTTP stream wrapper.
|
16 |
-
*/
|
17 |
-
class StreamHandler
|
18 |
-
{
|
19 |
-
private $lastHeaders = [];
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Sends an HTTP request.
|
23 |
-
*
|
24 |
-
* @param RequestInterface $request Request to send.
|
25 |
-
* @param array $options Request transfer options.
|
26 |
-
*
|
27 |
-
* @return PromiseInterface
|
28 |
-
*/
|
29 |
-
public function __invoke(RequestInterface $request, array $options)
|
30 |
-
{
|
31 |
-
// Sleep if there is a delay specified.
|
32 |
-
if (isset($options['delay'])) {
|
33 |
-
usleep($options['delay'] * 1000);
|
34 |
-
}
|
35 |
-
|
36 |
-
$startTime = isset($options['on_stats']) ? microtime(true) : null;
|
37 |
-
|
38 |
-
try {
|
39 |
-
// Does not support the expect header.
|
40 |
-
$request = $request->withoutHeader('Expect');
|
41 |
-
|
42 |
-
// Append a content-length header if body size is zero to match
|
43 |
-
// cURL's behavior.
|
44 |
-
if (0 === $request->getBody()->getSize()) {
|
45 |
-
$request = $request->withHeader('Content-Length', 0);
|
46 |
-
}
|
47 |
-
|
48 |
-
return $this->createResponse(
|
49 |
-
$request,
|
50 |
-
$options,
|
51 |
-
$this->createStream($request, $options),
|
52 |
-
$startTime
|
53 |
-
);
|
54 |
-
} catch (\InvalidArgumentException $e) {
|
55 |
-
throw $e;
|
56 |
-
} catch (\Exception $e) {
|
57 |
-
// Determine if the error was a networking error.
|
58 |
-
$message = $e->getMessage();
|
59 |
-
// This list can probably get more comprehensive.
|
60 |
-
if (strpos($message, 'getaddrinfo') // DNS lookup failed
|
61 |
-
|| strpos($message, 'Connection refused')
|
62 |
-
|| strpos($message, "couldn't connect to host") // error on HHVM
|
63 |
-
|| strpos($message, "connection attempt failed")
|
64 |
-
) {
|
65 |
-
$e = new ConnectException($e->getMessage(), $request, $e);
|
66 |
-
}
|
67 |
-
$e = RequestException::wrapException($request, $e);
|
68 |
-
$this->invokeStats($options, $request, $startTime, null, $e);
|
69 |
-
|
70 |
-
return \GuzzleHttp\Promise\rejection_for($e);
|
71 |
-
}
|
72 |
-
}
|
73 |
-
|
74 |
-
private function invokeStats(
|
75 |
-
array $options,
|
76 |
-
RequestInterface $request,
|
77 |
-
$startTime,
|
78 |
-
ResponseInterface $response = null,
|
79 |
-
$error = null
|
80 |
-
) {
|
81 |
-
if (isset($options['on_stats'])) {
|
82 |
-
$stats = new TransferStats(
|
83 |
-
$request,
|
84 |
-
$response,
|
85 |
-
microtime(true) - $startTime,
|
86 |
-
$error,
|
87 |
-
[]
|
88 |
-
);
|
89 |
-
call_user_func($options['on_stats'], $stats);
|
90 |
-
}
|
91 |
-
}
|
92 |
-
|
93 |
-
private function createResponse(
|
94 |
-
RequestInterface $request,
|
95 |
-
array $options,
|
96 |
-
$stream,
|
97 |
-
$startTime
|
98 |
-
) {
|
99 |
-
$hdrs = $this->lastHeaders;
|
100 |
-
$this->lastHeaders = [];
|
101 |
-
$parts = explode(' ', array_shift($hdrs), 3);
|
102 |
-
$ver = explode('/', $parts[0])[1];
|
103 |
-
$status = $parts[1];
|
104 |
-
$reason = isset($parts[2]) ? $parts[2] : null;
|
105 |
-
$headers = \GuzzleHttp\headers_from_lines($hdrs);
|
106 |
-
list($stream, $headers) = $this->checkDecode($options, $headers, $stream);
|
107 |
-
$stream = Psr7\stream_for($stream);
|
108 |
-
$sink = $stream;
|
109 |
-
|
110 |
-
if (strcasecmp('HEAD', $request->getMethod())) {
|
111 |
-
$sink = $this->createSink($stream, $options);
|
112 |
-
}
|
113 |
-
|
114 |
-
$response = new Psr7\Response($status, $headers, $sink, $ver, $reason);
|
115 |
-
|
116 |
-
if (isset($options['on_headers'])) {
|
117 |
-
try {
|
118 |
-
$options['on_headers']($response);
|
119 |
-
} catch (\Exception $e) {
|
120 |
-
$msg = 'An error was encountered during the on_headers event';
|
121 |
-
$ex = new RequestException($msg, $request, $response, $e);
|
122 |
-
return \GuzzleHttp\Promise\rejection_for($ex);
|
123 |
-
}
|
124 |
-
}
|
125 |
-
|
126 |
-
// Do not drain when the request is a HEAD request because they have
|
127 |
-
// no body.
|
128 |
-
if ($sink !== $stream) {
|
129 |
-
$this->drain(
|
130 |
-
$stream,
|
131 |
-
$sink,
|
132 |
-
$response->getHeaderLine('Content-Length')
|
133 |
-
);
|
134 |
-
}
|
135 |
-
|
136 |
-
$this->invokeStats($options, $request, $startTime, $response, null);
|
137 |
-
|
138 |
-
return new FulfilledPromise($response);
|
139 |
-
}
|
140 |
-
|
141 |
-
private function createSink(StreamInterface $stream, array $options)
|
142 |
-
{
|
143 |
-
if (!empty($options['stream'])) {
|
144 |
-
return $stream;
|
145 |
-
}
|
146 |
-
|
147 |
-
$sink = isset($options['sink'])
|
148 |
-
? $options['sink']
|
149 |
-
: fopen('php://temp', 'r+');
|
150 |
-
|
151 |
-
return is_string($sink)
|
152 |
-
? new Psr7\LazyOpenStream($sink, 'w+')
|
153 |
-
: Psr7\stream_for($sink);
|
154 |
-
}
|
155 |
-
|
156 |
-
private function checkDecode(array $options, array $headers, $stream)
|
157 |
-
{
|
158 |
-
// Automatically decode responses when instructed.
|
159 |
-
if (!empty($options['decode_content'])) {
|
160 |
-
$normalizedKeys = \GuzzleHttp\normalize_header_keys($headers);
|
161 |
-
if (isset($normalizedKeys['content-encoding'])) {
|
162 |
-
$encoding = $headers[$normalizedKeys['content-encoding']];
|
163 |
-
if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') {
|
164 |
-
$stream = new Psr7\InflateStream(
|
165 |
-
Psr7\stream_for($stream)
|
166 |
-
);
|
167 |
-
$headers['x-encoded-content-encoding']
|
168 |
-
= $headers[$normalizedKeys['content-encoding']];
|
169 |
-
// Remove content-encoding header
|
170 |
-
unset($headers[$normalizedKeys['content-encoding']]);
|
171 |
-
// Fix content-length header
|
172 |
-
if (isset($normalizedKeys['content-length'])) {
|
173 |
-
$headers['x-encoded-content-length']
|
174 |
-
= $headers[$normalizedKeys['content-length']];
|
175 |
-
|
176 |
-
$length = (int) $stream->getSize();
|
177 |
-
if ($length === 0) {
|
178 |
-
unset($headers[$normalizedKeys['content-length']]);
|
179 |
-
} else {
|
180 |
-
$headers[$normalizedKeys['content-length']] = [$length];
|
181 |
-
}
|
182 |
-
}
|
183 |
-
}
|
184 |
-
}
|
185 |
-
}
|
186 |
-
|
187 |
-
return [$stream, $headers];
|
188 |
-
}
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Drains the source stream into the "sink" client option.
|
192 |
-
*
|
193 |
-
* @param StreamInterface $source
|
194 |
-
* @param StreamInterface $sink
|
195 |
-
* @param string $contentLength Header specifying the amount of
|
196 |
-
* data to read.
|
197 |
-
*
|
198 |
-
* @return StreamInterface
|
199 |
-
* @throws \RuntimeException when the sink option is invalid.
|
200 |
-
*/
|
201 |
-
private function drain(
|
202 |
-
StreamInterface $source,
|
203 |
-
StreamInterface $sink,
|
204 |
-
$contentLength
|
205 |
-
) {
|
206 |
-
// If a content-length header is provided, then stop reading once
|
207 |
-
// that number of bytes has been read. This can prevent infinitely
|
208 |
-
// reading from a stream when dealing with servers that do not honor
|
209 |
-
// Connection: Close headers.
|
210 |
-
Psr7\copy_to_stream(
|
211 |
-
$source,
|
212 |
-
$sink,
|
213 |
-
(strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1
|
214 |
-
);
|
215 |
-
|
216 |
-
$sink->seek(0);
|
217 |
-
$source->close();
|
218 |
-
|
219 |
-
return $sink;
|
220 |
-
}
|
221 |
-
|
222 |
-
/**
|
223 |
-
* Create a resource and check to ensure it was created successfully
|
224 |
-
*
|
225 |
-
* @param callable $callback Callable that returns stream resource
|
226 |
-
*
|
227 |
-
* @return resource
|
228 |
-
* @throws \RuntimeException on error
|
229 |
-
*/
|
230 |
-
private function createResource(callable $callback)
|
231 |
-
{
|
232 |
-
$errors = null;
|
233 |
-
set_error_handler(function ($_, $msg, $file, $line) use (&$errors) {
|
234 |
-
$errors[] = [
|
235 |
-
'message' => $msg,
|
236 |
-
'file' => $file,
|
237 |
-
'line' => $line
|
238 |
-
];
|
239 |
-
return true;
|
240 |
-
});
|
241 |
-
|
242 |
-
$resource = $callback();
|
243 |
-
restore_error_handler();
|
244 |
-
|
245 |
-
if (!$resource) {
|
246 |
-
$message = 'Error creating resource: ';
|
247 |
-
foreach ($errors as $err) {
|
248 |
-
foreach ($err as $key => $value) {
|
249 |
-
$message .= "[$key] $value" . PHP_EOL;
|
250 |
-
}
|
251 |
-
}
|
252 |
-
throw new \RuntimeException(trim($message));
|
253 |
-
}
|
254 |
-
|
255 |
-
return $resource;
|
256 |
-
}
|
257 |
-
|
258 |
-
private function createStream(RequestInterface $request, array $options)
|
259 |
-
{
|
260 |
-
static $methods;
|
261 |
-
if (!$methods) {
|
262 |
-
$methods = array_flip(get_class_methods(__CLASS__));
|
263 |
-
}
|
264 |
-
|
265 |
-
// HTTP/1.1 streams using the PHP stream wrapper require a
|
266 |
-
// Connection: close header
|
267 |
-
if ($request->getProtocolVersion() == '1.1'
|
268 |
-
&& !$request->hasHeader('Connection')
|
269 |
-
) {
|
270 |
-
$request = $request->withHeader('Connection', 'close');
|
271 |
-
}
|
272 |
-
|
273 |
-
// Ensure SSL is verified by default
|
274 |
-
if (!isset($options['verify'])) {
|
275 |
-
$options['verify'] = true;
|
276 |
-
}
|
277 |
-
|
278 |
-
$params = [];
|
279 |
-
$context = $this->getDefaultContext($request);
|
280 |
-
|
281 |
-
if (isset($options['on_headers']) && !is_callable($options['on_headers'])) {
|
282 |
-
throw new \InvalidArgumentException('on_headers must be callable');
|
283 |
-
}
|
284 |
-
|
285 |
-
if (!empty($options)) {
|
286 |
-
foreach ($options as $key => $value) {
|
287 |
-
$method = "add_{$key}";
|
288 |
-
if (isset($methods[$method])) {
|
289 |
-
$this->{$method}($request, $context, $value, $params);
|
290 |
-
}
|
291 |
-
}
|
292 |
-
}
|
293 |
-
|
294 |
-
if (isset($options['stream_context'])) {
|
295 |
-
if (!is_array($options['stream_context'])) {
|
296 |
-
throw new \InvalidArgumentException('stream_context must be an array');
|
297 |
-
}
|
298 |
-
$context = array_replace_recursive(
|
299 |
-
$context,
|
300 |
-
$options['stream_context']
|
301 |
-
);
|
302 |
-
}
|
303 |
-
|
304 |
-
// Microsoft NTLM authentication only supported with curl handler
|
305 |
-
if (isset($options['auth'])
|
306 |
-
&& is_array($options['auth'])
|
307 |
-
&& isset($options['auth'][2])
|
308 |
-
&& 'ntlm' == $options['auth'][2]
|
309 |
-
) {
|
310 |
-
throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler');
|
311 |
-
}
|
312 |
-
|
313 |
-
$uri = $this->resolveHost($request, $options);
|
314 |
-
|
315 |
-
$context = $this->createResource(
|
316 |
-
function () use ($context, $params) {
|
317 |
-
return stream_context_create($context, $params);
|
318 |
-
}
|
319 |
-
);
|
320 |
-
|
321 |
-
return $this->createResource(
|
322 |
-
function () use ($uri, &$http_response_header, $context, $options) {
|
323 |
-
$resource = fopen((string) $uri, 'r', null, $context);
|
324 |
-
$this->lastHeaders = $http_response_header;
|
325 |
-
|
326 |
-
if (isset($options['read_timeout'])) {
|
327 |
-
$readTimeout = $options['read_timeout'];
|
328 |
-
$sec = (int) $readTimeout;
|
329 |
-
$usec = ($readTimeout - $sec) * 100000;
|
330 |
-
stream_set_timeout($resource, $sec, $usec);
|
331 |
-
}
|
332 |
-
|
333 |
-
return $resource;
|
334 |
-
}
|
335 |
-
);
|
336 |
-
}
|
337 |
-
|
338 |
-
private function resolveHost(RequestInterface $request, array $options)
|
339 |
-
{
|
340 |
-
$uri = $request->getUri();
|
341 |
-
|
342 |
-
if (isset($options['force_ip_resolve']) && !filter_var($uri->getHost(), FILTER_VALIDATE_IP)) {
|
343 |
-
if ('v4' === $options['force_ip_resolve']) {
|
344 |
-
$records = dns_get_record($uri->getHost(), DNS_A);
|
345 |
-
if (!isset($records[0]['ip'])) {
|
346 |
-
throw new ConnectException(sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request);
|
347 |
-
}
|
348 |
-
$uri = $uri->withHost($records[0]['ip']);
|
349 |
-
} elseif ('v6' === $options['force_ip_resolve']) {
|
350 |
-
$records = dns_get_record($uri->getHost(), DNS_AAAA);
|
351 |
-
if (!isset($records[0]['ipv6'])) {
|
352 |
-
throw new ConnectException(sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request);
|
353 |
-
}
|
354 |
-
$uri = $uri->withHost('[' . $records[0]['ipv6'] . ']');
|
355 |
-
}
|
356 |
-
}
|
357 |
-
|
358 |
-
return $uri;
|
359 |
-
}
|
360 |
-
|
361 |
-
private function getDefaultContext(RequestInterface $request)
|
362 |
-
{
|
363 |
-
$headers = '';
|
364 |
-
foreach ($request->getHeaders() as $name => $value) {
|
365 |
-
foreach ($value as $val) {
|
366 |
-
$headers .= "$name: $val\r\n";
|
367 |
-
}
|
368 |
-
}
|
369 |
-
|
370 |
-
$context = [
|
371 |
-
'http' => [
|
372 |
-
'method' => $request->getMethod(),
|
373 |
-
'header' => $headers,
|
374 |
-
'protocol_version' => $request->getProtocolVersion(),
|
375 |
-
'ignore_errors' => true,
|
376 |
-
'follow_location' => 0,
|
377 |
-
],
|
378 |
-
];
|
379 |
-
|
380 |
-
$body = (string) $request->getBody();
|
381 |
-
|
382 |
-
if (!empty($body)) {
|
383 |
-
$context['http']['content'] = $body;
|
384 |
-
// Prevent the HTTP handler from adding a Content-Type header.
|
385 |
-
if (!$request->hasHeader('Content-Type')) {
|
386 |
-
$context['http']['header'] .= "Content-Type:\r\n";
|
387 |
-
}
|
388 |
-
}
|
389 |
-
|
390 |
-
$context['http']['header'] = rtrim($context['http']['header']);
|
391 |
-
|
392 |
-
return $context;
|
393 |
-
}
|
394 |
-
|
395 |
-
private function add_proxy(RequestInterface $request, &$options, $value, &$params)
|
396 |
-
{
|
397 |
-
if (!is_array($value)) {
|
398 |
-
$options['http']['proxy'] = $value;
|
399 |
-
} else {
|
400 |
-
$scheme = $request->getUri()->getScheme();
|
401 |
-
if (isset($value[$scheme])) {
|
402 |
-
if (!isset($value['no'])
|
403 |
-
|| !\GuzzleHttp\is_host_in_noproxy(
|
404 |
-
$request->getUri()->getHost(),
|
405 |
-
$value['no']
|
406 |
-
)
|
407 |
-
) {
|
408 |
-
$options['http']['proxy'] = $value[$scheme];
|
409 |
-
}
|
410 |
-
}
|
411 |
-
}
|
412 |
-
}
|
413 |
-
|
414 |
-
private function add_timeout(RequestInterface $request, &$options, $value, &$params)
|
415 |
-
{
|
416 |
-
if ($value > 0) {
|
417 |
-
$options['http']['timeout'] = $value;
|
418 |
-
}
|
419 |
-
}
|
420 |
-
|
421 |
-
private function add_verify(RequestInterface $request, &$options, $value, &$params)
|
422 |
-
{
|
423 |
-
if ($value === true) {
|
424 |
-
// PHP 5.6 or greater will find the system cert by default. When
|
425 |
-
// < 5.6, use the Guzzle bundled cacert.
|
426 |
-
if (PHP_VERSION_ID < 50600) {
|
427 |
-
$options['ssl']['cafile'] = \GuzzleHttp\default_ca_bundle();
|
428 |
-
}
|
429 |
-
} elseif (is_string($value)) {
|
430 |
-
$options['ssl']['cafile'] = $value;
|
431 |
-
if (!file_exists($value)) {
|
432 |
-
throw new \RuntimeException("SSL CA bundle not found: $value");
|
433 |
-
}
|
434 |
-
} elseif ($value === false) {
|
435 |
-
$options['ssl']['verify_peer'] = false;
|
436 |
-
$options['ssl']['verify_peer_name'] = false;
|
437 |
-
return;
|
438 |
-
} else {
|
439 |
-
throw new \InvalidArgumentException('Invalid verify request option');
|
440 |
-
}
|
441 |
-
|
442 |
-
$options['ssl']['verify_peer'] = true;
|
443 |
-
$options['ssl']['verify_peer_name'] = true;
|
444 |
-
$options['ssl']['allow_self_signed'] = false;
|
445 |
-
}
|
446 |
-
|
447 |
-
private function add_cert(RequestInterface $request, &$options, $value, &$params)
|
448 |
-
{
|
449 |
-
if (is_array($value)) {
|
450 |
-
$options['ssl']['passphrase'] = $value[1];
|
451 |
-
$value = $value[0];
|
452 |
-
}
|
453 |
-
|
454 |
-
if (!file_exists($value)) {
|
455 |
-
throw new \RuntimeException("SSL certificate not found: {$value}");
|
456 |
-
}
|
457 |
-
|
458 |
-
$options['ssl']['local_cert'] = $value;
|
459 |
-
}
|
460 |
-
|
461 |
-
private function add_progress(RequestInterface $request, &$options, $value, &$params)
|
462 |
-
{
|
463 |
-
$this->addNotification(
|
464 |
-
$params,
|
465 |
-
function ($code, $a, $b, $c, $transferred, $total) use ($value) {
|
466 |
-
if ($code == STREAM_NOTIFY_PROGRESS) {
|
467 |
-
$value($total, $transferred, null, null);
|
468 |
-
}
|
469 |
-
}
|
470 |
-
);
|
471 |
-
}
|
472 |
-
|
473 |
-
private function add_debug(RequestInterface $request, &$options, $value, &$params)
|
474 |
-
{
|
475 |
-
if ($value === false) {
|
476 |
-
return;
|
477 |
-
}
|
478 |
-
|
479 |
-
static $map = [
|
480 |
-
STREAM_NOTIFY_CONNECT => 'CONNECT',
|
481 |
-
STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED',
|
482 |
-
STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT',
|
483 |
-
STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS',
|
484 |
-
STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS',
|
485 |
-
STREAM_NOTIFY_REDIRECTED => 'REDIRECTED',
|
486 |
-
STREAM_NOTIFY_PROGRESS => 'PROGRESS',
|
487 |
-
STREAM_NOTIFY_FAILURE => 'FAILURE',
|
488 |
-
STREAM_NOTIFY_COMPLETED => 'COMPLETED',
|
489 |
-
STREAM_NOTIFY_RESOLVE => 'RESOLVE',
|
490 |
-
];
|
491 |
-
static $args = ['severity', 'message', 'message_code',
|
492 |
-
'bytes_transferred', 'bytes_max'];
|
493 |
-
|
494 |
-
$value = \GuzzleHttp\debug_resource($value);
|
495 |
-
$ident = $request->getMethod() . ' ' . $request->getUri()->withFragment('');
|
496 |
-
$this->addNotification(
|
497 |
-
$params,
|
498 |
-
function () use ($ident, $value, $map, $args) {
|
499 |
-
$passed = func_get_args();
|
500 |
-
$code = array_shift($passed);
|
501 |
-
fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
|
502 |
-
foreach (array_filter($passed) as $i => $v) {
|
503 |
-
fwrite($value, $args[$i] . ': "' . $v . '" ');
|
504 |
-
}
|
505 |
-
fwrite($value, "\n");
|
506 |
-
}
|
507 |
-
);
|
508 |
-
}
|
509 |
-
|
510 |
-
private function addNotification(array &$params, callable $notify)
|
511 |
-
{
|
512 |
-
// Wrap the existing function if needed.
|
513 |
-
if (!isset($params['notification'])) {
|
514 |
-
$params['notification'] = $notify;
|
515 |
-
} else {
|
516 |
-
$params['notification'] = $this->callArray([
|
517 |
-
$params['notification'],
|
518 |
-
$notify
|
519 |
-
]);
|
520 |
-
}
|
521 |
-
}
|
522 |
-
|
523 |
-
private function callArray(array $functions)
|
524 |
-
{
|
525 |
-
return function () use ($functions) {
|
526 |
-
$args = func_get_args();
|
527 |
-
foreach ($functions as $fn) {
|
528 |
-
call_user_func_array($fn, $args);
|
529 |
-
}
|
530 |
-
};
|
531 |
-
}
|
532 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/HandlerStack.php
DELETED
@@ -1,273 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp;
|
3 |
-
|
4 |
-
use Psr\Http\Message\RequestInterface;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Creates a composed Guzzle handler function by stacking middlewares on top of
|
8 |
-
* an HTTP handler function.
|
9 |
-
*/
|
10 |
-
class HandlerStack
|
11 |
-
{
|
12 |
-
/** @var callable */
|
13 |
-
private $handler;
|
14 |
-
|
15 |
-
/** @var array */
|
16 |
-
private $stack = [];
|
17 |
-
|
18 |
-
/** @var callable|null */
|
19 |
-
private $cached;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Creates a default handler stack that can be used by clients.
|
23 |
-
*
|
24 |
-
* The returned handler will wrap the provided handler or use the most
|
25 |
-
* appropriate default handler for your system. The returned HandlerStack has
|
26 |
-
* support for cookies, redirects, HTTP error exceptions, and preparing a body
|
27 |
-
* before sending.
|
28 |
-
*
|
29 |
-
* The returned handler stack can be passed to a client in the "handler"
|
30 |
-
* option.
|
31 |
-
*
|
32 |
-
* @param callable $handler HTTP handler function to use with the stack. If no
|
33 |
-
* handler is provided, the best handler for your
|
34 |
-
* system will be utilized.
|
35 |
-
*
|
36 |
-
* @return HandlerStack
|
37 |
-
*/
|
38 |
-
public static function create(callable $handler = null)
|
39 |
-
{
|
40 |
-
$stack = new self($handler ?: choose_handler());
|
41 |
-
$stack->push(Middleware::httpErrors(), 'http_errors');
|
42 |
-
$stack->push(Middleware::redirect(), 'allow_redirects');
|
43 |
-
$stack->push(Middleware::cookies(), 'cookies');
|
44 |
-
$stack->push(Middleware::prepareBody(), 'prepare_body');
|
45 |
-
|
46 |
-
return $stack;
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* @param callable $handler Underlying HTTP handler.
|
51 |
-
*/
|
52 |
-
public function __construct(callable $handler = null)
|
53 |
-
{
|
54 |
-
$this->handler = $handler;
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Invokes the handler stack as a composed handler
|
59 |
-
*
|
60 |
-
* @param RequestInterface $request
|
61 |
-
* @param array $options
|
62 |
-
*/
|
63 |
-
public function __invoke(RequestInterface $request, array $options)
|
64 |
-
{
|
65 |
-
$handler = $this->resolve();
|
66 |
-
|
67 |
-
return $handler($request, $options);
|
68 |
-
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Dumps a string representation of the stack.
|
72 |
-
*
|
73 |
-
* @return string
|
74 |
-
*/
|
75 |
-
public function __toString()
|
76 |
-
{
|
77 |
-
$depth = 0;
|
78 |
-
$stack = [];
|
79 |
-
if ($this->handler) {
|
80 |
-
$stack[] = "0) Handler: " . $this->debugCallable($this->handler);
|
81 |
-
}
|
82 |
-
|
83 |
-
$result = '';
|
84 |
-
foreach (array_reverse($this->stack) as $tuple) {
|
85 |
-
$depth++;
|
86 |
-
$str = "{$depth}) Name: '{$tuple[1]}', ";
|
87 |
-
$str .= "Function: " . $this->debugCallable($tuple[0]);
|
88 |
-
$result = "> {$str}\n{$result}";
|
89 |
-
$stack[] = $str;
|
90 |
-
}
|
91 |
-
|
92 |
-
foreach (array_keys($stack) as $k) {
|
93 |
-
$result .= "< {$stack[$k]}\n";
|
94 |
-
}
|
95 |
-
|
96 |
-
return $result;
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Set the HTTP handler that actually returns a promise.
|
101 |
-
*
|
102 |
-
* @param callable $handler Accepts a request and array of options and
|
103 |
-
* returns a Promise.
|
104 |
-
*/
|
105 |
-
public function setHandler(callable $handler)
|
106 |
-
{
|
107 |
-
$this->handler = $handler;
|
108 |
-
$this->cached = null;
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Returns true if the builder has a handler.
|
113 |
-
*
|
114 |
-
* @return bool
|
115 |
-
*/
|
116 |
-
public function hasHandler()
|
117 |
-
{
|
118 |
-
return (bool) $this->handler;
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Unshift a middleware to the bottom of the stack.
|
123 |
-
*
|
124 |
-
* @param callable $middleware Middleware function
|
125 |
-
* @param string $name Name to register for this middleware.
|
126 |
-
*/
|
127 |
-
public function unshift(callable $middleware, $name = null)
|
128 |
-
{
|
129 |
-
array_unshift($this->stack, [$middleware, $name]);
|
130 |
-
$this->cached = null;
|
131 |
-
}
|
132 |
-
|
133 |
-
/**
|
134 |
-
* Push a middleware to the top of the stack.
|
135 |
-
*
|
136 |
-
* @param callable $middleware Middleware function
|
137 |
-
* @param string $name Name to register for this middleware.
|
138 |
-
*/
|
139 |
-
public function push(callable $middleware, $name = '')
|
140 |
-
{
|
141 |
-
$this->stack[] = [$middleware, $name];
|
142 |
-
$this->cached = null;
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
-
* Add a middleware before another middleware by name.
|
147 |
-
*
|
148 |
-
* @param string $findName Middleware to find
|
149 |
-
* @param callable $middleware Middleware function
|
150 |
-
* @param string $withName Name to register for this middleware.
|
151 |
-
*/
|
152 |
-
public function before($findName, callable $middleware, $withName = '')
|
153 |
-
{
|
154 |
-
$this->splice($findName, $withName, $middleware, true);
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Add a middleware after another middleware by name.
|
159 |
-
*
|
160 |
-
* @param string $findName Middleware to find
|
161 |
-
* @param callable $middleware Middleware function
|
162 |
-
* @param string $withName Name to register for this middleware.
|
163 |
-
*/
|
164 |
-
public function after($findName, callable $middleware, $withName = '')
|
165 |
-
{
|
166 |
-
$this->splice($findName, $withName, $middleware, false);
|
167 |
-
}
|
168 |
-
|
169 |
-
/**
|
170 |
-
* Remove a middleware by instance or name from the stack.
|
171 |
-
*
|
172 |
-
* @param callable|string $remove Middleware to remove by instance or name.
|
173 |
-
*/
|
174 |
-
public function remove($remove)
|
175 |
-
{
|
176 |
-
$this->cached = null;
|
177 |
-
$idx = is_callable($remove) ? 0 : 1;
|
178 |
-
$this->stack = array_values(array_filter(
|
179 |
-
$this->stack,
|
180 |
-
function ($tuple) use ($idx, $remove) {
|
181 |
-
return $tuple[$idx] !== $remove;
|
182 |
-
}
|
183 |
-
));
|
184 |
-
}
|
185 |
-
|
186 |
-
/**
|
187 |
-
* Compose the middleware and handler into a single callable function.
|
188 |
-
*
|
189 |
-
* @return callable
|
190 |
-
*/
|
191 |
-
public function resolve()
|
192 |
-
{
|
193 |
-
if (!$this->cached) {
|
194 |
-
if (!($prev = $this->handler)) {
|
195 |
-
throw new \LogicException('No handler has been specified');
|
196 |
-
}
|
197 |
-
|
198 |
-
foreach (array_reverse($this->stack) as $fn) {
|
199 |
-
$prev = $fn[0]($prev);
|
200 |
-
}
|
201 |
-
|
202 |
-
$this->cached = $prev;
|
203 |
-
}
|
204 |
-
|
205 |
-
return $this->cached;
|
206 |
-
}
|
207 |
-
|
208 |
-
/**
|
209 |
-
* @param $name
|
210 |
-
* @return int
|
211 |
-
*/
|
212 |
-
private function findByName($name)
|
213 |
-
{
|
214 |
-
foreach ($this->stack as $k => $v) {
|
215 |
-
if ($v[1] === $name) {
|
216 |
-
return $k;
|
217 |
-
}
|
218 |
-
}
|
219 |
-
|
220 |
-
throw new \InvalidArgumentException("Middleware not found: $name");
|
221 |
-
}
|
222 |
-
|
223 |
-
/**
|
224 |
-
* Splices a function into the middleware list at a specific position.
|
225 |
-
*
|
226 |
-
* @param $findName
|
227 |
-
* @param $withName
|
228 |
-
* @param callable $middleware
|
229 |
-
* @param $before
|
230 |
-
*/
|
231 |
-
private function splice($findName, $withName, callable $middleware, $before)
|
232 |
-
{
|
233 |
-
$this->cached = null;
|
234 |
-
$idx = $this->findByName($findName);
|
235 |
-
$tuple = [$middleware, $withName];
|
236 |
-
|
237 |
-
if ($before) {
|
238 |
-
if ($idx === 0) {
|
239 |
-
array_unshift($this->stack, $tuple);
|
240 |
-
} else {
|
241 |
-
$replacement = [$tuple, $this->stack[$idx]];
|
242 |
-
array_splice($this->stack, $idx, 1, $replacement);
|
243 |
-
}
|
244 |
-
} elseif ($idx === count($this->stack) - 1) {
|
245 |
-
$this->stack[] = $tuple;
|
246 |
-
} else {
|
247 |
-
$replacement = [$this->stack[$idx], $tuple];
|
248 |
-
array_splice($this->stack, $idx, 1, $replacement);
|
249 |
-
}
|
250 |
-
}
|
251 |
-
|
252 |
-
/**
|
253 |
-
* Provides a debug string for a given callable.
|
254 |
-
*
|
255 |
-
* @param array|callable $fn Function to write as a string.
|
256 |
-
*
|
257 |
-
* @return string
|
258 |
-
*/
|
259 |
-
private function debugCallable($fn)
|
260 |
-
{
|
261 |
-
if (is_string($fn)) {
|
262 |
-
return "callable({$fn})";
|
263 |
-
}
|
264 |
-
|
265 |
-
if (is_array($fn)) {
|
266 |
-
return is_string($fn[0])
|
267 |
-
? "callable({$fn[0]}::{$fn[1]})"
|
268 |
-
: "callable(['" . get_class($fn[0]) . "', '{$fn[1]}'])";
|
269 |
-
}
|
270 |
-
|
271 |
-
return 'callable(' . spl_object_hash($fn) . ')';
|
272 |
-
}
|
273 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/MessageFormatter.php
DELETED
@@ -1,180 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp;
|
3 |
-
|
4 |
-
use Psr\Http\Message\MessageInterface;
|
5 |
-
use Psr\Http\Message\RequestInterface;
|
6 |
-
use Psr\Http\Message\ResponseInterface;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Formats log messages using variable substitutions for requests, responses,
|
10 |
-
* and other transactional data.
|
11 |
-
*
|
12 |
-
* The following variable substitutions are supported:
|
13 |
-
*
|
14 |
-
* - {request}: Full HTTP request message
|
15 |
-
* - {response}: Full HTTP response message
|
16 |
-
* - {ts}: ISO 8601 date in GMT
|
17 |
-
* - {date_iso_8601} ISO 8601 date in GMT
|
18 |
-
* - {date_common_log} Apache common log date using the configured timezone.
|
19 |
-
* - {host}: Host of the request
|
20 |
-
* - {method}: Method of the request
|
21 |
-
* - {uri}: URI of the request
|
22 |
-
* - {version}: Protocol version
|
23 |
-
* - {target}: Request target of the request (path + query + fragment)
|
24 |
-
* - {hostname}: Hostname of the machine that sent the request
|
25 |
-
* - {code}: Status code of the response (if available)
|
26 |
-
* - {phrase}: Reason phrase of the response (if available)
|
27 |
-
* - {error}: Any error messages (if available)
|
28 |
-
* - {req_header_*}: Replace `*` with the lowercased name of a request header to add to the message
|
29 |
-
* - {res_header_*}: Replace `*` with the lowercased name of a response header to add to the message
|
30 |
-
* - {req_headers}: Request headers
|
31 |
-
* - {res_headers}: Response headers
|
32 |
-
* - {req_body}: Request body
|
33 |
-
* - {res_body}: Response body
|
34 |
-
*/
|
35 |
-
class MessageFormatter
|
36 |
-
{
|
37 |
-
/**
|
38 |
-
* Apache Common Log Format.
|
39 |
-
* @link http://httpd.apache.org/docs/2.4/logs.html#common
|
40 |
-
* @var string
|
41 |
-
*/
|
42 |
-
const CLF = "{hostname} {req_header_User-Agent} - [{date_common_log}] \"{method} {target} HTTP/{version}\" {code} {res_header_Content-Length}";
|
43 |
-
const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
|
44 |
-
const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';
|
45 |
-
|
46 |
-
/** @var string Template used to format log messages */
|
47 |
-
private $template;
|
48 |
-
|
49 |
-
/**
|
50 |
-
* @param string $template Log message template
|
51 |
-
*/
|
52 |
-
public function __construct($template = self::CLF)
|
53 |
-
{
|
54 |
-
$this->template = $template ?: self::CLF;
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Returns a formatted message string.
|
59 |
-
*
|
60 |
-
* @param RequestInterface $request Request that was sent
|
61 |
-
* @param ResponseInterface $response Response that was received
|
62 |
-
* @param \Exception $error Exception that was received
|
63 |
-
*
|
64 |
-
* @return string
|
65 |
-
*/
|
66 |
-
public function format(
|
67 |
-
RequestInterface $request,
|
68 |
-
ResponseInterface $response = null,
|
69 |
-
\Exception $error = null
|
70 |
-
) {
|
71 |
-
$cache = [];
|
72 |
-
|
73 |
-
return preg_replace_callback(
|
74 |
-
'/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
|
75 |
-
function (array $matches) use ($request, $response, $error, &$cache) {
|
76 |
-
if (isset($cache[$matches[1]])) {
|
77 |
-
return $cache[$matches[1]];
|
78 |
-
}
|
79 |
-
|
80 |
-
$result = '';
|
81 |
-
switch ($matches[1]) {
|
82 |
-
case 'request':
|
83 |
-
$result = Psr7\str($request);
|
84 |
-
break;
|
85 |
-
case 'response':
|
86 |
-
$result = $response ? Psr7\str($response) : '';
|
87 |
-
break;
|
88 |
-
case 'req_headers':
|
89 |
-
$result = trim($request->getMethod()
|
90 |
-
. ' ' . $request->getRequestTarget())
|
91 |
-
. ' HTTP/' . $request->getProtocolVersion() . "\r\n"
|
92 |
-
. $this->headers($request);
|
93 |
-
break;
|
94 |
-
case 'res_headers':
|
95 |
-
$result = $response ?
|
96 |
-
sprintf(
|
97 |
-
'HTTP/%s %d %s',
|
98 |
-
$response->getProtocolVersion(),
|
99 |
-
$response->getStatusCode(),
|
100 |
-
$response->getReasonPhrase()
|
101 |
-
) . "\r\n" . $this->headers($response)
|
102 |
-
: 'NULL';
|
103 |
-
break;
|
104 |
-
case 'req_body':
|
105 |
-
$result = $request->getBody();
|
106 |
-
break;
|
107 |
-
case 'res_body':
|
108 |
-
$result = $response ? $response->getBody() : 'NULL';
|
109 |
-
break;
|
110 |
-
case 'ts':
|
111 |
-
case 'date_iso_8601':
|
112 |
-
$result = gmdate('c');
|
113 |
-
break;
|
114 |
-
case 'date_common_log':
|
115 |
-
$result = date('d/M/Y:H:i:s O');
|
116 |
-
break;
|
117 |
-
case 'method':
|
118 |
-
$result = $request->getMethod();
|
119 |
-
break;
|
120 |
-
case 'version':
|
121 |
-
$result = $request->getProtocolVersion();
|
122 |
-
break;
|
123 |
-
case 'uri':
|
124 |
-
case 'url':
|
125 |
-
$result = $request->getUri();
|
126 |
-
break;
|
127 |
-
case 'target':
|
128 |
-
$result = $request->getRequestTarget();
|
129 |
-
break;
|
130 |
-
case 'req_version':
|
131 |
-
$result = $request->getProtocolVersion();
|
132 |
-
break;
|
133 |
-
case 'res_version':
|
134 |
-
$result = $response
|
135 |
-
? $response->getProtocolVersion()
|
136 |
-
: 'NULL';
|
137 |
-
break;
|
138 |
-
case 'host':
|
139 |
-
$result = $request->getHeaderLine('Host');
|
140 |
-
break;
|
141 |
-
case 'hostname':
|
142 |
-
$result = gethostname();
|
143 |
-
break;
|
144 |
-
case 'code':
|
145 |
-
$result = $response ? $response->getStatusCode() : 'NULL';
|
146 |
-
break;
|
147 |
-
case 'phrase':
|
148 |
-
$result = $response ? $response->getReasonPhrase() : 'NULL';
|
149 |
-
break;
|
150 |
-
case 'error':
|
151 |
-
$result = $error ? $error->getMessage() : 'NULL';
|
152 |
-
break;
|
153 |
-
default:
|
154 |
-
// handle prefixed dynamic headers
|
155 |
-
if (strpos($matches[1], 'req_header_') === 0) {
|
156 |
-
$result = $request->getHeaderLine(substr($matches[1], 11));
|
157 |
-
} elseif (strpos($matches[1], 'res_header_') === 0) {
|
158 |
-
$result = $response
|
159 |
-
? $response->getHeaderLine(substr($matches[1], 11))
|
160 |
-
: 'NULL';
|
161 |
-
}
|
162 |
-
}
|
163 |
-
|
164 |
-
$cache[$matches[1]] = $result;
|
165 |
-
return $result;
|
166 |
-
},
|
167 |
-
$this->template
|
168 |
-
);
|
169 |
-
}
|
170 |
-
|
171 |
-
private function headers(MessageInterface $message)
|
172 |
-
{
|
173 |
-
$result = '';
|
174 |
-
foreach ($message->getHeaders() as $name => $values) {
|
175 |
-
$result .= $name . ': ' . implode(', ', $values) . "\r\n";
|
176 |
-
}
|
177 |
-
|
178 |
-
return trim($result);
|
179 |
-
}
|
180 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Middleware.php
DELETED
@@ -1,255 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp;
|
3 |
-
|
4 |
-
use GuzzleHttp\Cookie\CookieJarInterface;
|
5 |
-
use GuzzleHttp\Exception\RequestException;
|
6 |
-
use GuzzleHttp\Promise\RejectedPromise;
|
7 |
-
use GuzzleHttp\Psr7;
|
8 |
-
use Psr\Http\Message\ResponseInterface;
|
9 |
-
use Psr\Log\LoggerInterface;
|
10 |
-
use Psr\Log\LogLevel;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Functions used to create and wrap handlers with handler middleware.
|
14 |
-
*/
|
15 |
-
final class Middleware
|
16 |
-
{
|
17 |
-
/**
|
18 |
-
* Middleware that adds cookies to requests.
|
19 |
-
*
|
20 |
-
* The options array must be set to a CookieJarInterface in order to use
|
21 |
-
* cookies. This is typically handled for you by a client.
|
22 |
-
*
|
23 |
-
* @return callable Returns a function that accepts the next handler.
|
24 |
-
*/
|
25 |
-
public static function cookies()
|
26 |
-
{
|
27 |
-
return function (callable $handler) {
|
28 |
-
return function ($request, array $options) use ($handler) {
|
29 |
-
if (empty($options['cookies'])) {
|
30 |
-
return $handler($request, $options);
|
31 |
-
} elseif (!($options['cookies'] instanceof CookieJarInterface)) {
|
32 |
-
throw new \InvalidArgumentException('cookies must be an instance of GuzzleHttp\Cookie\CookieJarInterface');
|
33 |
-
}
|
34 |
-
$cookieJar = $options['cookies'];
|
35 |
-
$request = $cookieJar->withCookieHeader($request);
|
36 |
-
return $handler($request, $options)
|
37 |
-
->then(
|
38 |
-
function ($response) use ($cookieJar, $request) {
|
39 |
-
$cookieJar->extractCookies($request, $response);
|
40 |
-
return $response;
|
41 |
-
}
|
42 |
-
);
|
43 |
-
};
|
44 |
-
};
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Middleware that throws exceptions for 4xx or 5xx responses when the
|
49 |
-
* "http_error" request option is set to true.
|
50 |
-
*
|
51 |
-
* @return callable Returns a function that accepts the next handler.
|
52 |
-
*/
|
53 |
-
public static function httpErrors()
|
54 |
-
{
|
55 |
-
return function (callable $handler) {
|
56 |
-
return function ($request, array $options) use ($handler) {
|
57 |
-
if (empty($options['http_errors'])) {
|
58 |
-
return $handler($request, $options);
|
59 |
-
}
|
60 |
-
return $handler($request, $options)->then(
|
61 |
-
function (ResponseInterface $response) use ($request, $handler) {
|
62 |
-
$code = $response->getStatusCode();
|
63 |
-
if ($code < 400) {
|
64 |
-
return $response;
|
65 |
-
}
|
66 |
-
throw RequestException::create($request, $response);
|
67 |
-
}
|
68 |
-
);
|
69 |
-
};
|
70 |
-
};
|
71 |
-
}
|
72 |
-
|
73 |
-
/**
|
74 |
-
* Middleware that pushes history data to an ArrayAccess container.
|
75 |
-
*
|
76 |
-
* @param array|\ArrayAccess $container Container to hold the history (by reference).
|
77 |
-
*
|
78 |
-
* @return callable Returns a function that accepts the next handler.
|
79 |
-
* @throws \InvalidArgumentException if container is not an array or ArrayAccess.
|
80 |
-
*/
|
81 |
-
public static function history(&$container)
|
82 |
-
{
|
83 |
-
if (!is_array($container) && !$container instanceof \ArrayAccess) {
|
84 |
-
throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess');
|
85 |
-
}
|
86 |
-
|
87 |
-
return function (callable $handler) use (&$container) {
|
88 |
-
return function ($request, array $options) use ($handler, &$container) {
|
89 |
-
return $handler($request, $options)->then(
|
90 |
-
function ($value) use ($request, &$container, $options) {
|
91 |
-
$container[] = [
|
92 |
-
'request' => $request,
|
93 |
-
'response' => $value,
|
94 |
-
'error' => null,
|
95 |
-
'options' => $options
|
96 |
-
];
|
97 |
-
return $value;
|
98 |
-
},
|
99 |
-
function ($reason) use ($request, &$container, $options) {
|
100 |
-
$container[] = [
|
101 |
-
'request' => $request,
|
102 |
-
'response' => null,
|
103 |
-
'error' => $reason,
|
104 |
-
'options' => $options
|
105 |
-
];
|
106 |
-
return \GuzzleHttp\Promise\rejection_for($reason);
|
107 |
-
}
|
108 |
-
);
|
109 |
-
};
|
110 |
-
};
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Middleware that invokes a callback before and after sending a request.
|
115 |
-
*
|
116 |
-
* The provided listener cannot modify or alter the response. It simply
|
117 |
-
* "taps" into the chain to be notified before returning the promise. The
|
118 |
-
* before listener accepts a request and options array, and the after
|
119 |
-
* listener accepts a request, options array, and response promise.
|
120 |
-
*
|
121 |
-
* @param callable $before Function to invoke before forwarding the request.
|
122 |
-
* @param callable $after Function invoked after forwarding.
|
123 |
-
*
|
124 |
-
* @return callable Returns a function that accepts the next handler.
|
125 |
-
*/
|
126 |
-
public static function tap(callable $before = null, callable $after = null)
|
127 |
-
{
|
128 |
-
return function (callable $handler) use ($before, $after) {
|
129 |
-
return function ($request, array $options) use ($handler, $before, $after) {
|
130 |
-
if ($before) {
|
131 |
-
$before($request, $options);
|
132 |
-
}
|
133 |
-
$response = $handler($request, $options);
|
134 |
-
if ($after) {
|
135 |
-
$after($request, $options, $response);
|
136 |
-
}
|
137 |
-
return $response;
|
138 |
-
};
|
139 |
-
};
|
140 |
-
}
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Middleware that handles request redirects.
|
144 |
-
*
|
145 |
-
* @return callable Returns a function that accepts the next handler.
|
146 |
-
*/
|
147 |
-
public static function redirect()
|
148 |
-
{
|
149 |
-
return function (callable $handler) {
|
150 |
-
return new RedirectMiddleware($handler);
|
151 |
-
};
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* Middleware that retries requests based on the boolean result of
|
156 |
-
* invoking the provided "decider" function.
|
157 |
-
*
|
158 |
-
* If no delay function is provided, a simple implementation of exponential
|
159 |
-
* backoff will be utilized.
|
160 |
-
*
|
161 |
-
* @param callable $decider Function that accepts the number of retries,
|
162 |
-
* a request, [response], and [exception] and
|
163 |
-
* returns true if the request is to be retried.
|
164 |
-
* @param callable $delay Function that accepts the number of retries and
|
165 |
-
* returns the number of milliseconds to delay.
|
166 |
-
*
|
167 |
-
* @return callable Returns a function that accepts the next handler.
|
168 |
-
*/
|
169 |
-
public static function retry(callable $decider, callable $delay = null)
|
170 |
-
{
|
171 |
-
return function (callable $handler) use ($decider, $delay) {
|
172 |
-
return new RetryMiddleware($decider, $handler, $delay);
|
173 |
-
};
|
174 |
-
}
|
175 |
-
|
176 |
-
/**
|
177 |
-
* Middleware that logs requests, responses, and errors using a message
|
178 |
-
* formatter.
|
179 |
-
*
|
180 |
-
* @param LoggerInterface $logger Logs messages.
|
181 |
-
* @param MessageFormatter $formatter Formatter used to create message strings.
|
182 |
-
* @param string $logLevel Level at which to log requests.
|
183 |
-
*
|
184 |
-
* @return callable Returns a function that accepts the next handler.
|
185 |
-
*/
|
186 |
-
public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = LogLevel::INFO)
|
187 |
-
{
|
188 |
-
return function (callable $handler) use ($logger, $formatter, $logLevel) {
|
189 |
-
return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) {
|
190 |
-
return $handler($request, $options)->then(
|
191 |
-
function ($response) use ($logger, $request, $formatter, $logLevel) {
|
192 |
-
$message = $formatter->format($request, $response);
|
193 |
-
$logger->log($logLevel, $message);
|
194 |
-
return $response;
|
195 |
-
},
|
196 |
-
function ($reason) use ($logger, $request, $formatter) {
|
197 |
-
$response = $reason instanceof RequestException
|
198 |
-
? $reason->getResponse()
|
199 |
-
: null;
|
200 |
-
$message = $formatter->format($request, $response, $reason);
|
201 |
-
$logger->notice($message);
|
202 |
-
return \GuzzleHttp\Promise\rejection_for($reason);
|
203 |
-
}
|
204 |
-
);
|
205 |
-
};
|
206 |
-
};
|
207 |
-
}
|
208 |
-
|
209 |
-
/**
|
210 |
-
* This middleware adds a default content-type if possible, a default
|
211 |
-
* content-length or transfer-encoding header, and the expect header.
|
212 |
-
*
|
213 |
-
* @return callable
|
214 |
-
*/
|
215 |
-
public static function prepareBody()
|
216 |
-
{
|
217 |
-
return function (callable $handler) {
|
218 |
-
return new PrepareBodyMiddleware($handler);
|
219 |
-
};
|
220 |
-
}
|
221 |
-
|
222 |
-
/**
|
223 |
-
* Middleware that applies a map function to the request before passing to
|
224 |
-
* the next handler.
|
225 |
-
*
|
226 |
-
* @param callable $fn Function that accepts a RequestInterface and returns
|
227 |
-
* a RequestInterface.
|
228 |
-
* @return callable
|
229 |
-
*/
|
230 |
-
public static function mapRequest(callable $fn)
|
231 |
-
{
|
232 |
-
return function (callable $handler) use ($fn) {
|
233 |
-
return function ($request, array $options) use ($handler, $fn) {
|
234 |
-
return $handler($fn($request), $options);
|
235 |
-
};
|
236 |
-
};
|
237 |
-
}
|
238 |
-
|
239 |
-
/**
|
240 |
-
* Middleware that applies a map function to the resolved promise's
|
241 |
-
* response.
|
242 |
-
*
|
243 |
-
* @param callable $fn Function that accepts a ResponseInterface and
|
244 |
-
* returns a ResponseInterface.
|
245 |
-
* @return callable
|
246 |
-
*/
|
247 |
-
public static function mapResponse(callable $fn)
|
248 |
-
{
|
249 |
-
return function (callable $handler) use ($fn) {
|
250 |
-
return function ($request, array $options) use ($handler, $fn) {
|
251 |
-
return $handler($request, $options)->then($fn);
|
252 |
-
};
|
253 |
-
};
|
254 |
-
}
|
255 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Pool.php
DELETED
@@ -1,123 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp;
|
3 |
-
|
4 |
-
use GuzzleHttp\Promise\PromisorInterface;
|
5 |
-
use Psr\Http\Message\RequestInterface;
|
6 |
-
use GuzzleHttp\Promise\EachPromise;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Sends and iterator of requests concurrently using a capped pool size.
|
10 |
-
*
|
11 |
-
* The pool will read from an iterator until it is cancelled or until the
|
12 |
-
* iterator is consumed. When a request is yielded, the request is sent after
|
13 |
-
* applying the "request_options" request options (if provided in the ctor).
|
14 |
-
*
|
15 |
-
* When a function is yielded by the iterator, the function is provided the
|
16 |
-
* "request_options" array that should be merged on top of any existing
|
17 |
-
* options, and the function MUST then return a wait-able promise.
|
18 |
-
*/
|
19 |
-
class Pool implements PromisorInterface
|
20 |
-
{
|
21 |
-
/** @var EachPromise */
|
22 |
-
private $each;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @param ClientInterface $client Client used to send the requests.
|
26 |
-
* @param array|\Iterator $requests Requests or functions that return
|
27 |
-
* requests to send concurrently.
|
28 |
-
* @param array $config Associative array of options
|
29 |
-
* - concurrency: (int) Maximum number of requests to send concurrently
|
30 |
-
* - options: Array of request options to apply to each request.
|
31 |
-
* - fulfilled: (callable) Function to invoke when a request completes.
|
32 |
-
* - rejected: (callable) Function to invoke when a request is rejected.
|
33 |
-
*/
|
34 |
-
public function __construct(
|
35 |
-
ClientInterface $client,
|
36 |
-
$requests,
|
37 |
-
array $config = []
|
38 |
-
) {
|
39 |
-
// Backwards compatibility.
|
40 |
-
if (isset($config['pool_size'])) {
|
41 |
-
$config['concurrency'] = $config['pool_size'];
|
42 |
-
} elseif (!isset($config['concurrency'])) {
|
43 |
-
$config['concurrency'] = 25;
|
44 |
-
}
|
45 |
-
|
46 |
-
if (isset($config['options'])) {
|
47 |
-
$opts = $config['options'];
|
48 |
-
unset($config['options']);
|
49 |
-
} else {
|
50 |
-
$opts = [];
|
51 |
-
}
|
52 |
-
|
53 |
-
$iterable = \GuzzleHttp\Promise\iter_for($requests);
|
54 |
-
$requests = function () use ($iterable, $client, $opts) {
|
55 |
-
foreach ($iterable as $key => $rfn) {
|
56 |
-
if ($rfn instanceof RequestInterface) {
|
57 |
-
yield $key => $client->sendAsync($rfn, $opts);
|
58 |
-
} elseif (is_callable($rfn)) {
|
59 |
-
yield $key => $rfn($opts);
|
60 |
-
} else {
|
61 |
-
throw new \InvalidArgumentException('Each value yielded by '
|
62 |
-
. 'the iterator must be a Psr7\Http\Message\RequestInterface '
|
63 |
-
. 'or a callable that returns a promise that fulfills '
|
64 |
-
. 'with a Psr7\Message\Http\ResponseInterface object.');
|
65 |
-
}
|
66 |
-
}
|
67 |
-
};
|
68 |
-
|
69 |
-
$this->each = new EachPromise($requests(), $config);
|
70 |
-
}
|
71 |
-
|
72 |
-
public function promise()
|
73 |
-
{
|
74 |
-
return $this->each->promise();
|
75 |
-
}
|
76 |
-
|
77 |
-
/**
|
78 |
-
* Sends multiple requests concurrently and returns an array of responses
|
79 |
-
* and exceptions that uses the same ordering as the provided requests.
|
80 |
-
*
|
81 |
-
* IMPORTANT: This method keeps every request and response in memory, and
|
82 |
-
* as such, is NOT recommended when sending a large number or an
|
83 |
-
* indeterminate number of requests concurrently.
|
84 |
-
*
|
85 |
-
* @param ClientInterface $client Client used to send the requests
|
86 |
-
* @param array|\Iterator $requests Requests to send concurrently.
|
87 |
-
* @param array $options Passes through the options available in
|
88 |
-
* {@see GuzzleHttp\Pool::__construct}
|
89 |
-
*
|
90 |
-
* @return array Returns an array containing the response or an exception
|
91 |
-
* in the same order that the requests were sent.
|
92 |
-
* @throws \InvalidArgumentException if the event format is incorrect.
|
93 |
-
*/
|
94 |
-
public static function batch(
|
95 |
-
ClientInterface $client,
|
96 |
-
$requests,
|
97 |
-
array $options = []
|
98 |
-
) {
|
99 |
-
$res = [];
|
100 |
-
self::cmpCallback($options, 'fulfilled', $res);
|
101 |
-
self::cmpCallback($options, 'rejected', $res);
|
102 |
-
$pool = new static($client, $requests, $options);
|
103 |
-
$pool->promise()->wait();
|
104 |
-
ksort($res);
|
105 |
-
|
106 |
-
return $res;
|
107 |
-
}
|
108 |
-
|
109 |
-
private static function cmpCallback(array &$options, $name, array &$results)
|
110 |
-
{
|
111 |
-
if (!isset($options[$name])) {
|
112 |
-
$options[$name] = function ($v, $k) use (&$results) {
|
113 |
-
$results[$k] = $v;
|
114 |
-
};
|
115 |
-
} else {
|
116 |
-
$currentFn = $options[$name];
|
117 |
-
$options[$name] = function ($v, $k) use (&$results, $currentFn) {
|
118 |
-
$currentFn($v, $k);
|
119 |
-
$results[$k] = $v;
|
120 |
-
};
|
121 |
-
}
|
122 |
-
}
|
123 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/PrepareBodyMiddleware.php
DELETED
@@ -1,106 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp;
|
3 |
-
|
4 |
-
use GuzzleHttp\Promise\PromiseInterface;
|
5 |
-
use GuzzleHttp\Psr7;
|
6 |
-
use Psr\Http\Message\RequestInterface;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Prepares requests that contain a body, adding the Content-Length,
|
10 |
-
* Content-Type, and Expect headers.
|
11 |
-
*/
|
12 |
-
class PrepareBodyMiddleware
|
13 |
-
{
|
14 |
-
/** @var callable */
|
15 |
-
private $nextHandler;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @param callable $nextHandler Next handler to invoke.
|
19 |
-
*/
|
20 |
-
public function __construct(callable $nextHandler)
|
21 |
-
{
|
22 |
-
$this->nextHandler = $nextHandler;
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @param RequestInterface $request
|
27 |
-
* @param array $options
|
28 |
-
*
|
29 |
-
* @return PromiseInterface
|
30 |
-
*/
|
31 |
-
public function __invoke(RequestInterface $request, array $options)
|
32 |
-
{
|
33 |
-
$fn = $this->nextHandler;
|
34 |
-
|
35 |
-
// Don't do anything if the request has no body.
|
36 |
-
if ($request->getBody()->getSize() === 0) {
|
37 |
-
return $fn($request, $options);
|
38 |
-
}
|
39 |
-
|
40 |
-
$modify = [];
|
41 |
-
|
42 |
-
// Add a default content-type if possible.
|
43 |
-
if (!$request->hasHeader('Content-Type')) {
|
44 |
-
if ($uri = $request->getBody()->getMetadata('uri')) {
|
45 |
-
if ($type = Psr7\mimetype_from_filename($uri)) {
|
46 |
-
$modify['set_headers']['Content-Type'] = $type;
|
47 |
-
}
|
48 |
-
}
|
49 |
-
}
|
50 |
-
|
51 |
-
// Add a default content-length or transfer-encoding header.
|
52 |
-
if (!$request->hasHeader('Content-Length')
|
53 |
-
&& !$request->hasHeader('Transfer-Encoding')
|
54 |
-
) {
|
55 |
-
$size = $request->getBody()->getSize();
|
56 |
-
if ($size !== null) {
|
57 |
-
$modify['set_headers']['Content-Length'] = $size;
|
58 |
-
} else {
|
59 |
-
$modify['set_headers']['Transfer-Encoding'] = 'chunked';
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
// Add the expect header if needed.
|
64 |
-
$this->addExpectHeader($request, $options, $modify);
|
65 |
-
|
66 |
-
return $fn(Psr7\modify_request($request, $modify), $options);
|
67 |
-
}
|
68 |
-
|
69 |
-
private function addExpectHeader(
|
70 |
-
RequestInterface $request,
|
71 |
-
array $options,
|
72 |
-
array &$modify
|
73 |
-
) {
|
74 |
-
// Determine if the Expect header should be used
|
75 |
-
if ($request->hasHeader('Expect')) {
|
76 |
-
return;
|
77 |
-
}
|
78 |
-
|
79 |
-
$expect = isset($options['expect']) ? $options['expect'] : null;
|
80 |
-
|
81 |
-
// Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0
|
82 |
-
if ($expect === false || $request->getProtocolVersion() < 1.1) {
|
83 |
-
return;
|
84 |
-
}
|
85 |
-
|
86 |
-
// The expect header is unconditionally enabled
|
87 |
-
if ($expect === true) {
|
88 |
-
$modify['set_headers']['Expect'] = '100-Continue';
|
89 |
-
return;
|
90 |
-
}
|
91 |
-
|
92 |
-
// By default, send the expect header when the payload is > 1mb
|
93 |
-
if ($expect === null) {
|
94 |
-
$expect = 1048576;
|
95 |
-
}
|
96 |
-
|
97 |
-
// Always add if the body cannot be rewound, the size cannot be
|
98 |
-
// determined, or the size is greater than the cutoff threshold
|
99 |
-
$body = $request->getBody();
|
100 |
-
$size = $body->getSize();
|
101 |
-
|
102 |
-
if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
|
103 |
-
$modify['set_headers']['Expect'] = '100-Continue';
|
104 |
-
}
|
105 |
-
}
|
106 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Promise/AggregateException.php
DELETED
@@ -1,16 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Promise;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Exception thrown when too many errors occur in the some() or any() methods.
|
6 |
-
*/
|
7 |
-
class AggregateException extends RejectionException
|
8 |
-
{
|
9 |
-
public function __construct($msg, array $reasons)
|
10 |
-
{
|
11 |
-
parent::__construct(
|
12 |
-
$reasons,
|
13 |
-
sprintf('%s; %d rejected promises', $msg, count($reasons))
|
14 |
-
);
|
15 |
-
}
|
16 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Promise/CancellationException.php
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Promise;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Exception that is set as the reason for a promise that has been cancelled.
|
6 |
-
*/
|
7 |
-
class CancellationException extends RejectionException
|
8 |
-
{
|
9 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Promise/Coroutine.php
DELETED
@@ -1,151 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Promise;
|
3 |
-
|
4 |
-
use Exception;
|
5 |
-
use Generator;
|
6 |
-
use Throwable;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Creates a promise that is resolved using a generator that yields values or
|
10 |
-
* promises (somewhat similar to C#'s async keyword).
|
11 |
-
*
|
12 |
-
* When called, the coroutine function will start an instance of the generator
|
13 |
-
* and returns a promise that is fulfilled with its final yielded value.
|
14 |
-
*
|
15 |
-
* Control is returned back to the generator when the yielded promise settles.
|
16 |
-
* This can lead to less verbose code when doing lots of sequential async calls
|
17 |
-
* with minimal processing in between.
|
18 |
-
*
|
19 |
-
* use GuzzleHttp\Promise;
|
20 |
-
*
|
21 |
-
* function createPromise($value) {
|
22 |
-
* return new Promise\FulfilledPromise($value);
|
23 |
-
* }
|
24 |
-
*
|
25 |
-
* $promise = Promise\coroutine(function () {
|
26 |
-
* $value = (yield createPromise('a'));
|
27 |
-
* try {
|
28 |
-
* $value = (yield createPromise($value . 'b'));
|
29 |
-
* } catch (\Exception $e) {
|
30 |
-
* // The promise was rejected.
|
31 |
-
* }
|
32 |
-
* yield $value . 'c';
|
33 |
-
* });
|
34 |
-
*
|
35 |
-
* // Outputs "abc"
|
36 |
-
* $promise->then(function ($v) { echo $v; });
|
37 |
-
*
|
38 |
-
* @param callable $generatorFn Generator function to wrap into a promise.
|
39 |
-
*
|
40 |
-
* @return Promise
|
41 |
-
* @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
|
42 |
-
*/
|
43 |
-
final class Coroutine implements PromiseInterface
|
44 |
-
{
|
45 |
-
/**
|
46 |
-
* @var PromiseInterface|null
|
47 |
-
*/
|
48 |
-
private $currentPromise;
|
49 |
-
|
50 |
-
/**
|
51 |
-
* @var Generator
|
52 |
-
*/
|
53 |
-
private $generator;
|
54 |
-
|
55 |
-
/**
|
56 |
-
* @var Promise
|
57 |
-
*/
|
58 |
-
private $result;
|
59 |
-
|
60 |
-
public function __construct(callable $generatorFn)
|
61 |
-
{
|
62 |
-
$this->generator = $generatorFn();
|
63 |
-
$this->result = new Promise(function () {
|
64 |
-
while (isset($this->currentPromise)) {
|
65 |
-
$this->currentPromise->wait();
|
66 |
-
}
|
67 |
-
});
|
68 |
-
$this->nextCoroutine($this->generator->current());
|
69 |
-
}
|
70 |
-
|
71 |
-
public function then(
|
72 |
-
callable $onFulfilled = null,
|
73 |
-
callable $onRejected = null
|
74 |
-
) {
|
75 |
-
return $this->result->then($onFulfilled, $onRejected);
|
76 |
-
}
|
77 |
-
|
78 |
-
public function otherwise(callable $onRejected)
|
79 |
-
{
|
80 |
-
return $this->result->otherwise($onRejected);
|
81 |
-
}
|
82 |
-
|
83 |
-
public function wait($unwrap = true)
|
84 |
-
{
|
85 |
-
return $this->result->wait($unwrap);
|
86 |
-
}
|
87 |
-
|
88 |
-
public function getState()
|
89 |
-
{
|
90 |
-
return $this->result->getState();
|
91 |
-
}
|
92 |
-
|
93 |
-
public function resolve($value)
|
94 |
-
{
|
95 |
-
$this->result->resolve($value);
|
96 |
-
}
|
97 |
-
|
98 |
-
public function reject($reason)
|
99 |
-
{
|
100 |
-
$this->result->reject($reason);
|
101 |
-
}
|
102 |
-
|
103 |
-
public function cancel()
|
104 |
-
{
|
105 |
-
$this->currentPromise->cancel();
|
106 |
-
$this->result->cancel();
|
107 |
-
}
|
108 |
-
|
109 |
-
private function nextCoroutine($yielded)
|
110 |
-
{
|
111 |
-
$this->currentPromise = promise_for($yielded)
|
112 |
-
->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
|
113 |
-
}
|
114 |
-
|
115 |
-
/**
|
116 |
-
* @internal
|
117 |
-
*/
|
118 |
-
public function _handleSuccess($value)
|
119 |
-
{
|
120 |
-
unset($this->currentPromise);
|
121 |
-
try {
|
122 |
-
$next = $this->generator->send($value);
|
123 |
-
if ($this->generator->valid()) {
|
124 |
-
$this->nextCoroutine($next);
|
125 |
-
} else {
|
126 |
-
$this->result->resolve($value);
|
127 |
-
}
|
128 |
-
} catch (Exception $exception) {
|
129 |
-
$this->result->reject($exception);
|
130 |
-
} catch (Throwable $throwable) {
|
131 |
-
$this->result->reject($throwable);
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
/**
|
136 |
-
* @internal
|
137 |
-
*/
|
138 |
-
public function _handleFailure($reason)
|
139 |
-
{
|
140 |
-
unset($this->currentPromise);
|
141 |
-
try {
|
142 |
-
$nextYield = $this->generator->throw(exception_for($reason));
|
143 |
-
// The throw was caught, so keep iterating on the coroutine
|
144 |
-
$this->nextCoroutine($nextYield);
|
145 |
-
} catch (Exception $exception) {
|
146 |
-
$this->result->reject($exception);
|
147 |
-
} catch (Throwable $throwable) {
|
148 |
-
$this->result->reject($throwable);
|
149 |
-
}
|
150 |
-
}
|
151 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Promise/EachPromise.php
DELETED
@@ -1,229 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Promise;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Represents a promise that iterates over many promises and invokes
|
6 |
-
* side-effect functions in the process.
|
7 |
-
*/
|
8 |
-
class EachPromise implements PromisorInterface
|
9 |
-
{
|
10 |
-
private $pending = [];
|
11 |
-
|
12 |
-
/** @var \Iterator */
|
13 |
-
private $iterable;
|
14 |
-
|
15 |
-
/** @var callable|int */
|
16 |
-
private $concurrency;
|
17 |
-
|
18 |
-
/** @var callable */
|
19 |
-
private $onFulfilled;
|
20 |
-
|
21 |
-
/** @var callable */
|
22 |
-
private $onRejected;
|
23 |
-
|
24 |
-
/** @var Promise */
|
25 |
-
private $aggregate;
|
26 |
-
|
27 |
-
/** @var bool */
|
28 |
-
private $mutex;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Configuration hash can include the following key value pairs:
|
32 |
-
*
|
33 |
-
* - fulfilled: (callable) Invoked when a promise fulfills. The function
|
34 |
-
* is invoked with three arguments: the fulfillment value, the index
|
35 |
-
* position from the iterable list of the promise, and the aggregate
|
36 |
-
* promise that manages all of the promises. The aggregate promise may
|
37 |
-
* be resolved from within the callback to short-circuit the promise.
|
38 |
-
* - rejected: (callable) Invoked when a promise is rejected. The
|
39 |
-
* function is invoked with three arguments: the rejection reason, the
|
40 |
-
* index position from the iterable list of the promise, and the
|
41 |
-
* aggregate promise that manages all of the promises. The aggregate
|
42 |
-
* promise may be resolved from within the callback to short-circuit
|
43 |
-
* the promise.
|
44 |
-
* - concurrency: (integer) Pass this configuration option to limit the
|
45 |
-
* allowed number of outstanding concurrently executing promises,
|
46 |
-
* creating a capped pool of promises. There is no limit by default.
|
47 |
-
*
|
48 |
-
* @param mixed $iterable Promises or values to iterate.
|
49 |
-
* @param array $config Configuration options
|
50 |
-
*/
|
51 |
-
public function __construct($iterable, array $config = [])
|
52 |
-
{
|
53 |
-
$this->iterable = iter_for($iterable);
|
54 |
-
|
55 |
-
if (isset($config['concurrency'])) {
|
56 |
-
$this->concurrency = $config['concurrency'];
|
57 |
-
}
|
58 |
-
|
59 |
-
if (isset($config['fulfilled'])) {
|
60 |
-
$this->onFulfilled = $config['fulfilled'];
|
61 |
-
}
|
62 |
-
|
63 |
-
if (isset($config['rejected'])) {
|
64 |
-
$this->onRejected = $config['rejected'];
|
65 |
-
}
|
66 |
-
}
|
67 |
-
|
68 |
-
public function promise()
|
69 |
-
{
|
70 |
-
if ($this->aggregate) {
|
71 |
-
return $this->aggregate;
|
72 |
-
}
|
73 |
-
|
74 |
-
try {
|
75 |
-
$this->createPromise();
|
76 |
-
$this->iterable->rewind();
|
77 |
-
$this->refillPending();
|
78 |
-
} catch (\Throwable $e) {
|
79 |
-
$this->aggregate->reject($e);
|
80 |
-
} catch (\Exception $e) {
|
81 |
-
$this->aggregate->reject($e);
|
82 |
-
}
|
83 |
-
|
84 |
-
return $this->aggregate;
|
85 |
-
}
|
86 |
-
|
87 |
-
private function createPromise()
|
88 |
-
{
|
89 |
-
$this->mutex = false;
|
90 |
-
$this->aggregate = new Promise(function () {
|
91 |
-
reset($this->pending);
|
92 |
-
if (empty($this->pending) && !$this->iterable->valid()) {
|
93 |
-
$this->aggregate->resolve(null);
|
94 |
-
return;
|
95 |
-
}
|
96 |
-
|
97 |
-
// Consume a potentially fluctuating list of promises while
|
98 |
-
// ensuring that indexes are maintained (precluding array_shift).
|
99 |
-
while ($promise = current($this->pending)) {
|
100 |
-
next($this->pending);
|
101 |
-
$promise->wait();
|
102 |
-
if ($this->aggregate->getState() !== PromiseInterface::PENDING) {
|
103 |
-
return;
|
104 |
-
}
|
105 |
-
}
|
106 |
-
});
|
107 |
-
|
108 |
-
// Clear the references when the promise is resolved.
|
109 |
-
$clearFn = function () {
|
110 |
-
$this->iterable = $this->concurrency = $this->pending = null;
|
111 |
-
$this->onFulfilled = $this->onRejected = null;
|
112 |
-
};
|
113 |
-
|
114 |
-
$this->aggregate->then($clearFn, $clearFn);
|
115 |
-
}
|
116 |
-
|
117 |
-
private function refillPending()
|
118 |
-
{
|
119 |
-
if (!$this->concurrency) {
|
120 |
-
// Add all pending promises.
|
121 |
-
while ($this->addPending() && $this->advanceIterator());
|
122 |
-
return;
|
123 |
-
}
|
124 |
-
|
125 |
-
// Add only up to N pending promises.
|
126 |
-
$concurrency = is_callable($this->concurrency)
|
127 |
-
? call_user_func($this->concurrency, count($this->pending))
|
128 |
-
: $this->concurrency;
|
129 |
-
$concurrency = max($concurrency - count($this->pending), 0);
|
130 |
-
// Concurrency may be set to 0 to disallow new promises.
|
131 |
-
if (!$concurrency) {
|
132 |
-
return;
|
133 |
-
}
|
134 |
-
// Add the first pending promise.
|
135 |
-
$this->addPending();
|
136 |
-
// Note this is special handling for concurrency=1 so that we do
|
137 |
-
// not advance the iterator after adding the first promise. This
|
138 |
-
// helps work around issues with generators that might not have the
|
139 |
-
// next value to yield until promise callbacks are called.
|
140 |
-
while (--$concurrency
|
141 |
-
&& $this->advanceIterator()
|
142 |
-
&& $this->addPending());
|
143 |
-
}
|
144 |
-
|
145 |
-
private function addPending()
|
146 |
-
{
|
147 |
-
if (!$this->iterable || !$this->iterable->valid()) {
|
148 |
-
return false;
|
149 |
-
}
|
150 |
-
|
151 |
-
$promise = promise_for($this->iterable->current());
|
152 |
-
$idx = $this->iterable->key();
|
153 |
-
|
154 |
-
$this->pending[$idx] = $promise->then(
|
155 |
-
function ($value) use ($idx) {
|
156 |
-
if ($this->onFulfilled) {
|
157 |
-
call_user_func(
|
158 |
-
$this->onFulfilled, $value, $idx, $this->aggregate
|
159 |
-
);
|
160 |
-
}
|
161 |
-
$this->step($idx);
|
162 |
-
},
|
163 |
-
function ($reason) use ($idx) {
|
164 |
-
if ($this->onRejected) {
|
165 |
-
call_user_func(
|
166 |
-
$this->onRejected, $reason, $idx, $this->aggregate
|
167 |
-
);
|
168 |
-
}
|
169 |
-
$this->step($idx);
|
170 |
-
}
|
171 |
-
);
|
172 |
-
|
173 |
-
return true;
|
174 |
-
}
|
175 |
-
|
176 |
-
private function advanceIterator()
|
177 |
-
{
|
178 |
-
// Place a lock on the iterator so that we ensure to not recurse,
|
179 |
-
// preventing fatal generator errors.
|
180 |
-
if ($this->mutex) {
|
181 |
-
return false;
|
182 |
-
}
|
183 |
-
|
184 |
-
$this->mutex = true;
|
185 |
-
|
186 |
-
try {
|
187 |
-
$this->iterable->next();
|
188 |
-
$this->mutex = false;
|
189 |
-
return true;
|
190 |
-
} catch (\Throwable $e) {
|
191 |
-
$this->aggregate->reject($e);
|
192 |
-
$this->mutex = false;
|
193 |
-
return false;
|
194 |
-
} catch (\Exception $e) {
|
195 |
-
$this->aggregate->reject($e);
|
196 |
-
$this->mutex = false;
|
197 |
-
return false;
|
198 |
-
}
|
199 |
-
}
|
200 |
-
|
201 |
-
private function step($idx)
|
202 |
-
{
|
203 |
-
// If the promise was already resolved, then ignore this step.
|
204 |
-
if ($this->aggregate->getState() !== PromiseInterface::PENDING) {
|
205 |
-
return;
|
206 |
-
}
|
207 |
-
|
208 |
-
unset($this->pending[$idx]);
|
209 |
-
|
210 |
-
// Only refill pending promises if we are not locked, preventing the
|
211 |
-
// EachPromise to recursively invoke the provided iterator, which
|
212 |
-
// cause a fatal error: "Cannot resume an already running generator"
|
213 |
-
if ($this->advanceIterator() && !$this->checkIfFinished()) {
|
214 |
-
// Add more pending promises if possible.
|
215 |
-
$this->refillPending();
|
216 |
-
}
|
217 |
-
}
|
218 |
-
|
219 |
-
private function checkIfFinished()
|
220 |
-
{
|
221 |
-
if (!$this->pending && !$this->iterable->valid()) {
|
222 |
-
// Resolve the promise if there's nothing left to do.
|
223 |
-
$this->aggregate->resolve(null);
|
224 |
-
return true;
|
225 |
-
}
|
226 |
-
|
227 |
-
return false;
|
228 |
-
}
|
229 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Promise/FulfilledPromise.php
DELETED
@@ -1,82 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Promise;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A promise that has been fulfilled.
|
6 |
-
*
|
7 |
-
* Thenning off of this promise will invoke the onFulfilled callback
|
8 |
-
* immediately and ignore other callbacks.
|
9 |
-
*/
|
10 |
-
class FulfilledPromise implements PromiseInterface
|
11 |
-
{
|
12 |
-
private $value;
|
13 |
-
|
14 |
-
public function __construct($value)
|
15 |
-
{
|
16 |
-
if (method_exists($value, 'then')) {
|
17 |
-
throw new \InvalidArgumentException(
|
18 |
-
'You cannot create a FulfilledPromise with a promise.');
|
19 |
-
}
|
20 |
-
|
21 |
-
$this->value = $value;
|
22 |
-
}
|
23 |
-
|
24 |
-
public function then(
|
25 |
-
callable $onFulfilled = null,
|
26 |
-
callable $onRejected = null
|
27 |
-
) {
|
28 |
-
// Return itself if there is no onFulfilled function.
|
29 |
-
if (!$onFulfilled) {
|
30 |
-
return $this;
|
31 |
-
}
|
32 |
-
|
33 |
-
$queue = queue();
|
34 |
-
$p = new Promise([$queue, 'run']);
|
35 |
-
$value = $this->value;
|
36 |
-
$queue->add(static function () use ($p, $value, $onFulfilled) {
|
37 |
-
if ($p->getState() === self::PENDING) {
|
38 |
-
try {
|
39 |
-
$p->resolve($onFulfilled($value));
|
40 |
-
} catch (\Throwable $e) {
|
41 |
-
$p->reject($e);
|
42 |
-
} catch (\Exception $e) {
|
43 |
-
$p->reject($e);
|
44 |
-
}
|
45 |
-
}
|
46 |
-
});
|
47 |
-
|
48 |
-
return $p;
|
49 |
-
}
|
50 |
-
|
51 |
-
public function otherwise(callable $onRejected)
|
52 |
-
{
|
53 |
-
return $this->then(null, $onRejected);
|
54 |
-
}
|
55 |
-
|
56 |
-
public function wait($unwrap = true, $defaultDelivery = null)
|
57 |
-
{
|
58 |
-
return $unwrap ? $this->value : null;
|
59 |
-
}
|
60 |
-
|
61 |
-
public function getState()
|
62 |
-
{
|
63 |
-
return self::FULFILLED;
|
64 |
-
}
|
65 |
-
|
66 |
-
public function resolve($value)
|
67 |
-
{
|
68 |
-
if ($value !== $this->value) {
|
69 |
-
throw new \LogicException("Cannot resolve a fulfilled promise");
|
70 |
-
}
|
71 |
-
}
|
72 |
-
|
73 |
-
public function reject($reason)
|
74 |
-
{
|
75 |
-
throw new \LogicException("Cannot reject a fulfilled promise");
|
76 |
-
}
|
77 |
-
|
78 |
-
public function cancel()
|
79 |
-
{
|
80 |
-
// pass
|
81 |
-
}
|
82 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Aws/GuzzleHttp/Promise/Promise.php
DELETED
@@ -1,280 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace GuzzleHttp\Promise;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Promises/A+ implementation that avoids recursion when possible.
|
6 |
-
*
|
7 |
-
* @link https://promisesaplus.com/
|
8 |
-
*/
|
9 |
-
class Promise implements PromiseInterface
|
10 |
-
{
|
11 |
-
private $state = self::PENDING;
|
12 |
-
private $result;
|
13 |
-
private $cancelFn;
|
14 |
-
private $waitFn;
|
15 |
-
private $waitList;
|
16 |
-
private $handlers = [];
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @param callable $waitFn Fn that when invoked resolves the promise.
|
20 |
-
* @param callable $cancelFn Fn that when invoked cancels the promise.
|
21 |
-
*/
|
22 |
-
public function __construct(
|
23 |
-
callable $waitFn = null,
|
24 |
-
callable $cancelFn = null
|
25 |
-
) {
|
26 |
-
$this->waitFn = $waitFn;
|
27 |
-
$this->cancelFn = $cancelFn;
|
28 |
-
}
|
29 |
-
|
30 |
-
public function then(
|
31 |
-
callable $onFulfilled = null,
|
32 |
-
callable $onRejected = null
|
33 |
-
) {
|
34 |
-
if ($this->state === self::PENDING) {
|
35 |
-
$p = new Promise(null, [$this, 'cancel']);
|
36 |
-
$this->handlers[] = [$p, $onFulfilled, $onRejected];
|
37 |
-
$p->waitList = $this->waitList;
|
38 |
-
$p->waitList[] = $this;
|
39 |
-
return $p;
|
40 |
-
}
|
41 |
-
|
42 |
-
// Return a fulfilled promise and immediately invoke any callbacks.
|
43 |
-
if ($this->state === self::FULFILLED) {
|
44 |
-
return $onFulfilled
|
45 |
-
? promise_for($this->result)->then($onFulfilled)
|
46 |
-
: promise_for($this->result);
|
47 |
-
}
|
48 |
-
|
49 |
-
// It's either cancelled or rejected, so return a rejected promise
|
50 |
-
// and immediately invoke any callbacks.
|
51 |
-
$rejection = rejection_for($this->result);
|
52 |
-
return $onRejected ? $rejection->then(null, $onRejected) : $rejection;
|
53 |
-
}
|
54 |
-
|
55 |
-
public function otherwise(callable $onRejected)
|
56 |
-
{
|
57 |
-
return $this->then(null, $onRejected);
|
58 |
-
}
|
59 |
-
|
60 |
-
public function wait($unwrap = true)
|
61 |
-
{
|
62 |
-
$this->waitIfPending();
|
63 |
-
|
64 |
-
$inner = $this->result instanceof PromiseInterface
|
65 |
-
? $this->result->wait($unwrap)
|
66 |
-
: $this->result;
|
67 |
-
|
68 |
-
if ($unwrap) {
|
69 |
-
if ($this->result instanceof PromiseInterface
|
70 |
-
|| $this->state === self::FULFILLED
|
71 |
-
) {
|
72 |
-
return $inner;
|
73 |
-
} else {
|
74 |
-
// It's rejected so "unwrap" and throw an exception.
|
75 |
-
throw exception_for($inner);
|
76 |
-
}
|
77 |
-
}
|
78 |
-
}
|
79 |
-
|
80 |
-
public function getState()
|
81 |
-
{
|
82 |
-
return $this->state;
|
83 |
-
}
|
84 |
-
|
85 |
-
public function cancel()
|
86 |
-
{
|
87 |
-
if ($this->state !== self::PENDING) {
|
88 |
-
return;
|
89 |
-
}
|
90 |
-
|
91 |
-
$this->waitFn = $this->waitList = null;
|
92 |
-
|
93 |
-
if ($this->cancelFn) {
|
94 |
-
$fn = $this->cancelFn;
|
95 |
-
$this->cancelFn = null;
|
96 |
-
try {
|
97 |
-
$fn();
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|