aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/aws/smithy-go/encoding/httpbinding
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@ydb.tech>2023-12-12 21:55:07 +0300
committervitalyisaev <vitalyisaev@ydb.tech>2023-12-12 22:25:10 +0300
commit4967f99474a4040ba150eb04995de06342252718 (patch)
treec9c118836513a8fab6e9fcfb25be5d404338bca7 /vendor/github.com/aws/smithy-go/encoding/httpbinding
parent2ce9cccb9b0bdd4cd7a3491dc5cbf8687cda51de (diff)
downloadydb-4967f99474a4040ba150eb04995de06342252718.tar.gz
YQ Connector: prepare code base for S3 integration
1. Кодовая база Коннектора переписана с помощью Go дженериков так, чтобы добавление нового источника данных (в частности S3 + csv) максимально переиспользовало имеющийся код (чтобы сохранялась логика нарезания на блоки данных, учёт трафика и пр.) 2. API Connector расширено для работы с S3, но ещё пока не протестировано.
Diffstat (limited to 'vendor/github.com/aws/smithy-go/encoding/httpbinding')
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go123
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/encode_test.go146
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/gotest/ya.make5
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go122
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/header_test.go295
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go108
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace_test.go67
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go107
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/query_test.go234
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/shared_test.go36
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go111
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/uri_test.go198
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/ya.make26
13 files changed, 1578 insertions, 0 deletions
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go
new file mode 100644
index 0000000000..543e7cf038
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go
@@ -0,0 +1,123 @@
+package httpbinding
+
+import (
+ "fmt"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+)
+
+const (
+ contentLengthHeader = "Content-Length"
+ floatNaN = "NaN"
+ floatInfinity = "Infinity"
+ floatNegInfinity = "-Infinity"
+)
+
+// An Encoder provides encoding of REST URI path, query, and header components
+// of an HTTP request. Can also encode a stream as the payload.
+//
+// Does not support SetFields.
+type Encoder struct {
+ path, rawPath, pathBuffer []byte
+
+ query url.Values
+ header http.Header
+}
+
+// NewEncoder creates a new encoder from the passed in request. It assumes that
+// raw path contains no valuable information at this point, so it passes in path
+// as path and raw path for subsequent trans
+func NewEncoder(path, query string, headers http.Header) (*Encoder, error) {
+ return NewEncoderWithRawPath(path, path, query, headers)
+}
+
+// NewHTTPBindingEncoder creates a new encoder from the passed in request. All query and
+// header values will be added on top of the request's existing values. Overwriting
+// duplicate values.
+func NewEncoderWithRawPath(path, rawPath, query string, headers http.Header) (*Encoder, error) {
+ parseQuery, err := url.ParseQuery(query)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse query string: %w", err)
+ }
+
+ e := &Encoder{
+ path: []byte(path),
+ rawPath: []byte(rawPath),
+ query: parseQuery,
+ header: headers.Clone(),
+ }
+
+ return e, nil
+}
+
+// Encode returns a REST protocol encoder for encoding HTTP bindings.
+//
+// Due net/http requiring `Content-Length` to be specified on the http.Request#ContentLength directly. Encode
+// will look for whether the header is present, and if so will remove it and set the respective value on http.Request.
+//
+// Returns any error occurring during encoding.
+func (e *Encoder) Encode(req *http.Request) (*http.Request, error) {
+ req.URL.Path, req.URL.RawPath = string(e.path), string(e.rawPath)
+ req.URL.RawQuery = e.query.Encode()
+
+ // net/http ignores Content-Length header and requires it to be set on http.Request
+ if v := e.header.Get(contentLengthHeader); len(v) > 0 {
+ iv, err := strconv.ParseInt(v, 10, 64)
+ if err != nil {
+ return nil, err
+ }
+ req.ContentLength = iv
+ e.header.Del(contentLengthHeader)
+ }
+
+ req.Header = e.header
+
+ return req, nil
+}
+
+// AddHeader returns a HeaderValue for appending to the given header name
+func (e *Encoder) AddHeader(key string) HeaderValue {
+ return newHeaderValue(e.header, key, true)
+}
+
+// SetHeader returns a HeaderValue for setting the given header name
+func (e *Encoder) SetHeader(key string) HeaderValue {
+ return newHeaderValue(e.header, key, false)
+}
+
+// Headers returns a Header used for encoding headers with the given prefix
+func (e *Encoder) Headers(prefix string) Headers {
+ return Headers{
+ header: e.header,
+ prefix: strings.TrimSpace(prefix),
+ }
+}
+
+// HasHeader returns if a header with the key specified exists with one or
+// more value.
+func (e Encoder) HasHeader(key string) bool {
+ return len(e.header[key]) != 0
+}
+
+// SetURI returns a URIValue used for setting the given path key
+func (e *Encoder) SetURI(key string) URIValue {
+ return newURIValue(&e.path, &e.rawPath, &e.pathBuffer, key)
+}
+
+// SetQuery returns a QueryValue used for setting the given query key
+func (e *Encoder) SetQuery(key string) QueryValue {
+ return NewQueryValue(e.query, key, false)
+}
+
+// AddQuery returns a QueryValue used for appending the given query key
+func (e *Encoder) AddQuery(key string) QueryValue {
+ return NewQueryValue(e.query, key, true)
+}
+
+// HasQuery returns if a query with the key specified exists with one or
+// more values.
+func (e *Encoder) HasQuery(key string) bool {
+ return len(e.query.Get(key)) != 0
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode_test.go
new file mode 100644
index 0000000000..6d972ae508
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode_test.go
@@ -0,0 +1,146 @@
+package httpbinding
+
+import (
+ "net/http"
+ "net/url"
+ "reflect"
+ "testing"
+)
+
+func TestEncoder(t *testing.T) {
+ actual := &http.Request{
+ Header: http.Header{
+ "custom-user-header": {"someValue"},
+ },
+ URL: &url.URL{
+ Path: "/some/{pathKeyOne}/{pathKeyTwo}",
+ RawQuery: "someExistingKeys=foobar",
+ },
+ }
+
+ expected := &http.Request{
+ Header: map[string][]string{
+ "custom-user-header": {"someValue"},
+ "x-amzn-header-foo": {"someValue"},
+ "x-amzn-meta-foo": {"someValue"},
+ },
+ URL: &url.URL{
+ Path: "/some/someValue/path",
+ RawPath: "/some/someValue/path",
+ RawQuery: "someExistingKeys=foobar&someKey=someValue&someKey=otherValue",
+ },
+ }
+
+ encoder, err := NewEncoder(actual.URL.Path, actual.URL.RawQuery, actual.Header)
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ // Headers
+ encoder.AddHeader("x-amzn-header-foo").String("someValue")
+ encoder.Headers("x-amzn-meta-").AddHeader("foo").String("someValue")
+
+ // Query
+ encoder.SetQuery("someKey").String("someValue")
+ encoder.AddQuery("someKey").String("otherValue")
+
+ // URI
+ if err := encoder.SetURI("pathKeyOne").String("someValue"); err != nil {
+ t.Errorf("expected no err, but got %v", err)
+ }
+
+ // URI
+ if err := encoder.SetURI("pathKeyTwo").String("path"); err != nil {
+ t.Errorf("expected no err, but got %v", err)
+ }
+
+ if actual, err = encoder.Encode(actual); err != nil {
+ t.Errorf("expected no err, but got %v", err)
+ }
+
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected %v, but got %v", expected, actual)
+ }
+}
+
+func TestEncoderHasHeader(t *testing.T) {
+ encoder, err := NewEncoder("/", "", http.Header{})
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if h := "i-dont-exist"; encoder.HasHeader(h) {
+ t.Errorf("expect %v not to be set", h)
+ }
+
+ encoder.AddHeader("I-do-exist").String("some value")
+
+ if h := "I-do-exist"; !encoder.HasHeader(h) {
+ t.Errorf("expect %v to be set", h)
+ }
+
+}
+
+func TestEncoderHasQuery(t *testing.T) {
+ encoder, err := NewEncoder("/", "", http.Header{})
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if q := "i-dont-exist"; encoder.HasQuery(q) {
+ t.Errorf("expect %v not to be set", q)
+ }
+
+ encoder.AddQuery("I-do-exist").String("some value")
+
+ if q := "I-do-exist"; !encoder.HasQuery(q) {
+ t.Errorf("expect %v to be set", q)
+ }
+
+}
+
+func TestEncodeContentLength(t *testing.T) {
+ cases := map[string]struct {
+ headerValue string
+ expected int64
+ wantErr bool
+ }{
+ "valid number": {
+ headerValue: "1024",
+ expected: 1024,
+ },
+ "invalid number": {
+ headerValue: "1024.5",
+ wantErr: true,
+ },
+ "not a number": {
+ headerValue: "NaN",
+ wantErr: true,
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ encoder, err := NewEncoder("/", "", http.Header{})
+ if err != nil {
+ t.Fatalf("expect no error, got %v", err)
+ }
+
+ encoder.SetHeader("Content-Length").String(tt.headerValue)
+
+ req := &http.Request{URL: &url.URL{}}
+ req, err = encoder.Encode(req)
+ if (err != nil) != tt.wantErr {
+ t.Fatalf("unexpected error value wantErr=%v", tt.wantErr)
+ } else if tt.wantErr {
+ return
+ }
+ if e, a := tt.expected, req.ContentLength; e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if v := req.Header.Get("Content-Length"); len(v) > 0 {
+ t.Errorf("expect header not to be set")
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/gotest/ya.make b/vendor/github.com/aws/smithy-go/encoding/httpbinding/gotest/ya.make
new file mode 100644
index 0000000000..c8a86501ea
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/gotest/ya.make
@@ -0,0 +1,5 @@
+GO_TEST_FOR(vendor/github.com/aws/smithy-go/encoding/httpbinding)
+
+LICENSE(Apache-2.0)
+
+END()
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go
new file mode 100644
index 0000000000..f9256e175f
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go
@@ -0,0 +1,122 @@
+package httpbinding
+
+import (
+ "encoding/base64"
+ "math"
+ "math/big"
+ "net/http"
+ "strconv"
+ "strings"
+)
+
+// Headers is used to encode header keys using a provided prefix
+type Headers struct {
+ header http.Header
+ prefix string
+}
+
+// AddHeader returns a HeaderValue used to append values to prefix+key
+func (h Headers) AddHeader(key string) HeaderValue {
+ return h.newHeaderValue(key, true)
+}
+
+// SetHeader returns a HeaderValue used to set the value of prefix+key
+func (h Headers) SetHeader(key string) HeaderValue {
+ return h.newHeaderValue(key, false)
+}
+
+func (h Headers) newHeaderValue(key string, append bool) HeaderValue {
+ return newHeaderValue(h.header, h.prefix+strings.TrimSpace(key), append)
+}
+
+// HeaderValue is used to encode values to an HTTP header
+type HeaderValue struct {
+ header http.Header
+ key string
+ append bool
+}
+
+func newHeaderValue(header http.Header, key string, append bool) HeaderValue {
+ return HeaderValue{header: header, key: strings.TrimSpace(key), append: append}
+}
+
+func (h HeaderValue) modifyHeader(value string) {
+ if h.append {
+ h.header[h.key] = append(h.header[h.key], value)
+ } else {
+ h.header[h.key] = append(h.header[h.key][:0], value)
+ }
+}
+
+// String encodes the value v as the header string value
+func (h HeaderValue) String(v string) {
+ h.modifyHeader(v)
+}
+
+// Byte encodes the value v as a query string value
+func (h HeaderValue) Byte(v int8) {
+ h.Long(int64(v))
+}
+
+// Short encodes the value v as a query string value
+func (h HeaderValue) Short(v int16) {
+ h.Long(int64(v))
+}
+
+// Integer encodes the value v as the header string value
+func (h HeaderValue) Integer(v int32) {
+ h.Long(int64(v))
+}
+
+// Long encodes the value v as the header string value
+func (h HeaderValue) Long(v int64) {
+ h.modifyHeader(strconv.FormatInt(v, 10))
+}
+
+// Boolean encodes the value v as a query string value
+func (h HeaderValue) Boolean(v bool) {
+ h.modifyHeader(strconv.FormatBool(v))
+}
+
+// Float encodes the value v as a query string value
+func (h HeaderValue) Float(v float32) {
+ h.float(float64(v), 32)
+}
+
+// Double encodes the value v as a query string value
+func (h HeaderValue) Double(v float64) {
+ h.float(v, 64)
+}
+
+func (h HeaderValue) float(v float64, bitSize int) {
+ switch {
+ case math.IsNaN(v):
+ h.String(floatNaN)
+ case math.IsInf(v, 1):
+ h.String(floatInfinity)
+ case math.IsInf(v, -1):
+ h.String(floatNegInfinity)
+ default:
+ h.modifyHeader(strconv.FormatFloat(v, 'f', -1, bitSize))
+ }
+}
+
+// BigInteger encodes the value v as a query string value
+func (h HeaderValue) BigInteger(v *big.Int) {
+ h.modifyHeader(v.String())
+}
+
+// BigDecimal encodes the value v as a query string value
+func (h HeaderValue) BigDecimal(v *big.Float) {
+ if i, accuracy := v.Int64(); accuracy == big.Exact {
+ h.Long(i)
+ return
+ }
+ h.modifyHeader(v.Text('e', -1))
+}
+
+// Blob encodes the value v as a base64 header string value
+func (h HeaderValue) Blob(v []byte) {
+ encodeToString := base64.StdEncoding.EncodeToString(v)
+ h.modifyHeader(encodeToString)
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/header_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header_test.go
new file mode 100644
index 0000000000..64e555c32b
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header_test.go
@@ -0,0 +1,295 @@
+package httpbinding
+
+import (
+ "fmt"
+ "math/big"
+ "net/http"
+ "reflect"
+ "testing"
+)
+
+func TestHeaderValue(t *testing.T) {
+ const keyName = "test-key"
+ const expectedKeyName = "test-key"
+
+ cases := map[string]struct {
+ header http.Header
+ args []interface{}
+ append bool
+ expected http.Header
+ }{
+ "set blob": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{[]byte("baz")},
+ expected: map[string][]string{
+ expectedKeyName: {"YmF6"},
+ },
+ },
+ "set boolean": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{true},
+ expected: map[string][]string{
+ expectedKeyName: {"true"},
+ },
+ },
+ "set string": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{"string value"},
+ expected: map[string][]string{
+ expectedKeyName: {"string value"},
+ },
+ },
+ "set byte": {
+ header: http.Header{expectedKeyName: []string{"127"}},
+ args: []interface{}{int8(127)},
+ expected: map[string][]string{
+ expectedKeyName: {"127"},
+ },
+ },
+ "set short": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int16(32767)},
+ expected: map[string][]string{
+ expectedKeyName: {"32767"},
+ },
+ },
+ "set integer": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int32(2147483647)},
+ expected: map[string][]string{
+ expectedKeyName: {"2147483647"},
+ },
+ },
+ "set long": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int64(9223372036854775807)},
+ expected: map[string][]string{
+ expectedKeyName: {"9223372036854775807"},
+ },
+ },
+ "set float": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{float32(3.14159)},
+ expected: map[string][]string{
+ expectedKeyName: {"3.14159"},
+ },
+ },
+ "set double": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{float64(3.14159)},
+ expected: map[string][]string{
+ expectedKeyName: {"3.14159"},
+ },
+ },
+ "set bigInteger": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{new(big.Int).SetInt64(42)},
+ expected: map[string][]string{
+ expectedKeyName: {"42"},
+ },
+ },
+ "set bigDecimal": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ expected: map[string][]string{
+ expectedKeyName: {"1.02410241024e+03"},
+ },
+ },
+ "add blob": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{[]byte("baz")},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "YmF6"},
+ },
+ },
+ "add bool": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{true},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "true"},
+ },
+ },
+ "add string": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{"string value"},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "string value"},
+ },
+ },
+ "add byte": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int8(127)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "127"},
+ },
+ },
+ "add short": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int16(32767)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "32767"},
+ },
+ },
+ "add integer": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int32(2147483647)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "2147483647"},
+ },
+ },
+ "add long": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int64(9223372036854775807)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "9223372036854775807"},
+ },
+ },
+ "add float": {
+ header: http.Header{expectedKeyName: []string{"1.61803"}},
+ args: []interface{}{float32(3.14159)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"1.61803", "3.14159"},
+ },
+ },
+ "add double": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{float64(3.14159)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "3.14159"},
+ },
+ },
+ "add bigInteger": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{new(big.Int).SetInt64(42)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "42"},
+ },
+ },
+ "add bigDecimal": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "1.02410241024e+03"},
+ },
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ if tt.header == nil {
+ tt.header = http.Header{}
+ }
+
+ hv := newHeaderValue(tt.header, keyName, tt.append)
+
+ if err := setHeader(hv, tt.args); err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if e, a := tt.expected, hv.header; !reflect.DeepEqual(e, a) {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
+
+func TestHeaders(t *testing.T) {
+ const prefix = "X-Amzn-Meta-"
+ cases := map[string]struct {
+ headers http.Header
+ values map[string]string
+ append bool
+ expected http.Header
+ }{
+ "set": {
+ headers: http.Header{
+ "X-Amzn-Meta-Foo": {"bazValue"},
+ },
+ values: map[string]string{
+ "Foo": "fooValue",
+ " Bar ": "barValue",
+ },
+ expected: http.Header{
+ "X-Amzn-Meta-Foo": {"fooValue"},
+ "X-Amzn-Meta-Bar": {"barValue"},
+ },
+ },
+ "add": {
+ headers: http.Header{
+ "X-Amzn-Meta-Foo": {"bazValue"},
+ },
+ values: map[string]string{
+ "Foo": "fooValue",
+ " Bar ": "barValue",
+ },
+ append: true,
+ expected: http.Header{
+ "X-Amzn-Meta-Foo": {"bazValue", "fooValue"},
+ "X-Amzn-Meta-Bar": {"barValue"},
+ },
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ headers := Headers{header: tt.headers, prefix: prefix}
+
+ var f func(key string) HeaderValue
+ if tt.append {
+ f = headers.AddHeader
+ } else {
+ f = headers.SetHeader
+ }
+
+ for key, value := range tt.values {
+ f(key).String(value)
+ }
+
+ if e, a := tt.expected, tt.headers; !reflect.DeepEqual(e, a) {
+ t.Errorf("expected %v, but got %v", e, a)
+ }
+ })
+ }
+}
+
+func setHeader(hv HeaderValue, args []interface{}) error {
+ value := args[0]
+
+ switch value.(type) {
+ case []byte:
+ return reflectCall(reflect.ValueOf(hv.Blob), args)
+ case bool:
+ return reflectCall(reflect.ValueOf(hv.Boolean), args)
+ case string:
+ return reflectCall(reflect.ValueOf(hv.String), args)
+ case int8:
+ return reflectCall(reflect.ValueOf(hv.Byte), args)
+ case int16:
+ return reflectCall(reflect.ValueOf(hv.Short), args)
+ case int32:
+ return reflectCall(reflect.ValueOf(hv.Integer), args)
+ case int64:
+ return reflectCall(reflect.ValueOf(hv.Long), args)
+ case float32:
+ return reflectCall(reflect.ValueOf(hv.Float), args)
+ case float64:
+ return reflectCall(reflect.ValueOf(hv.Double), args)
+ case *big.Int:
+ return reflectCall(reflect.ValueOf(hv.BigInteger), args)
+ case *big.Float:
+ return reflectCall(reflect.ValueOf(hv.BigDecimal), args)
+ default:
+ return fmt.Errorf("unhandled header value type")
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go
new file mode 100644
index 0000000000..e78926c9a5
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go
@@ -0,0 +1,108 @@
+package httpbinding
+
+import (
+ "bytes"
+ "fmt"
+)
+
+const (
+ uriTokenStart = '{'
+ uriTokenStop = '}'
+ uriTokenSkip = '+'
+)
+
+func bufCap(b []byte, n int) []byte {
+ if cap(b) < n {
+ return make([]byte, 0, n)
+ }
+
+ return b[0:0]
+}
+
+// replacePathElement replaces a single element in the path []byte.
+// Escape is used to control whether the value will be escaped using Amazon path escape style.
+func replacePathElement(path, fieldBuf []byte, key, val string, escape bool) ([]byte, []byte, error) {
+ fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
+ fieldBuf = append(fieldBuf, uriTokenStart)
+ fieldBuf = append(fieldBuf, key...)
+
+ start := bytes.Index(path, fieldBuf)
+ end := start + len(fieldBuf)
+ if start < 0 || len(path[end:]) == 0 {
+ // TODO what to do about error?
+ return path, fieldBuf, fmt.Errorf("invalid path index, start=%d,end=%d. %s", start, end, path)
+ }
+
+ encodeSep := true
+ if path[end] == uriTokenSkip {
+ // '+' token means do not escape slashes
+ encodeSep = false
+ end++
+ }
+
+ if escape {
+ val = EscapePath(val, encodeSep)
+ }
+
+ if path[end] != uriTokenStop {
+ return path, fieldBuf, fmt.Errorf("invalid path element, does not contain token stop, %s", path)
+ }
+ end++
+
+ fieldBuf = bufCap(fieldBuf, len(val))
+ fieldBuf = append(fieldBuf, val...)
+
+ keyLen := end - start
+ valLen := len(fieldBuf)
+
+ if keyLen == valLen {
+ copy(path[start:], fieldBuf)
+ return path, fieldBuf, nil
+ }
+
+ newLen := len(path) + (valLen - keyLen)
+ if len(path) < newLen {
+ path = path[:cap(path)]
+ }
+ if cap(path) < newLen {
+ newURI := make([]byte, newLen)
+ copy(newURI, path)
+ path = newURI
+ }
+
+ // shift
+ copy(path[start+valLen:], path[end:])
+ path = path[:newLen]
+ copy(path[start:], fieldBuf)
+
+ return path, fieldBuf, nil
+}
+
+// EscapePath escapes part of a URL path in Amazon style.
+func EscapePath(path string, encodeSep bool) string {
+ var buf bytes.Buffer
+ for i := 0; i < len(path); i++ {
+ c := path[i]
+ if noEscape[c] || (c == '/' && !encodeSep) {
+ buf.WriteByte(c)
+ } else {
+ fmt.Fprintf(&buf, "%%%02X", c)
+ }
+ }
+ return buf.String()
+}
+
+var noEscape [256]bool
+
+func init() {
+ for i := 0; i < len(noEscape); i++ {
+ // AWS expects every character except these to be escaped
+ noEscape[i] = (i >= 'A' && i <= 'Z') ||
+ (i >= 'a' && i <= 'z') ||
+ (i >= '0' && i <= '9') ||
+ i == '-' ||
+ i == '.' ||
+ i == '_' ||
+ i == '~'
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace_test.go
new file mode 100644
index 0000000000..689733ca00
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace_test.go
@@ -0,0 +1,67 @@
+package httpbinding
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestPathReplace(t *testing.T) {
+ cases := []struct {
+ Orig, ExpPath, ExpRawPath []byte
+ Key, Val string
+ }{
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/123/{key+}"),
+ ExpRawPath: []byte("/123/{key+}"),
+ Key: "bucket", Val: "123",
+ },
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/{bucket}/abc"),
+ ExpRawPath: []byte("/{bucket}/abc"),
+ Key: "key", Val: "abc",
+ },
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/{bucket}/a/b/c"),
+ ExpRawPath: []byte("/{bucket}/a/b/c"),
+ Key: "key", Val: "a/b/c",
+ },
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/1/2/3/{key+}"),
+ ExpRawPath: []byte("/1%2F2%2F3/{key+}"),
+ Key: "bucket", Val: "1/2/3",
+ },
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/reallylongvaluegoesheregrowingarray/{key+}"),
+ ExpRawPath: []byte("/reallylongvaluegoesheregrowingarray/{key+}"),
+ Key: "bucket", Val: "reallylongvaluegoesheregrowingarray",
+ },
+ }
+
+ var buffer [64]byte
+
+ for i, c := range cases {
+ origRaw := make([]byte, len(c.Orig))
+ copy(origRaw, c.Orig)
+
+ path, _, err := replacePathElement(c.Orig, buffer[:0], c.Key, c.Val, false)
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+ rawPath, _, err := replacePathElement(origRaw, buffer[:0], c.Key, c.Val, true)
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if e, a := c.ExpPath, path; bytes.Compare(e, a) != 0 {
+ t.Errorf("%d, expect uri path to be %q got %q", i, e, a)
+ }
+ if e, a := c.ExpRawPath, rawPath; bytes.Compare(e, a) != 0 {
+ t.Errorf("%d, expect uri raw path to be %q got %q", i, e, a)
+ }
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go
new file mode 100644
index 0000000000..c2e7d0a20f
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go
@@ -0,0 +1,107 @@
+package httpbinding
+
+import (
+ "encoding/base64"
+ "math"
+ "math/big"
+ "net/url"
+ "strconv"
+)
+
+// QueryValue is used to encode query key values
+type QueryValue struct {
+ query url.Values
+ key string
+ append bool
+}
+
+// NewQueryValue creates a new QueryValue which enables encoding
+// a query value into the given url.Values.
+func NewQueryValue(query url.Values, key string, append bool) QueryValue {
+ return QueryValue{
+ query: query,
+ key: key,
+ append: append,
+ }
+}
+
+func (qv QueryValue) updateKey(value string) {
+ if qv.append {
+ qv.query.Add(qv.key, value)
+ } else {
+ qv.query.Set(qv.key, value)
+ }
+}
+
+// Blob encodes v as a base64 query string value
+func (qv QueryValue) Blob(v []byte) {
+ encodeToString := base64.StdEncoding.EncodeToString(v)
+ qv.updateKey(encodeToString)
+}
+
+// Boolean encodes v as a query string value
+func (qv QueryValue) Boolean(v bool) {
+ qv.updateKey(strconv.FormatBool(v))
+}
+
+// String encodes v as a query string value
+func (qv QueryValue) String(v string) {
+ qv.updateKey(v)
+}
+
+// Byte encodes v as a query string value
+func (qv QueryValue) Byte(v int8) {
+ qv.Long(int64(v))
+}
+
+// Short encodes v as a query string value
+func (qv QueryValue) Short(v int16) {
+ qv.Long(int64(v))
+}
+
+// Integer encodes v as a query string value
+func (qv QueryValue) Integer(v int32) {
+ qv.Long(int64(v))
+}
+
+// Long encodes v as a query string value
+func (qv QueryValue) Long(v int64) {
+ qv.updateKey(strconv.FormatInt(v, 10))
+}
+
+// Float encodes v as a query string value
+func (qv QueryValue) Float(v float32) {
+ qv.float(float64(v), 32)
+}
+
+// Double encodes v as a query string value
+func (qv QueryValue) Double(v float64) {
+ qv.float(v, 64)
+}
+
+func (qv QueryValue) float(v float64, bitSize int) {
+ switch {
+ case math.IsNaN(v):
+ qv.String(floatNaN)
+ case math.IsInf(v, 1):
+ qv.String(floatInfinity)
+ case math.IsInf(v, -1):
+ qv.String(floatNegInfinity)
+ default:
+ qv.updateKey(strconv.FormatFloat(v, 'f', -1, bitSize))
+ }
+}
+
+// BigInteger encodes v as a query string value
+func (qv QueryValue) BigInteger(v *big.Int) {
+ qv.updateKey(v.String())
+}
+
+// BigDecimal encodes v as a query string value
+func (qv QueryValue) BigDecimal(v *big.Float) {
+ if i, accuracy := v.Int64(); accuracy == big.Exact {
+ qv.Long(i)
+ return
+ }
+ qv.updateKey(v.Text('e', -1))
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/query_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query_test.go
new file mode 100644
index 0000000000..62cf25cd67
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query_test.go
@@ -0,0 +1,234 @@
+package httpbinding
+
+import (
+ "fmt"
+ "math/big"
+ "net/url"
+ "reflect"
+ "testing"
+)
+
+func TestQueryValue(t *testing.T) {
+ const queryKey = "someKey"
+
+ cases := map[string]struct {
+ values url.Values
+ args []interface{}
+ append bool
+ expected url.Values
+ }{
+ "set blob": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{[]byte("baz")},
+ expected: map[string][]string{
+ queryKey: {"YmF6"},
+ },
+ },
+ "set bool": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{true},
+ expected: map[string][]string{
+ queryKey: {"true"},
+ },
+ },
+ "set string": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{"string value"},
+ expected: map[string][]string{
+ queryKey: {"string value"},
+ },
+ },
+ "set byte": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int8(127)},
+ expected: map[string][]string{
+ queryKey: {"127"},
+ },
+ },
+ "set short": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int16(32767)},
+ expected: map[string][]string{
+ queryKey: {"32767"},
+ },
+ },
+ "set integer": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int32(2147483647)},
+ expected: map[string][]string{
+ queryKey: {"2147483647"},
+ },
+ },
+ "set long": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int64(9223372036854775807)},
+ expected: map[string][]string{
+ queryKey: {"9223372036854775807"},
+ },
+ },
+ "set float": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{float32(3.14159)},
+ expected: map[string][]string{
+ queryKey: {"3.14159"},
+ },
+ },
+ "set double": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{float64(3.14159)},
+ expected: map[string][]string{
+ queryKey: {"3.14159"},
+ },
+ },
+ "set bigInteger": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{new(big.Int).SetInt64(1)},
+ expected: map[string][]string{
+ queryKey: {"1"},
+ },
+ },
+ "set bigDecimal": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ expected: map[string][]string{
+ queryKey: {"1.02410241024e+03"},
+ },
+ },
+ "add blob": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{[]byte("baz")},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "YmF6"},
+ },
+ },
+ "add bool": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{true},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "true"},
+ },
+ },
+ "add string": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{"string value"},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "string value"},
+ },
+ },
+ "add byte": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int8(127)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "127"},
+ },
+ },
+ "add short": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int16(32767)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "32767"},
+ },
+ },
+ "add integer": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int32(2147483647)},
+ expected: map[string][]string{
+ queryKey: {"2147483647"},
+ },
+ },
+ "add long": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int64(9223372036854775807)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "9223372036854775807"},
+ },
+ },
+ "add float": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{float32(3.14159)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "3.14159"},
+ },
+ },
+ "add double": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{float64(3.14159)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "3.14159"},
+ },
+ },
+ "add bigInteger": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{new(big.Int).SetInt64(1)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "1"},
+ },
+ },
+ "add bigDecimal": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "1.02410241024e+03"},
+ },
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ if tt.values == nil {
+ tt.values = url.Values{}
+ }
+
+ qv := NewQueryValue(tt.values, queryKey, tt.append)
+
+ if err := setQueryValue(qv, tt.args); err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if e, a := tt.expected, qv.query; !reflect.DeepEqual(e, a) {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
+
+func setQueryValue(qv QueryValue, args []interface{}) error {
+ value := args[0]
+
+ switch value.(type) {
+ case []byte:
+ return reflectCall(reflect.ValueOf(qv.Blob), args)
+ case bool:
+ return reflectCall(reflect.ValueOf(qv.Boolean), args)
+ case string:
+ return reflectCall(reflect.ValueOf(qv.String), args)
+ case int8:
+ return reflectCall(reflect.ValueOf(qv.Byte), args)
+ case int16:
+ return reflectCall(reflect.ValueOf(qv.Short), args)
+ case int32:
+ return reflectCall(reflect.ValueOf(qv.Integer), args)
+ case int64:
+ return reflectCall(reflect.ValueOf(qv.Long), args)
+ case float32:
+ return reflectCall(reflect.ValueOf(qv.Float), args)
+ case float64:
+ return reflectCall(reflect.ValueOf(qv.Double), args)
+ case *big.Int:
+ return reflectCall(reflect.ValueOf(qv.BigInteger), args)
+ case *big.Float:
+ return reflectCall(reflect.ValueOf(qv.BigDecimal), args)
+ default:
+ return fmt.Errorf("unhandled query value type")
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/shared_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/shared_test.go
new file mode 100644
index 0000000000..2b7518e1c7
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/shared_test.go
@@ -0,0 +1,36 @@
+package httpbinding
+
+import (
+ "fmt"
+ "reflect"
+)
+
+func reflectCall(funcValue reflect.Value, args []interface{}) error {
+ argValues := make([]reflect.Value, len(args))
+
+ for i, v := range args {
+ value := reflect.ValueOf(v)
+ argValues[i] = value
+ }
+
+ retValues := funcValue.Call(argValues)
+ if len(retValues) > 0 {
+ errValue := retValues[0]
+
+ if typeName := errValue.Type().Name(); typeName != "error" {
+ panic(fmt.Sprintf("expected first return argument to be error but got %v", typeName))
+ }
+
+ if errValue.IsNil() {
+ return nil
+ }
+
+ if err, ok := errValue.Interface().(error); ok {
+ return err
+ }
+
+ panic(fmt.Sprintf("expected %v to return error type, but got %v", funcValue.Type().String(), retValues[0].Type().String()))
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go
new file mode 100644
index 0000000000..f04e11984a
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go
@@ -0,0 +1,111 @@
+package httpbinding
+
+import (
+ "math"
+ "math/big"
+ "strconv"
+ "strings"
+)
+
+// URIValue is used to encode named URI parameters
+type URIValue struct {
+ path, rawPath, buffer *[]byte
+
+ key string
+}
+
+func newURIValue(path *[]byte, rawPath *[]byte, buffer *[]byte, key string) URIValue {
+ return URIValue{path: path, rawPath: rawPath, buffer: buffer, key: key}
+}
+
+func (u URIValue) modifyURI(value string) (err error) {
+ *u.path, *u.buffer, err = replacePathElement(*u.path, *u.buffer, u.key, value, false)
+ if err != nil {
+ return err
+ }
+ *u.rawPath, *u.buffer, err = replacePathElement(*u.rawPath, *u.buffer, u.key, value, true)
+ return err
+}
+
+// Boolean encodes v as a URI string value
+func (u URIValue) Boolean(v bool) error {
+ return u.modifyURI(strconv.FormatBool(v))
+}
+
+// String encodes v as a URI string value
+func (u URIValue) String(v string) error {
+ return u.modifyURI(v)
+}
+
+// Byte encodes v as a URI string value
+func (u URIValue) Byte(v int8) error {
+ return u.Long(int64(v))
+}
+
+// Short encodes v as a URI string value
+func (u URIValue) Short(v int16) error {
+ return u.Long(int64(v))
+}
+
+// Integer encodes v as a URI string value
+func (u URIValue) Integer(v int32) error {
+ return u.Long(int64(v))
+}
+
+// Long encodes v as a URI string value
+func (u URIValue) Long(v int64) error {
+ return u.modifyURI(strconv.FormatInt(v, 10))
+}
+
+// Float encodes v as a query string value
+func (u URIValue) Float(v float32) error {
+ return u.float(float64(v), 32)
+}
+
+// Double encodes v as a query string value
+func (u URIValue) Double(v float64) error {
+ return u.float(v, 64)
+}
+
+func (u URIValue) float(v float64, bitSize int) error {
+ switch {
+ case math.IsNaN(v):
+ return u.String(floatNaN)
+ case math.IsInf(v, 1):
+ return u.String(floatInfinity)
+ case math.IsInf(v, -1):
+ return u.String(floatNegInfinity)
+ default:
+ return u.modifyURI(strconv.FormatFloat(v, 'f', -1, bitSize))
+ }
+}
+
+// BigInteger encodes v as a query string value
+func (u URIValue) BigInteger(v *big.Int) error {
+ return u.modifyURI(v.String())
+}
+
+// BigDecimal encodes v as a query string value
+func (u URIValue) BigDecimal(v *big.Float) error {
+ if i, accuracy := v.Int64(); accuracy == big.Exact {
+ return u.Long(i)
+ }
+ return u.modifyURI(v.Text('e', -1))
+}
+
+// SplitURI parses a Smithy HTTP binding trait URI
+func SplitURI(uri string) (path, query string) {
+ queryStart := strings.IndexRune(uri, '?')
+ if queryStart == -1 {
+ path = uri
+ return path, query
+ }
+
+ path = uri[:queryStart]
+ if queryStart+1 >= len(uri) {
+ return path, query
+ }
+ query = uri[queryStart+1:]
+
+ return path, query
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri_test.go
new file mode 100644
index 0000000000..039e1e5baa
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri_test.go
@@ -0,0 +1,198 @@
+package httpbinding
+
+import (
+ "fmt"
+ "math/big"
+ "reflect"
+ "strconv"
+ "testing"
+)
+
+func TestURIValue(t *testing.T) {
+ const uriKey = "someKey"
+ const path = "/some/{someKey}/{path+}"
+
+ type expected struct {
+ path string
+ raw string
+ }
+
+ cases := map[string]struct {
+ path string
+ args []interface{}
+ expected expected
+ }{
+ "bool": {
+ path: path,
+ args: []interface{}{true},
+ expected: expected{
+ path: "/some/true/{path+}",
+ raw: "/some/true/{path+}",
+ },
+ },
+ "string": {
+ path: path,
+ args: []interface{}{"someValue"},
+ expected: expected{
+ path: "/some/someValue/{path+}",
+ raw: "/some/someValue/{path+}",
+ },
+ },
+ "byte": {
+ path: path,
+ args: []interface{}{int8(127)},
+ expected: expected{
+ path: "/some/127/{path+}",
+ raw: "/some/127/{path+}",
+ },
+ },
+ "short": {
+ path: path,
+ args: []interface{}{int16(32767)},
+ expected: expected{
+ path: "/some/32767/{path+}",
+ raw: "/some/32767/{path+}",
+ },
+ },
+ "integer": {
+ path: path,
+ args: []interface{}{int32(2147483647)},
+ expected: expected{
+ path: "/some/2147483647/{path+}",
+ raw: "/some/2147483647/{path+}",
+ },
+ },
+ "long": {
+ path: path,
+ args: []interface{}{int64(9223372036854775807)},
+ expected: expected{
+ path: "/some/9223372036854775807/{path+}",
+ raw: "/some/9223372036854775807/{path+}",
+ },
+ },
+ "float32": {
+ path: path,
+ args: []interface{}{float32(3.14159)},
+ expected: expected{
+ path: "/some/3.14159/{path+}",
+ raw: "/some/3.14159/{path+}",
+ },
+ },
+ "float64": {
+ path: path,
+ args: []interface{}{float64(3.14159)},
+ expected: expected{
+ path: "/some/3.14159/{path+}",
+ raw: "/some/3.14159/{path+}",
+ },
+ },
+ "bigInteger": {
+ path: path,
+ args: []interface{}{new(big.Int).SetInt64(1)},
+ expected: expected{
+ path: "/some/1/{path+}",
+ raw: "/some/1/{path+}",
+ },
+ },
+ "bigDecimal": {
+ path: path,
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ expected: expected{
+ path: "/some/1.02410241024e+03/{path+}",
+ raw: "/some/1.02410241024e%2B03/{path+}",
+ },
+ },
+ }
+
+ buffer := make([]byte, 1024)
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ pBytes, rBytes := []byte(tt.path), []byte(tt.path)
+
+ uv := newURIValue(&pBytes, &rBytes, &buffer, uriKey)
+
+ if err := setURI(uv, tt.args); err != nil {
+ t.Fatalf("expected no error, %v", err)
+ }
+
+ if e, a := tt.expected.path, string(pBytes); e != a {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+
+ if e, a := tt.expected.raw, string(rBytes); e != a {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
+
+func setURI(uv URIValue, args []interface{}) error {
+ value := args[0]
+
+ switch value.(type) {
+ case bool:
+ return reflectCall(reflect.ValueOf(uv.Boolean), args)
+ case string:
+ return reflectCall(reflect.ValueOf(uv.String), args)
+ case int8:
+ return reflectCall(reflect.ValueOf(uv.Byte), args)
+ case int16:
+ return reflectCall(reflect.ValueOf(uv.Short), args)
+ case int32:
+ return reflectCall(reflect.ValueOf(uv.Integer), args)
+ case int64:
+ return reflectCall(reflect.ValueOf(uv.Long), args)
+ case float32:
+ return reflectCall(reflect.ValueOf(uv.Float), args)
+ case float64:
+ return reflectCall(reflect.ValueOf(uv.Double), args)
+ case *big.Int:
+ return reflectCall(reflect.ValueOf(uv.BigInteger), args)
+ case *big.Float:
+ return reflectCall(reflect.ValueOf(uv.BigDecimal), args)
+ default:
+ return fmt.Errorf("unhandled value type")
+ }
+}
+
+func TestParseURI(t *testing.T) {
+ cases := []struct {
+ Value string
+ Path string
+ Query string
+ }{
+ {
+ Value: "/my/uri/foo/bar/baz",
+ Path: "/my/uri/foo/bar/baz",
+ Query: "",
+ },
+ {
+ Value: "/path?requiredKey",
+ Path: "/path",
+ Query: "requiredKey",
+ },
+ {
+ Value: "/path?",
+ Path: "/path",
+ Query: "",
+ },
+ {
+ Value: "?",
+ Path: "",
+ Query: "",
+ },
+ }
+
+ for i, tt := range cases {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ path, query := SplitURI(tt.Value)
+ if e, a := tt.Path, path; e != a {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ if e, a := tt.Query, query; e != a {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/ya.make b/vendor/github.com/aws/smithy-go/encoding/httpbinding/ya.make
new file mode 100644
index 0000000000..f1f0698636
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/ya.make
@@ -0,0 +1,26 @@
+GO_LIBRARY()
+
+LICENSE(Apache-2.0)
+
+SRCS(
+ encode.go
+ header.go
+ path_replace.go
+ query.go
+ uri.go
+)
+
+GO_TEST_SRCS(
+ encode_test.go
+ header_test.go
+ path_replace_test.go
+ query_test.go
+ shared_test.go
+ uri_test.go
+)
+
+END()
+
+RECURSE(
+ gotest
+)