diff options
Diffstat (limited to 'apps/files_external/3rdparty/aws-sdk-php/Aws/S3/S3Client.php')
-rw-r--r-- | apps/files_external/3rdparty/aws-sdk-php/Aws/S3/S3Client.php | 192 |
1 files changed, 90 insertions, 102 deletions
diff --git a/apps/files_external/3rdparty/aws-sdk-php/Aws/S3/S3Client.php b/apps/files_external/3rdparty/aws-sdk-php/Aws/S3/S3Client.php index 88c61b83dde..219e37eb92d 100644 --- a/apps/files_external/3rdparty/aws-sdk-php/Aws/S3/S3Client.php +++ b/apps/files_external/3rdparty/aws-sdk-php/Aws/S3/S3Client.php @@ -23,6 +23,8 @@ use Aws\Common\Client\UploadBodyListener; use Aws\Common\Enum\ClientOptions as Options; use Aws\Common\Exception\RuntimeException; use Aws\Common\Exception\InvalidArgumentException; +use Aws\Common\Signature\SignatureV4; +use Aws\Common\Signature\SignatureInterface; use Aws\Common\Model\MultipartUpload\AbstractTransfer; use Aws\S3\Exception\AccessDeniedException; use Aws\S3\Exception\Parser\S3ExceptionParser; @@ -30,10 +32,8 @@ use Aws\S3\Exception\S3Exception; use Aws\S3\Model\ClearBucket; use Aws\S3\Model\MultipartUpload\AbstractTransfer as AbstractMulti; use Aws\S3\Model\MultipartUpload\UploadBuilder; -use Aws\S3\S3Signature; use Aws\S3\Sync\DownloadSyncBuilder; use Aws\S3\Sync\UploadSyncBuilder; -use Aws\S3\Sync\AbstractSync; use Guzzle\Common\Collection; use Guzzle\Http\EntityBody; use Guzzle\Http\Message\RequestInterface; @@ -43,7 +43,6 @@ use Guzzle\Plugin\Backoff\CurlBackoffStrategy; use Guzzle\Plugin\Backoff\ExponentialBackoffStrategy; use Guzzle\Plugin\Backoff\HttpBackoffStrategy; use Guzzle\Plugin\Backoff\TruncatedBackoffStrategy; -use Guzzle\Plugin\Md5\CommandContentMd5Plugin; use Guzzle\Service\Command\CommandInterface; use Guzzle\Service\Command\Factory\AliasFactory; use Guzzle\Service\Command\Factory\CompositeFactory; @@ -53,6 +52,7 @@ use Guzzle\Service\Resource\ResourceIteratorInterface; /** * Client to interact with Amazon Simple Storage Service * + * @method S3SignatureInterface getSignature() Returns the signature implementation used with the client * @method Model abortMultipartUpload(array $args = array()) {@command S3 AbortMultipartUpload} * @method Model completeMultipartUpload(array $args = array()) {@command S3 CompleteMultipartUpload} * @method Model copyObject(array $args = array()) {@command S3 CopyObject} @@ -102,17 +102,17 @@ use Guzzle\Service\Resource\ResourceIteratorInterface; * @method Model restoreObject(array $args = array()) {@command S3 RestoreObject} * @method Model uploadPart(array $args = array()) {@command S3 UploadPart} * @method Model uploadPartCopy(array $args = array()) {@command S3 UploadPartCopy} - * @method waitUntilBucketExists(array $input) Wait until a bucket exists. The input array uses the parameters of the HeadBucket operation and waiter specific settings - * @method waitUntilBucketNotExists(array $input) Wait until a bucket does not exist. The input array uses the parameters of the HeadBucket operation and waiter specific settings - * @method waitUntilObjectExists(array $input) Wait until an object exists. The input array uses the parameters of the HeadObject operation and waiter specific settings + * @method waitUntilBucketExists(array $input) The input array uses the parameters of the HeadBucket operation and waiter specific settings + * @method waitUntilBucketNotExists(array $input) The input array uses the parameters of the HeadBucket operation and waiter specific settings + * @method waitUntilObjectExists(array $input) The input array uses the parameters of the HeadObject operation and waiter specific settings * @method ResourceIteratorInterface getListBucketsIterator(array $args = array()) The input array uses the parameters of the ListBuckets operation * @method ResourceIteratorInterface getListMultipartUploadsIterator(array $args = array()) The input array uses the parameters of the ListMultipartUploads operation - * @method ResourceIteratorInterface getListObjectsIterator(array $args = array()) The input array uses the parameters of the ListObjects operation * @method ResourceIteratorInterface getListObjectVersionsIterator(array $args = array()) The input array uses the parameters of the ListObjectVersions operation + * @method ResourceIteratorInterface getListObjectsIterator(array $args = array()) The input array uses the parameters of the ListObjects operation * @method ResourceIteratorInterface getListPartsIterator(array $args = array()) The input array uses the parameters of the ListParts operation * - * @link http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/service-s3.html User guide - * @link http://docs.aws.amazon.com/aws-sdk-php-2/latest/class-Aws.S3.S3Client.html API docs + * @link http://docs.aws.amazon.com/aws-sdk-php/guide/latest/service-s3.html User guide + * @link http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.S3.S3Client.html API docs */ class S3Client extends AbstractClient { @@ -149,51 +149,15 @@ class S3Client extends AbstractClient 'DeleteObjectExpirationConfig' => 'DeleteBucketLifecycle', ); - /** - * @inheritdoc - */ protected $directory = __DIR__; /** * Factory method to create a new Amazon S3 client using an array of configuration options. * - * The following array keys and values are available options: - * - * Credential options (key, secret, and optional token OR credentials is required) - * - * - key - AWS Access Key ID - * - secret - AWS secret access key - * - credentials - You can optionally provide a custom `Aws\Common\Credentials\CredentialsInterface` object - * - token - Custom AWS security token to use with request authentication - * - token.ttd - UNIX timestamp for when the custom credentials expire - * - credentials.cache - Used to cache credentials when using providers that require HTTP requests. Set the true - * to use the default APC cache or provide a `Guzzle\Cache\CacheAdapterInterface` object. - * - credentials.cache.key - Optional custom cache key to use with the credentials - * - credentials.client - Pass this option to specify a custom `Guzzle\Http\ClientInterface` to use if your - * credentials require a HTTP request (e.g. RefreshableInstanceProfileCredentials) - * - * Region and Endpoint options (a `region` and optional `scheme` OR a `base_url` is required) - * - * - region - Region name (e.g. 'us-east-1', 'us-west-1', 'us-west-2', 'eu-west-1', etc...) - * - scheme - URI Scheme of the base URL (e.g. 'https', 'http'). - * - base_url - Instead of using a `region` and `scheme`, you can specify a custom base URL for the client - * - * Generic client options - * - * - ssl.certificate_authority: Set to true to use the bundled CA cert (default), system to use the certificate - * bundled with your system, or pass the full path to an SSL certificate bundle. This option should be used when - * you encounter curl error code 60. - * - curl.options - Array of cURL options to apply to every request. - * See http://www.php.net/manual/en/function.curl-setopt.php for a list of available options - * - signature - You can optionally provide a custom signature implementation used to sign requests - * - client.backoff.logger - `Guzzle\Log\LogAdapterInterface` object used to log backoff retries. Use - * 'debug' to emit PHP warnings when a retry is issued. - * - client.backoff.logger.template - Optional template to use for exponential backoff log messages. See - * `Guzzle\Plugin\Backoff\BackoffLogger` for formatting information. - * * @param array|Collection $config Client configuration data * * @return self + * @link http://docs.aws.amazon.com/aws-sdk-php/guide/latest/configuration.html#client-configuration-options */ public static function factory($config = array()) { @@ -201,25 +165,14 @@ class S3Client extends AbstractClient // Configure the custom exponential backoff plugin for retrying S3 specific errors if (!isset($config[Options::BACKOFF])) { - $config[Options::BACKOFF] = new BackoffPlugin( - new TruncatedBackoffStrategy(3, - new HttpBackoffStrategy(null, - new SocketTimeoutChecker( - new CurlBackoffStrategy(null, - new ExpiredCredentialsChecker($exceptionParser, - new ExponentialBackoffStrategy() - ) - ) - ) - ) - ) - ); + $config[Options::BACKOFF] = self::createBackoffPlugin($exceptionParser); } + $config[Options::SIGNATURE] = $signature = self::createSignature($config); + $client = ClientBuilder::factory(__NAMESPACE__) ->setConfig($config) ->setConfigDefaults(array( - Options::SIGNATURE => new S3Signature(), Options::VERSION => self::LATEST_API_VERSION, Options::SERVICE_DESCRIPTION => __DIR__ . '/Resources/s3-%s.php' )) @@ -255,16 +208,17 @@ class S3Client extends AbstractClient // Use virtual hosted buckets when possible $client->addSubscriber(new BucketStyleListener()); - // Ensure that ACP headers are applied when needed $client->addSubscriber(new AcpListener()); - - // Validate and add Content-MD5 hashes - $client->addSubscriber(new CommandContentMd5Plugin()); + // Validate and add required Content-MD5 hashes (e.g. DeleteObjects) + $client->addSubscriber(new S3Md5Listener($signature)); // Allow for specifying bodies with file paths and file handles $client->addSubscriber(new UploadBodyListener(array('PutObject', 'UploadPart'))); + // Ensures that if a SSE-CPK key is provided, the key and md5 are formatted correctly + $client->addSubscriber(new SseCpkListener); + // Add aliases for some S3 operations $default = CompositeFactory::getDefaultChain($client); $default->add( @@ -277,7 +231,66 @@ class S3Client extends AbstractClient } /** - * Find out if a string is a valid name for an Amazon S3 bucket. + * Create an Amazon S3 specific backoff plugin + * + * @param S3ExceptionParser $exceptionParser + * + * @return BackoffPlugin + */ + private static function createBackoffPlugin(S3ExceptionParser $exceptionParser) + { + return new BackoffPlugin( + new TruncatedBackoffStrategy(3, + new CurlBackoffStrategy(null, + new HttpBackoffStrategy(null, + new SocketTimeoutChecker( + new ExpiredCredentialsChecker($exceptionParser, + new ExponentialBackoffStrategy() + ) + ) + ) + ) + ) + ); + } + + /** + * Create an appropriate signature based on the configuration settings + * + * @param $config + * + * @return \Aws\Common\Signature\SignatureInterface + * @throws InvalidArgumentException + */ + private static function createSignature($config) + { + $currentValue = isset($config[Options::SIGNATURE]) ? $config[Options::SIGNATURE] : null; + + // Use the Amazon S3 signature V4 when the value is set to "v4" or when + // the value is not set and the region starts with "cn-". + if ($currentValue == 'v4' || + (!$currentValue && isset($config['region']) && substr($config['region'], 0, 3) == 'cn-') + ) { + // Force SignatureV4 for specific regions or if specified in the config + $currentValue = new S3SignatureV4('s3'); + } elseif (!$currentValue || $currentValue == 's3') { + // Use the Amazon S3 signature by default + $currentValue = new S3Signature(); + } + + // A region is require with v4 + if ($currentValue instanceof SignatureV4 && !isset($config['region'])) { + throw new InvalidArgumentException('A region must be specified ' + . 'when using signature version 4'); + } + + return $currentValue; + } + + /** + * Determine if a string is a valid name for a DNS compatible Amazon S3 + * bucket, meaning the bucket can be used as a subdomain in a URL (e.g., + * "<bucket>.s3.amazonaws.com"). * * @param string $bucket The name of the bucket to check. * @@ -286,14 +299,12 @@ class S3Client extends AbstractClient public static function isValidBucketName($bucket) { $bucketLen = strlen($bucket); - if (!$bucket || $bucketLen < 3 || $bucketLen > 63 - // Cannot start or end with a '.' - || $bucket[0] == '.' - || $bucket[$bucketLen - 1] == '.' + if ($bucketLen < 3 || $bucketLen > 63 || // Cannot look like an IP address - || preg_match('/^\d+\.\d+\.\d+\.\d+$/', $bucket) + preg_match('/(\d+\.){3}\d+$/', $bucket) || // Cannot include special characters, must start and end with lower alnum - || !preg_match('/^[a-z0-9][a-z0-9\-.]*[a-z0-9]?$/', $bucket)) { + !preg_match('/^[a-z0-9]([a-z0-9\-\.]*[a-z0-9])?$/', $bucket) + ) { return false; } @@ -319,36 +330,7 @@ class S3Client extends AbstractClient . 'request object'); } - if ($expires instanceof \DateTime) { - $expires = $expires->getTimestamp(); - } elseif (!is_numeric($expires)) { - $expires = strtotime($expires); - } - - // Operate on a clone of the request, so the original is not altered - $request = clone $request; - - // URL encoding already occurs in the URI template expansion. Undo that and encode using the same encoding as - // GET object, PUT object, etc. - $path = $this->encodeKey(rawurldecode($request->getPath())); - $request->setPath($path); - - // Make sure to handle temporary credentials - if ($token = $this->credentials->getSecurityToken()) { - $request->setHeader('x-amz-security-token', $token); - $request->getQuery()->set('x-amz-security-token', $token); - } - - // Set query params required for pre-signed URLs - $request->getQuery() - ->set('AWSAccessKeyId', $this->credentials->getAccessKeyId()) - ->set('Expires', $expires) - ->set('Signature', $this->signature->signString( - $this->signature->createCanonicalizedString($request, $expires), - $this->credentials - )); - - return $request->getUrl(); + return $this->signature->createPresignedUrl($request, $this->credentials, $expires); } /** @@ -565,7 +547,13 @@ class S3Client extends AbstractClient */ public function uploadDirectory($directory, $bucket, $keyPrefix = null, array $options = array()) { - $options = Collection::fromConfig($options, array('base_dir' => $directory)); + $options = Collection::fromConfig( + $options, + array( + 'base_dir' => realpath($directory) ?: $directory + ) + ); + $builder = $options['builder'] ?: UploadSyncBuilder::getInstance(); $builder->uploadFromDirectory($directory) ->setClient($this) |