mirror of
https://github.com/minio/minio.git
synced 2024-12-23 21:55:53 -05:00
Signature-V4: Include content-length for signature calculation. (#2643)
This is to be compatible with clients which includes content-length for signature calculation (and hence deviating from AWS Signature-v4 spec)
This commit is contained in:
parent
a4afb312d4
commit
400e9309f1
@ -342,8 +342,21 @@ func doesSignatureMatch(hashedPayload string, r *http.Request, validateRegion bo
|
||||
return ErrContentSHA256Mismatch
|
||||
}
|
||||
|
||||
header := req.Header
|
||||
|
||||
// Signature-V4 spec excludes Content-Length from signed headers list for signature calculation.
|
||||
// But some clients deviate from this rule. Hence we consider Content-Length for signature
|
||||
// calculation to be compatible with such clients.
|
||||
for _, h := range signV4Values.SignedHeaders {
|
||||
if h == "content-length" {
|
||||
header = cloneHeader(req.Header)
|
||||
header.Add("content-length", strconv.FormatInt(r.ContentLength, 10))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Extract all the signed headers along with its values.
|
||||
extractedSignedHeaders, errCode := extractSignedHeaders(signV4Values.SignedHeaders, req.Header)
|
||||
extractedSignedHeaders, errCode := extractSignedHeaders(signV4Values.SignedHeaders, header)
|
||||
if errCode != ErrNone {
|
||||
return errCode
|
||||
}
|
||||
|
13
cmd/utils.go
13
cmd/utils.go
@ -21,6 +21,7 @@ import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
@ -30,6 +31,18 @@ import (
|
||||
"github.com/pkg/profile"
|
||||
)
|
||||
|
||||
// make a copy of http.Header
|
||||
func cloneHeader(h http.Header) http.Header {
|
||||
h2 := make(http.Header, len(h))
|
||||
for k, vv := range h {
|
||||
vv2 := make([]string, len(vv))
|
||||
copy(vv2, vv)
|
||||
h2[k] = vv2
|
||||
|
||||
}
|
||||
return h2
|
||||
}
|
||||
|
||||
// xmlDecoder provide decoded value in xml.
|
||||
func xmlDecoder(body io.Reader, v interface{}, size int64) error {
|
||||
var lbody io.Reader
|
||||
|
@ -16,7 +16,35 @@
|
||||
|
||||
package cmd
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests http.Header clone.
|
||||
func TestCloneHeader(t *testing.T) {
|
||||
headers := []http.Header{
|
||||
http.Header{
|
||||
"Content-Type": {"text/html; charset=UTF-8"},
|
||||
"Content-Length": {"0"},
|
||||
},
|
||||
http.Header{
|
||||
"Content-Length": {"0", "1", "2"},
|
||||
},
|
||||
http.Header{
|
||||
"Expires": {"-1"},
|
||||
"Content-Length": {"0"},
|
||||
"Content-Encoding": {"gzip"},
|
||||
},
|
||||
}
|
||||
for i, header := range headers {
|
||||
clonedHeader := cloneHeader(header)
|
||||
if !reflect.DeepEqual(header, clonedHeader) {
|
||||
t.Errorf("Test %d failed", i+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests maximum object size.
|
||||
func TestMaxObjectSize(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user