v4/presign: Fix presign requests when there are more signed headers. (#3222)

This fix removes a wrong logic which fails for requests which
have more signed headers in a presign request.

Fixes #3217
This commit is contained in:
Harshavardhana
2016-11-10 21:57:15 -08:00
committed by GitHub
parent cf022de4d5
commit a8ab02a73a
7 changed files with 129 additions and 37 deletions

View File

@@ -33,10 +33,17 @@ const unsignedPayload = "UNSIGNED-PAYLOAD"
// http Header "x-amz-content-sha256" == "UNSIGNED-PAYLOAD" indicates that the
// client did not calculate sha256 of the payload. Hence we skip calculating sha256.
// We also skip calculating sha256 for presigned requests without "x-amz-content-sha256" header.
// We also skip calculating sha256 for presigned requests without "x-amz-content-sha256"
// query header.
func skipContentSha256Cksum(r *http.Request) bool {
contentSha256 := r.Header.Get("X-Amz-Content-Sha256")
return isRequestUnsignedPayload(r) || (isRequestPresignedSignatureV4(r) && contentSha256 == "")
queryContentSha256 := r.URL.Query().Get("X-Amz-Content-Sha256")
isRequestPresignedUnsignedPayload := func(r *http.Request) bool {
if isRequestPresignedSignatureV4(r) {
return queryContentSha256 == "" || queryContentSha256 == unsignedPayload
}
return false
}
return isRequestUnsignedPayload(r) || isRequestPresignedUnsignedPayload(r)
}
// isValidRegion - verify if incoming region value is valid with configured Region.
@@ -99,27 +106,24 @@ func getURLEncodedName(name string) string {
return encodedName
}
// find whether "host" is part of list of signed headers.
func findHost(signedHeaders []string) APIErrorCode {
for _, header := range signedHeaders {
if header == "host" {
return ErrNone
}
if contains(signedHeaders, "host") {
return ErrNone
}
return ErrUnsignedHeaders
}
// extractSignedHeaders extract signed headers from Authorization header
func extractSignedHeaders(signedHeaders []string, reqHeaders http.Header) (http.Header, APIErrorCode) {
errCode := findHost(signedHeaders)
if errCode != ErrNone {
return nil, errCode
// find whether "host" is part of list of signed headers.
// if not return ErrUnsignedHeaders. "host" is mandatory.
if !contains(signedHeaders, "host") {
return nil, ErrUnsignedHeaders
}
extractedSignedHeaders := make(http.Header)
for _, header := range signedHeaders {
// `host` will not be found in the headers, can be found in r.Host.
// but its alway necessary that the list of signed headers containing host in it.
val, ok := reqHeaders[http.CanonicalHeaderKey(header)]
if !ok {
// Golang http server strips off 'Expect' header, if the
@@ -153,7 +157,6 @@ func extractSignedHeaders(signedHeaders []string, reqHeaders http.Header) (http.
}
extractedSignedHeaders[header] = val
}
return extractedSignedHeaders, ErrNone
}