appendUserAgent($client, 'feat/s3-encrypt/' . self::CRYPTO_VERSION); $this->client = $client; $config['params'] = []; if (!empty($config['bucket'])) { $config['params']['Bucket'] = $config['bucket']; } if (!empty($config['key'])) { $config['params']['Key'] = $config['key']; } $this->provider = $this->getMaterialsProvider($config); unset($config['@MaterialsProvider']); $this->keyCommitmentPolicy = $this->getKeyCommitmentPolicy($config); unset($config['@CommitmentPolicy']); $this->instructionFileSuffix = $this->getInstructionFileSuffix($config); unset($config['@InstructionFileSuffix']); $this->strategy = $this->getMetadataStrategy( $config, $this->instructionFileSuffix ); if ($this->strategy === null) { $this->strategy = self::getDefaultStrategy(); } unset($config['@MetadataStrategy']); $options = array_change_key_case($config); $cipherOptions = array_intersect_key( $options['@cipheroptions'], self::$allowedOptions ); if (empty($cipherOptions['Cipher'])) { throw new \InvalidArgumentException('An encryption cipher must be' . ' specified in @CipherOptions["Cipher"].'); } $this->algorithmSuite = AlgorithmSuite::validateCommitmentPolicyOnEncrypt( $cipherOptions, $this->keyCommitmentPolicy ); //= ../specification/s3-encryption/client.md#optional-api-operations //= type=implication //# - If implemented, CreateMultipartUpload MUST initiate a multipart upload. $config['prepare_data_source'] = $this->getEncryptingDataPreparer(); parent::__construct($client, $source, $config); if (!extension_loaded('openssl')) { throw new CryptoException("Unable to load `openssl` extension."); } } private static function getDefaultStrategy() { return new HeadersMetadataStrategy(); } private function getEncryptingDataPreparer() { return function() { // Defer encryption work until promise is executed $envelope = new MetadataEnvelope(); list($this->source, $params) = Promise\Create::promiseFor($this->encrypt( $this->source, $this->algorithmSuite, $this->config ?: [], $this->provider, $envelope ))->then( function ($bodyStream) use ($envelope) { $params = $this->strategy->save( $envelope, $this->config['params'] ); return [$bodyStream, $params]; } )->wait(); $this->source->rewind(); $this->config['params'] = $params; }; } }