W3 Total Cache - Version 2.1.3

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 Icon 128x128 W3 Total Cache
Version 2.1.3
Comparing to
See all releases

Code changes from version 2.1.2 to 2.1.3

Files changed (123) hide show
  1. CdnEngine_CloudFront.php +1 -1
  2. CdnEngine_Mirror_CloudFront.php +1 -1
  3. CdnEngine_S3.php +3 -2
  4. Cdnfsd_CloudFront_Engine.php +1 -1
  5. Cdnfsd_CloudFront_Popup.php +1 -1
  6. Enterprise_SnsBase.php +1 -1
  7. Generic_AdminActions_Default.php +1 -1
  8. Util_Theme.php +6 -6
  9. composer.json +18 -0
  10. composer.lock +605 -0
  11. inc/options/cdn/s3.php +1 -1
  12. inc/options/cdn/s3_compatible.php +1 -1
  13. lib/Aws/Aws/Api/ApiProvider.php +0 -244
  14. lib/Aws/Aws/Api/DateTimeResult.php +0 -41
  15. lib/Aws/Aws/Api/DocModel.php +0 -128
  16. lib/Aws/Aws/Api/ErrorParser/JsonParserTrait.php +0 -26
  17. lib/Aws/Aws/Api/ErrorParser/JsonRpcErrorParser.php +0 -31
  18. lib/Aws/Aws/Api/ErrorParser/RestJsonErrorParser.php +0 -35
  19. lib/Aws/Aws/Api/ErrorParser/XmlErrorParser.php +0 -82
  20. lib/Aws/Aws/Api/Parser/AbstractRestParser.php +0 -173
  21. lib/Aws/Aws/Api/Parser/Crc32ValidatingParser.php +0 -54
  22. lib/Aws/Aws/Api/Parser/DecodingEventStreamIterator.php +0 -335
  23. lib/Aws/Aws/Api/Parser/Exception/ParserException.php +0 -31
  24. lib/Aws/Aws/Api/Parser/JsonParser.php +0 -62
  25. lib/Aws/Aws/Api/Parser/PayloadParserTrait.php +0 -61
  26. lib/Aws/Aws/Api/Parser/XmlParser.php +0 -138
  27. lib/Aws/Aws/Api/Serializer/RestSerializer.php +0 -219
  28. lib/Aws/Aws/Api/Serializer/RestXmlSerializer.php +0 -34
  29. lib/Aws/Aws/Api/Serializer/XmlBody.php +0 -220
  30. lib/Aws/Aws/Api/Service.php +0 -448
  31. lib/Aws/Aws/Api/ShapeMap.php +0 -66
  32. lib/Aws/Aws/AwsClient.php +0 -402
  33. lib/Aws/Aws/AwsClientTrait.php +0 -92
  34. lib/Aws/Aws/ClientResolver.php +0 -768
  35. lib/Aws/Aws/ClientSideMonitoring/AbstractMonitoringMiddleware.php +0 -275
  36. lib/Aws/Aws/ClientSideMonitoring/Configuration.php +0 -65
  37. lib/Aws/Aws/ClientSideMonitoring/ConfigurationInterface.php +0 -37
  38. lib/Aws/Aws/ClientSideMonitoring/ConfigurationProvider.php +0 -342
  39. lib/Aws/Aws/CloudFront/CloudFrontClient.php +0 -190
  40. lib/Aws/Aws/CloudFront/Signer.php +0 -117
  41. lib/Aws/Aws/CloudFront/UrlSigner.php +0 -119
  42. lib/Aws/Aws/Command.php +0 -62
  43. lib/Aws/Aws/Credentials/CredentialProvider.php +0 -488
  44. lib/Aws/Aws/Credentials/EcsCredentialProvider.php +0 -88
  45. lib/Aws/Aws/Credentials/InstanceProfileProvider.php +0 -118
  46. lib/Aws/Aws/Endpoint/Partition.php +0 -183
  47. lib/Aws/Aws/Endpoint/PartitionEndpointProvider.php +0 -108
  48. lib/Aws/Aws/EndpointDiscovery/ConfigurationProvider.php +0 -333
  49. lib/Aws/Aws/EndpointDiscovery/EndpointDiscoveryMiddleware.php +0 -414
  50. lib/Aws/Aws/EndpointParameterMiddleware.php +0 -84
  51. lib/Aws/Aws/Exception/AwsException.php +0 -237
  52. lib/Aws/Aws/Handler/GuzzleV5/GuzzleHandler.php +0 -210
  53. lib/Aws/Aws/Handler/GuzzleV6/GuzzleHandler.php +0 -85
  54. lib/Aws/Aws/Middleware.php +0 -372
  55. lib/Aws/Aws/MockHandler.php +0 -145
  56. lib/Aws/Aws/MultiRegionClient.php +0 -236
  57. lib/Aws/Aws/PresignUrlMiddleware.php +0 -99
  58. lib/Aws/Aws/ResponseContainerInterface.php +0 -13
  59. lib/Aws/Aws/RetryMiddleware.php +0 -315
  60. lib/Aws/Aws/S3/AmbiguousSuccessParser.php +0 -68
  61. lib/Aws/Aws/S3/ApplyChecksumMiddleware.php +0 -78
  62. lib/Aws/Aws/S3/Crypto/HeadersMetadataStrategy.php +0 -52
  63. lib/Aws/Aws/S3/Crypto/S3EncryptionClient.php +0 -317
  64. lib/Aws/Aws/S3/Crypto/S3EncryptionMultipartUploader.php +0 -157
  65. lib/Aws/Aws/S3/MultipartCopy.php +0 -183
  66. lib/Aws/Aws/S3/MultipartUploader.php +0 -168
  67. lib/Aws/Aws/S3/ObjectCopier.php +0 -150
  68. lib/Aws/Aws/S3/ObjectUploader.php +0 -140
  69. lib/Aws/Aws/S3/PostObjectV4.php +0 -195
  70. lib/Aws/Aws/S3/PutObjectUrlMiddleware.php +0 -57
  71. lib/Aws/Aws/S3/S3Client.php +0 -633
  72. lib/Aws/Aws/S3/S3ClientInterface.php +0 -322
  73. lib/Aws/Aws/S3/S3EndpointMiddleware.php +0 -234
  74. lib/Aws/Aws/S3/S3MultiRegionClient.php +0 -339
  75. lib/Aws/Aws/S3/S3UriParser.php +0 -133
  76. lib/Aws/Aws/S3/StreamWrapper.php +0 -958
  77. lib/Aws/Aws/S3/Transfer.php +0 -428
  78. lib/Aws/Aws/Sdk.php +0 -466
  79. lib/Aws/Aws/Signature/AnonymousSignature.php +0 -26
  80. lib/Aws/Aws/Signature/S3SignatureV4.php +0 -68
  81. lib/Aws/Aws/Signature/SignatureInterface.php +0 -44
  82. lib/Aws/Aws/Signature/SignatureProvider.php +0 -131
  83. lib/Aws/Aws/Signature/SignatureV4.php +0 -412
  84. lib/Aws/Aws/Sns/Exception/InvalidSnsMessageException.php +0 -9
  85. lib/Aws/Aws/Sns/Message.php +0 -156
  86. lib/Aws/Aws/Sns/MessageValidator.php +0 -190
  87. lib/Aws/Aws/TraceMiddleware.php +0 -314
  88. lib/Aws/Aws/WrappedHttpHandler.php +0 -203
  89. lib/Aws/Aws/data/endpoints.json.php +0 -3
  90. lib/Aws/Aws/data/endpoints_prefix_history.json.php +0 -3
  91. lib/Aws/Aws/data/manifest.json.php +0 -3
  92. lib/Aws/Aws/data/s3/2006-03-01/api-2.json.php +0 -3
  93. lib/Aws/Aws/data/sns/2010-03-31/api-2.json.php +0 -3
  94. lib/Aws/Aws/functions.php +0 -411
  95. lib/Aws/Aws/signer/signerClient.php +0 -27
  96. lib/Aws/GuzzleHttp/Client.php +0 -422
  97. lib/Aws/GuzzleHttp/ClientInterface.php +0 -84
  98. lib/Aws/GuzzleHttp/Cookie/CookieJar.php +0 -314
  99. lib/Aws/GuzzleHttp/Cookie/CookieJarInterface.php +0 -84
  100. lib/Aws/GuzzleHttp/Cookie/FileCookieJar.php +0 -90
  101. lib/Aws/GuzzleHttp/Cookie/SessionCookieJar.php +0 -71
  102. lib/Aws/GuzzleHttp/Cookie/SetCookie.php +0 -403
  103. lib/Aws/GuzzleHttp/Exception/ClientException.php +0 -7
  104. lib/Aws/GuzzleHttp/Exception/GuzzleException.php +0 -13
  105. lib/Aws/GuzzleHttp/Exception/RequestException.php +0 -217
  106. lib/Aws/GuzzleHttp/Exception/ServerException.php +0 -7
  107. lib/Aws/GuzzleHttp/Exception/TooManyRedirectsException.php +0 -4
  108. lib/Aws/GuzzleHttp/Exception/TransferException.php +0 -4
  109. lib/Aws/GuzzleHttp/Handler/CurlFactory.php +0 -565
  110. lib/Aws/GuzzleHttp/Handler/CurlMultiHandler.php +0 -199
  111. lib/Aws/GuzzleHttp/Handler/MockHandler.php +0 -189
  112. lib/Aws/GuzzleHttp/Handler/StreamHandler.php +0 -532
  113. lib/Aws/GuzzleHttp/HandlerStack.php +0 -273
  114. lib/Aws/GuzzleHttp/MessageFormatter.php +0 -180
  115. lib/Aws/GuzzleHttp/Middleware.php +0 -255
  116. lib/Aws/GuzzleHttp/Pool.php +0 -123
  117. lib/Aws/GuzzleHttp/PrepareBodyMiddleware.php +0 -106
  118. lib/Aws/GuzzleHttp/Promise/AggregateException.php +0 -16
  119. lib/Aws/GuzzleHttp/Promise/CancellationException.php +0 -9
  120. lib/Aws/GuzzleHttp/Promise/Coroutine.php +0 -151
  121. lib/Aws/GuzzleHttp/Promise/EachPromise.php +0 -229
  122. lib/Aws/GuzzleHttp/Promise/FulfilledPromise.php +0 -82
  123. 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 W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
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 W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
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 W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
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 W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
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 W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
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 W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
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 = trim( $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="http://docs.amazonwebservices.com/AmazonS3/latest/DeveloperGuide/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>
62
  &lt;bucket&gt;.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="http://docs.amazonwebservices.com/AmazonS3/latest/DeveloperGuide/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>
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
-