vendor/aws/aws-sdk-php/src/S3/S3Client.php line 353

Open in your IDE?
  1. <?php
  2. namespace Aws\S3;
  3. use Aws\Api\ApiProvider;
  4. use Aws\Api\DocModel;
  5. use Aws\Api\Service;
  6. use Aws\AwsClient;
  7. use Aws\CacheInterface;
  8. use Aws\ClientResolver;
  9. use Aws\Command;
  10. use Aws\Exception\AwsException;
  11. use Aws\HandlerList;
  12. use Aws\InputValidationMiddleware;
  13. use Aws\Middleware;
  14. use Aws\Retry\QuotaManager;
  15. use Aws\RetryMiddleware;
  16. use Aws\ResultInterface;
  17. use Aws\CommandInterface;
  18. use Aws\RetryMiddlewareV2;
  19. use Aws\S3\UseArnRegion\Configuration;
  20. use Aws\S3\UseArnRegion\ConfigurationInterface;
  21. use Aws\S3\UseArnRegion\ConfigurationProvider as UseArnRegionConfigurationProvider;
  22. use Aws\S3\RegionalEndpoint\ConfigurationProvider;
  23. use GuzzleHttp\Exception\RequestException;
  24. use GuzzleHttp\Promise\Promise;
  25. use GuzzleHttp\Promise\PromiseInterface;
  26. use Psr\Http\Message\RequestInterface;
  27. /**
  28.  * Client used to interact with **Amazon Simple Storage Service (Amazon S3)**.
  29.  *
  30.  * @method \Aws\Result abortMultipartUpload(array $args = [])
  31.  * @method \GuzzleHttp\Promise\Promise abortMultipartUploadAsync(array $args = [])
  32.  * @method \Aws\Result completeMultipartUpload(array $args = [])
  33.  * @method \GuzzleHttp\Promise\Promise completeMultipartUploadAsync(array $args = [])
  34.  * @method \Aws\Result copyObject(array $args = [])
  35.  * @method \GuzzleHttp\Promise\Promise copyObjectAsync(array $args = [])
  36.  * @method \Aws\Result createBucket(array $args = [])
  37.  * @method \GuzzleHttp\Promise\Promise createBucketAsync(array $args = [])
  38.  * @method \Aws\Result createMultipartUpload(array $args = [])
  39.  * @method \GuzzleHttp\Promise\Promise createMultipartUploadAsync(array $args = [])
  40.  * @method \Aws\Result deleteBucket(array $args = [])
  41.  * @method \GuzzleHttp\Promise\Promise deleteBucketAsync(array $args = [])
  42.  * @method \Aws\Result deleteBucketAnalyticsConfiguration(array $args = [])
  43.  * @method \GuzzleHttp\Promise\Promise deleteBucketAnalyticsConfigurationAsync(array $args = [])
  44.  * @method \Aws\Result deleteBucketCors(array $args = [])
  45.  * @method \GuzzleHttp\Promise\Promise deleteBucketCorsAsync(array $args = [])
  46.  * @method \Aws\Result deleteBucketEncryption(array $args = [])
  47.  * @method \GuzzleHttp\Promise\Promise deleteBucketEncryptionAsync(array $args = [])
  48.  * @method \Aws\Result deleteBucketIntelligentTieringConfiguration(array $args = [])
  49.  * @method \GuzzleHttp\Promise\Promise deleteBucketIntelligentTieringConfigurationAsync(array $args = [])
  50.  * @method \Aws\Result deleteBucketInventoryConfiguration(array $args = [])
  51.  * @method \GuzzleHttp\Promise\Promise deleteBucketInventoryConfigurationAsync(array $args = [])
  52.  * @method \Aws\Result deleteBucketLifecycle(array $args = [])
  53.  * @method \GuzzleHttp\Promise\Promise deleteBucketLifecycleAsync(array $args = [])
  54.  * @method \Aws\Result deleteBucketMetricsConfiguration(array $args = [])
  55.  * @method \GuzzleHttp\Promise\Promise deleteBucketMetricsConfigurationAsync(array $args = [])
  56.  * @method \Aws\Result deleteBucketOwnershipControls(array $args = [])
  57.  * @method \GuzzleHttp\Promise\Promise deleteBucketOwnershipControlsAsync(array $args = [])
  58.  * @method \Aws\Result deleteBucketPolicy(array $args = [])
  59.  * @method \GuzzleHttp\Promise\Promise deleteBucketPolicyAsync(array $args = [])
  60.  * @method \Aws\Result deleteBucketReplication(array $args = [])
  61.  * @method \GuzzleHttp\Promise\Promise deleteBucketReplicationAsync(array $args = [])
  62.  * @method \Aws\Result deleteBucketTagging(array $args = [])
  63.  * @method \GuzzleHttp\Promise\Promise deleteBucketTaggingAsync(array $args = [])
  64.  * @method \Aws\Result deleteBucketWebsite(array $args = [])
  65.  * @method \GuzzleHttp\Promise\Promise deleteBucketWebsiteAsync(array $args = [])
  66.  * @method \Aws\Result deleteObject(array $args = [])
  67.  * @method \GuzzleHttp\Promise\Promise deleteObjectAsync(array $args = [])
  68.  * @method \Aws\Result deleteObjectTagging(array $args = [])
  69.  * @method \GuzzleHttp\Promise\Promise deleteObjectTaggingAsync(array $args = [])
  70.  * @method \Aws\Result deleteObjects(array $args = [])
  71.  * @method \GuzzleHttp\Promise\Promise deleteObjectsAsync(array $args = [])
  72.  * @method \Aws\Result deletePublicAccessBlock(array $args = [])
  73.  * @method \GuzzleHttp\Promise\Promise deletePublicAccessBlockAsync(array $args = [])
  74.  * @method \Aws\Result getBucketAccelerateConfiguration(array $args = [])
  75.  * @method \GuzzleHttp\Promise\Promise getBucketAccelerateConfigurationAsync(array $args = [])
  76.  * @method \Aws\Result getBucketAcl(array $args = [])
  77.  * @method \GuzzleHttp\Promise\Promise getBucketAclAsync(array $args = [])
  78.  * @method \Aws\Result getBucketAnalyticsConfiguration(array $args = [])
  79.  * @method \GuzzleHttp\Promise\Promise getBucketAnalyticsConfigurationAsync(array $args = [])
  80.  * @method \Aws\Result getBucketCors(array $args = [])
  81.  * @method \GuzzleHttp\Promise\Promise getBucketCorsAsync(array $args = [])
  82.  * @method \Aws\Result getBucketEncryption(array $args = [])
  83.  * @method \GuzzleHttp\Promise\Promise getBucketEncryptionAsync(array $args = [])
  84.  * @method \Aws\Result getBucketIntelligentTieringConfiguration(array $args = [])
  85.  * @method \GuzzleHttp\Promise\Promise getBucketIntelligentTieringConfigurationAsync(array $args = [])
  86.  * @method \Aws\Result getBucketInventoryConfiguration(array $args = [])
  87.  * @method \GuzzleHttp\Promise\Promise getBucketInventoryConfigurationAsync(array $args = [])
  88.  * @method \Aws\Result getBucketLifecycle(array $args = [])
  89.  * @method \GuzzleHttp\Promise\Promise getBucketLifecycleAsync(array $args = [])
  90.  * @method \Aws\Result getBucketLifecycleConfiguration(array $args = [])
  91.  * @method \GuzzleHttp\Promise\Promise getBucketLifecycleConfigurationAsync(array $args = [])
  92.  * @method \Aws\Result getBucketLocation(array $args = [])
  93.  * @method \GuzzleHttp\Promise\Promise getBucketLocationAsync(array $args = [])
  94.  * @method \Aws\Result getBucketLogging(array $args = [])
  95.  * @method \GuzzleHttp\Promise\Promise getBucketLoggingAsync(array $args = [])
  96.  * @method \Aws\Result getBucketMetricsConfiguration(array $args = [])
  97.  * @method \GuzzleHttp\Promise\Promise getBucketMetricsConfigurationAsync(array $args = [])
  98.  * @method \Aws\Result getBucketNotification(array $args = [])
  99.  * @method \GuzzleHttp\Promise\Promise getBucketNotificationAsync(array $args = [])
  100.  * @method \Aws\Result getBucketNotificationConfiguration(array $args = [])
  101.  * @method \GuzzleHttp\Promise\Promise getBucketNotificationConfigurationAsync(array $args = [])
  102.  * @method \Aws\Result getBucketOwnershipControls(array $args = [])
  103.  * @method \GuzzleHttp\Promise\Promise getBucketOwnershipControlsAsync(array $args = [])
  104.  * @method \Aws\Result getBucketPolicy(array $args = [])
  105.  * @method \GuzzleHttp\Promise\Promise getBucketPolicyAsync(array $args = [])
  106.  * @method \Aws\Result getBucketPolicyStatus(array $args = [])
  107.  * @method \GuzzleHttp\Promise\Promise getBucketPolicyStatusAsync(array $args = [])
  108.  * @method \Aws\Result getBucketReplication(array $args = [])
  109.  * @method \GuzzleHttp\Promise\Promise getBucketReplicationAsync(array $args = [])
  110.  * @method \Aws\Result getBucketRequestPayment(array $args = [])
  111.  * @method \GuzzleHttp\Promise\Promise getBucketRequestPaymentAsync(array $args = [])
  112.  * @method \Aws\Result getBucketTagging(array $args = [])
  113.  * @method \GuzzleHttp\Promise\Promise getBucketTaggingAsync(array $args = [])
  114.  * @method \Aws\Result getBucketVersioning(array $args = [])
  115.  * @method \GuzzleHttp\Promise\Promise getBucketVersioningAsync(array $args = [])
  116.  * @method \Aws\Result getBucketWebsite(array $args = [])
  117.  * @method \GuzzleHttp\Promise\Promise getBucketWebsiteAsync(array $args = [])
  118.  * @method \Aws\Result getObject(array $args = [])
  119.  * @method \GuzzleHttp\Promise\Promise getObjectAsync(array $args = [])
  120.  * @method \Aws\Result getObjectAcl(array $args = [])
  121.  * @method \GuzzleHttp\Promise\Promise getObjectAclAsync(array $args = [])
  122.  * @method \Aws\Result getObjectAttributes(array $args = [])
  123.  * @method \GuzzleHttp\Promise\Promise getObjectAttributesAsync(array $args = [])
  124.  * @method \Aws\Result getObjectLegalHold(array $args = [])
  125.  * @method \GuzzleHttp\Promise\Promise getObjectLegalHoldAsync(array $args = [])
  126.  * @method \Aws\Result getObjectLockConfiguration(array $args = [])
  127.  * @method \GuzzleHttp\Promise\Promise getObjectLockConfigurationAsync(array $args = [])
  128.  * @method \Aws\Result getObjectRetention(array $args = [])
  129.  * @method \GuzzleHttp\Promise\Promise getObjectRetentionAsync(array $args = [])
  130.  * @method \Aws\Result getObjectTagging(array $args = [])
  131.  * @method \GuzzleHttp\Promise\Promise getObjectTaggingAsync(array $args = [])
  132.  * @method \Aws\Result getObjectTorrent(array $args = [])
  133.  * @method \GuzzleHttp\Promise\Promise getObjectTorrentAsync(array $args = [])
  134.  * @method \Aws\Result getPublicAccessBlock(array $args = [])
  135.  * @method \GuzzleHttp\Promise\Promise getPublicAccessBlockAsync(array $args = [])
  136.  * @method \Aws\Result headBucket(array $args = [])
  137.  * @method \GuzzleHttp\Promise\Promise headBucketAsync(array $args = [])
  138.  * @method \Aws\Result headObject(array $args = [])
  139.  * @method \GuzzleHttp\Promise\Promise headObjectAsync(array $args = [])
  140.  * @method \Aws\Result listBucketAnalyticsConfigurations(array $args = [])
  141.  * @method \GuzzleHttp\Promise\Promise listBucketAnalyticsConfigurationsAsync(array $args = [])
  142.  * @method \Aws\Result listBucketIntelligentTieringConfigurations(array $args = [])
  143.  * @method \GuzzleHttp\Promise\Promise listBucketIntelligentTieringConfigurationsAsync(array $args = [])
  144.  * @method \Aws\Result listBucketInventoryConfigurations(array $args = [])
  145.  * @method \GuzzleHttp\Promise\Promise listBucketInventoryConfigurationsAsync(array $args = [])
  146.  * @method \Aws\Result listBucketMetricsConfigurations(array $args = [])
  147.  * @method \GuzzleHttp\Promise\Promise listBucketMetricsConfigurationsAsync(array $args = [])
  148.  * @method \Aws\Result listBuckets(array $args = [])
  149.  * @method \GuzzleHttp\Promise\Promise listBucketsAsync(array $args = [])
  150.  * @method \Aws\Result listMultipartUploads(array $args = [])
  151.  * @method \GuzzleHttp\Promise\Promise listMultipartUploadsAsync(array $args = [])
  152.  * @method \Aws\Result listObjectVersions(array $args = [])
  153.  * @method \GuzzleHttp\Promise\Promise listObjectVersionsAsync(array $args = [])
  154.  * @method \Aws\Result listObjects(array $args = [])
  155.  * @method \GuzzleHttp\Promise\Promise listObjectsAsync(array $args = [])
  156.  * @method \Aws\Result listObjectsV2(array $args = [])
  157.  * @method \GuzzleHttp\Promise\Promise listObjectsV2Async(array $args = [])
  158.  * @method \Aws\Result listParts(array $args = [])
  159.  * @method \GuzzleHttp\Promise\Promise listPartsAsync(array $args = [])
  160.  * @method \Aws\Result putBucketAccelerateConfiguration(array $args = [])
  161.  * @method \GuzzleHttp\Promise\Promise putBucketAccelerateConfigurationAsync(array $args = [])
  162.  * @method \Aws\Result putBucketAcl(array $args = [])
  163.  * @method \GuzzleHttp\Promise\Promise putBucketAclAsync(array $args = [])
  164.  * @method \Aws\Result putBucketAnalyticsConfiguration(array $args = [])
  165.  * @method \GuzzleHttp\Promise\Promise putBucketAnalyticsConfigurationAsync(array $args = [])
  166.  * @method \Aws\Result putBucketCors(array $args = [])
  167.  * @method \GuzzleHttp\Promise\Promise putBucketCorsAsync(array $args = [])
  168.  * @method \Aws\Result putBucketEncryption(array $args = [])
  169.  * @method \GuzzleHttp\Promise\Promise putBucketEncryptionAsync(array $args = [])
  170.  * @method \Aws\Result putBucketIntelligentTieringConfiguration(array $args = [])
  171.  * @method \GuzzleHttp\Promise\Promise putBucketIntelligentTieringConfigurationAsync(array $args = [])
  172.  * @method \Aws\Result putBucketInventoryConfiguration(array $args = [])
  173.  * @method \GuzzleHttp\Promise\Promise putBucketInventoryConfigurationAsync(array $args = [])
  174.  * @method \Aws\Result putBucketLifecycle(array $args = [])
  175.  * @method \GuzzleHttp\Promise\Promise putBucketLifecycleAsync(array $args = [])
  176.  * @method \Aws\Result putBucketLifecycleConfiguration(array $args = [])
  177.  * @method \GuzzleHttp\Promise\Promise putBucketLifecycleConfigurationAsync(array $args = [])
  178.  * @method \Aws\Result putBucketLogging(array $args = [])
  179.  * @method \GuzzleHttp\Promise\Promise putBucketLoggingAsync(array $args = [])
  180.  * @method \Aws\Result putBucketMetricsConfiguration(array $args = [])
  181.  * @method \GuzzleHttp\Promise\Promise putBucketMetricsConfigurationAsync(array $args = [])
  182.  * @method \Aws\Result putBucketNotification(array $args = [])
  183.  * @method \GuzzleHttp\Promise\Promise putBucketNotificationAsync(array $args = [])
  184.  * @method \Aws\Result putBucketNotificationConfiguration(array $args = [])
  185.  * @method \GuzzleHttp\Promise\Promise putBucketNotificationConfigurationAsync(array $args = [])
  186.  * @method \Aws\Result putBucketOwnershipControls(array $args = [])
  187.  * @method \GuzzleHttp\Promise\Promise putBucketOwnershipControlsAsync(array $args = [])
  188.  * @method \Aws\Result putBucketPolicy(array $args = [])
  189.  * @method \GuzzleHttp\Promise\Promise putBucketPolicyAsync(array $args = [])
  190.  * @method \Aws\Result putBucketReplication(array $args = [])
  191.  * @method \GuzzleHttp\Promise\Promise putBucketReplicationAsync(array $args = [])
  192.  * @method \Aws\Result putBucketRequestPayment(array $args = [])
  193.  * @method \GuzzleHttp\Promise\Promise putBucketRequestPaymentAsync(array $args = [])
  194.  * @method \Aws\Result putBucketTagging(array $args = [])
  195.  * @method \GuzzleHttp\Promise\Promise putBucketTaggingAsync(array $args = [])
  196.  * @method \Aws\Result putBucketVersioning(array $args = [])
  197.  * @method \GuzzleHttp\Promise\Promise putBucketVersioningAsync(array $args = [])
  198.  * @method \Aws\Result putBucketWebsite(array $args = [])
  199.  * @method \GuzzleHttp\Promise\Promise putBucketWebsiteAsync(array $args = [])
  200.  * @method \Aws\Result putObject(array $args = [])
  201.  * @method \GuzzleHttp\Promise\Promise putObjectAsync(array $args = [])
  202.  * @method \Aws\Result putObjectAcl(array $args = [])
  203.  * @method \GuzzleHttp\Promise\Promise putObjectAclAsync(array $args = [])
  204.  * @method \Aws\Result putObjectLegalHold(array $args = [])
  205.  * @method \GuzzleHttp\Promise\Promise putObjectLegalHoldAsync(array $args = [])
  206.  * @method \Aws\Result putObjectLockConfiguration(array $args = [])
  207.  * @method \GuzzleHttp\Promise\Promise putObjectLockConfigurationAsync(array $args = [])
  208.  * @method \Aws\Result putObjectRetention(array $args = [])
  209.  * @method \GuzzleHttp\Promise\Promise putObjectRetentionAsync(array $args = [])
  210.  * @method \Aws\Result putObjectTagging(array $args = [])
  211.  * @method \GuzzleHttp\Promise\Promise putObjectTaggingAsync(array $args = [])
  212.  * @method \Aws\Result putPublicAccessBlock(array $args = [])
  213.  * @method \GuzzleHttp\Promise\Promise putPublicAccessBlockAsync(array $args = [])
  214.  * @method \Aws\Result restoreObject(array $args = [])
  215.  * @method \GuzzleHttp\Promise\Promise restoreObjectAsync(array $args = [])
  216.  * @method \Aws\Result selectObjectContent(array $args = [])
  217.  * @method \GuzzleHttp\Promise\Promise selectObjectContentAsync(array $args = [])
  218.  * @method \Aws\Result uploadPart(array $args = [])
  219.  * @method \GuzzleHttp\Promise\Promise uploadPartAsync(array $args = [])
  220.  * @method \Aws\Result uploadPartCopy(array $args = [])
  221.  * @method \GuzzleHttp\Promise\Promise uploadPartCopyAsync(array $args = [])
  222.  * @method \Aws\Result writeGetObjectResponse(array $args = [])
  223.  * @method \GuzzleHttp\Promise\Promise writeGetObjectResponseAsync(array $args = [])
  224.  */
  225. class S3Client extends AwsClient implements S3ClientInterface
  226. {
  227.     use S3ClientTrait;
  228.     /** @var array */
  229.     private static $mandatoryAttributes = ['Bucket''Key'];
  230.     public static function getArguments()
  231.     {
  232.         $args parent::getArguments();
  233.         $args['retries']['fn'] = [__CLASS__'_applyRetryConfig'];
  234.         $args['api_provider']['fn'] = [__CLASS__'_applyApiProvider'];
  235.         return $args + [
  236.             'bucket_endpoint' => [
  237.                 'type'    => 'config',
  238.                 'valid'   => ['bool'],
  239.                 'doc'     => 'Set to true to send requests to a hardcoded '
  240.                     'bucket endpoint rather than create an endpoint as a '
  241.                     'result of injecting the bucket into the URL. This '
  242.                     'option is useful for interacting with CNAME endpoints.',
  243.             ],
  244.             'use_arn_region' => [
  245.                 'type'    => 'config',
  246.                 'valid'   => [
  247.                     'bool',
  248.                     Configuration::class,
  249.                     CacheInterface::class,
  250.                     'callable'
  251.                 ],
  252.                 'doc'     => 'Set to true to allow passed in ARNs to override'
  253.                     ' client region. Accepts...',
  254.                 'fn' => [__CLASS__'_apply_use_arn_region'],
  255.                 'default' => [UseArnRegionConfigurationProvider::class, 'defaultProvider'],
  256.             ],
  257.             'use_accelerate_endpoint' => [
  258.                 'type' => 'config',
  259.                 'valid' => ['bool'],
  260.                 'doc' => 'Set to true to send requests to an S3 Accelerate'
  261.                     ' endpoint by default. Can be enabled or disabled on'
  262.                     ' individual operations by setting'
  263.                     ' \'@use_accelerate_endpoint\' to true or false. Note:'
  264.                     ' you must enable S3 Accelerate on a bucket before it can'
  265.                     ' be accessed via an Accelerate endpoint.',
  266.                 'default' => false,
  267.             ],
  268.             'use_path_style_endpoint' => [
  269.                 'type' => 'config',
  270.                 'valid' => ['bool'],
  271.                 'doc' => 'Set to true to send requests to an S3 path style'
  272.                     ' endpoint by default.'
  273.                     ' Can be enabled or disabled on individual operations by setting'
  274.                     ' \'@use_path_style_endpoint\' to true or false.',
  275.                 'default' => false,
  276.             ],
  277.             'disable_multiregion_access_points' => [
  278.                 'type' => 'config',
  279.                 'valid' => ['bool'],
  280.                 'doc' => 'Set to true to disable the usage of'
  281.                     ' multi region access points. These are enabled by default.'
  282.                     ' Can be enabled or disabled on individual operations by setting'
  283.                     ' \'@disable_multiregion_access_points\' to true or false.',
  284.                 'default' => false,
  285.             ],
  286.         ];
  287.     }
  288.     /**
  289.      * {@inheritdoc}
  290.      *
  291.      * In addition to the options available to
  292.      * {@see Aws\AwsClient::__construct}, S3Client accepts the following
  293.      * options:
  294.      *
  295.      * - bucket_endpoint: (bool) Set to true to send requests to a
  296.      *   hardcoded bucket endpoint rather than create an endpoint as a result
  297.      *   of injecting the bucket into the URL. This option is useful for
  298.      *   interacting with CNAME endpoints.
  299.      * - calculate_md5: (bool) Set to false to disable calculating an MD5
  300.      *   for all Amazon S3 signed uploads.
  301.      * - s3_us_east_1_regional_endpoint:
  302.      *   (Aws\S3\RegionalEndpoint\ConfigurationInterface|Aws\CacheInterface\|callable|string|array)
  303.      *   Specifies whether to use regional or legacy endpoints for the us-east-1
  304.      *   region. Provide an Aws\S3\RegionalEndpoint\ConfigurationInterface object, an
  305.      *   instance of Aws\CacheInterface, a callable configuration provider used
  306.      *   to create endpoint configuration, a string value of `legacy` or
  307.      *   `regional`, or an associative array with the following keys:
  308.      *   endpoint_types: (string)  Set to `legacy` or `regional`, defaults to
  309.      *   `legacy`
  310.      * - use_accelerate_endpoint: (bool) Set to true to send requests to an S3
  311.      *   Accelerate endpoint by default. Can be enabled or disabled on
  312.      *   individual operations by setting '@use_accelerate_endpoint' to true or
  313.      *   false. Note: you must enable S3 Accelerate on a bucket before it can be
  314.      *   accessed via an Accelerate endpoint.
  315.      * - use_arn_region: (Aws\S3\UseArnRegion\ConfigurationInterface,
  316.      *   Aws\CacheInterface, bool, callable) Set to true to enable the client
  317.      *   to use the region from a supplied ARN argument instead of the client's
  318.      *   region. Provide an instance of Aws\S3\UseArnRegion\ConfigurationInterface,
  319.      *   an instance of Aws\CacheInterface, a callable that provides a promise for
  320.      *   a Configuration object, or a boolean value. Defaults to false (i.e.
  321.      *   the SDK will not follow the ARN region if it conflicts with the client
  322.      *   region and instead throw an error).
  323.      * - use_dual_stack_endpoint: (bool) Set to true to send requests to an S3
  324.      *   Dual Stack endpoint by default, which enables IPv6 Protocol.
  325.      *   Can be enabled or disabled on individual operations by setting
  326.      *   '@use_dual_stack_endpoint\' to true or false. Note:
  327.      *   you cannot use it together with an accelerate endpoint.
  328.      * - use_path_style_endpoint: (bool) Set to true to send requests to an S3
  329.      *   path style endpoint by default.
  330.      *   Can be enabled or disabled on individual operations by setting
  331.      *   '@use_path_style_endpoint\' to true or false. Note:
  332.      *   you cannot use it together with an accelerate endpoint.
  333.      * - disable_multiregion_access_points: (bool) Set to true to disable
  334.      *   sending multi region requests.  They are enabled by default.
  335.      *   Can be enabled or disabled on individual operations by setting
  336.      *   '@disable_multiregion_access_points\' to true or false. Note:
  337.      *   you cannot use it together with an accelerate or dualstack endpoint.
  338.      *
  339.      * @param array $args
  340.      */
  341.     public function __construct(array $args)
  342.     {
  343.         if (
  344.             !isset($args['s3_us_east_1_regional_endpoint'])
  345.             || $args['s3_us_east_1_regional_endpoint'] instanceof CacheInterface
  346.         ) {
  347.             $args['s3_us_east_1_regional_endpoint'] = ConfigurationProvider::defaultProvider($args);
  348.         }
  349.         parent::__construct($args);
  350.         $stack $this->getHandlerList();
  351.         $stack->appendInit(SSECMiddleware::wrap($this->getEndpoint()->getScheme()), 's3.ssec');
  352.         $stack->appendBuild(ApplyChecksumMiddleware::wrap($this->getApi()), 's3.checksum');
  353.         $stack->appendBuild(
  354.             Middleware::contentType(['PutObject''UploadPart']),
  355.             's3.content_type'
  356.         );
  357.         // Use the bucket style middleware when using a "bucket_endpoint" (for cnames)
  358.         if ($this->getConfig('bucket_endpoint')) {
  359.             $stack->appendBuild(BucketEndpointMiddleware::wrap(), 's3.bucket_endpoint');
  360.         } else {
  361.             $stack->appendBuild(
  362.                 S3EndpointMiddleware::wrap(
  363.                     $this->getRegion(),
  364.                     $this->getConfig('endpoint_provider'),
  365.                     [
  366.                         'accelerate' => $this->getConfig('use_accelerate_endpoint'),
  367.                         'path_style' => $this->getConfig('use_path_style_endpoint'),
  368.                         'use_fips_endpoint' => $this->getConfig('use_fips_endpoint'),
  369.                         'dual_stack' =>
  370.                             $this->getConfig('use_dual_stack_endpoint')->isUseDualStackEndpoint(),
  371.                     ]
  372.                 ),
  373.                 's3.endpoint_middleware'
  374.             );
  375.         }
  376.         $stack->appendBuild(
  377.             BucketEndpointArnMiddleware::wrap(
  378.                 $this->getApi(),
  379.                 $this->getRegion(),
  380.                 [
  381.                     'use_arn_region' => $this->getConfig('use_arn_region'),
  382.                     'accelerate' => $this->getConfig('use_accelerate_endpoint'),
  383.                     'path_style' => $this->getConfig('use_path_style_endpoint'),
  384.                     'dual_stack' =>
  385.                         $this->getConfig('use_dual_stack_endpoint')->isUseDualStackEndpoint(),
  386.                     'use_fips_endpoint' => $this->getConfig('use_fips_endpoint'),
  387.                     'disable_multiregion_access_points' =>
  388.                         $this->getConfig('disable_multiregion_access_points'),
  389.                     'endpoint' => isset($args['endpoint'])
  390.                         ? $args['endpoint']
  391.                         : null
  392.                 ]
  393.             ),
  394.             's3.bucket_endpoint_arn'
  395.         );
  396.         $stack->appendValidate(
  397.             InputValidationMiddleware::wrap($this->getApi(), self::$mandatoryAttributes),
  398.             'input_validation_middleware'
  399.         );
  400.         $stack->appendSign(PutObjectUrlMiddleware::wrap(), 's3.put_object_url');
  401.         $stack->appendSign(PermanentRedirectMiddleware::wrap(), 's3.permanent_redirect');
  402.         $stack->appendInit(Middleware::sourceFile($this->getApi()), 's3.source_file');
  403.         $stack->appendInit($this->getSaveAsParameter(), 's3.save_as');
  404.         $stack->appendInit($this->getLocationConstraintMiddleware(), 's3.location');
  405.         $stack->appendInit($this->getEncodingTypeMiddleware(), 's3.auto_encode');
  406.         $stack->appendInit($this->getHeadObjectMiddleware(), 's3.head_object');
  407.     }
  408.     /**
  409.      * Determine if a string is a valid name for a DNS compatible Amazon S3
  410.      * bucket.
  411.      *
  412.      * DNS compatible bucket names can be used as a subdomain in a URL (e.g.,
  413.      * "<bucket>.s3.amazonaws.com").
  414.      *
  415.      * @param string $bucket Bucket name to check.
  416.      *
  417.      * @return bool
  418.      */
  419.     public static function isBucketDnsCompatible($bucket)
  420.     {
  421.         $bucketLen strlen($bucket);
  422.         return ($bucketLen >= && $bucketLen <= 63) &&
  423.             // Cannot look like an IP address
  424.             !filter_var($bucketFILTER_VALIDATE_IP) &&
  425.             preg_match('/^[a-z0-9]([a-z0-9\-\.]*[a-z0-9])?$/'$bucket);
  426.     }
  427.     public static function _apply_use_arn_region($value, array &$argsHandlerList $list)
  428.     {
  429.         if ($value instanceof CacheInterface) {
  430.             $value UseArnRegionConfigurationProvider::defaultProvider($args);
  431.         }
  432.         if (is_callable($value)) {
  433.             $value $value();
  434.         }
  435.         if ($value instanceof PromiseInterface) {
  436.             $value $value->wait();
  437.         }
  438.         if ($value instanceof ConfigurationInterface) {
  439.             $args['use_arn_region'] = $value;
  440.         } else {
  441.             // The Configuration class itself will validate other inputs
  442.             $args['use_arn_region'] = new Configuration($value);
  443.         }
  444.     }
  445.     public function createPresignedRequest(CommandInterface $command$expires, array $options = [])
  446.     {
  447.         $command = clone $command;
  448.         $command->getHandlerList()->remove('signer');
  449.         /** @var \Aws\Signature\SignatureInterface $signer */
  450.         $signer call_user_func(
  451.             $this->getSignatureProvider(),
  452.             $this->getConfig('signature_version'),
  453.             $this->getConfig('signing_name'),
  454.             $this->getConfig('signing_region')
  455.         );
  456.         return $signer->presign(
  457.             \Aws\serialize($command),
  458.             $this->getCredentials()->wait(),
  459.             $expires,
  460.             $options
  461.         );
  462.     }
  463.     /**
  464.      * Returns the URL to an object identified by its bucket and key.
  465.      *
  466.      * The URL returned by this method is not signed nor does it ensure that the
  467.      * bucket and key given to the method exist. If you need a signed URL, then
  468.      * use the {@see \Aws\S3\S3Client::createPresignedRequest} method and get
  469.      * the URI of the signed request.
  470.      *
  471.      * @param string $bucket  The name of the bucket where the object is located
  472.      * @param string $key     The key of the object
  473.      *
  474.      * @return string The URL to the object
  475.      */
  476.     public function getObjectUrl($bucket$key)
  477.     {
  478.         $command $this->getCommand('GetObject', [
  479.             'Bucket' => $bucket,
  480.             'Key'    => $key
  481.         ]);
  482.         return (string) \Aws\serialize($command)->getUri();
  483.     }
  484.     /**
  485.      * Raw URL encode a key and allow for '/' characters
  486.      *
  487.      * @param string $key Key to encode
  488.      *
  489.      * @return string Returns the encoded key
  490.      */
  491.     public static function encodeKey($key)
  492.     {
  493.         return str_replace('%2F''/'rawurlencode($key));
  494.     }
  495.     /**
  496.      * Provides a middleware that removes the need to specify LocationConstraint on CreateBucket.
  497.      *
  498.      * @return \Closure
  499.      */
  500.     private function getLocationConstraintMiddleware()
  501.     {
  502.         $region $this->getRegion();
  503.         return static function (callable $handler) use ($region) {
  504.             return function (Command $command$request null) use ($handler$region) {
  505.                 if ($command->getName() === 'CreateBucket') {
  506.                     $locationConstraint = isset($command['CreateBucketConfiguration']['LocationConstraint'])
  507.                         ? $command['CreateBucketConfiguration']['LocationConstraint']
  508.                         : null;
  509.                     if ($locationConstraint === 'us-east-1') {
  510.                         unset($command['CreateBucketConfiguration']);
  511.                     } elseif ('us-east-1' !== $region && empty($locationConstraint)) {
  512.                         $command['CreateBucketConfiguration'] = ['LocationConstraint' => $region];
  513.                     }
  514.                 }
  515.                 return $handler($command$request);
  516.             };
  517.         };
  518.     }
  519.     /**
  520.      * Provides a middleware that supports the `SaveAs` parameter.
  521.      *
  522.      * @return \Closure
  523.      */
  524.     private function getSaveAsParameter()
  525.     {
  526.         return static function (callable $handler) {
  527.             return function (Command $command$request null) use ($handler) {
  528.                 if ($command->getName() === 'GetObject' && isset($command['SaveAs'])) {
  529.                     $command['@http']['sink'] = $command['SaveAs'];
  530.                     unset($command['SaveAs']);
  531.                 }
  532.                 return $handler($command$request);
  533.             };
  534.         };
  535.     }
  536.     /**
  537.      * Provides a middleware that disables content decoding on HeadObject
  538.      * commands.
  539.      *
  540.      * @return \Closure
  541.      */
  542.     private function getHeadObjectMiddleware()
  543.     {
  544.         return static function (callable $handler) {
  545.             return function (
  546.                 CommandInterface $command,
  547.                 RequestInterface $request null
  548.             ) use ($handler) {
  549.                 if ($command->getName() === 'HeadObject'
  550.                     && !isset($command['@http']['decode_content'])
  551.                 ) {
  552.                     $command['@http']['decode_content'] = false;
  553.                 }
  554.                 return $handler($command$request);
  555.             };
  556.         };
  557.     }
  558.     /**
  559.      * Provides a middleware that autopopulates the EncodingType parameter on
  560.      * ListObjects commands.
  561.      *
  562.      * @return \Closure
  563.      */
  564.     private function getEncodingTypeMiddleware()
  565.     {
  566.         return static function (callable $handler) {
  567.             return function (Command $command$request null) use ($handler) {
  568.                 $autoSet false;
  569.                 if ($command->getName() === 'ListObjects'
  570.                     && empty($command['EncodingType'])
  571.                 ) {
  572.                     $command['EncodingType'] = 'url';
  573.                     $autoSet true;
  574.                 }
  575.                 return $handler($command$request)
  576.                     ->then(function (ResultInterface $result) use ($autoSet) {
  577.                         if ($result['EncodingType'] === 'url' && $autoSet) {
  578.                             static $topLevel = [
  579.                                 'Delimiter',
  580.                                 'Marker',
  581.                                 'NextMarker',
  582.                                 'Prefix',
  583.                             ];
  584.                             static $nested = [
  585.                                 ['Contents''Key'],
  586.                                 ['CommonPrefixes''Prefix'],
  587.                             ];
  588.                             foreach ($topLevel as $key) {
  589.                                 if (isset($result[$key])) {
  590.                                     $result[$key] = urldecode($result[$key]);
  591.                                 }
  592.                             }
  593.                             foreach ($nested as $steps) {
  594.                                 if (isset($result[$steps[0]])) {
  595.                                     foreach ($result[$steps[0]] as $key => $part) {
  596.                                         if (isset($part[$steps[1]])) {
  597.                                             $result[$steps[0]][$key][$steps[1]]
  598.                                                 = urldecode($part[$steps[1]]);
  599.                                         }
  600.                                     }
  601.                                 }
  602.                             }
  603.                         }
  604.                         return $result;
  605.                     });
  606.             };
  607.         };
  608.     }
  609.     /** @internal */
  610.     public static function _applyRetryConfig($value$argsHandlerList $list)
  611.     {
  612.         if ($value) {
  613.             $config = \Aws\Retry\ConfigurationProvider::unwrap($value);
  614.             if ($config->getMode() === 'legacy') {
  615.                 $maxRetries $config->getMaxAttempts() - 1;
  616.                 $decider RetryMiddleware::createDefaultDecider($maxRetries);
  617.                 $decider = function ($retries$command$request$result$error) use ($decider$maxRetries) {
  618.                     $maxRetries null !== $command['@retries']
  619.                         ? $command['@retries']
  620.                         : $maxRetries;
  621.                     if ($decider($retries$command$request$result$error)) {
  622.                         return true;
  623.                     }
  624.                     if ($error instanceof AwsException
  625.                         && $retries $maxRetries
  626.                     ) {
  627.                         if ($error->getResponse()
  628.                             && $error->getResponse()->getStatusCode() >= 400
  629.                         ) {
  630.                             return strpos(
  631.                                     $error->getResponse()->getBody(),
  632.                                     'Your socket connection to the server'
  633.                                 ) !== false;
  634.                         }
  635.                         if ($error->getPrevious() instanceof RequestException) {
  636.                             // All commands except CompleteMultipartUpload are
  637.                             // idempotent and may be retried without worry if a
  638.                             // networking error has occurred.
  639.                             return $command->getName() !== 'CompleteMultipartUpload';
  640.                         }
  641.                     }
  642.                     return false;
  643.                 };
  644.                 $delay = [RetryMiddleware::class, 'exponentialDelay'];
  645.                 $list->appendSign(Middleware::retry($decider$delay), 'retry');
  646.             } else {
  647.                 $defaultDecider RetryMiddlewareV2::createDefaultDecider(
  648.                     new QuotaManager(),
  649.                     $config->getMaxAttempts()
  650.                 );
  651.                 $list->appendSign(
  652.                     RetryMiddlewareV2::wrap(
  653.                         $config,
  654.                         [
  655.                             'collect_stats' => $args['stats']['retries'],
  656.                             'decider' => function(
  657.                                 $attempts,
  658.                                 CommandInterface $cmd,
  659.                                 $result
  660.                             ) use ($defaultDecider$config) {
  661.                                 $isRetryable $defaultDecider($attempts$cmd$result);
  662.                                 if (!$isRetryable
  663.                                     && $result instanceof AwsException
  664.                                     && $attempts $config->getMaxAttempts()
  665.                                 ) {
  666.                                     if (!empty($result->getResponse())
  667.                                         && strpos(
  668.                                             $result->getResponse()->getBody(),
  669.                                             'Your socket connection to the server'
  670.                                         ) !== false
  671.                                     ) {
  672.                                         $isRetryable false;
  673.                                     }
  674.                                     if ($result->getPrevious() instanceof RequestException
  675.                                         && $cmd->getName() !== 'CompleteMultipartUpload'
  676.                                     ) {
  677.                                         $isRetryable true;
  678.                                     }
  679.                                 }
  680.                                 return $isRetryable;
  681.                             }
  682.                         ]
  683.                     ),
  684.                     'retry'
  685.                 );
  686.             }
  687.         }
  688.     }
  689.     /** @internal */
  690.     public static function _applyApiProvider($value, array &$argsHandlerList $list)
  691.     {
  692.         ClientResolver::_apply_api_provider($value$args);
  693.         $args['parser'] = new GetBucketLocationParser(
  694.             new ValidateResponseChecksumParser(
  695.                 new AmbiguousSuccessParser(
  696.                     new RetryableMalformedResponseParser(
  697.                         $args['parser'],
  698.                         $args['exception_class']
  699.                     ),
  700.                     $args['error_parser'],
  701.                     $args['exception_class']
  702.                 ),
  703.                 $args['api']
  704.             )
  705.         );
  706.     }
  707.     /**
  708.      * @internal
  709.      * @codeCoverageIgnore
  710.      */
  711.     public static function applyDocFilters(array $api, array $docs)
  712.     {
  713.         $b64 '<div class="alert alert-info">This value will be base64 encoded on your behalf.</div>';
  714.         $opt '<div class="alert alert-info">This value will be computed for you it is not supplied.</div>';
  715.         // Add a note on the CopyObject docs
  716.          $s3ExceptionRetryMessage "<p>Additional info on response behavior: if there is"
  717.             " an internal error in S3 after the request was successfully recieved,"
  718.             " a 200 response will be returned with an <code>S3Exception</code> embedded"
  719.             " in it; this will still be caught and retried by"
  720.             " <code>RetryMiddleware.</code></p>";
  721.         $docs['operations']['CopyObject'] .=  $s3ExceptionRetryMessage;
  722.         $docs['operations']['CompleteMultipartUpload'] .=  $s3ExceptionRetryMessage;
  723.         $docs['operations']['UploadPartCopy'] .=  $s3ExceptionRetryMessage;
  724.         $docs['operations']['UploadPart'] .=  $s3ExceptionRetryMessage;
  725.         // Add note about stream ownership in the putObject call
  726.         $guzzleStreamMessage "<p>Additional info on behavior of the stream"
  727.             " parameters: Psr7 takes ownership of streams and will automatically close"
  728.             " streams when this method is called with a stream as the <code>Body</code>"
  729.             " parameter.  To prevent this, set the <code>Body</code> using"
  730.             " <code>GuzzleHttp\Psr7\stream_for</code> method with a is an instance of"
  731.             " <code>Psr\Http\Message\StreamInterface</code>, and it will be returned"
  732.             " unmodified. This will allow you to keep the stream in scope. </p>";
  733.         $docs['operations']['PutObject'] .=  $guzzleStreamMessage;
  734.         // Add the SourceFile parameter.
  735.         $docs['shapes']['SourceFile']['base'] = 'The path to a file on disk to use instead of the Body parameter.';
  736.         $api['shapes']['SourceFile'] = ['type' => 'string'];
  737.         $api['shapes']['PutObjectRequest']['members']['SourceFile'] = ['shape' => 'SourceFile'];
  738.         $api['shapes']['UploadPartRequest']['members']['SourceFile'] = ['shape' => 'SourceFile'];
  739.         // Add the ContentSHA256 parameter.
  740.         $docs['shapes']['ContentSHA256']['base'] = 'A SHA256 hash of the body content of the request.';
  741.         $api['shapes']['ContentSHA256'] = ['type' => 'string'];
  742.         $api['shapes']['PutObjectRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256'];
  743.         $api['shapes']['UploadPartRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256'];
  744.         unset($api['shapes']['PutObjectRequest']['members']['ContentMD5']);
  745.         unset($api['shapes']['UploadPartRequest']['members']['ContentMD5']);
  746.         $docs['shapes']['ContentSHA256']['append'] = $opt;
  747.         // Add the SaveAs parameter.
  748.         $docs['shapes']['SaveAs']['base'] = 'The path to a file on disk to save the object data.';
  749.         $api['shapes']['SaveAs'] = ['type' => 'string'];
  750.         $api['shapes']['GetObjectRequest']['members']['SaveAs'] = ['shape' => 'SaveAs'];
  751.         // Several SSECustomerKey documentation updates.
  752.         $docs['shapes']['SSECustomerKey']['append'] = $b64;
  753.         $docs['shapes']['CopySourceSSECustomerKey']['append'] = $b64;
  754.         $docs['shapes']['SSECustomerKeyMd5']['append'] = $opt;
  755.         // Add the ObjectURL to various output shapes and documentation.
  756.         $docs['shapes']['ObjectURL']['base'] = 'The URI of the created object.';
  757.         $api['shapes']['ObjectURL'] = ['type' => 'string'];
  758.         $api['shapes']['PutObjectOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
  759.         $api['shapes']['CopyObjectOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
  760.         $api['shapes']['CompleteMultipartUploadOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
  761.         // Fix references to Location Constraint.
  762.         unset($api['shapes']['CreateBucketRequest']['payload']);
  763.         $api['shapes']['BucketLocationConstraint']['enum'] = [
  764.             "ap-northeast-1",
  765.             "ap-southeast-2",
  766.             "ap-southeast-1",
  767.             "cn-north-1",
  768.             "eu-central-1",
  769.             "eu-west-1",
  770.             "us-east-1",
  771.             "us-west-1",
  772.             "us-west-2",
  773.             "sa-east-1",
  774.         ];
  775.         // Add a note that the ContentMD5 is optional.
  776.         $docs['shapes']['ContentMD5']['append'] = '<div class="alert alert-info">The value will be computed on '
  777.             'your behalf.</div>';
  778.         return [
  779.             new Service($apiApiProvider::defaultProvider()),
  780.             new DocModel($docs)
  781.         ];
  782.     }
  783.     /**
  784.      * @internal
  785.      * @codeCoverageIgnore
  786.      */
  787.     public static function addDocExamples($examples)
  788.     {
  789.         $getObjectExample = [
  790.             'input' => [
  791.                 'Bucket' => 'arn:aws:s3:us-east-1:123456789012:accesspoint:myaccesspoint',
  792.                 'Key' => 'my-key'
  793.             ],
  794.             'output' => [
  795.                 'Body' => 'class GuzzleHttp\Psr7\Stream#208 (7) {...}',
  796.                 'ContentLength' => '11',
  797.                 'ContentType' => 'application/octet-stream',
  798.             ],
  799.             'comments' => [
  800.                 'input' => '',
  801.                 'output' => 'Simplified example output'
  802.             ],
  803.             'description' => 'The following example retrieves an object by referencing the bucket via an S3 accesss point ARN. Result output is simplified for the example.',
  804.             'id' => '',
  805.             'title' => 'To get an object via an S3 access point ARN'
  806.         ];
  807.         if (isset($examples['GetObject'])) {
  808.             $examples['GetObject'] []= $getObjectExample;
  809.         } else {
  810.             $examples['GetObject'] = [$getObjectExample];
  811.         }
  812.         $putObjectExample = [
  813.             'input' => [
  814.                 'Bucket' => 'arn:aws:s3:us-east-1:123456789012:accesspoint:myaccesspoint',
  815.                 'Key' => 'my-key',
  816.                 'Body' => 'my-body',
  817.             ],
  818.             'output' => [
  819.                 'ObjectURL' => 'https://my-bucket.s3.us-east-1.amazonaws.com/my-key'
  820.             ],
  821.             'comments' => [
  822.                 'input' => '',
  823.                 'output' => 'Simplified example output'
  824.             ],
  825.             'description' => 'The following example uploads an object by referencing the bucket via an S3 accesss point ARN. Result output is simplified for the example.',
  826.             'id' => '',
  827.             'title' => 'To upload an object via an S3 access point ARN'
  828.         ];
  829.         if (isset($examples['PutObject'])) {
  830.             $examples['PutObject'] []= $putObjectExample;
  831.         } else {
  832.             $examples['PutObject'] = [$putObjectExample];
  833.         }
  834.         return $examples;
  835.     }
  836. }