diff options
author | Niall Sheridan <nsheridan@gmail.com> | 2016-10-08 16:02:50 -0500 |
---|---|---|
committer | Niall Sheridan <nsheridan@gmail.com> | 2016-10-08 16:02:50 -0500 |
commit | baf7141d1dd0f99d561a2197a909c66dd389809d (patch) | |
tree | 92c176f713b0b28893344261b1e567db5e30ba79 /vendor/github.com/aws/aws-sdk-go/aws/request/request.go | |
parent | 696aebffe56853345d679d4d2b3051236423c6db (diff) |
Update dependencies
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/aws/request/request.go')
-rw-r--r-- | vendor/github.com/aws/aws-sdk-go/aws/request/request.go | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go index 2832aaa..8ef9715 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "net/http" "net/url" "reflect" @@ -42,6 +41,12 @@ type Request struct { LastSignedAt time.Time built bool + + // Need to persist an intermideant body betweend the input Body and HTTP + // request body because the HTTP Client's transport can maintain a reference + // to the HTTP request's body after the client has returned. This value is + // safe to use concurrently and rewraps the input Body for each HTTP request. + safeBody *offsetReader } // An Operation is the service API operation to be made. @@ -135,8 +140,8 @@ func (r *Request) SetStringBody(s string) { // SetReaderBody will set the request's body reader. func (r *Request) SetReaderBody(reader io.ReadSeeker) { - r.HTTPRequest.Body = newOffsetReader(reader, 0) r.Body = reader + r.ResetBody() } // Presign returns the request's signed URL. Error will be returned @@ -220,6 +225,24 @@ func (r *Request) Sign() error { return r.Error } +// ResetBody rewinds the request body backto its starting position, and +// set's the HTTP Request body reference. When the body is read prior +// to being sent in the HTTP request it will need to be rewound. +func (r *Request) ResetBody() { + if r.safeBody != nil { + r.safeBody.Close() + } + + r.safeBody = newOffsetReader(r.Body, r.BodyStart) + r.HTTPRequest.Body = r.safeBody +} + +// GetBody will return an io.ReadSeeker of the Request's underlying +// input body with a concurrency safe wrapper. +func (r *Request) GetBody() io.ReadSeeker { + return r.safeBody +} + // Send will send the request returning error if errors are encountered. // // Send will sign the request prior to sending. All Send Handlers will @@ -231,6 +254,8 @@ func (r *Request) Sign() error { // // readLoop() and getConn(req *Request, cm connectMethod) // https://github.com/golang/go/blob/master/src/net/http/transport.go +// +// Send will not close the request.Request's body. func (r *Request) Send() error { for { if aws.BoolValue(r.Retryable) { @@ -239,21 +264,15 @@ func (r *Request) Send() error { r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount)) } - var body io.ReadCloser - if reader, ok := r.HTTPRequest.Body.(*offsetReader); ok { - body = reader.CloseAndCopy(r.BodyStart) - } else { - if r.Config.Logger != nil { - r.Config.Logger.Log("Request body type has been overwritten. May cause race conditions") - } - r.Body.Seek(r.BodyStart, 0) - body = ioutil.NopCloser(r.Body) - } + // The previous http.Request will have a reference to the r.Body + // and the HTTP Client's Transport may still be reading from + // the request's body even though the Client's Do returned. + r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil) + r.ResetBody() - r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, body) + // Closing response body to ensure that no response body is leaked + // between retry attempts. if r.HTTPResponse != nil && r.HTTPResponse.Body != nil { - // Closing response body. Since we are setting a new request to send off, this - // response will get squashed and leaked. r.HTTPResponse.Body.Close() } } @@ -281,7 +300,6 @@ func (r *Request) Send() error { debugLogReqError(r, "Send Request", true, err) continue } - r.Handlers.UnmarshalMeta.Run(r) r.Handlers.ValidateResponse.Run(r) if r.Error != nil { |