You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.5 KiB
80 lines
2.5 KiB
package http
|
|
|
|
import (
|
|
"context"
|
|
"github.com/aws/smithy-go/logging"
|
|
"github.com/aws/smithy-go/middleware"
|
|
"io"
|
|
"io/ioutil"
|
|
)
|
|
|
|
// AddErrorCloseResponseBodyMiddleware adds the middleware to automatically
|
|
// close the response body of an operation request if the request response
|
|
// failed.
|
|
func AddErrorCloseResponseBodyMiddleware(stack *middleware.Stack) error {
|
|
return stack.Deserialize.Insert(&errorCloseResponseBodyMiddleware{}, "OperationDeserializer", middleware.Before)
|
|
}
|
|
|
|
type errorCloseResponseBodyMiddleware struct{}
|
|
|
|
func (*errorCloseResponseBodyMiddleware) ID() string {
|
|
return "ErrorCloseResponseBody"
|
|
}
|
|
|
|
func (m *errorCloseResponseBodyMiddleware) HandleDeserialize(
|
|
ctx context.Context, input middleware.DeserializeInput, next middleware.DeserializeHandler,
|
|
) (
|
|
output middleware.DeserializeOutput, metadata middleware.Metadata, err error,
|
|
) {
|
|
out, metadata, err := next.HandleDeserialize(ctx, input)
|
|
if err != nil {
|
|
if resp, ok := out.RawResponse.(*Response); ok && resp != nil && resp.Body != nil {
|
|
// Consume the full body to prevent TCP connection resets on some platforms
|
|
_, _ = io.Copy(ioutil.Discard, resp.Body)
|
|
// Do not validate that the response closes successfully.
|
|
resp.Body.Close()
|
|
}
|
|
}
|
|
|
|
return out, metadata, err
|
|
}
|
|
|
|
// AddCloseResponseBodyMiddleware adds the middleware to automatically close
|
|
// the response body of an operation request, after the response had been
|
|
// deserialized.
|
|
func AddCloseResponseBodyMiddleware(stack *middleware.Stack) error {
|
|
return stack.Deserialize.Insert(&closeResponseBody{}, "OperationDeserializer", middleware.Before)
|
|
}
|
|
|
|
type closeResponseBody struct{}
|
|
|
|
func (*closeResponseBody) ID() string {
|
|
return "CloseResponseBody"
|
|
}
|
|
|
|
func (m *closeResponseBody) HandleDeserialize(
|
|
ctx context.Context, input middleware.DeserializeInput, next middleware.DeserializeHandler,
|
|
) (
|
|
output middleware.DeserializeOutput, metadata middleware.Metadata, err error,
|
|
) {
|
|
out, metadata, err := next.HandleDeserialize(ctx, input)
|
|
if err != nil {
|
|
return out, metadata, err
|
|
}
|
|
|
|
if resp, ok := out.RawResponse.(*Response); ok {
|
|
// Consume the full body to prevent TCP connection resets on some platforms
|
|
_, copyErr := io.Copy(ioutil.Discard, resp.Body)
|
|
if copyErr != nil {
|
|
middleware.GetLogger(ctx).Logf(logging.Warn, "failed to discard remaining HTTP response body, this may affect connection reuse")
|
|
}
|
|
|
|
closeErr := resp.Body.Close()
|
|
if closeErr != nil {
|
|
middleware.GetLogger(ctx).Logf(logging.Warn, "failed to close HTTP response body, this may affect connection reuse")
|
|
}
|
|
}
|
|
|
|
return out, metadata, err
|
|
}
|