diff --git a/weed/s3api/s3_constants/header.go b/weed/s3api/s3_constants/header.go index 02335e0bd..c8f788bcb 100644 --- a/weed/s3api/s3_constants/header.go +++ b/weed/s3api/s3_constants/header.go @@ -87,6 +87,7 @@ const ( AmzTrailer = "X-Amz-Trailer" AmzSdkChecksumAlgorithm = "X-Amz-Sdk-Checksum-Algorithm" AmzChecksumType = "X-Amz-Checksum-Type" + AmzChecksumMode = "X-Amz-Checksum-Mode" // S3 checksum type values (x-amz-checksum-type). A COMPOSITE checksum is a // checksum-of-per-part-checksums ("base64-N"); a FULL_OBJECT checksum is the diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go index 142665c66..fb5f39660 100644 --- a/weed/s3api/s3api_object_handlers.go +++ b/weed/s3api/s3api_object_handlers.go @@ -2238,7 +2238,7 @@ func (s3a *S3ApiServer) setResponseHeaders(w http.ResponseWriter, r *http.Reques // 2. The response covers the full object (no Range header, no partNumber) // The stored checksum covers the full object; returning it for partial // responses causes SDK checksum validation failures. - if r != nil && r.Header.Get("X-Amz-Checksum-Mode") == "ENABLED" && r.Header.Get("Range") == "" && requestedPartNumber(r) == 0 { + if r != nil && strings.EqualFold(lookupHeaderOrQuery(r, parseRequestQuery(r), s3_constants.AmzChecksumMode), "ENABLED") && r.Header.Get("Range") == "" && requestedPartNumber(r) == 0 { if entry.Extended != nil { if algoName, ok := entry.Extended[s3_constants.ExtChecksumAlgorithm]; ok { if checksumVal, ok := entry.Extended[s3_constants.ExtChecksumValue]; ok {