chore: upgrade dependencies

This commit is contained in:
2022-06-09 12:30:53 +02:00
parent 7203f3d6a1
commit dcb93ec8f7
518 changed files with 27809 additions and 3222 deletions

View File

@@ -21,7 +21,7 @@ func AddContentChecksumMiddleware(stack *middleware.Stack) error {
return stack.Build.Add(&contentMD5Checksum{}, middleware.Before)
}
// ID the identifier for the checksum middleware
// ID returns the identifier for the checksum middleware
func (m *contentMD5Checksum) ID() string { return "ContentChecksum" }
// HandleBuild adds behavior to compute md5 checksum and add content-md5 header
@@ -45,6 +45,11 @@ func (m *contentMD5Checksum) HandleBuild(
stream := req.GetStream()
// compute checksum if payload is explicit
if stream != nil {
if !req.IsStreamSeekable() {
return out, metadata, fmt.Errorf(
"unseekable stream is not supported for computing md5 checksum")
}
v, err := computeMD5Checksum(stream)
if err != nil {
return out, metadata, fmt.Errorf("error computing md5 checksum, %w", err)

View File

@@ -14,7 +14,7 @@ type ClientDo interface {
Do(*http.Request) (*http.Response, error)
}
// ClientDoFunc provides a helper to wrap an function as an HTTP client for
// ClientDoFunc provides a helper to wrap a function as an HTTP client for
// round tripping requests.
type ClientDoFunc func(*http.Request) (*http.Response, error)
@@ -37,7 +37,7 @@ func NewClientHandler(client ClientDo) ClientHandler {
}
// Handle implements the middleware Handler interface, that will invoke the
// underlying HTTP client. Requires the input to be an Smithy *Request. Returns
// underlying HTTP client. Requires the input to be a Smithy *Request. Returns
// a smithy *Response, or error if the request failed.
func (c ClientHandler) Handle(ctx context.Context, input interface{}) (
out interface{}, metadata middleware.Metadata, err error,
@@ -91,7 +91,7 @@ type RequestSendError struct {
Err error
}
// ConnectionError return that the error is related to not being able to send
// ConnectionError returns that the error is related to not being able to send
// the request, or receive a response from the service.
func (e *RequestSendError) ConnectionError() bool {
return true
@@ -106,7 +106,7 @@ func (e *RequestSendError) Error() string {
return fmt.Sprintf("request send failed, %v", e.Err)
}
// NopClient provides a client that ignores the request, and returns a empty
// NopClient provides a client that ignores the request, and returns an empty
// successful HTTP response value.
type NopClient struct{}

View File

@@ -2,53 +2,125 @@ package http
import (
"fmt"
"strconv"
"strings"
"unicode"
)
func splitHeaderListValues(vs []string, splitFn func(string) ([]string, error)) ([]string, error) {
for i := 0; i < len(vs); i++ {
if len(vs[i]) == 0 {
continue
}
values := make([]string, 0, len(vs))
for i := 0; i < len(vs); i++ {
parts, err := splitFn(vs[i])
if err != nil {
return nil, err
}
if len(parts) < 2 {
continue
}
tmp := make([]string, len(vs)+len(parts)-1)
copy(tmp, vs[:i])
for j, p := range parts {
tmp[i+j] = strings.TrimSpace(p)
}
copy(tmp[i+len(parts):], vs[i+1:])
vs = tmp
i += len(parts) - 1
values = append(values, parts...)
}
return vs, nil
return values, nil
}
// SplitHeaderListValues attempts to split the elements of the slice by commas,
// and return a list of all values separated. Returns error if unable to
// separate the values.
func SplitHeaderListValues(vs []string) ([]string, error) {
return splitHeaderListValues(vs, commaSplit)
return splitHeaderListValues(vs, quotedCommaSplit)
}
func commaSplit(v string) ([]string, error) {
return strings.Split(v, ","), nil
func quotedCommaSplit(v string) (parts []string, err error) {
v = strings.TrimSpace(v)
expectMore := true
for i := 0; i < len(v); i++ {
if unicode.IsSpace(rune(v[i])) {
continue
}
expectMore = false
// leading space in part is ignored.
// Start of value must be non-space, or quote.
//
// - If quote, enter quoted mode, find next non-escaped quote to
// terminate the value.
// - Otherwise, find next comma to terminate value.
remaining := v[i:]
var value string
var valueLen int
if remaining[0] == '"' {
//------------------------------
// Quoted value
//------------------------------
var j int
var skipQuote bool
for j += 1; j < len(remaining); j++ {
if remaining[j] == '\\' || (remaining[j] != '\\' && skipQuote) {
skipQuote = !skipQuote
continue
}
if remaining[j] == '"' {
break
}
}
if j == len(remaining) || j == 1 {
return nil, fmt.Errorf("value %v missing closing double quote",
remaining)
}
valueLen = j + 1
tail := remaining[valueLen:]
var k int
for ; k < len(tail); k++ {
if !unicode.IsSpace(rune(tail[k])) && tail[k] != ',' {
return nil, fmt.Errorf("value %v has non-space trailing characters",
remaining)
}
if tail[k] == ',' {
expectMore = true
break
}
}
value = remaining[:valueLen]
value, err = strconv.Unquote(value)
if err != nil {
return nil, fmt.Errorf("failed to unquote value %v, %w", value, err)
}
// Pad valueLen to include trailing space(s) so `i` is updated correctly.
valueLen += k
} else {
//------------------------------
// Unquoted value
//------------------------------
// Index of the next comma is the length of the value, or end of string.
valueLen = strings.Index(remaining, ",")
if valueLen != -1 {
expectMore = true
} else {
valueLen = len(remaining)
}
value = strings.TrimSpace(remaining[:valueLen])
}
i += valueLen
parts = append(parts, value)
}
if expectMore {
parts = append(parts, "")
}
return parts, nil
}
// SplitHTTPDateTimestampHeaderListValues attempts to split the HTTP-Date
// timestamp values in the slice by commas, and return a list of all values
// separated. The split is aware of HTTP-Date timestamp format, and will skip
// separated. The split is aware of the HTTP-Date timestamp format, and will skip
// comma within the timestamp value. Returns an error if unable to split the
// timestamp values.
func SplitHTTPDateTimestampHeaderListValues(vs []string) ([]string, error) {
@@ -56,10 +128,10 @@ func SplitHTTPDateTimestampHeaderListValues(vs []string) ([]string, error) {
}
func splitHTTPDateHeaderValue(v string) ([]string, error) {
if n := strings.Count(v, ","); n == 1 {
// Skip values with only a single HTTPDate value
return nil, nil
} else if n == 0 || n%2 == 0 {
if n := strings.Count(v, ","); n <= 1 {
// Nothing to do if only contains a no, or single HTTPDate value
return []string{v}, nil
} else if n%2 == 0 {
return nil, fmt.Errorf("invalid timestamp HTTPDate header comma separations, %q", v)
}
@@ -71,7 +143,7 @@ func splitHTTPDateHeaderValue(v string) ([]string, error) {
if v[i] == ',' {
if doSplit {
doSplit = false
parts = append(parts, v[j:i])
parts = append(parts, strings.TrimSpace(v[j:i]))
j = i + 1
} else {
// Skip the first comma in the timestamp value since that
@@ -82,8 +154,9 @@ func splitHTTPDateHeaderValue(v string) ([]string, error) {
}
}
}
// Add final part
if j < len(v) {
parts = append(parts, v[j:])
parts = append(parts, strings.TrimSpace(v[j:]))
}
return parts, nil

View File

@@ -56,7 +56,7 @@ func ValidateEndpointHost(host string) error {
return nil
}
// ValidPortNumber return if the port is valid RFC 3986 port
// ValidPortNumber returns whether the port is valid RFC 3986 port.
func ValidPortNumber(port string) bool {
i, err := strconv.Atoi(port)
if err != nil {
@@ -69,7 +69,7 @@ func ValidPortNumber(port string) bool {
return true
}
// ValidHostLabel returns if the label is a valid RFC 3986 host label.
// ValidHostLabel returns whether the label is a valid RFC 3986 host abel.
func ValidHostLabel(label string) bool {
if l := len(label); l == 0 || l > 63 {
return false

View File

@@ -7,7 +7,7 @@ import (
"io"
)
// computeMD5Checksum computes base64 md5 checksum of an io.Reader contents.
// computeMD5Checksum computes base64 md5 checksum of an io.Reader's contents.
// Returns the byte slice of md5 checksum and an error.
func computeMD5Checksum(r io.Reader) ([]byte, error) {
h := md5.New()

View File

@@ -18,7 +18,7 @@ func AddComputeContentLengthMiddleware(stack *middleware.Stack) error {
return stack.Build.Add(&ComputeContentLength{}, middleware.After)
}
// ID the identifier for the ComputeContentLength
// ID returns the identifier for the ComputeContentLength.
func (m *ComputeContentLength) ID() string { return "ComputeContentLength" }
// HandleBuild adds the length of the serialized request to the HTTP header
@@ -44,12 +44,6 @@ func (m *ComputeContentLength) HandleBuild(
"failed getting length of request stream, %w", err)
} else if ok {
req.ContentLength = n
if n == 0 {
// If the content length could be determined, and the body is empty
// the stream must be cleared to prevent unexpected chunk encoding.
req, _ = req.SetStream(nil)
in.Request = req
}
}
return next.HandleBuild(ctx, in)
@@ -65,7 +59,7 @@ func ValidateContentLengthHeader(stack *middleware.Stack) error {
return stack.Build.Add(&validateContentLength{}, middleware.After)
}
// ID the identifier for the ComputeContentLength
// ID returns the identifier for the ComputeContentLength.
func (m *validateContentLength) ID() string { return "ValidateContentLength" }
// HandleBuild adds the length of the serialized request to the HTTP header

View File

@@ -11,7 +11,7 @@ type (
hostPrefixDisableKey struct{}
)
// GetHostnameImmutable retrieves if the endpoint hostname should be considered
// GetHostnameImmutable retrieves whether the endpoint hostname should be considered
// immutable or not.
//
// Scoped to stack values. Use middleware#ClearStackValues to clear all stack
@@ -21,7 +21,7 @@ func GetHostnameImmutable(ctx context.Context) (v bool) {
return v
}
// SetHostnameImmutable sets or modifies if the request's endpoint hostname
// SetHostnameImmutable sets or modifies whether the request's endpoint hostname
// should be considered immutable or not.
//
// Scoped to stack values. Use middleware#ClearStackValues to clear all stack
@@ -30,7 +30,7 @@ func SetHostnameImmutable(ctx context.Context, value bool) context.Context {
return middleware.WithStackValue(ctx, hostnameImmutableKey{}, value)
}
// IsEndpointHostPrefixDisabled retrieves if the hostname prefixing is
// IsEndpointHostPrefixDisabled retrieves whether the hostname prefixing is
// disabled.
//
// Scoped to stack values. Use middleware#ClearStackValues to clear all stack
@@ -40,8 +40,8 @@ func IsEndpointHostPrefixDisabled(ctx context.Context) (v bool) {
return v
}
// DisableEndpointHostPrefix sets or modifies if the request's endpoint host
// prefixing to be disabled. If value is set to true, endpoint host prefixing
// DisableEndpointHostPrefix sets or modifies whether the request's endpoint host
// prefixing should be disabled. If value is true, endpoint host prefixing
// will be disabled.
//
// Scoped to stack values. Use middleware#ClearStackValues to clear all stack

View File

@@ -20,7 +20,7 @@ type Request struct {
streamStartPos int64
}
// NewStackRequest returns an initialized request ready to populated with the
// NewStackRequest returns an initialized request ready to be populated with the
// HTTP request details. Returns empty interface so the function can be used as
// a parameter to the Smithy middleware Stack constructor.
func NewStackRequest() interface{} {
@@ -45,19 +45,23 @@ func (r *Request) Clone() *Request {
// to the request and ok set. If the length cannot be determined, an error will
// be returned.
func (r *Request) StreamLength() (size int64, ok bool, err error) {
if r.stream == nil {
return streamLength(r.stream, r.isStreamSeekable, r.streamStartPos)
}
func streamLength(stream io.Reader, seekable bool, startPos int64) (size int64, ok bool, err error) {
if stream == nil {
return 0, true, nil
}
if l, ok := r.stream.(interface{ Len() int }); ok {
if l, ok := stream.(interface{ Len() int }); ok {
return int64(l.Len()), true, nil
}
if !r.isStreamSeekable {
if !seekable {
return 0, false, nil
}
s := r.stream.(io.Seeker)
s := stream.(io.Seeker)
endOffset, err := s.Seek(0, io.SeekEnd)
if err != nil {
return 0, false, err
@@ -69,12 +73,12 @@ func (r *Request) StreamLength() (size int64, ok bool, err error) {
// file, and wants to skip the first N bytes uploading the rest. The
// application would move the file's offset N bytes, then hand it off to
// the SDK to send the remaining. The SDK should respect that initial offset.
_, err = s.Seek(r.streamStartPos, io.SeekStart)
_, err = s.Seek(startPos, io.SeekStart)
if err != nil {
return 0, false, err
}
return endOffset - r.streamStartPos, true, nil
return endOffset - startPos, true, nil
}
// RewindStream will rewind the io.Reader to the relative start position if it
@@ -98,28 +102,46 @@ func (r *Request) GetStream() io.Reader {
return r.stream
}
// IsStreamSeekable returns if the stream is seekable.
// IsStreamSeekable returns whether the stream is seekable.
func (r *Request) IsStreamSeekable() bool {
return r.isStreamSeekable
}
// SetStream returns a clone of the request with the stream set to the provided reader.
// May return an error if the provided reader is seekable but returns an error.
// SetStream returns a clone of the request with the stream set to the provided
// reader. May return an error if the provided reader is seekable but returns
// an error.
func (r *Request) SetStream(reader io.Reader) (rc *Request, err error) {
rc = r.Clone()
if reader == http.NoBody {
reader = nil
}
var isStreamSeekable bool
var streamStartPos int64
switch v := reader.(type) {
case io.Seeker:
n, err := v.Seek(0, io.SeekCurrent)
if err != nil {
return r, err
}
rc.isStreamSeekable = true
rc.streamStartPos = n
isStreamSeekable = true
streamStartPos = n
default:
rc.isStreamSeekable = false
// If the stream length can be determined, and is determined to be empty,
// use a nil stream to prevent confusion between empty vs not-empty
// streams.
length, ok, err := streamLength(reader, false, 0)
if err != nil {
return nil, err
} else if ok && length == 0 {
reader = nil
}
}
rc.stream = reader
rc.isStreamSeekable = isStreamSeekable
rc.streamStartPos = streamStartPos
return rc, err
}
@@ -139,7 +161,11 @@ func (r *Request) Build(ctx context.Context) *http.Request {
req.Body = ioutil.NopCloser(stream)
req.ContentLength = -1
default:
if r.stream != nil {
// HTTP Client Request must only have a non-nil body if the
// ContentLength is explicitly unknown (-1) or non-zero. The HTTP
// Client will interpret a non-nil body and ContentLength 0 as
// "unknown". This is unwanted behavior.
if req.ContentLength != 0 && r.stream != nil {
req.Body = iointernal.NewSafeReadCloser(ioutil.NopCloser(stream))
}
}
@@ -148,7 +174,7 @@ func (r *Request) Build(ctx context.Context) *http.Request {
}
// RequestCloner is a function that can take an input request type and clone the request
// for use in a subsequent retry attempt
// for use in a subsequent retry attempt.
func RequestCloner(v interface{}) interface{} {
return v.(*Request).Clone()
}

View File

@@ -18,7 +18,7 @@ type ResponseError struct {
Err error
}
// HttpStatusCode returns the HTTP response status code received from the service
// HTTPStatusCode returns the HTTP response status code received from the service.
func (e *ResponseError) HTTPStatusCode() int { return e.Response.StatusCode }
// HTTPResponse returns the HTTP response received from the service.