summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming.go')
-rw-r--r--vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming.go60
1 files changed, 41 insertions, 19 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)