summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/minio/minio-go/pkg/s3signer
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/minio/minio-go/pkg/s3signer')
-rw-r--r--vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming.go60
-rw-r--r--vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go6
-rw-r--r--vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4.go13
-rw-r--r--vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go8
4 files changed, 59 insertions, 28 deletions
diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming.go b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming.go
index 755fd1ac5..22059bb1d 100644
--- a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming.go
+++ b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming.go
@@ -21,6 +21,7 @@ import (
"encoding/hex"
"fmt"
"io"
+ "io/ioutil"
"net/http"
"strconv"
"strings"
@@ -92,9 +93,12 @@ func buildChunkStringToSign(t time.Time, region, previousSig string, chunkData [
// prepareStreamingRequest - prepares a request with appropriate
// headers before computing the seed signature.
-func prepareStreamingRequest(req *http.Request, dataLen int64, timestamp time.Time) {
+func prepareStreamingRequest(req *http.Request, sessionToken string, dataLen int64, timestamp time.Time) {
// Set x-amz-content-sha256 header.
req.Header.Set("X-Amz-Content-Sha256", streamingSignAlgorithm)
+ if sessionToken != "" {
+ req.Header.Set("X-Amz-Security-Token", sessionToken)
+ }
req.Header.Set("Content-Encoding", streamingEncoding)
req.Header.Set("X-Amz-Date", timestamp.Format(iso8601DateFormat))
@@ -138,6 +142,7 @@ func (s *StreamingReader) setSeedSignature(req *http.Request) {
type StreamingReader struct {
accessKeyID string
secretAccessKey string
+ sessionToken string
region string
prevSignature string
seedSignature string
@@ -195,16 +200,21 @@ func (s *StreamingReader) setStreamingAuthHeader(req *http.Request) {
// StreamingSignV4 - provides chunked upload signatureV4 support by
// implementing io.Reader.
-func StreamingSignV4(req *http.Request, accessKeyID, secretAccessKey,
+func StreamingSignV4(req *http.Request, accessKeyID, secretAccessKey, sessionToken,
region string, dataLen int64, reqTime time.Time) *http.Request {
// Set headers needed for streaming signature.
- prepareStreamingRequest(req, dataLen, reqTime)
+ prepareStreamingRequest(req, sessionToken, dataLen, reqTime)
+
+ if req.Body == nil {
+ req.Body = ioutil.NopCloser(bytes.NewReader([]byte("")))
+ }
stReader := &StreamingReader{
baseReadCloser: req.Body,
accessKeyID: accessKeyID,
secretAccessKey: secretAccessKey,
+ sessionToken: sessionToken,
region: region,
reqTime: reqTime,
chunkBuf: make([]byte, payloadChunkSize),
@@ -244,7 +254,18 @@ func (s *StreamingReader) Read(buf []byte) (int, error) {
s.chunkBufLen = 0
for {
n1, err := s.baseReadCloser.Read(s.chunkBuf[s.chunkBufLen:])
- if err == nil || err == io.ErrUnexpectedEOF {
+ // Usually we validate `err` first, but in this case
+ // we are validating n > 0 for the following reasons.
+ //
+ // 1. n > 0, err is one of io.EOF, nil (near end of stream)
+ // A Reader returning a non-zero number of bytes at the end
+ // of the input stream may return either err == EOF or err == nil
+ //
+ // 2. n == 0, err is io.EOF (actual end of stream)
+ //
+ // Callers should always process the n > 0 bytes returned
+ // before considering the error err.
+ if n1 > 0 {
s.chunkBufLen += n1
s.bytesRead += int64(n1)
@@ -255,25 +276,26 @@ func (s *StreamingReader) Read(buf []byte) (int, error) {
s.signChunk(s.chunkBufLen)
break
}
+ }
+ if err != nil {
+ if err == io.EOF {
+ // No more data left in baseReader - last chunk.
+ // Done reading the last chunk from baseReader.
+ s.done = true
+
+ // bytes read from baseReader different than
+ // content length provided.
+ if s.bytesRead != s.contentLen {
+ return 0, io.ErrUnexpectedEOF
+ }
- } else if err == io.EOF {
- // No more data left in baseReader - last chunk.
- // Done reading the last chunk from baseReader.
- s.done = true
-
- // bytes read from baseReader different than
- // content length provided.
- if s.bytesRead != s.contentLen {
- return 0, io.ErrUnexpectedEOF
+ // Sign the chunk and write it to s.buf.
+ s.signChunk(0)
+ break
}
-
- // Sign the chunk and write it to s.buf.
- s.signChunk(0)
- break
-
- } else {
return 0, err
}
+
}
}
return s.buf.Read(buf)
diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go
index 084a0dbab..1f49f2234 100644
--- a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go
+++ b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go
@@ -39,7 +39,7 @@ func TestGetSeedSignature(t *testing.T) {
t.Fatalf("Failed to parse time - %v", err)
}
- req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "us-east-1", int64(dataLen), reqTime)
+ req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", "us-east-1", int64(dataLen), reqTime)
actualSeedSignature := req.Body.(*StreamingReader).seedSignature
expectedSeedSignature := "007480502de61457e955731b0f5d191f7e6f54a8a0f6cc7974a5ebd887965686"
@@ -72,7 +72,7 @@ func TestSetStreamingAuthorization(t *testing.T) {
dataLen := int64(65 * 1024)
reqTime, _ := time.Parse(iso8601DateFormat, "20130524T000000Z")
- req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, location, dataLen, reqTime)
+ req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", location, dataLen, reqTime)
expectedAuthorization := "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=007480502de61457e955731b0f5d191f7e6f54a8a0f6cc7974a5ebd887965686"
@@ -96,7 +96,7 @@ func TestStreamingReader(t *testing.T) {
baseReader := ioutil.NopCloser(bytes.NewReader(bytes.Repeat([]byte("a"), 65*1024)))
req.Body = baseReader
- req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, location, dataLen, reqTime)
+ req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", location, dataLen, reqTime)
b, err := ioutil.ReadAll(req.Body)
if err != nil {
diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4.go b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4.go
index 245fb08c3..0d75dc162 100644
--- a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4.go
+++ b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4.go
@@ -206,7 +206,7 @@ func getStringToSignV4(t time.Time, location, canonicalRequest string) string {
// PreSignV4 presign the request, in accordance with
// http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html.
-func PreSignV4(req http.Request, accessKeyID, secretAccessKey, location string, expires int64) *http.Request {
+func PreSignV4(req http.Request, accessKeyID, secretAccessKey, sessionToken, location string, expires int64) *http.Request {
// Presign is not needed for anonymous credentials.
if accessKeyID == "" || secretAccessKey == "" {
return &req
@@ -228,6 +228,10 @@ func PreSignV4(req http.Request, accessKeyID, secretAccessKey, location string,
query.Set("X-Amz-Expires", strconv.FormatInt(expires, 10))
query.Set("X-Amz-SignedHeaders", signedHeaders)
query.Set("X-Amz-Credential", credential)
+ // Set session token if available.
+ if sessionToken != "" {
+ query.Set("X-Amz-Security-Token", sessionToken)
+ }
req.URL.RawQuery = query.Encode()
// Get canonical request.
@@ -260,7 +264,7 @@ func PostPresignSignatureV4(policyBase64 string, t time.Time, secretAccessKey, l
// SignV4 sign the request before Do(), in accordance with
// http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html.
-func SignV4(req http.Request, accessKeyID, secretAccessKey, location string) *http.Request {
+func SignV4(req http.Request, accessKeyID, secretAccessKey, sessionToken, location string) *http.Request {
// Signature calculation is not needed for anonymous credentials.
if accessKeyID == "" || secretAccessKey == "" {
return &req
@@ -272,6 +276,11 @@ func SignV4(req http.Request, accessKeyID, secretAccessKey, location string) *ht
// Set x-amz-date.
req.Header.Set("X-Amz-Date", t.Format(iso8601DateFormat))
+ // Set session token if available.
+ if sessionToken != "" {
+ req.Header.Set("X-Amz-Security-Token", sessionToken)
+ }
+
// Get canonical request.
canonicalRequest := getCanonicalRequest(req, v4IgnoredHeaders)
diff --git a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go
index 6f5ba1895..85ff063df 100644
--- a/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go
+++ b/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go
@@ -28,12 +28,12 @@ func TestSignatureCalculation(t *testing.T) {
if err != nil {
t.Fatal("Error:", err)
}
- req = SignV4(*req, "", "", "us-east-1")
+ req = SignV4(*req, "", "", "", "us-east-1")
if req.Header.Get("Authorization") != "" {
t.Fatal("Error: anonymous credentials should not have Authorization header.")
}
- req = PreSignV4(*req, "", "", "us-east-1", 0)
+ req = PreSignV4(*req, "", "", "", "us-east-1", 0)
if strings.Contains(req.URL.RawQuery, "X-Amz-Signature") {
t.Fatal("Error: anonymous credentials should not have Signature query resource.")
}
@@ -48,12 +48,12 @@ func TestSignatureCalculation(t *testing.T) {
t.Fatal("Error: anonymous credentials should not have Signature query resource.")
}
- req = SignV4(*req, "ACCESS-KEY", "SECRET-KEY", "us-east-1")
+ req = SignV4(*req, "ACCESS-KEY", "SECRET-KEY", "", "us-east-1")
if req.Header.Get("Authorization") == "" {
t.Fatal("Error: normal credentials should have Authorization header.")
}
- req = PreSignV4(*req, "ACCESS-KEY", "SECRET-KEY", "us-east-1", 0)
+ req = PreSignV4(*req, "ACCESS-KEY", "SECRET-KEY", "", "us-east-1", 0)
if !strings.Contains(req.URL.RawQuery, "X-Amz-Signature") {
t.Fatal("Error: normal credentials should have Signature query resource.")
}