diff options
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.go | 60 |
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) |