PluginProbe ʕ •ᴥ•ʔ
Transferito: WP Migration / trunk
Transferito: WP Migration vtrunk
trunk 11.4.0 12.0.0 13.1.0 14.0.0 14.0.11 14.0.7 14.1.0 14.1.1 14.1.2 14.1.3 14.1.4
transferito / vendor / aws / aws-sdk-php / src / S3 / ValidateResponseChecksumParser.php
transferito / vendor / aws / aws-sdk-php / src / S3 Last commit date
Crypto 11 months ago Exception 11 months ago RegionalEndpoint 11 months ago UseArnRegion 11 months ago AmbiguousSuccessParser.php 11 months ago ApplyChecksumMiddleware.php 11 months ago BatchDelete.php 11 months ago BucketEndpointArnMiddleware.php 11 months ago BucketEndpointMiddleware.php 11 months ago CalculatesChecksumTrait.php 11 months ago EndpointRegionHelperTrait.php 11 months ago GetBucketLocationParser.php 11 months ago MultipartCopy.php 11 months ago MultipartUploader.php 11 months ago MultipartUploadingTrait.php 11 months ago ObjectCopier.php 11 months ago ObjectUploader.php 11 months ago PermanentRedirectMiddleware.php 11 months ago PostObject.php 11 months ago PostObjectV4.php 11 months ago PutObjectUrlMiddleware.php 11 months ago RetryableMalformedResponseParser.php 11 months ago S3Client.php 11 months ago S3ClientInterface.php 11 months ago S3ClientTrait.php 11 months ago S3EndpointMiddleware.php 11 months ago S3MultiRegionClient.php 11 months ago S3UriParser.php 11 months ago SSECMiddleware.php 11 months ago StreamWrapper.php 11 months ago Transfer.php 11 months ago ValidateResponseChecksumParser.php 11 months ago
ValidateResponseChecksumParser.php
150 lines
1 <?php
2 namespace Aws\S3;
3
4 use Aws\Api\Parser\AbstractParser;
5 use Aws\Api\Service;
6 use Aws\Api\StructureShape;
7 use Aws\CommandInterface;
8 use Aws\S3\Exception\S3Exception;
9 use Psr\Http\Message\ResponseInterface;
10 use Psr\Http\Message\StreamInterface;
11
12 /**
13 * @internal Decorates a parser for the S3 service to validate the response checksum.
14 */
15 class ValidateResponseChecksumParser extends AbstractParser
16 {
17 use CalculatesChecksumTrait;
18 /**
19 * @param callable $parser Parser to wrap.
20 */
21 public function __construct(callable $parser, Service $api)
22 {
23 $this->api = $api;
24 $this->parser = $parser;
25 }
26
27 public function __invoke(
28 CommandInterface $command,
29 ResponseInterface $response
30 ) {
31 $fn = $this->parser;
32 $result = $fn($command, $response);
33
34 //Skip this middleware if the operation doesn't have an httpChecksum
35 $op = $this->api->getOperation($command->getName());
36 $checksumInfo = isset($op['httpChecksum'])
37 ? $op['httpChecksum']
38 : [];
39 if (empty($checksumInfo)) {
40 return $result;
41 }
42
43 //Skip this middleware if the operation doesn't send back a checksum, or the user doesn't opt in
44 $checksumModeEnabledMember = isset($checksumInfo['requestValidationModeMember'])
45 ? $checksumInfo['requestValidationModeMember']
46 : "";
47 $checksumModeEnabled = isset($command[$checksumModeEnabledMember])
48 ? $command[$checksumModeEnabledMember]
49 : "";
50 $responseAlgorithms = isset($checksumInfo['responseAlgorithms'])
51 ? $checksumInfo['responseAlgorithms']
52 : [];
53 if (empty($responseAlgorithms)
54 || strtolower($checksumModeEnabled) !== "enabled"
55 ) {
56 return $result;
57 }
58
59 if (extension_loaded('awscrt')) {
60 $checksumPriority = ['CRC32C', 'CRC32', 'SHA1', 'SHA256'];
61 } else {
62 $checksumPriority = ['CRC32', 'SHA1', 'SHA256'];
63 }
64 $checksumsToCheck = array_intersect($responseAlgorithms, $checksumPriority);
65 $checksumValidationInfo = $this->validateChecksum($checksumsToCheck, $response);
66
67 if ($checksumValidationInfo['status'] == "SUCCEEDED") {
68 $result['ChecksumValidated'] = $checksumValidationInfo['checksum'];
69 } else if ($checksumValidationInfo['status'] == "FAILED"){
70 //Ignore failed validations on GetObject if it's a multipart get which returned a full multipart object
71 if ($command->getName() == "GetObject"
72 && !empty($checksumValidationInfo['checksumHeaderValue'])
73 ) {
74 $headerValue = $checksumValidationInfo['checksumHeaderValue'];
75 $lastDashPos = strrpos($headerValue, '-');
76 $endOfChecksum = substr($headerValue, $lastDashPos + 1);
77 if (is_numeric($endOfChecksum)
78 && intval($endOfChecksum) > 1
79 && intval($endOfChecksum) < 10000) {
80 return $result;
81 }
82 }
83 throw new S3Exception(
84 "Calculated response checksum did not match the expected value",
85 $command
86 );
87 }
88 return $result;
89 }
90
91 public function parseMemberFromStream(
92 StreamInterface $stream,
93 StructureShape $member,
94 $response
95 ) {
96 return $this->parser->parseMemberFromStream($stream, $member, $response);
97 }
98
99 /**
100 * @param $checksumPriority
101 * @param ResponseInterface $response
102 */
103 public function validateChecksum($checksumPriority, ResponseInterface $response)
104 {
105 $checksumToValidate = $this->chooseChecksumHeaderToValidate(
106 $checksumPriority,
107 $response
108 );
109 $validationStatus = "SKIPPED";
110 $checksumHeaderValue = null;
111 if (!empty($checksumToValidate)) {
112 $checksumHeaderValue = $response->getHeader(
113 'x-amz-checksum-' . $checksumToValidate
114 );
115 if (isset($checksumHeaderValue)) {
116 $checksumHeaderValue = $checksumHeaderValue[0];
117 $calculatedChecksumValue = $this->getEncodedValue(
118 $checksumToValidate,
119 $response->getBody()
120 );
121 $validationStatus = $checksumHeaderValue == $calculatedChecksumValue
122 ? "SUCCEEDED"
123 : "FAILED";
124 }
125 }
126 return [
127 "status" => $validationStatus,
128 "checksum" => $checksumToValidate,
129 "checksumHeaderValue" => $checksumHeaderValue,
130 ];
131 }
132
133 /**
134 * @param $checksumPriority
135 * @param ResponseInterface $response
136 */
137 public function chooseChecksumHeaderToValidate(
138 $checksumPriority,
139 ResponseInterface $response
140 ) {
141 foreach ($checksumPriority as $checksum) {
142 $checksumHeader = 'x-amz-checksum-' . $checksum;
143 if ($response->hasHeader($checksumHeader)) {
144 return $checksum;
145 }
146 }
147 return null;
148 }
149 }
150