summaryrefslogtreecommitdiff
path: root/vendor/github.com/mitchellh/packer/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mitchellh/packer/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go')
-rw-r--r--vendor/github.com/mitchellh/packer/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go109
1 files changed, 65 insertions, 44 deletions
diff --git a/vendor/github.com/mitchellh/packer/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/mitchellh/packer/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
index 98bfe742..d68905ac 100644
--- a/vendor/github.com/mitchellh/packer/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
+++ b/vendor/github.com/mitchellh/packer/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
@@ -45,7 +45,7 @@
// If signing a request intended for HTTP2 server, and you're using Go 1.6.2
// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the
// request URL. https://github.com/golang/go/issues/16847 points to a bug in
-// Go pre 1.8 that failes to make HTTP2 requests using absolute URL in the HTTP
+// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP
// message. URL.Opaque generally will force Go to make requests with absolute URL.
// URL.RawPath does not do this, but RawPath must be a valid escaping of Path
// or url.EscapedPath will ignore the RawPath escaping.
@@ -55,7 +55,6 @@
package v4
import (
- "bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
@@ -194,6 +193,10 @@ type Signer struct {
// This value should only be used for testing. If it is nil the default
// time.Now will be used.
currentTimeFn func() time.Time
+
+ // UnsignedPayload will prevent signing of the payload. This will only
+ // work for services that have support for this.
+ UnsignedPayload bool
}
// NewSigner returns a Signer pointer configured with the credentials and optional
@@ -227,6 +230,7 @@ type signingCtx struct {
isPresign bool
formattedTime string
formattedShortTime string
+ unsignedPayload bool
bodyDigest string
signedHeaders string
@@ -317,6 +321,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
ServiceName: service,
Region: region,
DisableURIPathEscaping: v4.DisableURIPathEscaping,
+ unsignedPayload: v4.UnsignedPayload,
}
for key := range ctx.Query {
@@ -396,7 +401,7 @@ var SignRequestHandler = request.NamedHandler{
}
// SignSDKRequest signs an AWS request with the V4 signature. This
-// request handler is bested used only with the SDK's built in service client's
+// request handler should only be used with the SDK's built in service client's
// API operation requests.
//
// This function should not be used on its on its own, but in conjunction with
@@ -409,7 +414,18 @@ var SignRequestHandler = request.NamedHandler{
func SignSDKRequest(req *request.Request) {
signSDKRequestWithCurrTime(req, time.Now)
}
-func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time) {
+
+// BuildNamedHandler will build a generic handler for signing.
+func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler {
+ return request.NamedHandler{
+ Name: name,
+ Fn: func(req *request.Request) {
+ signSDKRequestWithCurrTime(req, time.Now, opts...)
+ },
+ }
+}
+
+func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) {
// If the request does not need to be signed ignore the signing of the
// request if the AnonymousCredentials object is used.
if req.Config.Credentials == credentials.AnonymousCredentials {
@@ -441,6 +457,10 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time
v4.DisableRequestBodyOverwrite = true
})
+ for _, opt := range opts {
+ opt(v4)
+ }
+
signingTime := req.Time
if !req.LastSignedAt.IsZero() {
signingTime = req.LastSignedAt
@@ -583,14 +603,18 @@ func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
headerValues := make([]string, len(headers))
for i, k := range headers {
if k == "host" {
- headerValues[i] = "host:" + ctx.Request.URL.Host
+ if ctx.Request.Host != "" {
+ headerValues[i] = "host:" + ctx.Request.Host
+ } else {
+ headerValues[i] = "host:" + ctx.Request.URL.Host
+ }
} else {
headerValues[i] = k + ":" +
strings.Join(ctx.SignedHeaderVals[k], ",")
}
}
-
- ctx.canonicalHeaders = strings.Join(stripExcessSpaces(headerValues), "\n")
+ stripExcessSpaces(headerValues)
+ ctx.canonicalHeaders = strings.Join(headerValues, "\n")
}
func (ctx *signingCtx) buildCanonicalString() {
@@ -634,14 +658,14 @@ func (ctx *signingCtx) buildSignature() {
func (ctx *signingCtx) buildBodyDigest() {
hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
if hash == "" {
- if ctx.isPresign && ctx.ServiceName == "s3" {
+ if ctx.unsignedPayload || (ctx.isPresign && ctx.ServiceName == "s3") {
hash = "UNSIGNED-PAYLOAD"
} else if ctx.Body == nil {
hash = emptyStringSHA256
} else {
hash = hex.EncodeToString(makeSha256Reader(ctx.Body))
}
- if ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
+ if ctx.unsignedPayload || ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
ctx.Request.Header.Set("X-Amz-Content-Sha256", hash)
}
}
@@ -692,49 +716,46 @@ func makeSha256Reader(reader io.ReadSeeker) []byte {
return hash.Sum(nil)
}
-const doubleSpaces = " "
+const doubleSpace = " "
-var doubleSpaceBytes = []byte(doubleSpaces)
-
-func stripExcessSpaces(headerVals []string) []string {
- vals := make([]string, len(headerVals))
- for i, str := range headerVals {
- // Trim leading and trailing spaces
- trimmed := strings.TrimSpace(str)
+// stripExcessSpaces will rewrite the passed in slice's string values to not
+// contain muliple side-by-side spaces.
+func stripExcessSpaces(vals []string) {
+ var j, k, l, m, spaces int
+ for i, str := range vals {
+ // Trim trailing spaces
+ for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- {
+ }
- idx := strings.Index(trimmed, doubleSpaces)
- var buf []byte
- for idx > -1 {
- // Multiple adjacent spaces found
- if buf == nil {
- // first time create the buffer
- buf = []byte(trimmed)
- }
+ // Trim leading spaces
+ for k = 0; k < j && str[k] == ' '; k++ {
+ }
+ str = str[k : j+1]
- stripToIdx := -1
- for j := idx + 1; j < len(buf); j++ {
- if buf[j] != ' ' {
- buf = append(buf[:idx+1], buf[j:]...)
- stripToIdx = j
- break
- }
- }
+ // Strip multiple spaces.
+ j = strings.Index(str, doubleSpace)
+ if j < 0 {
+ vals[i] = str
+ continue
+ }
- if stripToIdx >= 0 {
- idx = bytes.Index(buf[stripToIdx:], doubleSpaceBytes)
- if idx >= 0 {
- idx += stripToIdx
+ buf := []byte(str)
+ for k, m, l = j, j, len(buf); k < l; k++ {
+ if buf[k] == ' ' {
+ if spaces == 0 {
+ // First space.
+ buf[m] = buf[k]
+ m++
}
+ spaces++
} else {
- idx = -1
+ // End of multiple spaces.
+ spaces = 0
+ buf[m] = buf[k]
+ m++
}
}
- if buf != nil {
- vals[i] = string(buf)
- } else {
- vals[i] = trimmed
- }
+ vals[i] = string(buf[:m])
}
- return vals
}