From 62cae32f6f722bcbf5f97b69c125e19ea150776e Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Mon, 14 Aug 2017 16:47:26 -0700 Subject: [PATCH 1/3] aws/signer/v4: Correct V4 presign signature to include content sha25 in url Updates the V4 signer so that when a Presign is generated the X-Amz-Content-Sha256 header is added to the query string instead of being required to be in the header. This allows you to generate presigned URLs for GET requests, e.g S3.GetObject that do not require additional headers to be set by the downstream users of the presigned URL. Related to #1467 --- aws/request/request.go | 12 +++++++++--- aws/signer/v4/v4.go | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/aws/request/request.go b/aws/request/request.go index 088ba529025..911c058eef9 100644 --- a/aws/request/request.go +++ b/aws/request/request.go @@ -269,11 +269,17 @@ func (r *Request) Presign(expireTime time.Duration) (string, error) { return r.HTTPRequest.URL.String(), nil } -// PresignRequest behaves just like presign, but hoists all headers and signs them. -// Also returns the signed hash back to the user +// PresignRequest behaves just like presign, with the addition of returning a +// set of headers that were signed. +// +// Returns the URL string for the API operation with signature in the query string, +// and the HTTP headers that were included in the signature. These headers must +// be included in any HTTP request made with the presigned URL. +// +// To prevent hoisting any headers to the query string set NotHoist to true on +// this Request value prior to calling PresignRequest. func (r *Request) PresignRequest(expireTime time.Duration) (string, http.Header, error) { r.ExpireTime = expireTime - r.NotHoist = true r.Sign() if r.Error != nil { return "", nil, r.Error diff --git a/aws/signer/v4/v4.go b/aws/signer/v4/v4.go index d68905acbb1..15da57249a1 100644 --- a/aws/signer/v4/v4.go +++ b/aws/signer/v4/v4.go @@ -502,6 +502,8 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) { ctx.buildTime() // no depends ctx.buildCredentialString() // no depends + ctx.buildBodyDigest() + unsignedHeaders := ctx.Request.Header if ctx.isPresign { if !disableHeaderHoisting { @@ -513,7 +515,6 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) { } } - ctx.buildBodyDigest() ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) ctx.buildCanonicalString() // depends on canon headers / signed headers ctx.buildStringToSign() // depends on canon string From 175fb3ee280d47fbbf552d62ad5f9f1fd7b92622 Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Tue, 15 Aug 2017 13:35:51 -0700 Subject: [PATCH 2/3] fix unit tests for change --- aws/signer/v4/functional_test.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/aws/signer/v4/functional_test.go b/aws/signer/v4/functional_test.go index 9b6b0be241d..97bf3688ed0 100644 --- a/aws/signer/v4/functional_test.go +++ b/aws/signer/v4/functional_test.go @@ -45,7 +45,7 @@ func TestPresignHandler(t *testing.T) { expectedHost := "bucket.s3.mock-region.amazonaws.com" expectedDate := "19700101T000000Z" expectedHeaders := "content-disposition;host;x-amz-acl" - expectedSig := "2d76a414208c0eac2a23ef9c834db9635ecd5a0fbb447a00ad191f82d854f55b" + expectedSig := "a46583256431b09eb45ba4af2e6286d96a9835ed13721023dc8076dfdcb90fcb" expectedCred := "AKID/19700101/mock-region/s3/aws4_request" u, _ := url.Parse(urlstr) @@ -56,6 +56,7 @@ func TestPresignHandler(t *testing.T) { assert.Equal(t, expectedHeaders, urlQ.Get("X-Amz-SignedHeaders")) assert.Equal(t, expectedDate, urlQ.Get("X-Amz-Date")) assert.Equal(t, "300", urlQ.Get("X-Amz-Expires")) + assert.Equal(t, "UNSIGNED-PAYLOAD", urlQ.Get("X-Amz-Content-Sha256")) assert.NotContains(t, urlstr, "+") // + encoded as %20 } @@ -75,13 +76,12 @@ func TestPresignRequest(t *testing.T) { expectedHost := "bucket.s3.mock-region.amazonaws.com" expectedDate := "19700101T000000Z" - expectedHeaders := "content-disposition;host;x-amz-acl;x-amz-content-sha256" - expectedSig := "a5b2b500dfbf2eab5b4f55bec3e3752e04536ea1d5c047aa93bc9f1130a72cd2" + expectedHeaders := "content-disposition;host;x-amz-acl" + expectedSig := "a46583256431b09eb45ba4af2e6286d96a9835ed13721023dc8076dfdcb90fcb" expectedCred := "AKID/19700101/mock-region/s3/aws4_request" expectedHeaderMap := http.Header{ - "x-amz-acl": []string{"public-read"}, - "content-disposition": []string{"a+b c$d"}, - "x-amz-content-sha256": []string{"UNSIGNED-PAYLOAD"}, + "x-amz-acl": []string{"public-read"}, + "content-disposition": []string{"a+b c$d"}, } u, _ := url.Parse(urlstr) @@ -93,6 +93,7 @@ func TestPresignRequest(t *testing.T) { assert.Equal(t, expectedDate, urlQ.Get("X-Amz-Date")) assert.Equal(t, expectedHeaderMap, headers) assert.Equal(t, "300", urlQ.Get("X-Amz-Expires")) + assert.Equal(t, "UNSIGNED-PAYLOAD", urlQ.Get("X-Amz-Content-Sha256")) assert.NotContains(t, urlstr, "+") // + encoded as %20 } From ab0b0f3b31041131f98c4648206c3747455b9e1c Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Tue, 15 Aug 2017 13:58:03 -0700 Subject: [PATCH 3/3] remove assert from v4 package. --- aws/signer/v4/functional_test.go | 95 ++++++++++---- aws/signer/v4/v4_test.go | 207 +++++++++++++++++++++++-------- 2 files changed, 224 insertions(+), 78 deletions(-) diff --git a/aws/signer/v4/functional_test.go b/aws/signer/v4/functional_test.go index 97bf3688ed0..c5341a9351e 100644 --- a/aws/signer/v4/functional_test.go +++ b/aws/signer/v4/functional_test.go @@ -3,6 +3,8 @@ package v4_test import ( "net/http" "net/url" + "reflect" + "strings" "testing" "time" @@ -10,7 +12,6 @@ import ( "github.com/aws/aws-sdk-go/aws/signer/v4" "github.com/aws/aws-sdk-go/awstesting/unit" "github.com/aws/aws-sdk-go/service/s3" - "github.com/stretchr/testify/assert" ) var standaloneSignCases = []struct { @@ -40,7 +41,9 @@ func TestPresignHandler(t *testing.T) { req.Time = time.Unix(0, 0) urlstr, err := req.Presign(5 * time.Minute) - assert.NoError(t, err) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } expectedHost := "bucket.s3.mock-region.amazonaws.com" expectedDate := "19700101T000000Z" @@ -50,15 +53,31 @@ func TestPresignHandler(t *testing.T) { u, _ := url.Parse(urlstr) urlQ := u.Query() - assert.Equal(t, expectedHost, u.Host) - assert.Equal(t, expectedSig, urlQ.Get("X-Amz-Signature")) - assert.Equal(t, expectedCred, urlQ.Get("X-Amz-Credential")) - assert.Equal(t, expectedHeaders, urlQ.Get("X-Amz-SignedHeaders")) - assert.Equal(t, expectedDate, urlQ.Get("X-Amz-Date")) - assert.Equal(t, "300", urlQ.Get("X-Amz-Expires")) - assert.Equal(t, "UNSIGNED-PAYLOAD", urlQ.Get("X-Amz-Content-Sha256")) - - assert.NotContains(t, urlstr, "+") // + encoded as %20 + if e, a := expectedHost, u.Host; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedSig, urlQ.Get("X-Amz-Signature"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedCred, urlQ.Get("X-Amz-Credential"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedHeaders, urlQ.Get("X-Amz-SignedHeaders"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedDate, urlQ.Get("X-Amz-Date"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := "300", urlQ.Get("X-Amz-Expires"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := "UNSIGNED-PAYLOAD", urlQ.Get("X-Amz-Content-Sha256"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + + if e, a := "+", urlstr; strings.Contains(a, e) { // + encoded as %20 + t.Errorf("expect %v not to be in %v", e, a) + } } func TestPresignRequest(t *testing.T) { @@ -72,7 +91,9 @@ func TestPresignRequest(t *testing.T) { req.Time = time.Unix(0, 0) urlstr, headers, err := req.PresignRequest(5 * time.Minute) - assert.NoError(t, err) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } expectedHost := "bucket.s3.mock-region.amazonaws.com" expectedDate := "19700101T000000Z" @@ -86,16 +107,34 @@ func TestPresignRequest(t *testing.T) { u, _ := url.Parse(urlstr) urlQ := u.Query() - assert.Equal(t, expectedHost, u.Host) - assert.Equal(t, expectedSig, urlQ.Get("X-Amz-Signature")) - assert.Equal(t, expectedCred, urlQ.Get("X-Amz-Credential")) - assert.Equal(t, expectedHeaders, urlQ.Get("X-Amz-SignedHeaders")) - assert.Equal(t, expectedDate, urlQ.Get("X-Amz-Date")) - assert.Equal(t, expectedHeaderMap, headers) - assert.Equal(t, "300", urlQ.Get("X-Amz-Expires")) - assert.Equal(t, "UNSIGNED-PAYLOAD", urlQ.Get("X-Amz-Content-Sha256")) - - assert.NotContains(t, urlstr, "+") // + encoded as %20 + if e, a := expectedHost, u.Host; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedSig, urlQ.Get("X-Amz-Signature"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedCred, urlQ.Get("X-Amz-Credential"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedHeaders, urlQ.Get("X-Amz-SignedHeaders"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedDate, urlQ.Get("X-Amz-Date"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedHeaderMap, headers; !reflect.DeepEqual(e, a) { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := "300", urlQ.Get("X-Amz-Expires"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := "UNSIGNED-PAYLOAD", urlQ.Get("X-Amz-Content-Sha256"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + + if e, a := "+", urlstr; strings.Contains(a, e) { // + encoded as %20 + t.Errorf("expect %v not to be in %v", e, a) + } } func TestStandaloneSign_CustomURIEscape(t *testing.T) { @@ -108,14 +147,20 @@ func TestStandaloneSign_CustomURIEscape(t *testing.T) { host := "https://subdomain.us-east-1.es.amazonaws.com" req, err := http.NewRequest("GET", host, nil) - assert.NoError(t, err) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } req.URL.Path = `/log-*/_search` req.URL.Opaque = "//subdomain.us-east-1.es.amazonaws.com/log-%2A/_search" _, err = signer.Sign(req, nil, "es", "us-east-1", time.Unix(0, 0)) - assert.NoError(t, err) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } actual := req.Header.Get("Authorization") - assert.Equal(t, expectSig, actual) + if e, a := expectSig, actual; e != a { + t.Errorf("expect %v, got %v", e, a) + } } diff --git a/aws/signer/v4/v4_test.go b/aws/signer/v4/v4_test.go index e94e6349108..45d0eb8869a 100644 --- a/aws/signer/v4/v4_test.go +++ b/aws/signer/v4/v4_test.go @@ -6,12 +6,11 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "reflect" "strings" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/request" @@ -55,7 +54,9 @@ func TestStripExcessHeaders(t *testing.T) { stripExcessSpaces(vals) for i := 0; i < len(vals); i++ { - assert.Equal(t, expected[i], vals[i], "test: %d", i) + if e, a := expected[i], vals[i]; e != a { + t.Errorf("%d, expect %v, got %v", i, e, a) + } } } @@ -105,12 +106,24 @@ func TestPresignRequest(t *testing.T) { expectedTarget := "prefix.Operation" q := req.URL.Query() - assert.Equal(t, expectedSig, q.Get("X-Amz-Signature")) - assert.Equal(t, expectedCred, q.Get("X-Amz-Credential")) - assert.Equal(t, expectedHeaders, q.Get("X-Amz-SignedHeaders")) - assert.Equal(t, expectedDate, q.Get("X-Amz-Date")) - assert.Empty(t, q.Get("X-Amz-Meta-Other-Header")) - assert.Equal(t, expectedTarget, q.Get("X-Amz-Target")) + if e, a := expectedSig, q.Get("X-Amz-Signature"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedCred, q.Get("X-Amz-Credential"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedHeaders, q.Get("X-Amz-SignedHeaders"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedDate, q.Get("X-Amz-Date"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if a := q.Get("X-Amz-Meta-Other-Header"); len(a) != 0 { + t.Errorf("expect %v to be empty", a) + } + if e, a := expectedTarget, q.Get("X-Amz-Target"); e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestPresignBodyWithArrayRequest(t *testing.T) { @@ -127,12 +140,24 @@ func TestPresignBodyWithArrayRequest(t *testing.T) { expectedTarget := "prefix.Operation" q := req.URL.Query() - assert.Equal(t, expectedSig, q.Get("X-Amz-Signature")) - assert.Equal(t, expectedCred, q.Get("X-Amz-Credential")) - assert.Equal(t, expectedHeaders, q.Get("X-Amz-SignedHeaders")) - assert.Equal(t, expectedDate, q.Get("X-Amz-Date")) - assert.Empty(t, q.Get("X-Amz-Meta-Other-Header")) - assert.Equal(t, expectedTarget, q.Get("X-Amz-Target")) + if e, a := expectedSig, q.Get("X-Amz-Signature"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedCred, q.Get("X-Amz-Credential"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedHeaders, q.Get("X-Amz-SignedHeaders"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedDate, q.Get("X-Amz-Date"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if a := q.Get("X-Amz-Meta-Other-Header"); len(a) != 0 { + t.Errorf("expect %v to be empty, was not", a) + } + if e, a := expectedTarget, q.Get("X-Amz-Target"); e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestSignRequest(t *testing.T) { @@ -144,8 +169,12 @@ func TestSignRequest(t *testing.T) { expectedSig := "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/dynamodb/aws4_request, SignedHeaders=content-length;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=ea766cabd2ec977d955a3c2bae1ae54f4515d70752f2207618396f20aa85bd21" q := req.Header - assert.Equal(t, expectedSig, q.Get("Authorization")) - assert.Equal(t, expectedDate, q.Get("X-Amz-Date")) + if e, a := expectedSig, q.Get("Authorization"); e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := expectedDate, q.Get("X-Amz-Date"); e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestSignBodyS3(t *testing.T) { @@ -153,7 +182,9 @@ func TestSignBodyS3(t *testing.T) { signer := buildSigner() signer.Sign(req, body, "s3", "us-east-1", time.Now()) hash := req.Header.Get("X-Amz-Content-Sha256") - assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash) + if e, a := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash; e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestSignBodyGlacier(t *testing.T) { @@ -161,7 +192,9 @@ func TestSignBodyGlacier(t *testing.T) { signer := buildSigner() signer.Sign(req, body, "glacier", "us-east-1", time.Now()) hash := req.Header.Get("X-Amz-Content-Sha256") - assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash) + if e, a := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash; e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestPresignEmptyBodyS3(t *testing.T) { @@ -169,7 +202,9 @@ func TestPresignEmptyBodyS3(t *testing.T) { signer := buildSigner() signer.Presign(req, body, "s3", "us-east-1", 5*time.Minute, time.Now()) hash := req.Header.Get("X-Amz-Content-Sha256") - assert.Equal(t, "UNSIGNED-PAYLOAD", hash) + if e, a := "UNSIGNED-PAYLOAD", hash; e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestSignPrecomputedBodyChecksum(t *testing.T) { @@ -178,7 +213,9 @@ func TestSignPrecomputedBodyChecksum(t *testing.T) { signer := buildSigner() signer.Sign(req, body, "dynamodb", "us-east-1", time.Now()) hash := req.Header.Get("X-Amz-Content-Sha256") - assert.Equal(t, "PRECOMPUTED", hash) + if e, a := "PRECOMPUTED", hash; e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestAnonymousCredentials(t *testing.T) { @@ -195,14 +232,26 @@ func TestAnonymousCredentials(t *testing.T) { SignSDKRequest(r) urlQ := r.HTTPRequest.URL.Query() - assert.Empty(t, urlQ.Get("X-Amz-Signature")) - assert.Empty(t, urlQ.Get("X-Amz-Credential")) - assert.Empty(t, urlQ.Get("X-Amz-SignedHeaders")) - assert.Empty(t, urlQ.Get("X-Amz-Date")) + if a := urlQ.Get("X-Amz-Signature"); len(a) != 0 { + t.Errorf("expect %v to be empty, was not", a) + } + if a := urlQ.Get("X-Amz-Credential"); len(a) != 0 { + t.Errorf("expect %v to be empty, was not", a) + } + if a := urlQ.Get("X-Amz-SignedHeaders"); len(a) != 0 { + t.Errorf("expect %v to be empty, was not", a) + } + if a := urlQ.Get("X-Amz-Date"); len(a) != 0 { + t.Errorf("expect %v to be empty, was not", a) + } hQ := r.HTTPRequest.Header - assert.Empty(t, hQ.Get("Authorization")) - assert.Empty(t, hQ.Get("X-Amz-Date")) + if a := hQ.Get("Authorization"); len(a) != 0 { + t.Errorf("expect %v to be empty, was not", a) + } + if a := hQ.Get("X-Amz-Date"); len(a) != 0 { + t.Errorf("expect %v to be empty, was not", a) + } } func TestIgnoreResignRequestWithValidCreds(t *testing.T) { @@ -228,7 +277,9 @@ func TestIgnoreResignRequestWithValidCreds(t *testing.T) { // when it is resigned. return time.Now().Add(1 * time.Second) }) - assert.NotEqual(t, sig, r.HTTPRequest.Header.Get("Authorization")) + if e, a := sig, r.HTTPRequest.Header.Get("Authorization"); e == a { + t.Errorf("expect %v to be %v, but was not", e, a) + } } func TestIgnorePreResignRequestWithValidCreds(t *testing.T) { @@ -255,7 +306,9 @@ func TestIgnorePreResignRequestWithValidCreds(t *testing.T) { // when it is resigned. return time.Now().Add(1 * time.Second) }) - assert.NotEqual(t, sig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature")) + if e, a := sig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature"); e == a { + t.Errorf("expect %v to be %v, but was not", e, a) + } } func TestResignRequestExpiredCreds(t *testing.T) { @@ -279,8 +332,12 @@ func TestResignRequestExpiredCreds(t *testing.T) { break } } - assert.NotEmpty(t, origSignedHeaders) - assert.NotContains(t, origSignedHeaders, "authorization") + if a := origSignedHeaders; len(a) == 0 { + t.Errorf("expect not to be empty, but was") + } + if e, a := origSignedHeaders, "authorization"; strings.Contains(a, e) { + t.Errorf("expect %v to not be in %v, but was", e, a) + } origSignedAt := r.LastSignedAt creds.Expire() @@ -291,7 +348,9 @@ func TestResignRequestExpiredCreds(t *testing.T) { return time.Now().Add(1 * time.Second) }) updatedQuerySig := r.HTTPRequest.Header.Get("Authorization") - assert.NotEqual(t, querySig, updatedQuerySig) + if e, a := querySig, updatedQuerySig; e == a { + t.Errorf("expect %v to be %v, was not", e, a) + } var updatedSignedHeaders string for _, p := range strings.Split(updatedQuerySig, ", ") { @@ -300,9 +359,15 @@ func TestResignRequestExpiredCreds(t *testing.T) { break } } - assert.NotEmpty(t, updatedSignedHeaders) - assert.NotContains(t, updatedQuerySig, "authorization") - assert.NotEqual(t, origSignedAt, r.LastSignedAt) + if a := updatedSignedHeaders; len(a) == 0 { + t.Errorf("expect not to be empty, but was") + } + if e, a := updatedQuerySig, "authorization"; strings.Contains(a, e) { + t.Errorf("expect %v to not be in %v, but was", e, a) + } + if e, a := origSignedAt, r.LastSignedAt; e == a { + t.Errorf("expect %v to be %v, was not", e, a) + } } func TestPreResignRequestExpiredCreds(t *testing.T) { @@ -327,7 +392,9 @@ func TestPreResignRequestExpiredCreds(t *testing.T) { SignSDKRequest(r) querySig := r.HTTPRequest.URL.Query().Get("X-Amz-Signature") signedHeaders := r.HTTPRequest.URL.Query().Get("X-Amz-SignedHeaders") - assert.NotEmpty(t, signedHeaders) + if a := signedHeaders; len(a) == 0 { + t.Errorf("expect not to be empty, but was") + } origSignedAt := r.LastSignedAt creds.Expire() @@ -336,11 +403,19 @@ func TestPreResignRequestExpiredCreds(t *testing.T) { // Simulate the request occurred 15 minutes in the past return time.Now().Add(-48 * time.Hour) }) - assert.NotEqual(t, querySig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature")) + if e, a := querySig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature"); e == a { + t.Errorf("expect %v to be %v, was not", e, a) + } resignedHeaders := r.HTTPRequest.URL.Query().Get("X-Amz-SignedHeaders") - assert.Equal(t, signedHeaders, resignedHeaders) - assert.NotContains(t, signedHeaders, "x-amz-signedHeaders") - assert.NotEqual(t, origSignedAt, r.LastSignedAt) + if e, a := signedHeaders, resignedHeaders; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := signedHeaders, "x-amz-signedHeaders"; strings.Contains(a, e) { + t.Errorf("expect %v to not be in %v, but was", e, a) + } + if e, a := origSignedAt, r.LastSignedAt; e == a { + t.Errorf("expect %v to be %v, was not", e, a) + } } func TestResignRequestExpiredRequest(t *testing.T) { @@ -364,8 +439,12 @@ func TestResignRequestExpiredRequest(t *testing.T) { // Simulate the request occurred 15 minutes in the past return time.Now().Add(15 * time.Minute) }) - assert.NotEqual(t, querySig, r.HTTPRequest.Header.Get("Authorization")) - assert.NotEqual(t, origSignedAt, r.LastSignedAt) + if e, a := querySig, r.HTTPRequest.Header.Get("Authorization"); e == a { + t.Errorf("expect %v to be %v, was not", e, a) + } + if e, a := origSignedAt, r.LastSignedAt; e == a { + t.Errorf("expect %v to be %v, was not", e, a) + } } func TestSignWithRequestBody(t *testing.T) { @@ -377,19 +456,29 @@ func TestSignWithRequestBody(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { b, err := ioutil.ReadAll(r.Body) r.Body.Close() - assert.NoError(t, err) - assert.Equal(t, expectBody, b) + if err != nil { + t.Errorf("expect no error, got %v", err) + } + if e, a := expectBody, b; !reflect.DeepEqual(e, a) { + t.Errorf("expect %v, got %v", e, a) + } w.WriteHeader(http.StatusOK) })) req, err := http.NewRequest("POST", server.URL, nil) _, err = signer.Sign(req, bytes.NewReader(expectBody), "service", "region", time.Now()) - assert.NoError(t, err) + if err != nil { + t.Errorf("expect not no error, got %v", err) + } resp, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) + if err != nil { + t.Errorf("expect not no error, got %v", err) + } + if e, a := http.StatusOK, resp.StatusCode; e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestSignWithRequestBody_Overwrite(t *testing.T) { @@ -401,8 +490,12 @@ func TestSignWithRequestBody_Overwrite(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { b, err := ioutil.ReadAll(r.Body) r.Body.Close() - assert.NoError(t, err) - assert.Equal(t, len(expectBody), len(b)) + if err != nil { + t.Errorf("expect not no error, got %v", err) + } + if e, a := len(expectBody), len(b); e != a { + t.Errorf("expect %v, got %v", e, a) + } w.WriteHeader(http.StatusOK) })) @@ -411,11 +504,17 @@ func TestSignWithRequestBody_Overwrite(t *testing.T) { _, err = signer.Sign(req, nil, "service", "region", time.Now()) req.ContentLength = 0 - assert.NoError(t, err) + if err != nil { + t.Errorf("expect not no error, got %v", err) + } resp, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) + if err != nil { + t.Errorf("expect not no error, got %v", err) + } + if e, a := http.StatusOK, resp.StatusCode; e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestBuildCanonicalRequest(t *testing.T) { @@ -433,7 +532,9 @@ func TestBuildCanonicalRequest(t *testing.T) { ctx.buildCanonicalString() expected := "https://example.org/bucket/key-._~,!@#$%^&*()?Foo=z&Foo=o&Foo=m&Foo=a" - assert.Equal(t, expected, ctx.Request.URL.String()) + if e, a := expected, ctx.Request.URL.String(); e != a { + t.Errorf("expect %v, got %v", e, a) + } } func TestSignWithBody_ReplaceRequestBody(t *testing.T) {