mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -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
|
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.
|
// 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 {
|
if errCode != ErrNone {
|
||||||
return errCode
|
return errCode
|
||||||
}
|
}
|
||||||
|
13
cmd/utils.go
13
cmd/utils.go
@ -21,6 +21,7 @@ import (
|
|||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
@ -30,6 +31,18 @@ import (
|
|||||||
"github.com/pkg/profile"
|
"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.
|
// xmlDecoder provide decoded value in xml.
|
||||||
func xmlDecoder(body io.Reader, v interface{}, size int64) error {
|
func xmlDecoder(body io.Reader, v interface{}, size int64) error {
|
||||||
var lbody io.Reader
|
var lbody io.Reader
|
||||||
|
@ -16,7 +16,35 @@
|
|||||||
|
|
||||||
package cmd
|
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.
|
// Tests maximum object size.
|
||||||
func TestMaxObjectSize(t *testing.T) {
|
func TestMaxObjectSize(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user