From 452351a93a49aff15fd0e44d022f802fd53899f3 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 10:24:19 -0700 Subject: [PATCH 01/23] Add requestChecksumCalculation and responseChecksumValidation configs & AWSChecksumCalculationMode enum type for both config options. --- .../AWSDefaultClientConfiguration.swift | 19 +++++++++++++++ .../AWSChecksumCalculationMode.swift | 24 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/AWSChecksumCalculationMode.swift diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Config/AWSDefaultClientConfiguration.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Config/AWSDefaultClientConfiguration.swift index f94f82ac728..dec432b3142 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Config/AWSDefaultClientConfiguration.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Config/AWSDefaultClientConfiguration.swift @@ -7,6 +7,7 @@ import SmithyIdentity import SmithyIdentityAPI +import enum AWSSDKChecksums.AWSChecksumCalculationMode public protocol AWSDefaultClientConfiguration { /// The AWS credential identity resolver to be used for AWS credentials. @@ -45,4 +46,22 @@ public protocol AWSDefaultClientConfiguration { /// /// If set, this value gets used when resolving max attempts value from the standard progression of potential sources. If no value could be resolved, the SDK uses max attempts value of 3 by default. var maxAttempts: Int? { get set } + + /// The AWS request checksum calculation mode to use. + /// + /// If `.whenRequired`, the client calculates checksum for the request payload only if the operation requires it. + /// If `.whenSupported`, the client calculates checksum for the request payload if the operation supports it. + /// + /// Default mode is `.whenSupported`. + /// + /// If no algorithm was chosen and no checksum was provided, CRC32 checksum algorithm is used by default. + var requestChecksumCalculation: AWSChecksumCalculationMode { get set } + + /// The AWS response checksum calculation mode to use. + /// + /// If `.whenRequired`, the client validates checksum of the response only if the top-level input field for `requestValidationModeMember` is set to `.enabled` and SDK supports the checksum algorithm. + /// If `.whenSupported`, the client validates checksum of the response if the operation supports it and SDK supports at least one of the checksum algorithms returend by service. + /// + /// Default mode is `.whenSupported`. + var responseChecksumValidation: AWSChecksumCalculationMode { get set } } diff --git a/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/AWSChecksumCalculationMode.swift b/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/AWSChecksumCalculationMode.swift new file mode 100644 index 00000000000..70c2d490cf9 --- /dev/null +++ b/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/AWSChecksumCalculationMode.swift @@ -0,0 +1,24 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +public enum AWSChecksumCalculationMode: String { + case whenRequired = "when_required" + case whenSupported = "when_supported" + + public init?(caseInsensitiveRawValue: String) { + let lowercasedValue = caseInsensitiveRawValue.lowercased() + + switch lowercasedValue { + case AWSChecksumCalculationMode.whenRequired.rawValue: + self = .whenRequired + case AWSChecksumCalculationMode.whenSupported.rawValue: + self = .whenSupported + default: + return nil + } + } +} From 5e736d2c680d45061986275696cc65634ca2862d Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 10:26:35 -0700 Subject: [PATCH 02/23] Add value resolvers for requestChecksumCalculation and responseChecksumValidation config options. --- .../AWSClientConfigDefaultsProvider.swift | 35 ++++++++++++++++ .../Config/AWSChecksumsConfig.swift | 41 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Config/AWSChecksumsConfig.swift diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/AWSClientConfigDefaultsProvider.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/AWSClientConfigDefaultsProvider.swift index a404faef401..8ac9fc5efd6 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/AWSClientConfigDefaultsProvider.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/AWSClientConfigDefaultsProvider.swift @@ -18,6 +18,7 @@ import enum ClientRuntime.ClientLogMode import struct SmithyRetries.DefaultRetryStrategy import struct SmithyRetries.ExponentialBackoffStrategy import struct SmithyRetriesAPI.RetryStrategyOptions +import enum AWSSDKChecksums.AWSChecksumCalculationMode typealias RuntimeConfigType = DefaultSDKRuntimeConfiguration @@ -84,6 +85,40 @@ public class AWSClientConfigDefaultsProvider { return resolvedAppID } + public static func requestChecksumCalculation( + _ requestChecksumCalculation: AWSChecksumCalculationMode? = nil + ) throws -> AWSChecksumCalculationMode { + let fileBasedConfig = try CRTFileBasedConfiguration.make() + let resolvedRequestChecksumCalculation: AWSChecksumCalculationMode + if let requestChecksumCalculation { + resolvedRequestChecksumCalculation = requestChecksumCalculation + } else { + resolvedRequestChecksumCalculation = AWSChecksumsConfig.requestChecksumCalculation( + configValue: nil, + profileName: nil, + fileBasedConfig: fileBasedConfig + ) + } + return resolvedRequestChecksumCalculation + } + + public static func responseChecksumValidation( + _ responseChecksumValidation: AWSChecksumCalculationMode? = nil + ) throws -> AWSChecksumCalculationMode { + let fileBasedConfig = try CRTFileBasedConfiguration.make() + let resolvedResponseChecksumValidation: AWSChecksumCalculationMode + if let responseChecksumValidation { + resolvedResponseChecksumValidation = responseChecksumValidation + } else { + resolvedResponseChecksumValidation = AWSChecksumsConfig.responseChecksumValidation( + configValue: nil, + profileName: nil, + fileBasedConfig: fileBasedConfig + ) + } + return resolvedResponseChecksumValidation + } + public static func retryMode(_ retryMode: AWSRetryMode? = nil) throws -> AWSRetryMode { let fileBasedConfig = try CRTFileBasedConfiguration.make() let resolvedRetryMode: AWSRetryMode? diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Config/AWSChecksumsConfig.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Config/AWSChecksumsConfig.swift new file mode 100644 index 00000000000..530041eeecc --- /dev/null +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Config/AWSChecksumsConfig.swift @@ -0,0 +1,41 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import enum AWSSDKChecksums.AWSChecksumCalculationMode +@_spi(FileBasedConfig) import AWSSDKCommon + +public enum AWSChecksumsConfig { + static func requestChecksumCalculation( + configValue: AWSChecksumCalculationMode?, + profileName: String?, + fileBasedConfig: FileBasedConfiguration + ) -> AWSChecksumCalculationMode { + return FieldResolver( + configValue: configValue, + envVarName: "AWS_REQUEST_CHECKSUM_CALCULATION", + configFieldName: "request_checksum_calculation", + fileBasedConfig: fileBasedConfig, + profileName: profileName, + converter: { AWSChecksumCalculationMode(caseInsensitiveRawValue: $0) } + ).value ?? .whenSupported + } + + static func responseChecksumValidation( + configValue: AWSChecksumCalculationMode?, + profileName: String?, + fileBasedConfig: FileBasedConfiguration + ) -> AWSChecksumCalculationMode { + return FieldResolver( + configValue: configValue, + envVarName: "AWS_RESPONSE_CHECKSUM_VALIDATION", + configFieldName: "response_checksum_validation", + fileBasedConfig: fileBasedConfig, + profileName: profileName, + converter: { AWSChecksumCalculationMode(caseInsensitiveRawValue: $0) } + ).value ?? .whenSupported + } +} From 780e3f31cc945ca2eb7336d5b4bcb99186fc1f00 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 10:49:32 -0700 Subject: [PATCH 03/23] Add requestChecksumCalculation and responseChecksumValidation configs to codegen side; add type info for AWSChecksumCalculationMode to codegen side. --- .../aws/swift/codegen/AWSSwiftDependency.kt | 9 +++++++++ .../config/AWSDefaultClientConfiguration.kt | 15 ++++++++++++++- .../swiftmodules/AWSSDKChecksumsTypes.kt | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/swiftmodules/AWSSDKChecksumsTypes.kt diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSSwiftDependency.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSSwiftDependency.kt index 0d1dcdcf80a..cbc42b08bc3 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSSwiftDependency.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSSwiftDependency.kt @@ -8,6 +8,15 @@ import software.amazon.smithy.swift.codegen.SwiftDependency class AWSSwiftDependency { companion object { + val AWS_SDK_CHECKSUMS = SwiftDependency( + "AWSSDKChecksums", + "main", + "0.0.1", + "aws-sdk-swift", + "../../../aws-sdk-swift", + "AWSSDKChecksums", + SwiftDependency.DistributionMethod.SPR, + ) val AWS_SDK_IDENTITY = SwiftDependency( "AWSSDKIdentity", "main", diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/config/AWSDefaultClientConfiguration.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/config/AWSDefaultClientConfiguration.kt index fbe32df636b..cef14523dda 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/config/AWSDefaultClientConfiguration.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/config/AWSDefaultClientConfiguration.kt @@ -6,6 +6,7 @@ package software.amazon.smithy.aws.swift.codegen.config import software.amazon.smithy.aws.swift.codegen.swiftmodules.AWSClientRuntimeTypes +import software.amazon.smithy.aws.swift.codegen.swiftmodules.AWSSDKChecksumsTypes import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.swift.codegen.config.ClientConfiguration import software.amazon.smithy.swift.codegen.config.ConfigProperty @@ -39,6 +40,18 @@ class AWSDefaultClientConfiguration : ClientConfiguration { { it.format("\$N.retryMode()", AWSClientRuntimeTypes.Core.AWSClientConfigDefaultsProvider) }, true ), - ConfigProperty("maxAttempts", SwiftTypes.Int.toOptional()) + ConfigProperty("maxAttempts", SwiftTypes.Int.toOptional()), + ConfigProperty( + "requestChecksumCalculation", + AWSSDKChecksumsTypes.AWSChecksumCalculationMode, + { it.format("\$N.requestChecksumCalculation(requestChecksumCalculation)", AWSClientRuntimeTypes.Core.AWSClientConfigDefaultsProvider) }, + true + ), + ConfigProperty( + "responseChecksumValidation", + AWSSDKChecksumsTypes.AWSChecksumCalculationMode, + { it.format("\$N.responseChecksumValidation(responseChecksumValidation)", AWSClientRuntimeTypes.Core.AWSClientConfigDefaultsProvider) }, + true + ), ) } diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/swiftmodules/AWSSDKChecksumsTypes.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/swiftmodules/AWSSDKChecksumsTypes.kt new file mode 100644 index 00000000000..e4b50b3fdab --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/swiftmodules/AWSSDKChecksumsTypes.kt @@ -0,0 +1,18 @@ +package software.amazon.smithy.aws.swift.codegen.swiftmodules + +import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency +import software.amazon.smithy.codegen.core.Symbol +import software.amazon.smithy.swift.codegen.SwiftDeclaration +import software.amazon.smithy.swift.codegen.swiftmodules.SwiftSymbol + +object AWSSDKChecksumsTypes { + val AWSChecksumCalculationMode = runtimeSymbol("AWSChecksumCalculationMode", SwiftDeclaration.ENUM) +} + +private fun runtimeSymbol(name: String, declaration: SwiftDeclaration? = null): Symbol = SwiftSymbol.make( + name, + declaration, + AWSSwiftDependency.AWS_SDK_CHECKSUMS, + emptyList(), + emptyList(), +) From 8fba8dd25970c127b40a1cab1e20198fe29baafd Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 10:50:53 -0700 Subject: [PATCH 04/23] Add context extension for getting and setting the new config options; use this in setter codegen. --- .../AWSSDKChecksums/Context+Checksum.swift | 39 +++++++++++++++++++ .../codegen/AWSHTTPProtocolCustomizations.kt | 2 + 2 files changed, 41 insertions(+) create mode 100644 Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/Context+Checksum.swift diff --git a/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/Context+Checksum.swift b/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/Context+Checksum.swift new file mode 100644 index 00000000000..5d11b342427 --- /dev/null +++ b/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/Context+Checksum.swift @@ -0,0 +1,39 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import class Smithy.Context +import class Smithy.ContextBuilder +import struct Smithy.AttributeKey + +public extension Context { + var requestChecksumCalculation: AWSChecksumCalculationMode { + get { attributes.get(key: requestChecksumCalculationKey) ?? .whenSupported } + set { attributes.set(key: requestChecksumCalculationKey, value: newValue) } + } + + var responseChecksumValidation: AWSChecksumCalculationMode { + get { attributes.get(key: responseChecksumValidationKey) ?? .whenSupported } + set { attributes.set(key: responseChecksumValidationKey, value: newValue) } + } +} + +public extension ContextBuilder { + @discardableResult + func withRequestChecksumCalculation(value: AWSChecksumCalculationMode) -> Self { + self.attributes.set(key: requestChecksumCalculationKey, value: value) + return self + } + + @discardableResult + func withResponseChecksumValidation(value: AWSChecksumCalculationMode) -> Self { + self.attributes.set(key: responseChecksumValidationKey, value: value) + return self + } +} + +private let requestChecksumCalculationKey = AttributeKey(name: "requestChecksumCalculation") +private let responseChecksumValidationKey = AttributeKey(name: "responseChecksumValidation") diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHTTPProtocolCustomizations.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHTTPProtocolCustomizations.kt index 5e03894b2b9..e3c37fef9ba 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHTTPProtocolCustomizations.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHTTPProtocolCustomizations.kt @@ -30,6 +30,8 @@ abstract class AWSHTTPProtocolCustomizations : DefaultHTTPProtocolCustomizations writer.write(" .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: \$S)", "aws.auth#sigv4") writer.write(" .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: \$S)", "aws.auth#sigv4a") writer.write(" .withRegion(value: config.region)") + writer.write(" .withRequestChecksumCalculation(value: config.requestChecksumCalculation)") + writer.write(" .withResponseChecksumValidation(value: config.responseChecksumValidation)") if (AWSAuthUtils.hasSigV4AuthScheme(ctx.model, ctx.service, op)) { val signingName = AWSAuthUtils.signingServiceName(serviceShape) writer.write(" .withSigningName(value: \$S)", signingName) From 6922099b2603ad10e1be35bab92531a35d377be3 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 10:52:55 -0700 Subject: [PATCH 05/23] Clean up flexchex request middleware conditionals into one logical flow and add in default algorithm selection logic. --- .../FlexibleChecksumsRequestMiddleware.swift | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift index fce7a9b79f8..89db9586682 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift @@ -18,9 +18,11 @@ public struct FlexibleChecksumsRequestMiddleware Date: Wed, 23 Oct 2024 10:54:50 -0700 Subject: [PATCH 06/23] Fix validation mode logic in flexchex response middleware; now it uses user input as it's supposed to. --- .../FlexibleChecksumsResponseMiddleware.swift | 6 +++--- .../FlexibleChecksumsResponseIntegration.kt | 10 +++------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsResponseMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsResponseMiddleware.swift index b4b4ba23c55..1b4deead2f3 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsResponseMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsResponseMiddleware.swift @@ -19,10 +19,10 @@ public struct FlexibleChecksumsResponseMiddleware(validationMode: \$L)", + "\$N<\$L, \$L>(validationMode: input.\$L?.rawValue ?? \"unset\")", AWSClientRuntimeTypes.Core.FlexibleChecksumsResponseMiddleware, inputShapeName, outputShapeName, - validationMode, + validationModeMemberName, ) } } From 5206a1ee077a83c7094cfb7f15d46b0cdcab911c Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 10:55:54 -0700 Subject: [PATCH 07/23] Update flexchex request middleware codegen to pass in request checksum required flag to initializer. --- .../FlexibleChecksumsRequestIntegration.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/flexiblechecksums/FlexibleChecksumsRequestIntegration.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/flexiblechecksums/FlexibleChecksumsRequestIntegration.kt index 51fe7441fe9..c76b3b2d834 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/flexiblechecksums/FlexibleChecksumsRequestIntegration.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/flexiblechecksums/FlexibleChecksumsRequestIntegration.kt @@ -38,7 +38,7 @@ class FlexibleChecksumsRequestIntegration : SwiftIntegration { } } -private fun String.lowercaseFirstLetter(): String = +fun String.lowercaseFirstLetter(): String = takeIf { it.isNotEmpty() }?.let { it.first().lowercase() + it.substring(1) } ?: this private object FlexibleChecksumRequestMiddleware : MiddlewareRenderable { @@ -52,14 +52,16 @@ private object FlexibleChecksumRequestMiddleware : MiddlewareRenderable { val inputShapeName = MiddlewareShapeUtils.inputSymbol(ctx.symbolProvider, ctx.model, op).name val outputShapeName = MiddlewareShapeUtils.outputSymbol(ctx.symbolProvider, ctx.model, op).name val httpChecksumTrait = op.getTrait(HttpChecksumTrait::class.java).orElse(null) - val inputMemberName = httpChecksumTrait?.requestAlgorithmMember?.get()?.lowercaseFirstLetter() + val algorithmMemberName = httpChecksumTrait?.requestAlgorithmMember?.get()?.lowercaseFirstLetter() + val requestChecksumIsRequired = httpChecksumTrait?.isRequestChecksumRequired writer.write( - "\$N<\$L, \$L>(checksumAlgorithm: input.\$L?.rawValue)", + "\$N<\$L, \$L>(requestChecksumRequired: \$L, checksumAlgorithm: input.\$L?.rawValue)", AWSClientRuntimeTypes.Core.FlexibleChecksumsRequestMiddleware, inputShapeName, outputShapeName, - inputMemberName, + requestChecksumIsRequired, + algorithmMemberName, ) } } From 436757ae04bd19f8717c1a828c766dc8f11b5702 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 10:57:43 -0700 Subject: [PATCH 08/23] Update runtime tests for flexchex middlewares + add a test for no request checksum calculation flow. --- .../FlexibleChecksumsMiddlewareTests.swift | 89 +++++++++++-------- 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift b/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift index 508cea05379..e3b8786a065 100644 --- a/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift +++ b/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift @@ -33,6 +33,8 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { .withPath(value: "/") .withOperation(value: "Test Operation") .withLogger(value: testLogger) + .withRequestChecksumCalculation(value: .whenSupported) + .withResponseChecksumValidation(value: .whenSupported) .build() var metricsAttributes = Attributes() metricsAttributes.set(key: OrchestratorMetricsAttributesKeys.service, value: "Service") @@ -49,8 +51,8 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { let checksumAlgorithm = "sha256" let testData = ByteStream.data(Data("Hello, world!".utf8)) setNormalPayload(payload: testData) - addFlexibleChecksumsRequestMiddleware(checksumAlgorithm: checksumAlgorithm) - addFlexibleChecksumsResponseMiddleware(validationMode: true) + addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) + addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertHeaderIsPresentAndValidationOccurs( expectedHeader: "x-amz-checksum-sha256", responseBody: testData, @@ -62,8 +64,8 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { let checksumAlgorithm = "sha1" let testData = ByteStream.data(Data("Hello, world!".utf8)) setNormalPayload(payload: testData) - addFlexibleChecksumsRequestMiddleware(checksumAlgorithm: checksumAlgorithm) - addFlexibleChecksumsResponseMiddleware(validationMode: true) + addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) + addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertHeaderIsPresentAndValidationOccurs( expectedHeader: "x-amz-checksum-sha1", responseBody: testData, @@ -75,8 +77,8 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { let checksumAlgorithm = "crc32" let testData = ByteStream.data(Data("Hello, world!".utf8)) setNormalPayload(payload: testData) - addFlexibleChecksumsRequestMiddleware(checksumAlgorithm: checksumAlgorithm) - addFlexibleChecksumsResponseMiddleware(validationMode: true) + addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) + addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertHeaderIsPresentAndValidationOccurs( expectedHeader: "x-amz-checksum-crc32", responseBody: testData, @@ -88,8 +90,8 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { let checksumAlgorithm = "crc32c" let testData = ByteStream.data(Data("Hello, world!".utf8)) setNormalPayload(payload: testData) - addFlexibleChecksumsRequestMiddleware(checksumAlgorithm: checksumAlgorithm) - addFlexibleChecksumsResponseMiddleware(validationMode: true) + addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) + addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertHeaderIsPresentAndValidationOccurs( expectedHeader: "x-amz-checksum-crc32c", responseBody: testData, @@ -97,24 +99,39 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { ) } - func testNilChecksumAlgorithm() async throws { + func testUseDefaultChecksumAlgorithm() async throws { let testData = ByteStream.data(Data("Hello, world!".utf8)) setNormalPayload(payload: testData) - addFlexibleChecksumsRequestMiddleware(checksumAlgorithm: nil) - addFlexibleChecksumsResponseMiddleware(validationMode: false) + addFlexibleChecksumsRequestMiddleware(false, nil) + addFlexibleChecksumsResponseMiddleware("unset") try await AssertHeaderIsPresentAndValidationOccurs( checkLogs: [ - "No checksum provided! Skipping flexible checksums workflow...", - "Checksum validation should not be performed! Skipping workflow..." + "No algorithm chosen by user. Defaulting to CRC32 checksum algorithm." ] ) } - private func addFlexibleChecksumsRequestMiddleware(checksumAlgorithm: String?) { - builder.interceptors.add(FlexibleChecksumsRequestMiddleware(checksumAlgorithm: checksumAlgorithm)) + func testNoRequestChecksumCalculation() async throws { + let testData = ByteStream.data(Data("Hello, world!".utf8)) + setNormalPayload(payload: testData) + // Change requestChecksumCalculation config to .whenRequired + builder.attributes.requestChecksumCalculation = .whenRequired + addFlexibleChecksumsRequestMiddleware(false, nil) + addFlexibleChecksumsResponseMiddleware("unset") + try await AssertHeaderIsPresentAndValidationOccurs( + checkLogs: [ + "Checksum not required for the operation.", + "Client config `requestChecksumCalculation` set to `.whenRequired`", + "No checksum algorithm chosen by the user. Skipping checksum calculation..." + ] + ) + } + + private func addFlexibleChecksumsRequestMiddleware(_ requestChecksumRequired: Bool, _ checksumAlgorithm: String?) { + builder.interceptors.add(FlexibleChecksumsRequestMiddleware(requestChecksumRequired: requestChecksumRequired, checksumAlgorithm: checksumAlgorithm)) } - private func addFlexibleChecksumsResponseMiddleware(validationMode: Bool, priorityList: [String] = []) { + private func addFlexibleChecksumsResponseMiddleware(_ validationMode: String, _ priorityList: [String] = []) { builder.interceptors.add(FlexibleChecksumsResponseMiddleware( validationMode: validationMode, priorityList: priorityList @@ -153,8 +170,8 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { setStreamingPayload(payload: testData, checksum: checksumAlgorithm) - addFlexibleChecksumsRequestMiddleware(checksumAlgorithm: checksumAlgorithm) - addFlexibleChecksumsResponseMiddleware(validationMode: true) + addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) + addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertionsWhenStreaming( expectedHeader: "x-amz-checksum-crc32", responseBody: testData, @@ -169,29 +186,29 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { func testAlgorithmSelectionCase1() async throws -> () { let colA = ["crc64", "crc32", "crc32c"] let colB = ["crc32c", "crc32"] - let validationMode = false + let validationMode = "unset" var colBHeaders = Headers() colB.forEach { checksum in - colBHeaders.add(name: "x-amz-checksum-\(checksum)", value: "AAAAA") + colBHeaders.add(name: "x-amz-checksum-\(checksum)", value: "yKEG5Q==") } - addFlexibleChecksumsResponseMiddleware(validationMode: validationMode, priorityList: colA) + addFlexibleChecksumsResponseMiddleware(validationMode, colA) try await AssertValidationAsExpected( responseHeaders: colBHeaders, - validationMode: validationMode, - expectedValidationHeader: nil + validationMode: true, // true since responseChecksumValidation is set to .whenSupported + expectedValidationHeader: "x-amz-checksum-crc32c" ) } func testAlgorithmSelectionCase2() async throws -> () { let colA = ["sha256", "crc32"] - let validationMode = true + let validationMode = "ENABLED" var colBHeaders = Headers() // Add only sha256 header in response colBHeaders.add(name: "x-amz-checksum-sha256", value: "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=") - addFlexibleChecksumsResponseMiddleware(validationMode: validationMode, priorityList: colA) + addFlexibleChecksumsResponseMiddleware(validationMode, colA) try await AssertValidationAsExpected( responseHeaders: colBHeaders, - validationMode: validationMode, + validationMode: true, expectedValidationHeader: "x-amz-checksum-sha256" ) } @@ -199,43 +216,43 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { func testAlgorithmSelectionCase3() async throws -> () { let colA = ["sha256", "crc32"] let colB = ["crc32", "sha256"] - let validationMode = true + let validationMode = "ENABLED" var colBHeaders = Headers() // Add both sha256 header and crc32 in response // Add expected crc32 checksum as value since it should take priority colB.forEach { checksum in colBHeaders.add(name: "x-amz-checksum-\(checksum)", value: "6+bG5g==") } - addFlexibleChecksumsResponseMiddleware(validationMode: validationMode, priorityList: colA) + addFlexibleChecksumsResponseMiddleware(validationMode, colA) try await AssertValidationAsExpected( responseHeaders: colBHeaders, - validationMode: validationMode, + validationMode: true, expectedValidationHeader: "x-amz-checksum-crc32" ) } func testAlgorithmSelectionCase4() async throws -> () { let colA = ["crc32", "crc32c"] - let validationMode = false + let validationMode = "unset" var colBHeaders = Headers() // crc64 is not modeled in the service so no validation should be perforemd, but we shouldnt error colBHeaders.add(name: "x-amz-checksum-crc64", value: "6+bG5g==") - addFlexibleChecksumsResponseMiddleware(validationMode: validationMode, priorityList: colA) + addFlexibleChecksumsResponseMiddleware(validationMode, colA) try await AssertValidationAsExpected( responseHeaders: colBHeaders, - validationMode: validationMode, + validationMode: false, expectedValidationHeader: nil ) } func getChecksumMismatchException() async throws -> () { - let validationMode = true + let validationMode = "ENABLED" var testHeaders = Headers() testHeaders.add(name: "x-amz-checksum-crc32", value: "AAAA==") - addFlexibleChecksumsResponseMiddleware(validationMode: validationMode) + addFlexibleChecksumsResponseMiddleware(validationMode) try await AssertValidationAsExpected( responseHeaders: testHeaders, - validationMode: validationMode, + validationMode: true, expectedValidationHeader: "x-amz-checksum-crc32", expectedChecksumMismatch: true ) @@ -355,7 +372,7 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { let expectedChecksumSHA256 = "ZOyIygCyaOW6GjVnihtTFtIS9PNmskdyMlNKiuyjfzw=" let signingConfig = SigningConfig(algorithm: .signingV4, signatureType: .requestHeaders, service: "S3", region: "us-west-2", signedBodyValue: .unsignedPayload) setPutPayload(payload: testData, checksumSHA256: expectedChecksumSHA256, signingConfig: signingConfig) - addFlexibleChecksumsRequestMiddleware(checksumAlgorithm: checksumAlgorithm) + addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) try await assertPutRequestHeaders(expectedChecksumSHA256: expectedChecksumSHA256) } From 095890c2d3dbf7546cc98b627f95fe69d0519161 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 10:58:11 -0700 Subject: [PATCH 09/23] Update codegen tests. --- .../swift/codegen/PresignerGeneratorTests.kt | 8 ++++++++ .../AWSRestJson1ProtocolGeneratorTests.kt | 20 ++++++++++++------- .../FlexibleChecksumMiddlewareTests.kt | 4 ++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt index 7d63cd5e313..551a36f82c2 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt @@ -36,6 +36,8 @@ extension GetFooInput { .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4") .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4a") .withRegion(value: config.region) + .withRequestChecksumCalculation(value: config.requestChecksumCalculation) + .withResponseChecksumValidation(value: config.responseChecksumValidation) .withSigningName(value: "example-signing-name") .withSigningRegion(value: config.signingRegion) .build() @@ -105,6 +107,8 @@ extension PostFooInput { .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4") .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4a") .withRegion(value: config.region) + .withRequestChecksumCalculation(value: config.requestChecksumCalculation) + .withResponseChecksumValidation(value: config.responseChecksumValidation) .withSigningName(value: "example-signing-name") .withSigningRegion(value: config.signingRegion) .build() @@ -177,6 +181,8 @@ extension PutFooInput { .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4") .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4a") .withRegion(value: config.region) + .withRequestChecksumCalculation(value: config.requestChecksumCalculation) + .withResponseChecksumValidation(value: config.responseChecksumValidation) .withSigningName(value: "example-signing-name") .withSigningRegion(value: config.signingRegion) .build() @@ -249,6 +255,8 @@ extension PutObjectInput { .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4") .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4a") .withRegion(value: config.region) + .withRequestChecksumCalculation(value: config.requestChecksumCalculation) + .withResponseChecksumValidation(value: config.responseChecksumValidation) .withSigningName(value: "s3") .withSigningRegion(value: config.signingRegion) .build() diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt index e32fc311c1f..0c425595935 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt @@ -95,6 +95,10 @@ extension ExampleClient { public var maxAttempts: Swift.Int? + public var requestChecksumCalculation: AWSSDKChecksums.AWSChecksumCalculationMode + + public var responseChecksumValidation: AWSSDKChecksums.AWSChecksumCalculationMode + public var region: Swift.String? public var signingRegion: Swift.String? @@ -127,13 +131,15 @@ extension ExampleClient { internal let logger: Smithy.LogAgent - private init(_ useFIPS: Swift.Bool?, _ useDualStack: Swift.Bool?, _ appID: Swift.String?, _ awsCredentialIdentityResolver: any SmithyIdentity.AWSCredentialIdentityResolver, _ awsRetryMode: AWSClientRuntime.AWSRetryMode, _ maxAttempts: Swift.Int?, _ region: Swift.String?, _ signingRegion: Swift.String?, _ endpointResolver: EndpointResolver, _ telemetryProvider: ClientRuntime.TelemetryProvider, _ retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions, _ clientLogMode: ClientRuntime.ClientLogMode, _ endpoint: Swift.String?, _ idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator, _ httpClientEngine: SmithyHTTPAPI.HTTPClient, _ httpClientConfiguration: ClientRuntime.HttpClientConfiguration, _ authSchemes: SmithyHTTPAuthAPI.AuthSchemes?, _ authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver, _ bearerTokenIdentityResolver: any SmithyIdentity.BearerTokenIdentityResolver, _ interceptorProviders: [ClientRuntime.InterceptorProvider], _ httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider]) { + private init(_ useFIPS: Swift.Bool?, _ useDualStack: Swift.Bool?, _ appID: Swift.String?, _ awsCredentialIdentityResolver: any SmithyIdentity.AWSCredentialIdentityResolver, _ awsRetryMode: AWSClientRuntime.AWSRetryMode, _ maxAttempts: Swift.Int?, _ requestChecksumCalculation: AWSSDKChecksums.AWSChecksumCalculationMode, _ responseChecksumValidation: AWSSDKChecksums.AWSChecksumCalculationMode, _ region: Swift.String?, _ signingRegion: Swift.String?, _ endpointResolver: EndpointResolver, _ telemetryProvider: ClientRuntime.TelemetryProvider, _ retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions, _ clientLogMode: ClientRuntime.ClientLogMode, _ endpoint: Swift.String?, _ idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator, _ httpClientEngine: SmithyHTTPAPI.HTTPClient, _ httpClientConfiguration: ClientRuntime.HttpClientConfiguration, _ authSchemes: SmithyHTTPAuthAPI.AuthSchemes?, _ authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver, _ bearerTokenIdentityResolver: any SmithyIdentity.BearerTokenIdentityResolver, _ interceptorProviders: [ClientRuntime.InterceptorProvider], _ httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider]) { self.useFIPS = useFIPS self.useDualStack = useDualStack self.appID = appID self.awsCredentialIdentityResolver = awsCredentialIdentityResolver self.awsRetryMode = awsRetryMode self.maxAttempts = maxAttempts + self.requestChecksumCalculation = requestChecksumCalculation + self.responseChecksumValidation = responseChecksumValidation self.region = region self.signingRegion = signingRegion self.endpointResolver = endpointResolver @@ -152,20 +158,20 @@ extension ExampleClient { self.logger = telemetryProvider.loggerProvider.getLogger(name: ExampleClient.clientName) } - public convenience init(useFIPS: Swift.Bool? = nil, useDualStack: Swift.Bool? = nil, appID: Swift.String? = nil, awsCredentialIdentityResolver: (any SmithyIdentity.AWSCredentialIdentityResolver)? = nil, awsRetryMode: AWSClientRuntime.AWSRetryMode? = nil, maxAttempts: Swift.Int? = nil, region: Swift.String? = nil, signingRegion: Swift.String? = nil, endpointResolver: EndpointResolver? = nil, telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, httpClientEngine: SmithyHTTPAPI.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: SmithyHTTPAuthAPI.AuthSchemes? = nil, authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver? = nil, bearerTokenIdentityResolver: (any SmithyIdentity.BearerTokenIdentityResolver)? = nil, interceptorProviders: [ClientRuntime.InterceptorProvider]? = nil, httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider]? = nil) throws { - self.init(useFIPS, useDualStack, try appID ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.appID(), try awsCredentialIdentityResolver ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver), try awsRetryMode ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.retryMode(), maxAttempts, region, signingRegion, try endpointResolver ?? DefaultEndpointResolver(), telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, try retryStrategyOptions ?? AWSClientConfigDefaultsProvider.retryStrategyOptions(awsRetryMode, maxAttempts), clientLogMode ?? AWSClientConfigDefaultsProvider.clientLogMode(), endpoint, idempotencyTokenGenerator ?? AWSClientConfigDefaultsProvider.idempotencyTokenGenerator(), httpClientEngine ?? AWSClientConfigDefaultsProvider.httpClientEngine(), httpClientConfiguration ?? AWSClientConfigDefaultsProvider.httpClientConfiguration(), authSchemes ?? [AWSSDKHTTPAuth.SigV4AuthScheme()], authSchemeResolver ?? DefaultExampleAuthSchemeResolver(), bearerTokenIdentityResolver ?? SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), interceptorProviders ?? [], httpInterceptorProviders ?? []) + public convenience init(useFIPS: Swift.Bool? = nil, useDualStack: Swift.Bool? = nil, appID: Swift.String? = nil, awsCredentialIdentityResolver: (any SmithyIdentity.AWSCredentialIdentityResolver)? = nil, awsRetryMode: AWSClientRuntime.AWSRetryMode? = nil, maxAttempts: Swift.Int? = nil, requestChecksumCalculation: AWSSDKChecksums.AWSChecksumCalculationMode? = nil, responseChecksumValidation: AWSSDKChecksums.AWSChecksumCalculationMode? = nil, region: Swift.String? = nil, signingRegion: Swift.String? = nil, endpointResolver: EndpointResolver? = nil, telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, httpClientEngine: SmithyHTTPAPI.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: SmithyHTTPAuthAPI.AuthSchemes? = nil, authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver? = nil, bearerTokenIdentityResolver: (any SmithyIdentity.BearerTokenIdentityResolver)? = nil, interceptorProviders: [ClientRuntime.InterceptorProvider]? = nil, httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider]? = nil) throws { + self.init(useFIPS, useDualStack, try appID ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.appID(), try awsCredentialIdentityResolver ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver), try awsRetryMode ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.retryMode(), maxAttempts, try requestChecksumCalculation ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.requestChecksumCalculation(requestChecksumCalculation), try responseChecksumValidation ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.responseChecksumValidation(responseChecksumValidation), region, signingRegion, try endpointResolver ?? DefaultEndpointResolver(), telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, try retryStrategyOptions ?? AWSClientConfigDefaultsProvider.retryStrategyOptions(awsRetryMode, maxAttempts), clientLogMode ?? AWSClientConfigDefaultsProvider.clientLogMode(), endpoint, idempotencyTokenGenerator ?? AWSClientConfigDefaultsProvider.idempotencyTokenGenerator(), httpClientEngine ?? AWSClientConfigDefaultsProvider.httpClientEngine(), httpClientConfiguration ?? AWSClientConfigDefaultsProvider.httpClientConfiguration(), authSchemes ?? [AWSSDKHTTPAuth.SigV4AuthScheme()], authSchemeResolver ?? DefaultExampleAuthSchemeResolver(), bearerTokenIdentityResolver ?? SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), interceptorProviders ?? [], httpInterceptorProviders ?? []) } - public convenience init(useFIPS: Swift.Bool? = nil, useDualStack: Swift.Bool? = nil, appID: Swift.String? = nil, awsCredentialIdentityResolver: (any SmithyIdentity.AWSCredentialIdentityResolver)? = nil, awsRetryMode: AWSClientRuntime.AWSRetryMode? = nil, maxAttempts: Swift.Int? = nil, region: Swift.String? = nil, signingRegion: Swift.String? = nil, endpointResolver: EndpointResolver? = nil, telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, httpClientEngine: SmithyHTTPAPI.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: SmithyHTTPAuthAPI.AuthSchemes? = nil, authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver? = nil, bearerTokenIdentityResolver: (any SmithyIdentity.BearerTokenIdentityResolver)? = nil, interceptorProviders: [ClientRuntime.InterceptorProvider]? = nil, httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider]? = nil) async throws { - self.init(useFIPS, useDualStack, try appID ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.appID(), try awsCredentialIdentityResolver ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver), try awsRetryMode ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.retryMode(), maxAttempts, try await AWSClientRuntime.AWSClientConfigDefaultsProvider.region(region), try await AWSClientRuntime.AWSClientConfigDefaultsProvider.region(region), try endpointResolver ?? DefaultEndpointResolver(), telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, try retryStrategyOptions ?? AWSClientConfigDefaultsProvider.retryStrategyOptions(awsRetryMode, maxAttempts), clientLogMode ?? AWSClientConfigDefaultsProvider.clientLogMode(), endpoint, idempotencyTokenGenerator ?? AWSClientConfigDefaultsProvider.idempotencyTokenGenerator(), httpClientEngine ?? AWSClientConfigDefaultsProvider.httpClientEngine(), httpClientConfiguration ?? AWSClientConfigDefaultsProvider.httpClientConfiguration(), authSchemes ?? [AWSSDKHTTPAuth.SigV4AuthScheme()], authSchemeResolver ?? DefaultExampleAuthSchemeResolver(), bearerTokenIdentityResolver ?? SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), interceptorProviders ?? [], httpInterceptorProviders ?? []) + public convenience init(useFIPS: Swift.Bool? = nil, useDualStack: Swift.Bool? = nil, appID: Swift.String? = nil, awsCredentialIdentityResolver: (any SmithyIdentity.AWSCredentialIdentityResolver)? = nil, awsRetryMode: AWSClientRuntime.AWSRetryMode? = nil, maxAttempts: Swift.Int? = nil, requestChecksumCalculation: AWSSDKChecksums.AWSChecksumCalculationMode? = nil, responseChecksumValidation: AWSSDKChecksums.AWSChecksumCalculationMode? = nil, region: Swift.String? = nil, signingRegion: Swift.String? = nil, endpointResolver: EndpointResolver? = nil, telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, httpClientEngine: SmithyHTTPAPI.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: SmithyHTTPAuthAPI.AuthSchemes? = nil, authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver? = nil, bearerTokenIdentityResolver: (any SmithyIdentity.BearerTokenIdentityResolver)? = nil, interceptorProviders: [ClientRuntime.InterceptorProvider]? = nil, httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider]? = nil) async throws { + self.init(useFIPS, useDualStack, try appID ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.appID(), try awsCredentialIdentityResolver ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver), try awsRetryMode ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.retryMode(), maxAttempts, try requestChecksumCalculation ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.requestChecksumCalculation(requestChecksumCalculation), try responseChecksumValidation ?? AWSClientRuntime.AWSClientConfigDefaultsProvider.responseChecksumValidation(responseChecksumValidation), try await AWSClientRuntime.AWSClientConfigDefaultsProvider.region(region), try await AWSClientRuntime.AWSClientConfigDefaultsProvider.region(region), try endpointResolver ?? DefaultEndpointResolver(), telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, try retryStrategyOptions ?? AWSClientConfigDefaultsProvider.retryStrategyOptions(awsRetryMode, maxAttempts), clientLogMode ?? AWSClientConfigDefaultsProvider.clientLogMode(), endpoint, idempotencyTokenGenerator ?? AWSClientConfigDefaultsProvider.idempotencyTokenGenerator(), httpClientEngine ?? AWSClientConfigDefaultsProvider.httpClientEngine(), httpClientConfiguration ?? AWSClientConfigDefaultsProvider.httpClientConfiguration(), authSchemes ?? [AWSSDKHTTPAuth.SigV4AuthScheme()], authSchemeResolver ?? DefaultExampleAuthSchemeResolver(), bearerTokenIdentityResolver ?? SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), interceptorProviders ?? [], httpInterceptorProviders ?? []) } public convenience required init() async throws { - try await self.init(useFIPS: nil, useDualStack: nil, appID: nil, awsCredentialIdentityResolver: nil, awsRetryMode: nil, maxAttempts: nil, region: nil, signingRegion: nil, endpointResolver: nil, telemetryProvider: nil, retryStrategyOptions: nil, clientLogMode: nil, endpoint: nil, idempotencyTokenGenerator: nil, httpClientEngine: nil, httpClientConfiguration: nil, authSchemes: nil, authSchemeResolver: nil, bearerTokenIdentityResolver: nil, interceptorProviders: nil, httpInterceptorProviders: nil) + try await self.init(useFIPS: nil, useDualStack: nil, appID: nil, awsCredentialIdentityResolver: nil, awsRetryMode: nil, maxAttempts: nil, requestChecksumCalculation: nil, responseChecksumValidation: nil, region: nil, signingRegion: nil, endpointResolver: nil, telemetryProvider: nil, retryStrategyOptions: nil, clientLogMode: nil, endpoint: nil, idempotencyTokenGenerator: nil, httpClientEngine: nil, httpClientConfiguration: nil, authSchemes: nil, authSchemeResolver: nil, bearerTokenIdentityResolver: nil, interceptorProviders: nil, httpInterceptorProviders: nil) } public convenience init(region: String) throws { - self.init(nil, nil, try AWSClientRuntime.AWSClientConfigDefaultsProvider.appID(), try AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(), try AWSClientRuntime.AWSClientConfigDefaultsProvider.retryMode(), nil, region, region, try DefaultEndpointResolver(), ClientRuntime.DefaultTelemetry.provider, try AWSClientConfigDefaultsProvider.retryStrategyOptions(), AWSClientConfigDefaultsProvider.clientLogMode(), nil, AWSClientConfigDefaultsProvider.idempotencyTokenGenerator(), AWSClientConfigDefaultsProvider.httpClientEngine(), AWSClientConfigDefaultsProvider.httpClientConfiguration(), [AWSSDKHTTPAuth.SigV4AuthScheme()], DefaultExampleAuthSchemeResolver(), SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), [], []) + self.init(nil, nil, try AWSClientRuntime.AWSClientConfigDefaultsProvider.appID(), try AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(), try AWSClientRuntime.AWSClientConfigDefaultsProvider.retryMode(), nil, try AWSClientRuntime.AWSClientConfigDefaultsProvider.requestChecksumCalculation(requestChecksumCalculation), try AWSClientRuntime.AWSClientConfigDefaultsProvider.responseChecksumValidation(responseChecksumValidation), region, region, try DefaultEndpointResolver(), ClientRuntime.DefaultTelemetry.provider, try AWSClientConfigDefaultsProvider.retryStrategyOptions(), AWSClientConfigDefaultsProvider.clientLogMode(), nil, AWSClientConfigDefaultsProvider.idempotencyTokenGenerator(), AWSClientConfigDefaultsProvider.httpClientEngine(), AWSClientConfigDefaultsProvider.httpClientConfiguration(), [AWSSDKHTTPAuth.SigV4AuthScheme()], DefaultExampleAuthSchemeResolver(), SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), [], []) } public var partitionID: String? { diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt index d29e5e3de3e..750f61e9c46 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt @@ -16,7 +16,7 @@ class FlexibleChecksumMiddlewareTests { val contents = TestUtils.getFileContents(context.manifest, "Sources/Example/ChecksumTestsClient.swift") contents.shouldSyntacticSanityCheck() val expectedContents = """ - builder.interceptors.add(AWSClientRuntime.FlexibleChecksumsRequestMiddleware(checksumAlgorithm: input.checksumAlgorithm?.rawValue)) + builder.interceptors.add(AWSClientRuntime.FlexibleChecksumsRequestMiddleware(requestChecksumRequired: true, checksumAlgorithm: input.checksumAlgorithm?.rawValue)) """ contents.shouldContainOnlyOnce(expectedContents) } @@ -27,7 +27,7 @@ class FlexibleChecksumMiddlewareTests { val contents = TestUtils.getFileContents(context.manifest, "Sources/Example/ChecksumTestsClient.swift") contents.shouldSyntacticSanityCheck() val expectedContents = """ - builder.interceptors.add(AWSClientRuntime.FlexibleChecksumsResponseMiddleware(validationMode: true)) + builder.interceptors.add(AWSClientRuntime.FlexibleChecksumsResponseMiddleware(validationMode: input.validationMode?.rawValue ?? "unset")) """ contents.shouldContainOnlyOnce(expectedContents) } From 93264a4f4225add41c86dc66665e86cb3542c401 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 15:21:48 -0700 Subject: [PATCH 10/23] Add CRC64NVME as one of the algorithms to check for in flexchex response middleware. --- .../Middlewares/FlexibleChecksumsResponseMiddleware.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsResponseMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsResponseMiddleware.swift index 1b4deead2f3..0f84a2a4fa7 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsResponseMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsResponseMiddleware.swift @@ -15,6 +15,7 @@ public struct FlexibleChecksumsResponseMiddleware Date: Wed, 23 Oct 2024 15:56:06 -0700 Subject: [PATCH 11/23] Add test case for no response validation when validation mode unset and responseChecksumValidation config is .whenRequired. --- .../FlexibleChecksumsMiddlewareTests.swift | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift b/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift index e3b8786a065..d39d703b99d 100644 --- a/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift +++ b/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift @@ -235,7 +235,8 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { let colA = ["crc32", "crc32c"] let validationMode = "unset" var colBHeaders = Headers() - // crc64 is not modeled in the service so no validation should be perforemd, but we shouldnt error + // crc64 is supported for this request (not included in colA array), + // so no validation should be performed, but we shouldnt error colBHeaders.add(name: "x-amz-checksum-crc64", value: "6+bG5g==") addFlexibleChecksumsResponseMiddleware(validationMode, colA) try await AssertValidationAsExpected( @@ -245,7 +246,24 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { ) } - func getChecksumMismatchException() async throws -> () { + func testNoResponseValidationOccurs() async throws -> () { + let colA = ["crc32", "crc32c"] + let validationMode = "unset" + var colBHeaders = Headers() + colBHeaders.add(name: "x-amz-checksum-crc32", value: "6+bG5g==") + // Change responseChecksumValidation config to .whenRequired + builder.attributes.responseChecksumValidation = .whenSupported + addFlexibleChecksumsResponseMiddleware(validationMode, colA) + // Since responseChecksumValidation config is set to .whenRequired and validationMode is not "ENABLED", + // no response checksum validation should occur. + try await AssertValidationAsExpected( + responseHeaders: colBHeaders, + validationMode: true, + expectedValidationHeader: "x-amz-checksum-crc32" + ) + } + + func testChecksumMismatchException() async throws -> () { let validationMode = "ENABLED" var testHeaders = Headers() testHeaders.add(name: "x-amz-checksum-crc32", value: "AAAA==") From 798c31b5d0c29f8dd06145e03da9dfcf8a082e94 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 16:59:51 -0700 Subject: [PATCH 12/23] Address compile time errors in generated code. --- .../Sources/AWSSDKSwiftCLI/Resources/Package.Base.txt | 3 ++- .../aws/swift/codegen/AWSHttpProtocolServiceClient.kt | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.txt b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.txt index dd7afe70594..bda8749d293 100644 --- a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.txt +++ b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.txt @@ -103,7 +103,8 @@ private var runtimeTargets: [Target] { .smithyEventStreamsAuthAPI, .awsSDKCommon, .awsSDKHTTPAuth, - .awsSDKIdentity + .awsSDKIdentity, + .awsSDKChecksums, ], path: "Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime", resources: [ diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolServiceClient.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolServiceClient.kt index 45c13684990..86d8bea51c5 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolServiceClient.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolServiceClient.kt @@ -126,6 +126,12 @@ class AWSHttpProtocolServiceClient( "retryStrategyOptions" -> { "try AWSClientConfigDefaultsProvider.retryStrategyOptions()" } + "requestChecksumCalculation" -> { + "try AWSClientConfigDefaultsProvider.requestChecksumCalculation()" + } + "responseChecksumValidation" -> { + "try AWSClientConfigDefaultsProvider.responseChecksumValidation()" + } else -> { it.default?.render(writer) ?: "nil" } From 8ce4364fff2c68cfee127da42bc58fb1bb8ecfba Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Wed, 23 Oct 2024 17:10:14 -0700 Subject: [PATCH 13/23] Update codegen test --- .../codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt index 0c425595935..d00b9ea70a6 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt @@ -171,7 +171,7 @@ extension ExampleClient { } public convenience init(region: String) throws { - self.init(nil, nil, try AWSClientRuntime.AWSClientConfigDefaultsProvider.appID(), try AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(), try AWSClientRuntime.AWSClientConfigDefaultsProvider.retryMode(), nil, try AWSClientRuntime.AWSClientConfigDefaultsProvider.requestChecksumCalculation(requestChecksumCalculation), try AWSClientRuntime.AWSClientConfigDefaultsProvider.responseChecksumValidation(responseChecksumValidation), region, region, try DefaultEndpointResolver(), ClientRuntime.DefaultTelemetry.provider, try AWSClientConfigDefaultsProvider.retryStrategyOptions(), AWSClientConfigDefaultsProvider.clientLogMode(), nil, AWSClientConfigDefaultsProvider.idempotencyTokenGenerator(), AWSClientConfigDefaultsProvider.httpClientEngine(), AWSClientConfigDefaultsProvider.httpClientConfiguration(), [AWSSDKHTTPAuth.SigV4AuthScheme()], DefaultExampleAuthSchemeResolver(), SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), [], []) + self.init(nil, nil, try AWSClientRuntime.AWSClientConfigDefaultsProvider.appID(), try AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(), try AWSClientRuntime.AWSClientConfigDefaultsProvider.retryMode(), nil, try AWSClientConfigDefaultsProvider.requestChecksumCalculation(), try AWSClientConfigDefaultsProvider.responseChecksumValidation(), region, region, try DefaultEndpointResolver(), ClientRuntime.DefaultTelemetry.provider, try AWSClientConfigDefaultsProvider.retryStrategyOptions(), AWSClientConfigDefaultsProvider.clientLogMode(), nil, AWSClientConfigDefaultsProvider.idempotencyTokenGenerator(), AWSClientConfigDefaultsProvider.httpClientEngine(), AWSClientConfigDefaultsProvider.httpClientConfiguration(), [AWSSDKHTTPAuth.SigV4AuthScheme()], DefaultExampleAuthSchemeResolver(), SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), [], []) } public var partitionID: String? { From c6d69d2f1fdb726d782c3852303cc50c5f66a096 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Thu, 24 Oct 2024 10:44:24 -0700 Subject: [PATCH 14/23] Skip checksum flow if body is empty + ignore checksum of checksums that end with -#. --- .../FlexibleChecksumsRequestMiddleware.swift | 5 +++-- .../FlexibleChecksumsResponseMiddleware.swift | 10 +++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift index 89db9586682..7982cd88523 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift @@ -81,7 +81,8 @@ public struct FlexibleChecksumsRequestMiddleware Date: Thu, 24 Oct 2024 17:23:38 -0700 Subject: [PATCH 15/23] Add edge case handling for a stream body with size below chunked threshold, hence checksum header must be sent in original request rather than in trailing header. --- .../FlexibleChecksumsRequestMiddleware.swift | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift index 7982cd88523..39384b53d5f 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift @@ -9,6 +9,7 @@ import enum SmithyChecksumsAPI.ChecksumAlgorithm import enum SmithyChecksums.ChecksumMismatchException import enum Smithy.ClientError import class Smithy.Context +import struct Foundation.Data import AwsCommonRuntimeKit import AWSSDKChecksums import ClientRuntime @@ -80,31 +81,47 @@ public struct FlexibleChecksumsRequestMiddleware Date: Fri, 8 Nov 2024 15:33:38 -0800 Subject: [PATCH 16/23] Add business metric feature ID tracking for flexible checksum v2. --- .../FlexibleChecksumsRequestMiddleware.swift | 4 +- .../UserAgent/AWSUserAgentMetadata.swift | 15 +++++- .../UserAgent/BusinessMetrics.swift | 50 +++++++++---------- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift index 39384b53d5f..969bf3004de 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift @@ -74,6 +74,9 @@ public struct FlexibleChecksumsRequestMiddleware>(name: "BusinessMetrics") -/* List of readable "feature ID" to "metric value"; last updated on 08/19/2024 - [Feature ID] [Metric Value] [Flag Supported] - "RESOURCE_MODEL" : "A" : - "WAITER" : "B" : - "PAGINATOR" : "C" : - "RETRY_MODE_LEGACY" : "D" : Y - "RETRY_MODE_STANDARD" : "E" : Y - "RETRY_MODE_ADAPTIVE" : "F" : Y - "S3_TRANSFER" : "G" : - "S3_CRYPTO_V1N" : "H" : - "S3_CRYPTO_V2" : "I" : - "S3_EXPRESS_BUCKET" : "J" : - "S3_ACCESS_GRANTS" : "K" : - "GZIP_REQUEST_COMPRESSION" : "L" : - "PROTOCOL_RPC_V2_CBOR" : "M" : - "ENDPOINT_OVERRIDE" : "N" : Y - "ACCOUNT_ID_ENDPOINT" : "O" : - "ACCOUNT_ID_MODE_PREFERRED" : "P" : - "ACCOUNT_ID_MODE_DISABLED" : "Q" : - "ACCOUNT_ID_MODE_REQUIRED" : "R" : - "SIGV4A_SIGNING" : "S" : Y - "RESOLVED_ACCOUNT_ID" : "T" : - */ private func setFlagsIntoContext( config: UserAgentValuesFromConfig, context: Context ) { - // Handle D, E, F switch config.awsRetryMode { case .legacy: context.businessMetrics = ["RETRY_MODE_LEGACY": "D"] @@ -95,12 +71,34 @@ private func setFlagsIntoContext( case .adaptive: context.businessMetrics = ["RETRY_MODE_ADAPTIVE": "F"] } - // Handle N if let endpoint = config.endpoint, !endpoint.isEmpty { context.businessMetrics = ["ENDPOINT_OVERRIDE": "N"] } - // Handle S if context.selectedAuthScheme?.schemeID == "aws.auth#sigv4a" { context.businessMetrics = ["SIGV4A_SIGNING": "S"] } + switch context.checksum { + case .crc32: + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_REQ_CRC32": "U"] + case .crc32c: + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_REQ_CRC32C": "V"] + case .crc64nvme: + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_REQ_CRC64": "W"] + case .sha1: + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_REQ_SHA1": "X"] + case .sha256: + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_REQ_SHA256": "Y"] + default: + break + } + if config.requestChecksumCalculation == .whenSupported { + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED": "Z"] + } else { + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED": "a"] + } + if config.responseChecksumValidation == .whenSupported { + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED": "b"] + } else { + context.businessMetrics = ["FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED": "c"] + } } From a45ad36f95d7677044121ac1ad039a1375bbeaa1 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Fri, 8 Nov 2024 16:26:07 -0800 Subject: [PATCH 17/23] Update initializer call in test. --- .../UserAgent/BusinessMetricsTests.swift | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/UserAgent/BusinessMetricsTests.swift b/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/UserAgent/BusinessMetricsTests.swift index 672db12cadb..61bbdf16765 100644 --- a/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/UserAgent/BusinessMetricsTests.swift +++ b/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/UserAgent/BusinessMetricsTests.swift @@ -28,7 +28,13 @@ class BusinessMetricsTests: XCTestCase { let userAgent = AWSUserAgentMetadata.fromConfigAndContext( serviceID: "test", version: "1.0", - config: UserAgentValuesFromConfig(appID: nil, endpoint: nil, awsRetryMode: .standard), + config: UserAgentValuesFromConfig( + appID: nil, + endpoint: nil, + awsRetryMode: .standard, + requestChecksumCalculation: .whenRequired, + responseChecksumValidation: .whenRequired + ), context: context ) // Assert values in context match with values assigned to user agent @@ -50,11 +56,17 @@ class BusinessMetricsTests: XCTestCase { let userAgent = AWSUserAgentMetadata.fromConfigAndContext( serviceID: "test", version: "1.0", - config: UserAgentValuesFromConfig(appID: nil, endpoint: "test-endpoint", awsRetryMode: .adaptive), + config: UserAgentValuesFromConfig( + appID: nil, + endpoint: "test-endpoint", + awsRetryMode: .adaptive, + requestChecksumCalculation: .whenSupported, + responseChecksumValidation: .whenSupported + ), context: context ) // F comes from retry mode being adaptive & N comes from endpoint override - let expectedString = "m/A,B,F,N,S" + let expectedString = "m/A,B,F,N,S,Z,b" XCTAssertEqual(userAgent.businessMetrics?.description, expectedString) } } From 92c45c9eaf8a373eaf29e8244b12b3d87defb9cf Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Fri, 15 Nov 2024 10:58:20 -0800 Subject: [PATCH 18/23] Reflect context thread-safe changes upstream. --- .../Sources/AWSSDKChecksums/Context+Checksum.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/Context+Checksum.swift b/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/Context+Checksum.swift index 5d11b342427..7bf5e059578 100644 --- a/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/Context+Checksum.swift +++ b/Sources/Core/AWSSDKChecksums/Sources/AWSSDKChecksums/Context+Checksum.swift @@ -11,13 +11,13 @@ import struct Smithy.AttributeKey public extension Context { var requestChecksumCalculation: AWSChecksumCalculationMode { - get { attributes.get(key: requestChecksumCalculationKey) ?? .whenSupported } - set { attributes.set(key: requestChecksumCalculationKey, value: newValue) } + get { get(key: requestChecksumCalculationKey) ?? .whenSupported } + set { set(key: requestChecksumCalculationKey, value: newValue) } } var responseChecksumValidation: AWSChecksumCalculationMode { - get { attributes.get(key: responseChecksumValidationKey) ?? .whenSupported } - set { attributes.set(key: responseChecksumValidationKey, value: newValue) } + get { get(key: responseChecksumValidationKey) ?? .whenSupported } + set { set(key: responseChecksumValidationKey, value: newValue) } } } From 472111af50ac2a55ba3c9fd019bfb4d8e2eb59d1 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Tue, 19 Nov 2024 13:43:41 -0800 Subject: [PATCH 19/23] Fill impl gaps against SEP. --- .../FlexibleChecksumsRequestMiddleware.swift | 27 +++++++++++----- .../FlexibleChecksumsRequestIntegration.kt | 32 ++++++++++++++++--- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift index 969bf3004de..77be91a4a9b 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift @@ -21,10 +21,16 @@ public struct FlexibleChecksumsRequestMiddleware(it) } - val useFlexibleChecksum = (httpChecksumTrait != null) && - (httpChecksumTrait.requestAlgorithmMember?.orElse(null) != null) && - (input?.memberNames?.any { it == httpChecksumTrait.requestAlgorithmMember.get() } == true) + /* + Flexible checksum request middleware must be added only if: + - The operation has @httpChecksum trait + - (The `requestChecksumRequired` of @httpChecksum trait is set to `true`) || + (the `requestAlgorithmMember` is modeled) + - Of course, add the middleware if both are true as well. + In the case that `requestAlgorithmMember` is not modeled but `requestChecksumRequired` is `true`, + SDK clients use default checksum algorithm: CRC32. + */ + val useFlexibleChecksum = httpChecksumTrait != null && ( + ( + (httpChecksumTrait.requestAlgorithmMember?.orElse(null) != null) && + (input?.memberNames?.any { it == httpChecksumTrait.requestAlgorithmMember.get() } == true) + ) || (httpChecksumTrait.isRequestChecksumRequired) + ) if (useFlexibleChecksum) { operationMiddleware.appendMiddleware(operationShape, FlexibleChecksumRequestMiddleware) @@ -52,16 +68,22 @@ private object FlexibleChecksumRequestMiddleware : MiddlewareRenderable { val inputShapeName = MiddlewareShapeUtils.inputSymbol(ctx.symbolProvider, ctx.model, op).name val outputShapeName = MiddlewareShapeUtils.outputSymbol(ctx.symbolProvider, ctx.model, op).name val httpChecksumTrait = op.getTrait(HttpChecksumTrait::class.java).orElse(null) - val algorithmMemberName = httpChecksumTrait?.requestAlgorithmMember?.get()?.lowercaseFirstLetter() + val algorithmMemberName = httpChecksumTrait?.requestAlgorithmMember?.get()?.lowercaseFirstLetter()?.let { + "input.$it?.rawValue" + } ?: "nil" val requestChecksumIsRequired = httpChecksumTrait?.isRequestChecksumRequired + val algoHeaderName = ctx.model.expectShape(op.inputShape).getMember(algorithmMemberName)?.getOrNull()?.getTrait()?.value?.let { + "\"$it\"" + } ?: "nil" writer.write( - "\$N<\$L, \$L>(requestChecksumRequired: \$L, checksumAlgorithm: input.\$L?.rawValue)", + "\$N<\$L, \$L>(requestChecksumRequired: \$L, checksumAlgorithm: \$L, checksumAlgoHeaderName: \$L)", AWSClientRuntimeTypes.Core.FlexibleChecksumsRequestMiddleware, inputShapeName, outputShapeName, requestChecksumIsRequired, algorithmMemberName, + algoHeaderName ) } } From eabc32e8f90c9a748e01dce419886dcd2906607d Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Tue, 19 Nov 2024 14:13:09 -0800 Subject: [PATCH 20/23] Update codegen test & fix optional chaining. --- .../FlexibleChecksumsRequestIntegration.kt | 10 ++++++---- .../customizations/FlexibleChecksumMiddlewareTests.kt | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/flexiblechecksums/FlexibleChecksumsRequestIntegration.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/flexiblechecksums/FlexibleChecksumsRequestIntegration.kt index 98cef6449ea..1c62fdb9843 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/flexiblechecksums/FlexibleChecksumsRequestIntegration.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/flexiblechecksums/FlexibleChecksumsRequestIntegration.kt @@ -68,13 +68,15 @@ private object FlexibleChecksumRequestMiddleware : MiddlewareRenderable { val inputShapeName = MiddlewareShapeUtils.inputSymbol(ctx.symbolProvider, ctx.model, op).name val outputShapeName = MiddlewareShapeUtils.outputSymbol(ctx.symbolProvider, ctx.model, op).name val httpChecksumTrait = op.getTrait(HttpChecksumTrait::class.java).orElse(null) - val algorithmMemberName = httpChecksumTrait?.requestAlgorithmMember?.get()?.lowercaseFirstLetter()?.let { + val algorithmMemberName = httpChecksumTrait?.requestAlgorithmMember?.getOrNull()?.lowercaseFirstLetter()?.let { "input.$it?.rawValue" } ?: "nil" val requestChecksumIsRequired = httpChecksumTrait?.isRequestChecksumRequired - val algoHeaderName = ctx.model.expectShape(op.inputShape).getMember(algorithmMemberName)?.getOrNull()?.getTrait()?.value?.let { - "\"$it\"" - } ?: "nil" + val algoHeaderName = if (httpChecksumTrait?.requestAlgorithmMember?.getOrNull() != null) { + ctx.model.expectShape(op.inputShape).getMember(httpChecksumTrait.requestAlgorithmMember.get())?.getOrNull()?.getTrait()?.value?.let { + "\"$it\"" + } ?: "nil" + } else { "nil" } writer.write( "\$N<\$L, \$L>(requestChecksumRequired: \$L, checksumAlgorithm: \$L, checksumAlgoHeaderName: \$L)", diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt index 750f61e9c46..81fa6bc864f 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt @@ -16,7 +16,7 @@ class FlexibleChecksumMiddlewareTests { val contents = TestUtils.getFileContents(context.manifest, "Sources/Example/ChecksumTestsClient.swift") contents.shouldSyntacticSanityCheck() val expectedContents = """ - builder.interceptors.add(AWSClientRuntime.FlexibleChecksumsRequestMiddleware(requestChecksumRequired: true, checksumAlgorithm: input.checksumAlgorithm?.rawValue)) + builder.interceptors.add(AWSClientRuntime.FlexibleChecksumsRequestMiddleware(requestChecksumRequired: true, checksumAlgorithm: input.checksumAlgorithm?.rawValue, checksumAlgoHeaderName: "x-amz-request-algorithm")) """ contents.shouldContainOnlyOnce(expectedContents) } From bebffb10d1f335f401da1ed5974b96d6962025d5 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Tue, 19 Nov 2024 14:50:08 -0800 Subject: [PATCH 21/23] Fill unit test gap for flex checksum middlewares --- .../FlexibleChecksumsMiddlewareTests.swift | 56 +++++++++++++++---- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift b/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift index c304f019048..aff4ae82827 100644 --- a/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift +++ b/Sources/Core/AWSClientRuntime/Tests/AWSClientRuntimeTests/Middlewares/FlexibleChecksumsMiddlewareTests.swift @@ -49,62 +49,95 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { func testNormalPayloadSha256() async throws { let checksumAlgorithm = "sha256" - let testData = ByteStream.data(Data("Hello, world!".utf8)) + let testData = ByteStream.data(Data("Hello world".utf8)) setNormalPayload(payload: testData) addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertHeaderIsPresentAndValidationOccurs( expectedHeader: "x-amz-checksum-sha256", responseBody: testData, - expectedChecksum: "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=" + expectedChecksum: "ZOyIygCyaOW6GjVnihtTFtIS9PNmskdyMlNKiuyjfzw=" ) } func testNormalPayloadSha1() async throws { let checksumAlgorithm = "sha1" - let testData = ByteStream.data(Data("Hello, world!".utf8)) + let testData = ByteStream.data(Data("Hello world".utf8)) setNormalPayload(payload: testData) addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertHeaderIsPresentAndValidationOccurs( expectedHeader: "x-amz-checksum-sha1", responseBody: testData, - expectedChecksum: "lDpwLQbzRZmu4fjajvn3KWAx1pk=" + expectedChecksum: "e1AsOh9IyGCa4hLN+2Od7jlnP14=" ) } func testNormalPayloadCRC32() async throws { let checksumAlgorithm = "crc32" - let testData = ByteStream.data(Data("Hello, world!".utf8)) + let testData = ByteStream.data(Data("Hello world".utf8)) setNormalPayload(payload: testData) addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertHeaderIsPresentAndValidationOccurs( expectedHeader: "x-amz-checksum-crc32", responseBody: testData, - expectedChecksum: "6+bG5g==" + expectedChecksum: "i9aeUg==" ) } func testNormalPayloadCRC32C() async throws { let checksumAlgorithm = "crc32c" - let testData = ByteStream.data(Data("Hello, world!".utf8)) + let testData = ByteStream.data(Data("Hello world".utf8)) setNormalPayload(payload: testData) addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) addFlexibleChecksumsResponseMiddleware("ENABLED") try await AssertHeaderIsPresentAndValidationOccurs( expectedHeader: "x-amz-checksum-crc32c", responseBody: testData, - expectedChecksum: "yKEG5Q==" + expectedChecksum: "crUfeA==" ) } - func testUseDefaultChecksumAlgorithm() async throws { - let testData = ByteStream.data(Data("Hello, world!".utf8)) + func testNormalPayloadCRC64NVME() async throws { + let checksumAlgorithm = "crc64nvme" + let testData = ByteStream.data(Data("Hello world".utf8)) setNormalPayload(payload: testData) + addFlexibleChecksumsRequestMiddleware(true, checksumAlgorithm) + addFlexibleChecksumsResponseMiddleware("ENABLED") + try await AssertHeaderIsPresentAndValidationOccurs( + expectedHeader: "x-amz-checksum-crc64nvme", + responseBody: testData, + expectedChecksum: "OOJZ0D8xKts=" + ) + } + + func testUseDefaultChecksumAlgorithm1() async throws { + let testData = ByteStream.data(Data("Hello world".utf8)) + setNormalPayload(payload: testData) + builder.attributes.responseChecksumValidation = .whenRequired addFlexibleChecksumsRequestMiddleware(false, nil) addFlexibleChecksumsResponseMiddleware("unset") try await AssertHeaderIsPresentAndValidationOccurs( + expectedHeader: "x-amz-checksum-crc32", + checkLogs: [ + "No algorithm chosen by user. Defaulting to CRC32 checksum algorithm.", + "Checksum validation should not be performed! Skipping workflow..." + ] + ) + } + + func testUseDefaultChecksumAlgorithm2() async throws { + let testData = ByteStream.data(Data("Hello world".utf8)) + setNormalPayload(payload: testData) + builder.attributes.requestChecksumCalculation = .whenRequired + builder.attributes.responseChecksumValidation = .whenRequired + addFlexibleChecksumsRequestMiddleware(true, nil) + addFlexibleChecksumsResponseMiddleware("ENABLED") + try await AssertHeaderIsPresentAndValidationOccurs( + expectedHeader: "x-amz-checksum-crc32", + responseBody: testData, + expectedChecksum: "i9aeUg==", checkLogs: [ "No algorithm chosen by user. Defaulting to CRC32 checksum algorithm." ] @@ -114,7 +147,6 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { func testNoRequestChecksumCalculation() async throws { let testData = ByteStream.data(Data("Hello, world!".utf8)) setNormalPayload(payload: testData) - // Change requestChecksumCalculation config to .whenRequired builder.attributes.requestChecksumCalculation = .whenRequired addFlexibleChecksumsRequestMiddleware(false, nil) addFlexibleChecksumsResponseMiddleware("unset") @@ -128,7 +160,7 @@ class FlexibleChecksumsMiddlewareTests: XCTestCase { } private func addFlexibleChecksumsRequestMiddleware(_ requestChecksumRequired: Bool, _ checksumAlgorithm: String?) { - builder.interceptors.add(FlexibleChecksumsRequestMiddleware(requestChecksumRequired: requestChecksumRequired, checksumAlgorithm: checksumAlgorithm)) + builder.interceptors.add(FlexibleChecksumsRequestMiddleware(requestChecksumRequired: requestChecksumRequired, checksumAlgorithm: checksumAlgorithm, checksumAlgoHeaderName: "x-amz-checksum-algorithm")) } private func addFlexibleChecksumsResponseMiddleware(_ validationMode: String, _ priorityList: [String] = []) { From d6932b33e71c402ff488f7aa38f3c0f2ab7ffb3b Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Tue, 19 Nov 2024 14:53:01 -0800 Subject: [PATCH 22/23] Temporarily comment out manual fill for requestAlgorithmMember http header. --- .../Middlewares/FlexibleChecksumsRequestMiddleware.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift index 77be91a4a9b..7ecc30b26b3 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift @@ -73,9 +73,10 @@ public struct FlexibleChecksumsRequestMiddleware Date: Tue, 26 Nov 2024 10:03:26 -0800 Subject: [PATCH 23/23] Add PRESIGN_URL flow to flexchex request middleware. --- .../FlexibleChecksumsRequestMiddleware.swift | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift index 7ecc30b26b3..fa2de1daa14 100644 --- a/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift +++ b/Sources/Core/AWSClientRuntime/Sources/AWSClientRuntime/Middlewares/FlexibleChecksumsRequestMiddleware.swift @@ -8,6 +8,7 @@ import enum SmithyChecksumsAPI.ChecksumAlgorithm import enum SmithyChecksums.ChecksumMismatchException import enum Smithy.ClientError +import struct Smithy.URIQueryItem import class Smithy.Context import struct Foundation.Data import AwsCommonRuntimeKit @@ -41,16 +42,42 @@ public struct FlexibleChecksumsRequestMiddleware