You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
nextcloud-server/apps/files_external/3rdparty/aws-sdk-php/Aws/CloudFront/CloudFrontClient.php

271 lines
15 KiB

<?php
/**
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
namespace Aws\CloudFront;
use Aws\Common\Client\AbstractClient;
use Aws\Common\Client\ClientBuilder;
use Aws\Common\Credentials\Credentials;
use Aws\Common\Enum\ClientOptions as Options;
use Aws\Common\Exception\InvalidArgumentException;
use Aws\Common\Exception\Parser\DefaultXmlExceptionParser;
use Aws\Common\Exception\RequiredExtensionNotLoadedException;
use Guzzle\Common\Collection;
use Guzzle\Http\Url;
use Guzzle\Service\Resource\Model;
use Guzzle\Service\Resource\ResourceIteratorInterface;
/**
* Client to interact with Amazon CloudFront
*
* @method Model createCloudFrontOriginAccessIdentity(array $args = array()) {@command CloudFront CreateCloudFrontOriginAccessIdentity}
* @method Model createDistribution(array $args = array()) {@command CloudFront CreateDistribution}
* @method Model createInvalidation(array $args = array()) {@command CloudFront CreateInvalidation}
* @method Model createStreamingDistribution(array $args = array()) {@command CloudFront CreateStreamingDistribution}
* @method Model deleteCloudFrontOriginAccessIdentity(array $args = array()) {@command CloudFront DeleteCloudFrontOriginAccessIdentity}
* @method Model deleteDistribution(array $args = array()) {@command CloudFront DeleteDistribution}
* @method Model deleteStreamingDistribution(array $args = array()) {@command CloudFront DeleteStreamingDistribution}
* @method Model getCloudFrontOriginAccessIdentity(array $args = array()) {@command CloudFront GetCloudFrontOriginAccessIdentity}
* @method Model getCloudFrontOriginAccessIdentityConfig(array $args = array()) {@command CloudFront GetCloudFrontOriginAccessIdentityConfig}
* @method Model getDistribution(array $args = array()) {@command CloudFront GetDistribution}
* @method Model getDistributionConfig(array $args = array()) {@command CloudFront GetDistributionConfig}
* @method Model getInvalidation(array $args = array()) {@command CloudFront GetInvalidation}
* @method Model getStreamingDistribution(array $args = array()) {@command CloudFront GetStreamingDistribution}
* @method Model getStreamingDistributionConfig(array $args = array()) {@command CloudFront GetStreamingDistributionConfig}
* @method Model listCloudFrontOriginAccessIdentities(array $args = array()) {@command CloudFront ListCloudFrontOriginAccessIdentities}
* @method Model listDistributions(array $args = array()) {@command CloudFront ListDistributions}
* @method Model listInvalidations(array $args = array()) {@command CloudFront ListInvalidations}
* @method Model listStreamingDistributions(array $args = array()) {@command CloudFront ListStreamingDistributions}
* @method Model updateCloudFrontOriginAccessIdentity(array $args = array()) {@command CloudFront UpdateCloudFrontOriginAccessIdentity}
* @method Model updateDistribution(array $args = array()) {@command CloudFront UpdateDistribution}
* @method Model updateStreamingDistribution(array $args = array()) {@command CloudFront UpdateStreamingDistribution}
* @method waitUntilStreamingDistributionDeployed(array $input) Wait until a streaming distribution is deployed. The input array uses the parameters of the GetStreamingDistribution operation and waiter specific settings
* @method waitUntilDistributionDeployed(array $input) Wait until a distribution is deployed. The input array uses the parameters of the GetDistribution operation and waiter specific settings
* @method waitUntilInvalidationCompleted(array $input) Wait until an invalidation has completed. The input array uses the parameters of the GetInvalidation operation and waiter specific settings
* @method ResourceIteratorInterface getListCloudFrontOriginAccessIdentitiesIterator(array $args = array()) The input array uses the parameters of the ListCloudFrontOriginAccessIdentities operation
* @method ResourceIteratorInterface getListDistributionsIterator(array $args = array()) The input array uses the parameters of the ListDistributions operation
* @method ResourceIteratorInterface getListInvalidationsIterator(array $args = array()) The input array uses the parameters of the ListInvalidations operation
* @method ResourceIteratorInterface getListStreamingDistributionsIterator(array $args = array()) The input array uses the parameters of the ListStreamingDistributions operation
*
* @link http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/service-cloudfront.html User guide
* @link http://docs.aws.amazon.com/aws-sdk-php-2/latest/class-Aws.CloudFront.CloudFrontClient.html API docs
*/
class CloudFrontClient extends AbstractClient
{
const LATEST_API_VERSION = '2013-05-12';
/**
* Factory method to create a new Amazon CloudFront client using an array of configuration 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
*
* - 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
* - 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.
*
* Options specific to CloudFront
*
* - key_pair_id: The ID of the key pair used to sign CloudFront URLs for private distributions.
* - private_key: The filepath ot the private key used to sign CloudFront URLs for private distributions.
*
* @param array|Collection $config Client configuration data
*
* @return self
*/
public static function factory($config = array())
{
// Decide which signature to use
if (isset($config[Options::VERSION]) && $config[Options::VERSION] < self::LATEST_API_VERSION) {
$config[Options::SIGNATURE] = new CloudFrontSignature();
}
// Instantiate the CloudFront client
return ClientBuilder::factory(__NAMESPACE__)
->setConfig($config)
->setConfigDefaults(array(
Options::VERSION => self::LATEST_API_VERSION,
Options::SERVICE_DESCRIPTION => __DIR__ . '/Resources/cloudfront-%s.php',
))
->setExceptionParser(new DefaultXmlExceptionParser())
->setIteratorsConfig(array(
'token_param' => 'Marker',
'token_key' => 'NextMarker',
'more_key' => 'IsTruncated',
'result_key' => 'Items',
'operations' => array(
'ListCloudFrontOriginAccessIdentities',
'ListDistributions',
'ListInvalidations',
'ListStreamingDistributions'
)
))
->build();
}
/**
* Create a signed URL. Keep in mind that URLs meant for use in media/flash players may have different requirements
* for URL formats (e.g. some require that the extension be removed, some require the file name to be prefixed -
* mp4:<path>, some require you to add "/cfx/st" into your URL). See
* http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/WorkingWithStreamingDistributions.html for
* additional details and help.
*
* This method accepts an array of configuration options:
* - url: (string) URL of the resource being signed (can include query string and wildcards). For example:
* rtmp://s5c39gqb8ow64r.cloudfront.net/videos/mp3_name.mp3
* http://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes
* - policy: (string) JSON policy. Use this option when creating a signed URL for a custom policy.
* - expires: (int) UTC Unix timestamp used when signing with a canned policy. Not required when passing a
* custom 'policy' option.
* - key_pair_id: (string) The ID of the key pair used to sign CloudFront URLs for private distributions.
* - private_key: (string) The filepath ot the private key used to sign CloudFront URLs for private distributions.
*
* @param array $options Array of configuration options used when signing
*
* @return string The file URL with authentication parameters
* @throws InvalidArgumentException if key_pair_id and private_key have not been configured on the client
* @throws RequiredExtensionNotLoadedException if the openssl extension is not installed
* @link http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/WorkingWithStreamingDistributions.html
*/
public function getSignedUrl(array $options)
{
if (!extension_loaded('openssl')) {
//@codeCoverageIgnoreStart
throw new RequiredExtensionNotLoadedException('The openssl extension is required to sign CloudFront urls.');
//@codeCoverageIgnoreEnd
}
// Initialize the configuration data and ensure that the url was specified
$options = Collection::fromConfig($options, array_filter(array(
'key_pair_id' => $this->getConfig('key_pair_id'),
'private_key' => $this->getConfig('private_key'),
)), array('url', 'key_pair_id', 'private_key'));
// Determine the scheme of the url
$urlSections = explode('://', $options['url']);
if (count($urlSections) < 2) {
throw new InvalidArgumentException('Invalid URL: ' . $options['url']);
}
// Get the real scheme by removing wildcards from the scheme
$scheme = str_replace('*', '', $urlSections[0]);
$policy = $options['policy'] ?: $this->createCannedPolicy($scheme, $options['url'], $options['expires']);
// Strip whitespace from the policy
$policy = str_replace(' ', '', $policy);
$url = Url::factory($scheme . '://' . $urlSections[1]);
if ($options['policy']) {
// Custom policies require that the encoded policy be specified in the URL
$url->getQuery()->set('Policy', strtr(base64_encode($policy), '+=/', '-_~'));
} else {
// Canned policies require that the Expires parameter be set in the URL
$url->getQuery()->set('Expires', $options['expires']);
}
// Sign the policy using the CloudFront private key
$signedPolicy = $this->rsaSha1Sign($policy, $options['private_key']);
// Remove whitespace, base64 encode the policy, and replace special characters
$signedPolicy = strtr(base64_encode($signedPolicy), '+=/', '-_~');
$url->getQuery()
->useUrlEncoding(false)
->set('Signature', $signedPolicy)
->set('Key-Pair-Id', $options['key_pair_id']);
if ($scheme != 'rtmp') {
// HTTP and HTTPS signed URLs include the full URL
return (string) $url;
} else {
// Use a relative URL when creating Flash player URLs
$url->setScheme(null)->setHost(null);
return substr($url, 1);
}
}
/**
* Sign a policy string using OpenSSL RSA SHA1
*
* @param string $policy Policy to sign
* @param string $privateKeyFilename File containing the OpenSSL private key
*
* @return string
*/
protected function rsaSha1Sign($policy, $privateKeyFilename)
{
$signature = '';
openssl_sign($policy, $signature, file_get_contents($privateKeyFilename));
return $signature;
}
/**
* Create a canned policy for a particular URL and expiration
*
* @param string $scheme Parsed scheme without wildcards
* @param string $url URL that is being signed
* @param int $expires Time in which the signature expires
*
* @return string
* @throws InvalidArgumentException if the expiration is not set
*/
protected function createCannedPolicy($scheme, $url, $expires)
{
if (!$expires) {
throw new InvalidArgumentException('An expires option is required when using a canned policy');
}
// Generate a canned policy
if ($scheme == 'http' || $scheme == 'https') {
$resource = $url;
} elseif ($scheme == 'rtmp') {
$parts = parse_url($url);
$pathParts = pathinfo($parts['path']);
// Add path leading to file, strip file extension, and add a query string if present
$resource = ltrim($pathParts['dirname'] . '/' . $pathParts['basename'], '/')
. (isset($parts['query']) ? "?{$parts['query']}" : '');
} else {
throw new InvalidArgumentException("Invalid URI scheme: {$scheme}. Must be one of http or rtmp.");
}
return sprintf(
'{"Statement":[{"Resource":"%s","Condition":{"DateLessThan":{"AWS:EpochTime":%d}}}]}',
$resource,
$expires
);
}
}