From 7c0a9acb30de1885fea2f5c009b649d88d8dcf52 Mon Sep 17 00:00:00 2001 From: 7y-9 Date: Wed, 10 Jun 2026 15:30:43 +0800 Subject: [PATCH] fix(s3api): normalize checksum trailer header names (#9905) Problem: SigV4 chunked upload checksum trailer parsing rejected mixed-case checksum header names even though HTTP header field names are case-insensitive. Root cause: extractChecksumAlgorithm compared the x-amz-trailer value and trailer header key against exact lowercase strings. Fix: Trim and lowercase checksum trailer header names before matching supported checksum algorithms. Reproduction: go test ./weed/s3api -run TestExtractChecksumAlgorithmIsCaseInsensitive -count=1 with X-Amz-Checksum-Crc32; before the fix it returned unsupported checksum algorithm. Validation: gofmt -w weed/s3api/chunked_reader_v4.go weed/s3api/chunked_reader_v4_test.go; git diff --check; go test ./weed/s3api -run TestExtractChecksumAlgorithmIsCaseInsensitive -count=1; go test ./weed/s3api -count=1 Co-authored-by: Codex --- weed/s3api/chunked_reader_v4.go | 2 ++ weed/s3api/chunked_reader_v4_test.go | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/weed/s3api/chunked_reader_v4.go b/weed/s3api/chunked_reader_v4.go index 0d8677b20..31c711921 100644 --- a/weed/s3api/chunked_reader_v4.go +++ b/weed/s3api/chunked_reader_v4.go @@ -31,6 +31,7 @@ import ( "hash/crc32" "io" "net/http" + "strings" "time" "github.com/seaweedfs/seaweedfs/weed/glog" @@ -138,6 +139,7 @@ func (iam *IdentityAccessManagement) newChunkedReader(req *http.Request) (io.Rea func extractChecksumAlgorithm(amzTrailerHeader string) (ChecksumAlgorithm, error) { // Extract checksum algorithm from the x-amz-trailer header. + amzTrailerHeader = strings.ToLower(strings.TrimSpace(amzTrailerHeader)) switch amzTrailerHeader { case "x-amz-checksum-crc32": return ChecksumAlgorithmCRC32, nil diff --git a/weed/s3api/chunked_reader_v4_test.go b/weed/s3api/chunked_reader_v4_test.go index 3da13a71a..e386129c0 100644 --- a/weed/s3api/chunked_reader_v4_test.go +++ b/weed/s3api/chunked_reader_v4_test.go @@ -30,6 +30,16 @@ const ( defaultRegion = "us-east-1" ) +func TestExtractChecksumAlgorithmIsCaseInsensitive(t *testing.T) { + got, err := extractChecksumAlgorithm("X-Amz-Checksum-Crc32") + if err != nil { + t.Fatalf("extractChecksumAlgorithm returned error: %v", err) + } + if got != ChecksumAlgorithmCRC32 { + t.Fatalf("extractChecksumAlgorithm() = %v, want %v", got, ChecksumAlgorithmCRC32) + } +} + func generateStreamingUnsignedPayloadTrailerPayload(includeFinalCRLF bool) string { // This test will implement the following scenario: // https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html