| 1 |
<?php |
| 2 |
|
| 3 |
namespace Dudlewebs\WPMCS\s3\Aws\S3; |
| 4 |
|
| 5 |
use Dudlewebs\WPMCS\s3\Aws\Api\Service; |
| 6 |
use Dudlewebs\WPMCS\s3\Aws\CommandInterface; |
| 7 |
use Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7; |
| 8 |
use InvalidArgumentException; |
| 9 |
use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface; |
| 10 |
/** |
| 11 |
* Apply required or optional checksums to requests before sending. |
| 12 |
* |
| 13 |
* IMPORTANT: This middleware must be added after the "build" step. |
| 14 |
* |
| 15 |
* @internal |
| 16 |
*/ |
| 17 |
class ApplyChecksumMiddleware |
| 18 |
{ |
| 19 |
use CalculatesChecksumTrait; |
| 20 |
private static $sha256 = ['PutObject', 'UploadPart']; |
| 21 |
/** @var Service */ |
| 22 |
private $api; |
| 23 |
private $nextHandler; |
| 24 |
/** |
| 25 |
* Create a middleware wrapper function. |
| 26 |
* |
| 27 |
* @param Service $api |
| 28 |
* @return callable |
| 29 |
*/ |
| 30 |
public static function wrap(Service $api) |
| 31 |
{ |
| 32 |
return function (callable $handler) use($api) { |
| 33 |
return new self($handler, $api); |
| 34 |
}; |
| 35 |
} |
| 36 |
public function __construct(callable $nextHandler, Service $api) |
| 37 |
{ |
| 38 |
$this->api = $api; |
| 39 |
$this->nextHandler = $nextHandler; |
| 40 |
} |
| 41 |
public function __invoke(CommandInterface $command, RequestInterface $request) |
| 42 |
{ |
| 43 |
$next = $this->nextHandler; |
| 44 |
$name = $command->getName(); |
| 45 |
$body = $request->getBody(); |
| 46 |
$op = $this->api->getOperation($command->getName()); |
| 47 |
$checksumInfo = isset($op['httpChecksum']) ? $op['httpChecksum'] : []; |
| 48 |
$checksumMemberName = \array_key_exists('requestAlgorithmMember', $checksumInfo) ? $checksumInfo['requestAlgorithmMember'] : ""; |
| 49 |
$requestedAlgorithm = isset($command[$checksumMemberName]) ? $command[$checksumMemberName] : null; |
| 50 |
if (!empty($checksumMemberName) && !empty($requestedAlgorithm)) { |
| 51 |
$requestedAlgorithm = \strtolower($requestedAlgorithm); |
| 52 |
$checksumMember = $op->getInput()->getMember($checksumMemberName); |
| 53 |
$supportedAlgorithms = isset($checksumMember['enum']) ? \array_map('strtolower', $checksumMember['enum']) : null; |
| 54 |
if (\is_array($supportedAlgorithms) && \in_array($requestedAlgorithm, $supportedAlgorithms)) { |
| 55 |
$headerName = "x-amz-checksum-{$requestedAlgorithm}"; |
| 56 |
$encoded = $this->getEncodedValue($requestedAlgorithm, $body); |
| 57 |
if (!$request->hasHeader($headerName)) { |
| 58 |
$request = $request->withHeader($headerName, $encoded); |
| 59 |
} |
| 60 |
} else { |
| 61 |
throw new InvalidArgumentException("Unsupported algorithm supplied for input variable {$checksumMemberName}." . " Supported checksums for this operation include: " . \implode(", ", $supportedAlgorithms) . "."); |
| 62 |
} |
| 63 |
return $next($command, $request); |
| 64 |
} |
| 65 |
if (!empty($checksumInfo)) { |
| 66 |
//if the checksum member is absent, check if it's required |
| 67 |
$checksumRequired = isset($checksumInfo['requestChecksumRequired']) ? $checksumInfo['requestChecksumRequired'] : null; |
| 68 |
if (!empty($checksumRequired) && !$request->hasHeader('Content-MD5')) { |
| 69 |
// Set the content MD5 header for operations that require it. |
| 70 |
$request = $request->withHeader('Content-MD5', \base64_encode(Psr7\Utils::hash($body, 'md5', \true))); |
| 71 |
return $next($command, $request); |
| 72 |
} |
| 73 |
} |
| 74 |
if (\in_array($name, self::$sha256) && $command['ContentSHA256']) { |
| 75 |
// Set the content hash header if provided in the parameters. |
| 76 |
$request = $request->withHeader('X-Amz-Content-Sha256', $command['ContentSHA256']); |
| 77 |
} |
| 78 |
return $next($command, $request); |
| 79 |
} |
| 80 |
} |
| 81 |
|