PluginProbe
Media Cloud Sync / 1.2.13
Media Cloud Sync v1.2.13
1.4.2 1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 All 36 releases
media-cloud-sync / includes / sdk / s3 / Aws / S3 / ApplyChecksumMiddleware.php

ApplyChecksumMiddleware.php in Media Cloud Sync 1.2.13, at includes/sdk/s3/Aws/S3/ApplyChecksumMiddleware.php

108 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 use Dudlewebs\WPMCS\s3\Psr\Http\Message\StreamInterface;
11 /**
12 * Apply required or optional checksums to requests before sending.
13 *
14 * IMPORTANT: This middleware must be added after the "build" step.
15 *
16 * @internal
17 */
18 class ApplyChecksumMiddleware
19 {
20 use CalculatesChecksumTrait;
21 private static $sha256AndMd5 = ['PutObject', 'UploadPart'];
22 /** @var Service */
23 private $api;
24 private $nextHandler;
25 /**
26 * Create a middleware wrapper function.
27 *
28 * @param Service $api
29 * @return callable
30 */
31 public static function wrap(Service $api)
32 {
33 return function (callable $handler) use($api) {
34 return new self($handler, $api);
35 };
36 }
37 public function __construct(callable $nextHandler, Service $api)
38 {
39 $this->api = $api;
40 $this->nextHandler = $nextHandler;
41 }
42 public function __invoke(CommandInterface $command, RequestInterface $request)
43 {
44 $next = $this->nextHandler;
45 $name = $command->getName();
46 $body = $request->getBody();
47 //Checks if AddContentMD5 has been specified for PutObject or UploadPart
48 $addContentMD5 = $command['AddContentMD5'] ?? null;
49 $op = $this->api->getOperation($command->getName());
50 $checksumInfo = $op['httpChecksum'] ?? [];
51 $checksumMemberName = \array_key_exists('requestAlgorithmMember', $checksumInfo) ? $checksumInfo['requestAlgorithmMember'] : "";
52 $requestedAlgorithm = $command[$checksumMemberName] ?? null;
53 if (!empty($checksumMemberName) && !empty($requestedAlgorithm)) {
54 $requestedAlgorithm = \strtolower($requestedAlgorithm);
55 $checksumMember = $op->getInput()->getMember($checksumMemberName);
56 $supportedAlgorithms = isset($checksumMember['enum']) ? \array_map('strtolower', $checksumMember['enum']) : null;
57 if (\is_array($supportedAlgorithms) && \in_array($requestedAlgorithm, $supportedAlgorithms)) {
58 $request = $this->addAlgorithmHeader($requestedAlgorithm, $request, $body);
59 } else {
60 throw new InvalidArgumentException("Unsupported algorithm supplied for input variable {$checksumMemberName}." . " Supported checksums for this operation include: " . \implode(", ", $supportedAlgorithms) . ".");
61 }
62 return $next($command, $request);
63 }
64 if (!empty($checksumInfo)) {
65 //if the checksum member is absent, check if it's required
66 $checksumRequired = $checksumInfo['requestChecksumRequired'] ?? null;
67 if (!empty($checksumRequired) || \in_array($name, self::$sha256AndMd5) && $addContentMD5) {
68 //S3Express doesn't support MD5; default to crc32 instead
69 if ($this->isS3Express($command)) {
70 $request = $this->addAlgorithmHeader('crc32', $request, $body);
71 } elseif (!$request->hasHeader('Content-MD5')) {
72 // Set the content MD5 header for operations that require it.
73 $request = $request->withHeader('Content-MD5', \base64_encode(Psr7\Utils::hash($body, 'md5', \true)));
74 }
75 return $next($command, $request);
76 }
77 }
78 if (\in_array($name, self::$sha256AndMd5) && $command['ContentSHA256']) {
79 // Set the content hash header if provided in the parameters.
80 $request = $request->withHeader('X-Amz-Content-Sha256', $command['ContentSHA256']);
81 }
82 return $next($command, $request);
83 }
84 /**
85 * @param string $requestedAlgorithm
86 * @param RequestInterface $request
87 * @param StreamInterface $body
88 * @return RequestInterface
89 */
90 private function addAlgorithmHeader(string $requestedAlgorithm, RequestInterface $request, StreamInterface $body)
91 {
92 $headerName = "x-amz-checksum-{$requestedAlgorithm}";
93 if (!$request->hasHeader($headerName)) {
94 $encoded = $this->getEncodedValue($requestedAlgorithm, $body);
95 $request = $request->withHeader($headerName, $encoded);
96 }
97 return $request;
98 }
99 /**
100 * @param CommandInterface $command
101 * @return bool
102 */
103 private function isS3Express(CommandInterface $command) : bool
104 {
105 return isset($command['@context']['signing_service']) && $command['@context']['signing_service'] === 's3express';
106 }
107 }
108