Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fix MD5 middleware codegen & runtime code to match spec #885

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,24 @@ public struct ContentMD5Middleware<OperationStackInput, OperationStackOutput> {
public init() {}

private func addHeaders(builder: HTTPRequestBuilder, attributes: Context) async throws {
// Skip MD5 hash if using checksums
if builder.headers.exists(name: "x-amz-sdk-checksum-algorithm") {
// Initialize logger
guard let logger = attributes.getLogger() else {
throw ClientError.unknownError("No logger found!")
}

// Skip MD5 hash if using flexible checksum
if builder.headers.headers.contains(where: {
$0.name.lowercased().starts(with: "x-amz-checksum-")
}) {
logger.debug("Flexible checksum configured. Skipping MD5 checksum calculation.")
return
}

// Skip MD5 hash if it was provided in input by the user
if builder.headers.headers.contains(where: {
$0.name.lowercased() == "content-md5"
}) {
logger.debug("MD5 checksum hash provided in the input. Skipping MD5 checksum calculation.")
return
}

Expand All @@ -42,15 +58,9 @@ public struct ContentMD5Middleware<OperationStackInput, OperationStackOutput> {
let hashResult = try md5Hasher.digest().toBase64String()
builder.updateHeader(name: "Content-MD5", value: hashResult)
} catch {
guard let logger = attributes.getLogger() else {
return
}
logger.error("Could not compute Content-MD5 of stream due to error \(error)")
}
default:
guard let logger = attributes.getLogger() else {
return
}
logger.error("Unhandled case for Content-MD5")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,18 @@ class ContentMD5Middleware(

/**
* Check if MD5 checksum is required
* The Md5 middleware will only be installed if the operation requires a checksum and the user has not opted-in to flexible checksums.
* The Md5 middleware will only be generated if the operation is marked with @httpChecksumRequired trait or if
* only the requestChecksumRequired property of the httpChecksum is set.
* https://smithy.io/2.0/aws/aws-core.html#behavior-with-httpchecksumrequired
*
* ContentMD5Middleware will skip checksum calculation if flexible checksum was calculated for request already,
* determined by presence of a header with "x-amz-checksum-" prefix.
*/
private fun OperationShape.isMD5ChecksumRequired(): Boolean =
// the checksum requirement can be modeled in either HttpChecksumTrait's `requestChecksumRequired` or the HttpChecksumRequired trait
getTrait<HttpChecksumTrait>()?.isRequestChecksumRequired == true || hasTrait<HttpChecksumRequiredTrait>()
private fun OperationShape.isMD5ChecksumRequired(): Boolean {
val httpChecksumTrait = getTrait<HttpChecksumTrait>()
val onlyRequestChecksumRequiredIsSetInHttpChecksumTrait = httpChecksumTrait?.isRequestChecksumRequired == true &&
httpChecksumTrait.requestAlgorithmMember?.isEmpty == true &&
httpChecksumTrait.requestValidationModeMember?.isEmpty == true &&
httpChecksumTrait.responseAlgorithms?.isEmpty() == true
return onlyRequestChecksumRequiredIsSetInHttpChecksumTrait || hasTrait<HttpChecksumRequiredTrait>()
}
Loading