8#include <aws/core/AmazonWebServiceRequest.h>
9#include <aws/core/http/HttpRequest.h>
10#include <aws/core/http/HttpResponse.h>
11#include <aws/core/utils/HashingUtils.h>
12#include <aws/core/utils/crypto/CRC32.h>
13#include <aws/core/utils/crypto/CRC64.h>
14#include <aws/core/utils/crypto/MD5.h>
15#include <aws/core/utils/crypto/PrecalculatedHash.h>
16#include <aws/core/utils/crypto/Sha1.h>
17#include <aws/core/utils/crypto/Sha256.h>
18#include <smithy/interceptor/Interceptor.h>
44 : m_requestChecksumCalculation(configuration.checksumConfig.requestChecksumCalculation),
45 m_responseChecksumValidation(configuration.checksumConfig.responseChecksumValidation) {}
54 if (request.
GetBody() !=
nullptr) {
64 if (httpRequest ==
nullptr) {
66 "Checksum request validation missing request",
false};
70 addChecksumConfigurationFeatures(request);
71 if ((!request.GetChecksumAlgorithmName().empty() && m_requestChecksumCalculation == RequestChecksumCalculation::WHEN_SUPPORTED) ||
72 request.RequestChecksumRequired()) {
75 if (!checksumAlgorithmName.empty()) {
77 const Aws::String checksumType =
"x-amz-checksum-" + checksumAlgorithmName;
79 const auto checksumHeader = headers.find(checksumType);
80 bool checksumValueAndAlgorithmProvided = checksumHeader != headers.end();
85 if (request.IsStreaming() && checksumValueAndAlgorithmProvided) {
86 addChecksumFeatureForChecksumName(checksumAlgorithmName, request);
88 httpRequest->SetRequestHash(checksumAlgorithmName, hash);
89 }
else if (checksumValueAndAlgorithmProvided) {
90 httpRequest->SetHeaderValue(checksumType, checksumHeader->second);
91 }
else if (checksumAlgorithmName ==
"crc64nvme") {
93 if (request.IsStreaming()) {
98 }
else if (checksumAlgorithmName ==
"crc32") {
100 if (request.IsStreaming()) {
105 }
else if (checksumAlgorithmName ==
"crc32c") {
107 if (request.IsStreaming()) {
112 }
else if (checksumAlgorithmName ==
"sha256") {
114 if (request.IsStreaming()) {
119 }
else if (checksumAlgorithmName ==
"sha1") {
121 if (request.IsStreaming()) {
127 AWS_LOGSTREAM_WARN(
AWS_SMITHY_CLIENT_CHECKSUM,
"Checksum algorithm: " << checksumAlgorithmName <<
"is not supported by SDK.");
133 if ((!request.GetResponseChecksumAlgorithmNames().empty() &&
134 m_responseChecksumValidation == ResponseChecksumValidation::WHEN_SUPPORTED) ||
135 request.ShouldValidateResponseChecksum()) {
136 for (
const Aws::String& responseChecksumAlgorithmName : request.GetResponseChecksumAlgorithmNames()) {
138 if (responseChecksum ==
"crc32c") {
140 httpRequest->AddResponseValidationHash(
"crc32c", crc32c);
141 }
else if (responseChecksum ==
"crc32") {
143 httpRequest->AddResponseValidationHash(
"crc32", crc32);
144 }
else if (responseChecksum ==
"sha1") {
146 httpRequest->AddResponseValidationHash(
"sha1", sha1);
147 }
else if (responseChecksum ==
"sha256") {
149 httpRequest->AddResponseValidationHash(
"sha256", sha256);
150 }
else if (responseChecksum ==
"crc64nvme") {
152 httpRequest->AddResponseValidationHash(
"crc64nvme", crc64);
155 "Checksum algorithm: " << responseChecksum <<
" is not supported in validating response body yet.");
159 httpRequest->SetHeaderValue(
"x-amz-checksum-mode",
"enabled");
168 if (httpRequest ==
nullptr || httpResponse ==
nullptr) {
170 "Checksum response validation missing request or response",
false};
172 for (
const auto& hashIterator : httpRequest->GetResponseValidationHashes()) {
175 if (httpResponse->HasHeader(checksumHeaderKey.c_str())) {
176 const Aws::String& checksumHeaderValue = httpResponse->GetHeader(checksumHeaderKey);
179 "Response checksums mismatch",
false };
181 error.SetResponseCode(httpResponse->GetResponseCode());
182 error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost());
189 << httpRequest->GetURIString()
190 <<
" using checksum algorithm: " << hashIterator.first);
199 if (checksumName ==
"crc32") {
201 }
else if (checksumName ==
"crc32c") {
203 }
else if (checksumName ==
"crc64") {
205 }
else if (checksumName ==
"sha1") {
207 }
else if (checksumName ==
"sha256") {
215 switch (m_requestChecksumCalculation) {
218 default: AWS_LOG_ERROR(
AWS_SMITHY_CLIENT_CHECKSUM,
"could not add useragent feature for checksum request configuration");
break;
221 switch (m_responseChecksumValidation) {
224 default: AWS_LOG_ERROR(
AWS_SMITHY_CLIENT_CHECKSUM,
"could not add useragent feature for checksum response configuration");
break;
virtual std::shared_ptr< Aws::IOStream > GetBody() const =0
void AddUserAgentFeature(Aws::Client::UserAgentFeature feature) const
void SetResponseHeaders(const Aws::Http::HeaderValueCollection &headers)
static ByteBuffer CalculateCRC32(const Aws::String &str)
static Aws::String Base64Encode(const ByteBuffer &byteBuffer)
static ByteBuffer CalculateCRC64(const Aws::String &str)
static ByteBuffer CalculateSHA1(const Aws::String &str)
static ByteBuffer CalculateCRC32C(const Aws::String &str)
static ByteBuffer CalculateSHA256(const Aws::String &str)
static Aws::String ToLower(const char *source)
Aws::Http::HeaderValueCollection HeaderValueCollection
ChecksumInterceptor(const ChecksumInterceptor &other)=delete
ChecksumInterceptor & operator=(ChecksumInterceptor &&other) noexcept=default
ChecksumInterceptor()=default
ModifyRequestOutcome ModifyBeforeSigning(interceptor::InterceptorContext &context) override
ChecksumInterceptor & operator=(const ChecksumInterceptor &other)=delete
ModifyResponseOutcome ModifyBeforeDeserialization(interceptor::InterceptorContext &context) override
Aws::Client::RequestChecksumCalculation RequestChecksumCalculation
~ChecksumInterceptor() override=default
static std::shared_ptr< Aws::IOStream > GetBodyStream(const Aws::AmazonWebServiceRequest &request)
Aws::Client::ResponseChecksumValidation ResponseChecksumValidation
ChecksumInterceptor(ChecksumInterceptor &&other) noexcept=default
ChecksumInterceptor(const ClientConfiguration &configuration)
const Aws::AmazonWebServiceRequest & GetModeledRequest() const
std::shared_ptr< Aws::Http::HttpRequest > GetTransmitRequest() const
std::shared_ptr< Aws::Http::HttpResponse > GetTransmitResponse() const
RequestChecksumCalculation
ResponseChecksumValidation
@ FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED
@ FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED
@ FLEXIBLE_CHECKSUMS_REQ_CRC64
@ FLEXIBLE_CHECKSUMS_REQ_CRC32C
@ FLEXIBLE_CHECKSUMS_REQ_SHA1
@ FLEXIBLE_CHECKSUMS_REQ_CRC32
@ FLEXIBLE_CHECKSUMS_REQ_SHA256
@ FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED
@ FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED
Aws::Map< Aws::String, Aws::String > HeaderValueCollection
std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > > String
static const char AWS_SMITHY_CLIENT_CHECKSUM[]
static const char CHECKSUM_CONTENT_MD5_HEADER[]