Update aws-sdk to 1.42.27

Upgrade the aws golang SDK to 1.42.27 to add the new options for
configuring S3 dualstack endpoints.

Signed-off-by: Adam Kaplan <adam.kaplan@redhat.com>
This commit is contained in:
Adam Kaplan 2022-01-04 17:09:44 -05:00
parent 6a977a5a75
commit 81a2d171ee
151 changed files with 51741 additions and 8821 deletions

View file

@ -5,6 +5,10 @@ import (
"sync"
)
// InputWriterCloseErrorCode is used to denote an error occurred
// while closing the event stream input writer.
const InputWriterCloseErrorCode = "EventStreamInputWriterCloseError"
type messageError struct {
code string
msg string

View file

@ -61,49 +61,3 @@ func (w *EventWriter) marshal(event Marshaler) (eventstream.Message, error) {
msg.Headers.Set(EventTypeHeader, eventstream.StringValue(eventType))
return msg, nil
}
//type EventEncoder struct {
// encoder Encoder
// ppayloadMarshaler protocol.PayloadMarshaler
// eventTypeFor func(Marshaler) (string, error)
//}
//
//func (e EventEncoder) Encode(event Marshaler) error {
// msg, err := e.marshal(event)
// if err != nil {
// return err
// }
//
// return w.encoder.Encode(msg)
//}
//
//func (e EventEncoder) marshal(event Marshaler) (eventstream.Message, error) {
// eventType, err := w.eventTypeFor(event)
// if err != nil {
// return eventstream.Message{}, err
// }
//
// msg, err := event.MarshalEvent(w.payloadMarshaler)
// if err != nil {
// return eventstream.Message{}, err
// }
//
// msg.Headers.Set(EventTypeHeader, eventstream.StringValue(eventType))
// return msg, nil
//}
//
//func (w *EventWriter) marshal(event Marshaler) (eventstream.Message, error) {
// eventType, err := w.eventTypeFor(event)
// if err != nil {
// return eventstream.Message{}, err
// }
//
// msg, err := event.MarshalEvent(w.payloadMarshaler)
// if err != nil {
// return eventstream.Message{}, err
// }
//
// msg.Headers.Set(EventTypeHeader, eventstream.StringValue(eventType))
// return msg, nil
//}
//

View file

@ -1,9 +1,10 @@
package protocol
import (
"strings"
"github.com/aws/aws-sdk-go/aws/request"
"net"
"strconv"
"strings"
)
// ValidateEndpointHostHandler is a request handler that will validate the
@ -22,8 +23,26 @@ var ValidateEndpointHostHandler = request.NamedHandler{
// 3986 host. Returns error if the host is not valid.
func ValidateEndpointHost(opName, host string) error {
paramErrs := request.ErrInvalidParams{Context: opName}
labels := strings.Split(host, ".")
var hostname string
var port string
var err error
if strings.Contains(host, ":") {
hostname, port, err = net.SplitHostPort(host)
if err != nil {
paramErrs.Add(request.NewErrParamFormat("endpoint", err.Error(), host))
}
if !ValidPortNumber(port) {
paramErrs.Add(request.NewErrParamFormat("endpoint port number", "[0-65535]", port))
}
} else {
hostname = host
}
labels := strings.Split(hostname, ".")
for i, label := range labels {
if i == len(labels)-1 && len(label) == 0 {
// Allow trailing dot for FQDN hosts.
@ -36,7 +55,11 @@ func ValidateEndpointHost(opName, host string) error {
}
}
if len(host) > 255 {
if len(hostname) == 0 {
paramErrs.Add(request.NewErrParamMinLen("endpoint host", 1))
}
if len(hostname) > 255 {
paramErrs.Add(request.NewErrParamMaxLen(
"endpoint host", 255, host,
))
@ -66,3 +89,16 @@ func ValidHostLabel(label string) bool {
return true
}
// ValidPortNumber return if the port is valid RFC 3986 port
func ValidPortNumber(port string) bool {
i, err := strconv.Atoi(port)
if err != nil {
return false
}
if i < 0 || i > 65535 {
return false
}
return true
}

View file

@ -82,13 +82,17 @@ func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag)
field, _ := value.Type().FieldByName(payload)
tag = field.Tag
value = elemOf(value.FieldByName(payload))
if !value.IsValid() {
if !value.IsValid() && tag.Get("type") != "structure" {
return nil
}
}
buf.WriteByte('{')
defer buf.WriteString("}")
if !value.IsValid() {
return nil
}
t := value.Type()
first := true
@ -144,8 +148,6 @@ func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag)
}
buf.WriteString("}")
return nil
}

View file

@ -0,0 +1,87 @@
// Package jsonrpc provides JSON RPC utilities for serialization of AWS
// requests and responses.
package jsonrpc
//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/input/json.json build_test.go
//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/output/json.json unmarshal_test.go
import (
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
"github.com/aws/aws-sdk-go/private/protocol/rest"
)
var emptyJSON = []byte("{}")
// BuildHandler is a named request handler for building jsonrpc protocol
// requests
var BuildHandler = request.NamedHandler{
Name: "awssdk.jsonrpc.Build",
Fn: Build,
}
// UnmarshalHandler is a named request handler for unmarshaling jsonrpc
// protocol requests
var UnmarshalHandler = request.NamedHandler{
Name: "awssdk.jsonrpc.Unmarshal",
Fn: Unmarshal,
}
// UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc
// protocol request metadata
var UnmarshalMetaHandler = request.NamedHandler{
Name: "awssdk.jsonrpc.UnmarshalMeta",
Fn: UnmarshalMeta,
}
// Build builds a JSON payload for a JSON RPC request.
func Build(req *request.Request) {
var buf []byte
var err error
if req.ParamsFilled() {
buf, err = jsonutil.BuildJSON(req.Params)
if err != nil {
req.Error = awserr.New(request.ErrCodeSerialization, "failed encoding JSON RPC request", err)
return
}
} else {
buf = emptyJSON
}
// Always serialize the body, don't suppress it.
req.SetBufferBody(buf)
if req.ClientInfo.TargetPrefix != "" {
target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name
req.HTTPRequest.Header.Add("X-Amz-Target", target)
}
// Only set the content type if one is not already specified and an
// JSONVersion is specified.
if ct, v := req.HTTPRequest.Header.Get("Content-Type"), req.ClientInfo.JSONVersion; len(ct) == 0 && len(v) != 0 {
jsonVersion := req.ClientInfo.JSONVersion
req.HTTPRequest.Header.Set("Content-Type", "application/x-amz-json-"+jsonVersion)
}
}
// Unmarshal unmarshals a response for a JSON RPC service.
func Unmarshal(req *request.Request) {
defer req.HTTPResponse.Body.Close()
if req.DataFilled() {
err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body)
if err != nil {
req.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization, "failed decoding JSON RPC response", err),
req.HTTPResponse.StatusCode,
req.RequestID,
)
}
}
return
}
// UnmarshalMeta unmarshals headers from a response for a JSON RPC service.
func UnmarshalMeta(req *request.Request) {
rest.UnmarshalMeta(req)
}

View file

@ -0,0 +1,107 @@
package jsonrpc
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol"
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
)
// UnmarshalTypedError provides unmarshaling errors API response errors
// for both typed and untyped errors.
type UnmarshalTypedError struct {
exceptions map[string]func(protocol.ResponseMetadata) error
}
// NewUnmarshalTypedError returns an UnmarshalTypedError initialized for the
// set of exception names to the error unmarshalers
func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError {
return &UnmarshalTypedError{
exceptions: exceptions,
}
}
// UnmarshalError attempts to unmarshal the HTTP response error as a known
// error type. If unable to unmarshal the error type, the generic SDK error
// type will be used.
func (u *UnmarshalTypedError) UnmarshalError(
resp *http.Response,
respMeta protocol.ResponseMetadata,
) (error, error) {
var buf bytes.Buffer
var jsonErr jsonErrorResponse
teeReader := io.TeeReader(resp.Body, &buf)
err := jsonutil.UnmarshalJSONError(&jsonErr, teeReader)
if err != nil {
return nil, err
}
body := ioutil.NopCloser(&buf)
// Code may be separated by hash(#), with the last element being the code
// used by the SDK.
codeParts := strings.SplitN(jsonErr.Code, "#", 2)
code := codeParts[len(codeParts)-1]
msg := jsonErr.Message
if fn, ok := u.exceptions[code]; ok {
// If exception code is know, use associated constructor to get a value
// for the exception that the JSON body can be unmarshaled into.
v := fn(respMeta)
err := jsonutil.UnmarshalJSONCaseInsensitive(v, body)
if err != nil {
return nil, err
}
return v, nil
}
// fallback to unmodeled generic exceptions
return awserr.NewRequestFailure(
awserr.New(code, msg, nil),
respMeta.StatusCode,
respMeta.RequestID,
), nil
}
// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc
// protocol request errors
var UnmarshalErrorHandler = request.NamedHandler{
Name: "awssdk.jsonrpc.UnmarshalError",
Fn: UnmarshalError,
}
// UnmarshalError unmarshals an error response for a JSON RPC service.
func UnmarshalError(req *request.Request) {
defer req.HTTPResponse.Body.Close()
var jsonErr jsonErrorResponse
err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body)
if err != nil {
req.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization,
"failed to unmarshal error message", err),
req.HTTPResponse.StatusCode,
req.RequestID,
)
return
}
codes := strings.SplitN(jsonErr.Code, "#", 2)
req.Error = awserr.NewRequestFailure(
awserr.New(codes[len(codes)-1], jsonErr.Message, nil),
req.HTTPResponse.StatusCode,
req.RequestID,
)
}
type jsonErrorResponse struct {
Code string `json:"__type"`
Message string `json:"message"`
}

View file

@ -98,7 +98,7 @@ func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bo
// Support the ability to customize values to be marshaled as a
// blob even though they were modeled as a string. Required for S3
// API operations like SSECustomerKey is modeled as stirng but
// API operations like SSECustomerKey is modeled as string but
// required to be base64 encoded in request.
if field.Tag.Get("marshal-as") == "blob" {
m = m.Convert(byteSliceType)

View file

@ -28,18 +28,27 @@ func PayloadMember(i interface{}) interface{} {
return nil
}
// PayloadType returns the type of a payload field member of i if there is one, or "".
const nopayloadPayloadType = "nopayload"
// PayloadType returns the type of a payload field member of i if there is one,
// or "".
func PayloadType(i interface{}) string {
v := reflect.Indirect(reflect.ValueOf(i))
if !v.IsValid() {
return ""
}
if field, ok := v.Type().FieldByName("_"); ok {
if noPayload := field.Tag.Get(nopayloadPayloadType); noPayload != "" {
return nopayloadPayloadType
}
if payloadName := field.Tag.Get("payload"); payloadName != "" {
if member, ok := v.Type().FieldByName(payloadName); ok {
return member.Tag.Get("type")
}
}
}
return ""
}

View file

@ -140,7 +140,7 @@ func unmarshalLocationElements(resp *http.Response, v reflect.Value, lowerCaseHe
prefix := field.Tag.Get("locationName")
err := unmarshalHeaderMap(m, resp.Header, prefix, lowerCaseHeaderMaps)
if err != nil {
awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
return awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
}
}
}

View file

@ -0,0 +1,59 @@
// Package restjson provides RESTful JSON serialization of AWS
// requests and responses.
package restjson
//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/input/rest-json.json build_test.go
//go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/output/rest-json.json unmarshal_test.go
import (
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
"github.com/aws/aws-sdk-go/private/protocol/rest"
)
// BuildHandler is a named request handler for building restjson protocol
// requests
var BuildHandler = request.NamedHandler{
Name: "awssdk.restjson.Build",
Fn: Build,
}
// UnmarshalHandler is a named request handler for unmarshaling restjson
// protocol requests
var UnmarshalHandler = request.NamedHandler{
Name: "awssdk.restjson.Unmarshal",
Fn: Unmarshal,
}
// UnmarshalMetaHandler is a named request handler for unmarshaling restjson
// protocol request metadata
var UnmarshalMetaHandler = request.NamedHandler{
Name: "awssdk.restjson.UnmarshalMeta",
Fn: UnmarshalMeta,
}
// Build builds a request for the REST JSON protocol.
func Build(r *request.Request) {
rest.Build(r)
if t := rest.PayloadType(r.Params); t == "structure" || t == "" {
if v := r.HTTPRequest.Header.Get("Content-Type"); len(v) == 0 {
r.HTTPRequest.Header.Set("Content-Type", "application/json")
}
jsonrpc.Build(r)
}
}
// Unmarshal unmarshals a response body for the REST JSON protocol.
func Unmarshal(r *request.Request) {
if t := rest.PayloadType(r.Data); t == "structure" || t == "" {
jsonrpc.Unmarshal(r)
} else {
rest.Unmarshal(r)
}
}
// UnmarshalMeta unmarshals response headers for the REST JSON protocol.
func UnmarshalMeta(r *request.Request) {
rest.UnmarshalMeta(r)
}

View file

@ -0,0 +1,134 @@
package restjson
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol"
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
"github.com/aws/aws-sdk-go/private/protocol/rest"
)
const (
errorTypeHeader = "X-Amzn-Errortype"
errorMessageHeader = "X-Amzn-Errormessage"
)
// UnmarshalTypedError provides unmarshaling errors API response errors
// for both typed and untyped errors.
type UnmarshalTypedError struct {
exceptions map[string]func(protocol.ResponseMetadata) error
}
// NewUnmarshalTypedError returns an UnmarshalTypedError initialized for the
// set of exception names to the error unmarshalers
func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError {
return &UnmarshalTypedError{
exceptions: exceptions,
}
}
// UnmarshalError attempts to unmarshal the HTTP response error as a known
// error type. If unable to unmarshal the error type, the generic SDK error
// type will be used.
func (u *UnmarshalTypedError) UnmarshalError(
resp *http.Response,
respMeta protocol.ResponseMetadata,
) (error, error) {
code := resp.Header.Get(errorTypeHeader)
msg := resp.Header.Get(errorMessageHeader)
body := resp.Body
if len(code) == 0 {
// If unable to get code from HTTP headers have to parse JSON message
// to determine what kind of exception this will be.
var buf bytes.Buffer
var jsonErr jsonErrorResponse
teeReader := io.TeeReader(resp.Body, &buf)
err := jsonutil.UnmarshalJSONError(&jsonErr, teeReader)
if err != nil {
return nil, err
}
body = ioutil.NopCloser(&buf)
code = jsonErr.Code
msg = jsonErr.Message
}
// If code has colon separators remove them so can compare against modeled
// exception names.
code = strings.SplitN(code, ":", 2)[0]
if fn, ok := u.exceptions[code]; ok {
// If exception code is know, use associated constructor to get a value
// for the exception that the JSON body can be unmarshaled into.
v := fn(respMeta)
if err := jsonutil.UnmarshalJSONCaseInsensitive(v, body); err != nil {
return nil, err
}
if err := rest.UnmarshalResponse(resp, v, true); err != nil {
return nil, err
}
return v, nil
}
// fallback to unmodeled generic exceptions
return awserr.NewRequestFailure(
awserr.New(code, msg, nil),
respMeta.StatusCode,
respMeta.RequestID,
), nil
}
// UnmarshalErrorHandler is a named request handler for unmarshaling restjson
// protocol request errors
var UnmarshalErrorHandler = request.NamedHandler{
Name: "awssdk.restjson.UnmarshalError",
Fn: UnmarshalError,
}
// UnmarshalError unmarshals a response error for the REST JSON protocol.
func UnmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close()
var jsonErr jsonErrorResponse
err := jsonutil.UnmarshalJSONError(&jsonErr, r.HTTPResponse.Body)
if err != nil {
r.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization,
"failed to unmarshal response error", err),
r.HTTPResponse.StatusCode,
r.RequestID,
)
return
}
code := r.HTTPResponse.Header.Get(errorTypeHeader)
if code == "" {
code = jsonErr.Code
}
msg := r.HTTPResponse.Header.Get(errorMessageHeader)
if msg == "" {
msg = jsonErr.Message
}
code = strings.SplitN(code, ":", 2)[0]
r.Error = awserr.NewRequestFailure(
awserr.New(code, jsonErr.Message, nil),
r.HTTPResponse.StatusCode,
r.RequestID,
)
}
type jsonErrorResponse struct {
Code string `json:"code"`
Message string `json:"message"`
}

View file

@ -1,6 +1,8 @@
package protocol
import (
"bytes"
"fmt"
"math"
"strconv"
"time"
@ -19,15 +21,18 @@ const (
// Output time is intended to not contain decimals
const (
// RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT
RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT"
RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT"
rfc822TimeFormatSingleDigitDay = "Mon, _2 Jan 2006 15:04:05 GMT"
rfc822TimeFormatSingleDigitDayTwoDigitYear = "Mon, _2 Jan 06 15:04:05 GMT"
// This format is used for output time without seconds precision
RFC822OutputTimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
// RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z
ISO8601TimeFormat = "2006-01-02T15:04:05.999999999Z"
ISO8601TimeFormat = "2006-01-02T15:04:05.999999999Z"
iso8601TimeFormatNoZ = "2006-01-02T15:04:05.999999999"
// This format is used for output time without seconds precision
// This format is used for output time with fractional second precision up to milliseconds
ISO8601OutputTimeFormat = "2006-01-02T15:04:05.999999999Z"
)
@ -48,7 +53,7 @@ func IsKnownTimestampFormat(name string) bool {
// FormatTime returns a string value of the time.
func FormatTime(name string, t time.Time) string {
t = t.UTC()
t = t.UTC().Truncate(time.Millisecond)
switch name {
case RFC822TimeFormatName:
@ -67,10 +72,21 @@ func FormatTime(name string, t time.Time) string {
// the time if it was able to be parsed, and fails otherwise.
func ParseTime(formatName, value string) (time.Time, error) {
switch formatName {
case RFC822TimeFormatName:
return time.Parse(RFC822TimeFormat, value)
case ISO8601TimeFormatName:
return time.Parse(ISO8601TimeFormat, value)
case RFC822TimeFormatName: // Smithy HTTPDate format
return tryParse(value,
RFC822TimeFormat,
rfc822TimeFormatSingleDigitDay,
rfc822TimeFormatSingleDigitDayTwoDigitYear,
time.RFC850,
time.ANSIC,
)
case ISO8601TimeFormatName: // Smithy DateTime format
return tryParse(value,
ISO8601TimeFormat,
iso8601TimeFormatNoZ,
time.RFC3339Nano,
time.RFC3339,
)
case UnixTimeFormatName:
v, err := strconv.ParseFloat(value, 64)
_, dec := math.Modf(v)
@ -83,3 +99,36 @@ func ParseTime(formatName, value string) (time.Time, error) {
panic("unknown timestamp format name, " + formatName)
}
}
func tryParse(v string, formats ...string) (time.Time, error) {
var errs parseErrors
for _, f := range formats {
t, err := time.Parse(f, v)
if err != nil {
errs = append(errs, parseError{
Format: f,
Err: err,
})
continue
}
return t, nil
}
return time.Time{}, fmt.Errorf("unable to parse time string, %v", errs)
}
type parseErrors []parseError
func (es parseErrors) Error() string {
var s bytes.Buffer
for _, e := range es {
fmt.Fprintf(&s, "\n * %q: %v", e.Format, e.Err)
}
return "parse errors:" + s.String()
}
type parseError struct {
Format string
Err error
}

View file

@ -308,6 +308,8 @@ func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag refl
if tag.Get("xmlAttribute") != "" { // put into current node's attribute list
attr := xml.Attr{Name: xname, Value: str}
current.Attr = append(current.Attr, attr)
} else if len(xname.Local) == 0 {
current.Text = str
} else { // regular text node
current.AddChild(&XMLNode{Name: xname, Text: str})
}

View file

@ -18,6 +18,14 @@ type XMLNode struct {
parent *XMLNode
}
// textEncoder is a string type alias that implemnts the TextMarshaler interface.
// This alias type is used to ensure that the line feed (\n) (U+000A) is escaped.
type textEncoder string
func (t textEncoder) MarshalText() ([]byte, error) {
return []byte(t), nil
}
// NewXMLElement returns a pointer to a new XMLNode initialized to default values.
func NewXMLElement(name xml.Name) *XMLNode {
return &XMLNode{
@ -130,11 +138,16 @@ func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
attrs = sortedAttrs
}
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: attrs})
startElement := xml.StartElement{Name: node.Name, Attr: attrs}
if node.Text != "" {
e.EncodeToken(xml.CharData([]byte(node.Text)))
} else if sorted {
e.EncodeElement(textEncoder(node.Text), startElement)
return e.Flush()
}
e.EncodeToken(startElement)
if sorted {
sortedNames := []string{}
for k := range node.Children {
sortedNames = append(sortedNames, k)
@ -154,6 +167,7 @@ func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
}
}
e.EncodeToken(xml.EndElement{Name: node.Name})
e.EncodeToken(startElement.End())
return e.Flush()
}