/** * Create a new OAuth 1.0 plugin * * @param array $config Configuration array containing these parameters: * - string 'request_method' Consumer request method. Use the class constants. * - string 'callback' OAuth callback * - string 'consumer_key' Consumer key * - string 'consumer_secret' Consumer secret * - string 'token' Token * - string 'token_secret' Token secret * - string 'verifier' OAuth verifier. * - string 'version' OAuth version. Defaults to 1.0 * - string 'signature_method' Custom signature method * - bool 'disable_post_params' Set to true to prevent POST parameters from being signed * - array|Closure 'signature_callback' Custom signature callback that accepts a string to sign and a signing key */ public function __construct($config) { $this->config = Collection::fromConfig($config, array('version' => '1.0', 'request_method' => self::REQUEST_METHOD_HEADER, 'consumer_key' => 'anonymous', 'consumer_secret' => 'anonymous', 'signature_method' => 'HMAC-SHA1', 'signature_callback' => function ($stringToSign, $key) { return hash_hmac('sha1', $stringToSign, $key, true); }), array('signature_method', 'signature_callback', 'version', 'consumer_key', 'consumer_secret')); }
/** * Performs the building logic using all of the parameters that have been * set and falling back to default values. Returns an instantiate service * client with credentials prepared and plugins attached. * * @return AwsClientInterface * @throws InvalidArgumentException */ public function build() { // Resolve configuration $config = Collection::fromConfig($this->config, array_merge(self::$commonConfigDefaults, $this->configDefaults), self::$commonConfigRequirements + $this->configRequirements); if (!isset($config['endpoint_provider'])) { $config['endpoint_provider'] = RulesEndpointProvider::fromDefaults(); } // Resolve the endpoint, signature, and credentials $description = $this->updateConfigFromDescription($config); $signature = $this->getSignature($description, $config); $credentials = $this->getCredentials($config); // Resolve exception parser if (!$this->exceptionParser) { $this->exceptionParser = new DefaultXmlExceptionParser(); } // Resolve backoff strategy $backoff = $config->get(Options::BACKOFF); if ($backoff === null) { $backoff = new BackoffPlugin(new TruncatedBackoffStrategy(3, new ThrottlingErrorChecker($this->exceptionParser, new CurlBackoffStrategy(null, new HttpBackoffStrategy(array(500, 503, 509), new ExpiredCredentialsChecker($this->exceptionParser, new ExponentialBackoffStrategy())))))); $config->set(Options::BACKOFF, $backoff); } if ($backoff) { $this->addBackoffLogger($backoff, $config); } // Determine service and class name $clientClass = 'Aws\\Common\\Client\\DefaultClient'; if ($this->clientNamespace) { $serviceName = substr($this->clientNamespace, strrpos($this->clientNamespace, '\\') + 1); $clientClass = $this->clientNamespace . '\\' . $serviceName . 'Client'; } /** @var $client AwsClientInterface */ $client = new $clientClass($credentials, $signature, $config); $client->setDescription($description); // Add exception marshaling so that more descriptive exception are thrown if ($this->clientNamespace) { $exceptionFactory = new NamespaceExceptionFactory($this->exceptionParser, "{$this->clientNamespace}\\Exception", "{$this->clientNamespace}\\Exception\\{$serviceName}Exception"); $client->addSubscriber(new ExceptionListener($exceptionFactory)); } // Add the UserAgentPlugin to append to the User-Agent header of requests $client->addSubscriber(new UserAgentListener()); // Filters used for the cache plugin $client->getConfig()->set('params.cache.key_filter', 'header=date,x-amz-date,x-amz-security-token,x-amzn-authorization'); // Set the iterator resource factory based on the provided iterators config $client->setResourceIteratorFactory(new AwsResourceIteratorFactory($this->iteratorsConfig, new ResourceIteratorClassFactory($this->clientNamespace . '\\Iterator'))); // Disable parameter validation if needed if ($config->get(Options::VALIDATION) === false) { $params = $config->get('command.params') ?: array(); $params['command.disable_validation'] = true; $config->set('command.params', $params); } return $client; }
/** * Recursively uploads all files in a given directory to a given bucket. * * @param string $directory Full path to a directory to upload * @param string $bucket Name of the bucket * @param string $keyPrefix Virtual directory key prefix to add to each upload * @param array $options Associative array of upload options * - params: Array of parameters to use with each PutObject operation performed during the transfer * - base_dir: Base directory to remove from each object key * - force: Set to true to upload every file, even if the file is already in Amazon S3 and has not changed * - concurrency: Maximum number of parallel uploads (defaults to 10) * - debug: Set to true or an fopen resource to enable debug mode to print information about each upload * - multipart_upload_size: When the size of a file exceeds this value, the file will be uploaded using a * multipart upload. * * @see Aws\S3\S3Sync\S3Sync for more options and customization */ public function uploadDirectory($directory, $bucket, $keyPrefix = null, array $options = array()) { $options = Collection::fromConfig($options, array('base_dir' => realpath($directory) ?: $directory)); $builder = $options['builder'] ?: UploadSyncBuilder::getInstance(); $builder->uploadFromDirectory($directory)->setClient($this)->setBucket($bucket)->setKeyPrefix($keyPrefix)->setConcurrency($options['concurrency'] ?: 5)->setBaseDir($options['base_dir'])->force($options['force'])->setOperationParams($options['params'] ?: array())->enableDebugOutput($options['debug']); if ($options->hasKey('multipart_upload_size')) { $builder->setMultipartUploadSize($options['multipart_upload_size']); } $builder->build()->transfer(); }
/** * @param array $options Associative array of options: * - client: (S3Client) used to transfer requests * - bucket: (string) Amazon S3 bucket * - iterator: (\Iterator) Iterator that yields SplFileInfo objects to transfer * - source_converter: (FilenameConverterInterface) Converter used to convert filenames * - *: Any other options required by subclasses */ public function __construct(array $options) { $this->options = Collection::fromConfig($options, array('concurrency' => 10), array('client', 'bucket', 'iterator', 'source_converter')); $this->init(); }
/** * Analyzes the provided data and turns it into useful data that can be * consumed and used to build an upload form * * @return PostObject */ public function prepareData() { // Validate required options $options = Collection::fromConfig($this->data, array('ttd' => '+1 hour', 'key' => '^${filename}')); // Format ttd option $ttd = $options['ttd']; $ttd = is_numeric($ttd) ? (int) $ttd : strtotime($ttd); unset($options['ttd']); // If a policy or policy callback were provided, extract those from the options $rawJsonPolicy = $options['policy']; $policyCallback = $options['policy_callback']; unset($options['policy'], $options['policy_callback']); // Setup policy document $policy = array('expiration' => gmdate(DateFormat::ISO8601_S3, $ttd), 'conditions' => array(array('bucket' => $this->bucket))); // Configure the endpoint/action $url = Url::factory($this->client->getBaseUrl()); if ($url->getScheme() === 'https' && strpos($this->bucket, '.') !== false) { // Use path-style URLs $url->setPath($this->bucket); } else { // Use virtual-style URLs $url->setHost($this->bucket . '.' . $url->getHost()); } // Setup basic form $this->formAttributes = array('action' => (string) $url, 'method' => 'POST', 'enctype' => 'multipart/form-data'); $this->formInputs = array('AWSAccessKeyId' => $this->client->getCredentials()->getAccessKeyId()); // Add success action status $status = (int) $options->get('success_action_status'); if ($status && in_array($status, array(200, 201, 204))) { $this->formInputs['success_action_status'] = (string) $status; $policy['conditions'][] = array('success_action_status' => (string) $status); unset($options['success_action_status']); } // Add other options foreach ($options as $key => $value) { $value = (string) $value; if ($value[0] === '^') { $value = substr($value, 1); $this->formInputs[$key] = $value; $value = preg_replace('/\\$\\{(\\w*)\\}/', '', $value); $policy['conditions'][] = array('starts-with', '$' . $key, $value); } else { $this->formInputs[$key] = $value; $policy['conditions'][] = array($key => $value); } } // Handle the policy $policy = is_callable($policyCallback) ? $policyCallback($policy, $this) : $policy; $this->jsonPolicy = $rawJsonPolicy ?: json_encode($policy); $this->applyPolicy(); return $this; }
/** * Factory method to create a new InstanceMetadataClient using an array * of configuration options. * * The configuration options accepts the following array keys and values: * - base_url: Override the base URL of the instance metadata server * - version: Version of the metadata server to interact with * * @param array|Collection $config Configuration options * * @return InstanceMetadataClient */ public static function factory($config = array()) { $config = Collection::fromConfig($config, array(Options::BASE_URL => 'http://169.254.169.254/{version}/', 'version' => 'latest', 'request.options' => array('connect_timeout' => 5, 'timeout' => 10)), array('base_url', 'version')); return new self($config); }