Skip to content

Commit ddeb5ed

Browse files
committed
ChecksumInterceptor.h - Refactor ModifyBeforeSigning logic for readability/scalability
1 parent 17879fd commit ddeb5ed

File tree

1 file changed

+92
-73
lines changed

1 file changed

+92
-73
lines changed

src/aws-cpp-sdk-core/include/smithy/client/features/ChecksumInterceptor.h

Lines changed: 92 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -82,56 +82,10 @@ class ChecksumInterceptor : public smithy::interceptor::Interceptor {
8282
// For non-streaming payload, the resolved checksum location is always header.
8383
// For streaming payload, the resolved checksum location depends on whether it is an unsigned payload, we let
8484
// AwsAuthSigner decide it.
85-
if (request.IsStreaming() && checksumValueAndAlgorithmProvided) {
86-
addChecksumFeatureForChecksumName(checksumAlgorithmName, request);
87-
if (httpRequest->GetRequestHash().second == nullptr) {
88-
const auto hash = Aws::MakeShared<PrecalculatedHash>(AWS_SMITHY_CLIENT_CHECKSUM, checksumHeader->second);
89-
httpRequest->SetRequestHash(checksumAlgorithmName, hash);
90-
}
91-
} else if (checksumValueAndAlgorithmProvided) {
92-
httpRequest->SetHeaderValue(checksumType, checksumHeader->second);
93-
} else if (checksumAlgorithmName == "crc64nvme") {
94-
request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC64);
95-
if (request.IsStreaming()) {
96-
if (httpRequest->GetRequestHash().second == nullptr)
97-
httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<CRC64>(AWS_SMITHY_CLIENT_CHECKSUM));
98-
} else {
99-
httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateCRC64(*(GetBodyStream(request)))));
100-
}
101-
} else if (checksumAlgorithmName == "crc32") {
102-
request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC32);
103-
if (request.IsStreaming()) {
104-
if (httpRequest->GetRequestHash().second == nullptr)
105-
httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<CRC32>(AWS_SMITHY_CLIENT_CHECKSUM));
106-
} else {
107-
httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateCRC32(*(GetBodyStream(request)))));
108-
}
109-
} else if (checksumAlgorithmName == "crc32c") {
110-
request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC32C);
111-
if (request.IsStreaming()) {
112-
if (httpRequest->GetRequestHash().second == nullptr)
113-
httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<CRC32C>(AWS_SMITHY_CLIENT_CHECKSUM));
114-
} else {
115-
httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateCRC32C(*(GetBodyStream(request)))));
116-
}
117-
} else if (checksumAlgorithmName == "sha256") {
118-
request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_SHA256);
119-
if (request.IsStreaming()) {
120-
if (httpRequest->GetRequestHash().second == nullptr)
121-
httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<Sha256>(AWS_SMITHY_CLIENT_CHECKSUM));
122-
} else {
123-
httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateSHA256(*(GetBodyStream(request)))));
124-
}
125-
} else if (checksumAlgorithmName == "sha1") {
126-
request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_SHA1);
127-
if (request.IsStreaming()) {
128-
if (httpRequest->GetRequestHash().second == nullptr)
129-
httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<Sha1>(AWS_SMITHY_CLIENT_CHECKSUM));
130-
} else {
131-
httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateSHA1(*(GetBodyStream(request)))));
132-
}
85+
if (checksumValueAndAlgorithmProvided) {
86+
handleProvidedChecksum(request, httpRequest, checksumAlgorithmName, checksumType, checksumHeader->second);
13387
} else {
134-
AWS_LOGSTREAM_WARN(AWS_SMITHY_CLIENT_CHECKSUM, "Checksum algorithm: " << checksumAlgorithmName << "is not supported by SDK.");
88+
calculateAndSetChecksum(request, httpRequest, checksumAlgorithmName, checksumType);
13589
}
13690
}
13791
}
@@ -140,30 +94,7 @@ class ChecksumInterceptor : public smithy::interceptor::Interceptor {
14094
if ((!request.GetResponseChecksumAlgorithmNames().empty() &&
14195
m_responseChecksumValidation == ResponseChecksumValidation::WHEN_SUPPORTED) ||
14296
request.ShouldValidateResponseChecksum()) {
143-
for (const Aws::String& responseChecksumAlgorithmName : request.GetResponseChecksumAlgorithmNames()) {
144-
const auto responseChecksum = Aws::Utils::StringUtils::ToLower(responseChecksumAlgorithmName.c_str());
145-
if (responseChecksum == "crc32c") {
146-
std::shared_ptr<CRC32C> crc32c = Aws::MakeShared<CRC32C>(AWS_SMITHY_CLIENT_CHECKSUM);
147-
httpRequest->AddResponseValidationHash("crc32c", crc32c);
148-
} else if (responseChecksum == "crc32") {
149-
std::shared_ptr<CRC32> crc32 = Aws::MakeShared<CRC32>(AWS_SMITHY_CLIENT_CHECKSUM);
150-
httpRequest->AddResponseValidationHash("crc32", crc32);
151-
} else if (responseChecksum == "sha1") {
152-
std::shared_ptr<Sha1> sha1 = Aws::MakeShared<Sha1>(AWS_SMITHY_CLIENT_CHECKSUM);
153-
httpRequest->AddResponseValidationHash("sha1", sha1);
154-
} else if (responseChecksum == "sha256") {
155-
std::shared_ptr<Sha256> sha256 = Aws::MakeShared<Sha256>(AWS_SMITHY_CLIENT_CHECKSUM);
156-
httpRequest->AddResponseValidationHash("sha256", sha256);
157-
} else if (responseChecksum == "crc64nvme") {
158-
std::shared_ptr<CRC64> crc64 = Aws::MakeShared<CRC64>(AWS_SMITHY_CLIENT_CHECKSUM);
159-
httpRequest->AddResponseValidationHash("crc64nvme", crc64);
160-
} else {
161-
AWS_LOGSTREAM_WARN(AWS_SMITHY_CLIENT_CHECKSUM,
162-
"Checksum algorithm: " << responseChecksum << " is not supported in validating response body yet.");
163-
}
164-
}
165-
// we have to set the checksum mode to enabled if it was not previously
166-
httpRequest->SetHeaderValue("x-amz-checksum-mode", "enabled");
97+
SetResponseChecksum(request, httpRequest);
16798
}
16899

169100
return httpRequest;
@@ -240,6 +171,94 @@ class ChecksumInterceptor : public smithy::interceptor::Interceptor {
240171
}
241172
}
242173

174+
void handleProvidedChecksum(const Aws::AmazonWebServiceRequest& request, std::shared_ptr<Aws::Http::HttpRequest> httpRequest,
175+
const Aws::String& algorithm, const Aws::String& checksumType, const Aws::String& checksumValue) {
176+
if (request.IsStreaming()) {
177+
addChecksumFeatureForChecksumName(algorithm, request);
178+
if (httpRequest->GetRequestHash().second == nullptr) {
179+
auto hash = Aws::MakeShared<PrecalculatedHash>(AWS_SMITHY_CLIENT_CHECKSUM, checksumValue);
180+
httpRequest->SetRequestHash(algorithm, hash);
181+
}
182+
} else {
183+
httpRequest->SetHeaderValue(checksumType, checksumValue);
184+
}
185+
}
186+
187+
void calculateAndSetChecksum(const Aws::AmazonWebServiceRequest& request, std::shared_ptr<Aws::Http::HttpRequest> httpRequest,
188+
const Aws::String& algorithm, const Aws::String& checksumType) {
189+
static const Aws::UnorderedMap<Aws::String, ChecksumHandler> algorithmMap = {
190+
{"crc64nvme",
191+
{[]() { return Aws::MakeShared<CRC64>(AWS_SMITHY_CLIENT_CHECKSUM); },
192+
[](Aws::IOStream& stream) { return HashingUtils::Base64Encode(HashingUtils::CalculateCRC64(stream)); },
193+
Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC64}},
194+
{"crc32",
195+
{[]() { return Aws::MakeShared<CRC32>(AWS_SMITHY_CLIENT_CHECKSUM); },
196+
[](Aws::IOStream& stream) { return HashingUtils::Base64Encode(HashingUtils::CalculateCRC32(stream)); },
197+
Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC32}},
198+
{"crc32c",
199+
{[]() { return Aws::MakeShared<CRC32C>(AWS_SMITHY_CLIENT_CHECKSUM); },
200+
[](Aws::IOStream& stream) { return HashingUtils::Base64Encode(HashingUtils::CalculateCRC32C(stream)); },
201+
Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC32C}},
202+
{"sha256",
203+
{[]() { return Aws::MakeShared<Sha256>(AWS_SMITHY_CLIENT_CHECKSUM); },
204+
[](Aws::IOStream& stream) { return HashingUtils::Base64Encode(HashingUtils::CalculateSHA256(stream)); },
205+
Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_SHA256}},
206+
{"sha1",
207+
{[]() { return Aws::MakeShared<Sha1>(AWS_SMITHY_CLIENT_CHECKSUM); },
208+
[](Aws::IOStream& stream) { return HashingUtils::Base64Encode(HashingUtils::CalculateSHA1(stream)); },
209+
Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_SHA1}}
210+
};
211+
212+
auto it = algorithmMap.find(algorithm);
213+
if (it == algorithmMap.end()) {
214+
AWS_LOGSTREAM_WARN(AWS_SMITHY_CLIENT_CHECKSUM, "Checksum algorithm: " << algorithm << " is not supported by SDK.");
215+
return;
216+
}
217+
218+
request.AddUserAgentFeature(it->second.userAgentFeature);
219+
220+
if (request.IsStreaming()) {
221+
if (httpRequest->GetRequestHash().second == nullptr) {
222+
httpRequest->SetRequestHash(algorithm, it->second.createHash());
223+
}
224+
} else {
225+
httpRequest->SetHeaderValue(checksumType, it->second.calculateHash(*GetBodyStream(request)));
226+
}
227+
}
228+
229+
void SetResponseChecksum(const Aws::AmazonWebServiceRequest& request, std::shared_ptr<Aws::Http::HttpRequest> httpRequest) {
230+
for (const Aws::String& responseChecksumAlgorithmName : request.GetResponseChecksumAlgorithmNames()) {
231+
const auto responseChecksum = Aws::Utils::StringUtils::ToLower(responseChecksumAlgorithmName.c_str());
232+
if (responseChecksum == "crc32c") {
233+
std::shared_ptr<CRC32C> crc32c = Aws::MakeShared<CRC32C>(AWS_SMITHY_CLIENT_CHECKSUM);
234+
httpRequest->AddResponseValidationHash("crc32c", crc32c);
235+
} else if (responseChecksum == "crc32") {
236+
std::shared_ptr<CRC32> crc32 = Aws::MakeShared<CRC32>(AWS_SMITHY_CLIENT_CHECKSUM);
237+
httpRequest->AddResponseValidationHash("crc32", crc32);
238+
} else if (responseChecksum == "sha1") {
239+
std::shared_ptr<Sha1> sha1 = Aws::MakeShared<Sha1>(AWS_SMITHY_CLIENT_CHECKSUM);
240+
httpRequest->AddResponseValidationHash("sha1", sha1);
241+
} else if (responseChecksum == "sha256") {
242+
std::shared_ptr<Sha256> sha256 = Aws::MakeShared<Sha256>(AWS_SMITHY_CLIENT_CHECKSUM);
243+
httpRequest->AddResponseValidationHash("sha256", sha256);
244+
} else if (responseChecksum == "crc64nvme") {
245+
std::shared_ptr<CRC64> crc64 = Aws::MakeShared<CRC64>(AWS_SMITHY_CLIENT_CHECKSUM);
246+
httpRequest->AddResponseValidationHash("crc64nvme", crc64);
247+
} else {
248+
AWS_LOGSTREAM_WARN(AWS_SMITHY_CLIENT_CHECKSUM,
249+
"Checksum algorithm: " << responseChecksum << " is not supported in validating response body yet.");
250+
}
251+
}
252+
// we have to set the checksum mode to enabled if it was not previously
253+
httpRequest->SetHeaderValue("x-amz-checksum-mode", "enabled");
254+
}
255+
256+
struct ChecksumHandler {
257+
std::function<std::shared_ptr<Aws::Utils::Crypto::Hash>()> createHash;
258+
std::function<Aws::String(Aws::IOStream&)> calculateHash;
259+
Aws::Client::UserAgentFeature userAgentFeature;
260+
};
261+
243262
RequestChecksumCalculation m_requestChecksumCalculation{RequestChecksumCalculation::WHEN_SUPPORTED};
244263
ResponseChecksumValidation m_responseChecksumValidation{ResponseChecksumValidation::WHEN_SUPPORTED};
245264
};

0 commit comments

Comments
 (0)