From 62cae32f6f722bcbf5f97b69c125e19ea150776e Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Mon, 14 Aug 2017 16:47:26 -0700 Subject: [PATCH] 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