ModifyRequestOutcome ModifyBeforeSigning()

in src/aws-cpp-sdk-core/include/smithy/client/features/ChecksumInterceptor.h [61:163]


  ModifyRequestOutcome ModifyBeforeSigning(interceptor::InterceptorContext& context) override {
    const auto& httpRequest = context.GetTransmitRequest();
    const auto& request = context.GetModeledRequest();
    if (httpRequest == nullptr) {
      return Aws::Client::AWSError<Aws::Client::CoreErrors>{Aws::Client::CoreErrors::VALIDATION, "ValidationErrorException",
                                                            "Checksum request validation missing request", false};
    }

    // Add RequestChecksum
    addChecksumConfigurationFeatures(request);
    if ((!request.GetChecksumAlgorithmName().empty() && m_requestChecksumCalculation == RequestChecksumCalculation::WHEN_SUPPORTED) ||
        request.RequestChecksumRequired()) {
      Aws::String checksumAlgorithmName = Aws::Utils::StringUtils::ToLower(request.GetChecksumAlgorithmName().c_str());
      // Check if user has provided the checksum algorithm
      if (!checksumAlgorithmName.empty()) {
        // Check if user has provided a checksum value for the specified algorithm
        const Aws::String checksumType = "x-amz-checksum-" + checksumAlgorithmName;
        const HeaderValueCollection& headers = request.GetHeaders();
        const auto checksumHeader = headers.find(checksumType);
        bool checksumValueAndAlgorithmProvided = checksumHeader != headers.end();

        // For non-streaming payload, the resolved checksum location is always header.
        // For streaming payload, the resolved checksum location depends on whether it is an unsigned payload, we let
        // AwsAuthSigner decide it.
        if (request.IsStreaming() && checksumValueAndAlgorithmProvided) {
          addChecksumFeatureForChecksumName(checksumAlgorithmName, request);
          const auto hash = Aws::MakeShared<PrecalculatedHash>(AWS_SMITHY_CLIENT_CHECKSUM, checksumHeader->second);
          httpRequest->SetRequestHash(checksumAlgorithmName, hash);
        } else if (checksumValueAndAlgorithmProvided) {
          httpRequest->SetHeaderValue(checksumType, checksumHeader->second);
        } else if (checksumAlgorithmName == "crc64nvme") {
          request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC64);
          if (request.IsStreaming()) {
            httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<CRC64>(AWS_SMITHY_CLIENT_CHECKSUM));
          } else {
            httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateCRC64(*(GetBodyStream(request)))));
          }
        } else if (checksumAlgorithmName == "crc32") {
          request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC32);
          if (request.IsStreaming()) {
            httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<CRC32>(AWS_SMITHY_CLIENT_CHECKSUM));
          } else {
            httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateCRC32(*(GetBodyStream(request)))));
          }
        } else if (checksumAlgorithmName == "crc32c") {
          request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_CRC32C);
          if (request.IsStreaming()) {
            httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<CRC32C>(AWS_SMITHY_CLIENT_CHECKSUM));
          } else {
            httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateCRC32C(*(GetBodyStream(request)))));
          }
        } else if (checksumAlgorithmName == "sha256") {
          request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_SHA256);
          if (request.IsStreaming()) {
            httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<Sha256>(AWS_SMITHY_CLIENT_CHECKSUM));
          } else {
            httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateSHA256(*(GetBodyStream(request)))));
          }
        } else if (checksumAlgorithmName == "sha1") {
          request.AddUserAgentFeature(Aws::Client::UserAgentFeature::FLEXIBLE_CHECKSUMS_REQ_SHA1);
          if (request.IsStreaming()) {
            httpRequest->SetRequestHash(checksumAlgorithmName, Aws::MakeShared<Sha1>(AWS_SMITHY_CLIENT_CHECKSUM));
          } else {
            httpRequest->SetHeaderValue(checksumType, HashingUtils::Base64Encode(HashingUtils::CalculateSHA1(*(GetBodyStream(request)))));
          }
        } else {
          AWS_LOGSTREAM_WARN(AWS_SMITHY_CLIENT_CHECKSUM, "Checksum algorithm: " << checksumAlgorithmName << "is not supported by SDK.");
        }
      }
    }

    // Add response checksum
    if ((!request.GetResponseChecksumAlgorithmNames().empty() &&
         m_responseChecksumValidation == ResponseChecksumValidation::WHEN_SUPPORTED) ||
        request.ShouldValidateResponseChecksum()) {
      for (const Aws::String& responseChecksumAlgorithmName : request.GetResponseChecksumAlgorithmNames()) {
        const auto responseChecksum = Aws::Utils::StringUtils::ToLower(responseChecksumAlgorithmName.c_str());
        if (responseChecksum == "crc32c") {
          std::shared_ptr<CRC32C> crc32c = Aws::MakeShared<CRC32C>(AWS_SMITHY_CLIENT_CHECKSUM);
          httpRequest->AddResponseValidationHash("crc32c", crc32c);
        } else if (responseChecksum == "crc32") {
          std::shared_ptr<CRC32> crc32 = Aws::MakeShared<CRC32>(AWS_SMITHY_CLIENT_CHECKSUM);
          httpRequest->AddResponseValidationHash("crc32", crc32);
        } else if (responseChecksum == "sha1") {
          std::shared_ptr<Sha1> sha1 = Aws::MakeShared<Sha1>(AWS_SMITHY_CLIENT_CHECKSUM);
          httpRequest->AddResponseValidationHash("sha1", sha1);
        } else if (responseChecksum == "sha256") {
          std::shared_ptr<Sha256> sha256 = Aws::MakeShared<Sha256>(AWS_SMITHY_CLIENT_CHECKSUM);
          httpRequest->AddResponseValidationHash("sha256", sha256);
        } else if (responseChecksum == "crc64nvme") {
          std::shared_ptr<CRC64> crc64 = Aws::MakeShared<CRC64>(AWS_SMITHY_CLIENT_CHECKSUM);
          httpRequest->AddResponseValidationHash("crc64nvme", crc64);
        } else {
          AWS_LOGSTREAM_WARN(AWS_SMITHY_CLIENT_CHECKSUM,
                             "Checksum algorithm: " << responseChecksum << " is not supported in validating response body yet.");
        }
      }
      // we have to set the checksum mode to enabled if it was not previously
      httpRequest->SetHeaderValue("x-amz-checksum-mode", "enabled");
    }

    return httpRequest;
  }