From d9bab6b3bdb6e9438c9e7c5bc382fb1d3d24ee4d Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Fri, 4 Nov 2016 00:41:25 +0100 Subject: [PATCH] sigv4: Trim and shrink spaces in headers values (#3162) --- cmd/signature-v4-utils.go | 16 ++++++++++++++++ cmd/signature-v4-utils_test.go | 28 ++++++++++++++++++++++++++++ cmd/signature-v4.go | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/cmd/signature-v4-utils.go b/cmd/signature-v4-utils.go index b0e5bc6ea..675c9b9b6 100644 --- a/cmd/signature-v4-utils.go +++ b/cmd/signature-v4-utils.go @@ -157,3 +157,19 @@ func extractSignedHeaders(signedHeaders []string, reqHeaders http.Header) (http. return extractedSignedHeaders, ErrNone } + +// Trim leading and trailing spaces and replace sequential spaces with one space, following Trimall() +// in http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html +func signV4TrimAll(input string) string { + // Remove all whitespaces first + cleanWhiteSpaces := func(r rune) rune { + switch r { + case '\t', '\n', '\u000b', '\r', '\f': + return ' ' + } + return r + } + input = strings.Map(cleanWhiteSpaces, input) + // Compress adjacent spaces to one space and return + return strings.Join(strings.Fields(input), " ") +} diff --git a/cmd/signature-v4-utils_test.go b/cmd/signature-v4-utils_test.go index 03418a08d..71995bd94 100644 --- a/cmd/signature-v4-utils_test.go +++ b/cmd/signature-v4-utils_test.go @@ -211,3 +211,31 @@ func TestFindHost(t *testing.T) { t.Fatalf("Expected the APIErrorCode to be %d, but got %d", ErrNone, errCode) } } + +// TestSigV4TrimAll - tests the logic of TrimAll() function +func TestSigV4TrimAll(t *testing.T) { + testCases := []struct { + // Input. + inputStr string + // Expected result. + result string + }{ + {"本語", "本語"}, + {" abc ", "abc"}, + {" a b ", "a b"}, + {"a b ", "a b"}, + {"a b", "a b"}, + {"a b", "a b"}, + {" a b c ", "a b c"}, + {"a \t b c ", "a b c"}, + {"\"a \t b c ", "\"a b c"}, + } + + // Tests generated values from url encoded name. + for i, testCase := range testCases { + result := signV4TrimAll(testCase.inputStr) + if testCase.result != result { + t.Errorf("Test %d: Expected sigV4TrimAll result to be \"%s\", but found it to be \"%s\" instead", i+1, testCase.result, result) + } + } +} diff --git a/cmd/signature-v4.go b/cmd/signature-v4.go index 15952e8ac..333d4ecf3 100644 --- a/cmd/signature-v4.go +++ b/cmd/signature-v4.go @@ -68,7 +68,7 @@ func getCanonicalHeaders(signedHeaders http.Header, host string) string { if idx > 0 { buf.WriteByte(',') } - buf.WriteString(v) + buf.WriteString(signV4TrimAll(v)) } buf.WriteByte('\n') }