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->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']); $config['prepare_data_source'] = $this->getEncryptingDataPreparer(); parent::__construct($client, $source, $config); } 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->config['@cipheroptions'] ?: [], $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; }; } }