Skip to content

Commit

Permalink
Fix MD5 middleware generation criteria in codegen code & MD5 checksum…
Browse files Browse the repository at this point in the history
… hash calculation critera in runtime code.
  • Loading branch information
Sichan Yoo committed Dec 14, 2024
1 parent aa57fd7 commit 93e1c4b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
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>()
}

0 comments on commit 93e1c4b

Please sign in to comment.