diff --git a/private/signer/v4/v4.go b/private/signer/v4/v4.go index 14b0c661611..5611e593d16 100644 --- a/private/signer/v4/v4.go +++ b/private/signer/v4/v4.go @@ -303,13 +303,18 @@ func (v4 *signer) buildCanonicalHeaders(r rule, header http.Header) { if !r.IsValid(canonicalKey) { continue // ignored header } - - lowerCaseKey := strings.ToLower(k) - headers = append(headers, lowerCaseKey) - if v4.signedHeaderVals == nil { v4.signedHeaderVals = make(http.Header) } + + lowerCaseKey := strings.ToLower(k) + if _, ok := v4.signedHeaderVals[lowerCaseKey]; ok { + // include additional values + v4.signedHeaderVals[lowerCaseKey] = append(v4.signedHeaderVals[lowerCaseKey], v...) + continue + } + + headers = append(headers, lowerCaseKey) v4.signedHeaderVals[lowerCaseKey] = v } sort.Strings(headers) @@ -326,7 +331,7 @@ func (v4 *signer) buildCanonicalHeaders(r rule, header http.Header) { headerValues[i] = "host:" + v4.Request.URL.Host } else { headerValues[i] = k + ":" + - strings.Join(v4.Request.Header[http.CanonicalHeaderKey(k)], ",") + strings.Join(v4.signedHeaderVals[k], ",") } } diff --git a/private/signer/v4/v4_test.go b/private/signer/v4/v4_test.go index a417a64b4c4..f8e4f4ce727 100644 --- a/private/signer/v4/v4_test.go +++ b/private/signer/v4/v4_test.go @@ -23,6 +23,8 @@ func buildSigner(serviceName string, region string, signTime time.Time, expireTi req.Header.Add("Content-Type", "application/x-amz-json-1.0") req.Header.Add("Content-Length", string(len(body))) req.Header.Add("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)") + req.Header.Add("X-Amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)") + req.Header.Add("X-amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)") return signer{ Request: req, @@ -54,8 +56,8 @@ func TestPresignRequest(t *testing.T) { signer.sign() expectedDate := "19700101T000000Z" - expectedHeaders := "content-type;host;x-amz-meta-other-header" - expectedSig := "4fe8944ddd3e83a32bc874955e734e5a349116bfce2d4f43171e0f7572b842f6" + expectedHeaders := "content-type;host;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore" + expectedSig := "59c79b83112a55d188a0708cdfd776f19e4265e700990c60798a05d8923a1300" expectedCred := "AKID/19700101/us-east-1/dynamodb/aws4_request" expectedTarget := "prefix.Operation" @@ -73,7 +75,7 @@ func TestSignRequest(t *testing.T) { signer.sign() expectedDate := "19700101T000000Z" - expectedSig := "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-meta-other-header;x-amz-security-token;x-amz-target, Signature=5d3983fb3de907bdc2f3a6951d968e510f0252a8358c038f7680aa02374eeb67" + expectedSig := "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore;x-amz-security-token;x-amz-target, Signature=47f95059b6f4c3fb5043545281560b3366961d3014757f8aac7480953c344509" q := signer.Request.Header assert.Equal(t, expectedSig, q.Get("Authorization"))