diff options
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/private/protocol/rest')
3 files changed, 562 insertions, 0 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go new file mode 100644 index 0000000..7161835 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go | |||
@@ -0,0 +1,290 @@ | |||
1 | // Package rest provides RESTful serialization of AWS requests and responses. | ||
2 | package rest | ||
3 | |||
4 | import ( | ||
5 | "bytes" | ||
6 | "encoding/base64" | ||
7 | "encoding/json" | ||
8 | "fmt" | ||
9 | "io" | ||
10 | "net/http" | ||
11 | "net/url" | ||
12 | "path" | ||
13 | "reflect" | ||
14 | "strconv" | ||
15 | "strings" | ||
16 | "time" | ||
17 | |||
18 | "github.com/aws/aws-sdk-go/aws" | ||
19 | "github.com/aws/aws-sdk-go/aws/awserr" | ||
20 | "github.com/aws/aws-sdk-go/aws/request" | ||
21 | ) | ||
22 | |||
23 | // RFC822 returns an RFC822 formatted timestamp for AWS protocols | ||
24 | const RFC822 = "Mon, 2 Jan 2006 15:04:05 GMT" | ||
25 | |||
26 | // Whether the byte value can be sent without escaping in AWS URLs | ||
27 | var noEscape [256]bool | ||
28 | |||
29 | var errValueNotSet = fmt.Errorf("value not set") | ||
30 | |||
31 | func init() { | ||
32 | for i := 0; i < len(noEscape); i++ { | ||
33 | // AWS expects every character except these to be escaped | ||
34 | noEscape[i] = (i >= 'A' && i <= 'Z') || | ||
35 | (i >= 'a' && i <= 'z') || | ||
36 | (i >= '0' && i <= '9') || | ||
37 | i == '-' || | ||
38 | i == '.' || | ||
39 | i == '_' || | ||
40 | i == '~' | ||
41 | } | ||
42 | } | ||
43 | |||
44 | // BuildHandler is a named request handler for building rest protocol requests | ||
45 | var BuildHandler = request.NamedHandler{Name: "awssdk.rest.Build", Fn: Build} | ||
46 | |||
47 | // Build builds the REST component of a service request. | ||
48 | func Build(r *request.Request) { | ||
49 | if r.ParamsFilled() { | ||
50 | v := reflect.ValueOf(r.Params).Elem() | ||
51 | buildLocationElements(r, v, false) | ||
52 | buildBody(r, v) | ||
53 | } | ||
54 | } | ||
55 | |||
56 | // BuildAsGET builds the REST component of a service request with the ability to hoist | ||
57 | // data from the body. | ||
58 | func BuildAsGET(r *request.Request) { | ||
59 | if r.ParamsFilled() { | ||
60 | v := reflect.ValueOf(r.Params).Elem() | ||
61 | buildLocationElements(r, v, true) | ||
62 | buildBody(r, v) | ||
63 | } | ||
64 | } | ||
65 | |||
66 | func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bool) { | ||
67 | query := r.HTTPRequest.URL.Query() | ||
68 | |||
69 | // Setup the raw path to match the base path pattern. This is needed | ||
70 | // so that when the path is mutated a custom escaped version can be | ||
71 | // stored in RawPath that will be used by the Go client. | ||
72 | r.HTTPRequest.URL.RawPath = r.HTTPRequest.URL.Path | ||
73 | |||
74 | for i := 0; i < v.NumField(); i++ { | ||
75 | m := v.Field(i) | ||
76 | if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) { | ||
77 | continue | ||
78 | } | ||
79 | |||
80 | if m.IsValid() { | ||
81 | field := v.Type().Field(i) | ||
82 | name := field.Tag.Get("locationName") | ||
83 | if name == "" { | ||
84 | name = field.Name | ||
85 | } | ||
86 | if kind := m.Kind(); kind == reflect.Ptr { | ||
87 | m = m.Elem() | ||
88 | } else if kind == reflect.Interface { | ||
89 | if !m.Elem().IsValid() { | ||
90 | continue | ||
91 | } | ||
92 | } | ||
93 | if !m.IsValid() { | ||
94 | continue | ||
95 | } | ||
96 | if field.Tag.Get("ignore") != "" { | ||
97 | continue | ||
98 | } | ||
99 | |||
100 | var err error | ||
101 | switch field.Tag.Get("location") { | ||
102 | case "headers": // header maps | ||
103 | err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag) | ||
104 | case "header": | ||
105 | err = buildHeader(&r.HTTPRequest.Header, m, name, field.Tag) | ||
106 | case "uri": | ||
107 | err = buildURI(r.HTTPRequest.URL, m, name, field.Tag) | ||
108 | case "querystring": | ||
109 | err = buildQueryString(query, m, name, field.Tag) | ||
110 | default: | ||
111 | if buildGETQuery { | ||
112 | err = buildQueryString(query, m, name, field.Tag) | ||
113 | } | ||
114 | } | ||
115 | r.Error = err | ||
116 | } | ||
117 | if r.Error != nil { | ||
118 | return | ||
119 | } | ||
120 | } | ||
121 | |||
122 | r.HTTPRequest.URL.RawQuery = query.Encode() | ||
123 | if !aws.BoolValue(r.Config.DisableRestProtocolURICleaning) { | ||
124 | cleanPath(r.HTTPRequest.URL) | ||
125 | } | ||
126 | } | ||
127 | |||
128 | func buildBody(r *request.Request, v reflect.Value) { | ||
129 | if field, ok := v.Type().FieldByName("_"); ok { | ||
130 | if payloadName := field.Tag.Get("payload"); payloadName != "" { | ||
131 | pfield, _ := v.Type().FieldByName(payloadName) | ||
132 | if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { | ||
133 | payload := reflect.Indirect(v.FieldByName(payloadName)) | ||
134 | if payload.IsValid() && payload.Interface() != nil { | ||
135 | switch reader := payload.Interface().(type) { | ||
136 | case io.ReadSeeker: | ||
137 | r.SetReaderBody(reader) | ||
138 | case []byte: | ||
139 | r.SetBufferBody(reader) | ||
140 | case string: | ||
141 | r.SetStringBody(reader) | ||
142 | default: | ||
143 | r.Error = awserr.New("SerializationError", | ||
144 | "failed to encode REST request", | ||
145 | fmt.Errorf("unknown payload type %s", payload.Type())) | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | |||
153 | func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.StructTag) error { | ||
154 | str, err := convertType(v, tag) | ||
155 | if err == errValueNotSet { | ||
156 | return nil | ||
157 | } else if err != nil { | ||
158 | return awserr.New("SerializationError", "failed to encode REST request", err) | ||
159 | } | ||
160 | |||
161 | header.Add(name, str) | ||
162 | |||
163 | return nil | ||
164 | } | ||
165 | |||
166 | func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag) error { | ||
167 | prefix := tag.Get("locationName") | ||
168 | for _, key := range v.MapKeys() { | ||
169 | str, err := convertType(v.MapIndex(key), tag) | ||
170 | if err == errValueNotSet { | ||
171 | continue | ||
172 | } else if err != nil { | ||
173 | return awserr.New("SerializationError", "failed to encode REST request", err) | ||
174 | |||
175 | } | ||
176 | |||
177 | header.Add(prefix+key.String(), str) | ||
178 | } | ||
179 | return nil | ||
180 | } | ||
181 | |||
182 | func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) error { | ||
183 | value, err := convertType(v, tag) | ||
184 | if err == errValueNotSet { | ||
185 | return nil | ||
186 | } else if err != nil { | ||
187 | return awserr.New("SerializationError", "failed to encode REST request", err) | ||
188 | } | ||
189 | |||
190 | u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1) | ||
191 | u.Path = strings.Replace(u.Path, "{"+name+"+}", value, -1) | ||
192 | |||
193 | u.RawPath = strings.Replace(u.RawPath, "{"+name+"}", EscapePath(value, true), -1) | ||
194 | u.RawPath = strings.Replace(u.RawPath, "{"+name+"+}", EscapePath(value, false), -1) | ||
195 | |||
196 | return nil | ||
197 | } | ||
198 | |||
199 | func buildQueryString(query url.Values, v reflect.Value, name string, tag reflect.StructTag) error { | ||
200 | switch value := v.Interface().(type) { | ||
201 | case []*string: | ||
202 | for _, item := range value { | ||
203 | query.Add(name, *item) | ||
204 | } | ||
205 | case map[string]*string: | ||
206 | for key, item := range value { | ||
207 | query.Add(key, *item) | ||
208 | } | ||
209 | case map[string][]*string: | ||
210 | for key, items := range value { | ||
211 | for _, item := range items { | ||
212 | query.Add(key, *item) | ||
213 | } | ||
214 | } | ||
215 | default: | ||
216 | str, err := convertType(v, tag) | ||
217 | if err == errValueNotSet { | ||
218 | return nil | ||
219 | } else if err != nil { | ||
220 | return awserr.New("SerializationError", "failed to encode REST request", err) | ||
221 | } | ||
222 | query.Set(name, str) | ||
223 | } | ||
224 | |||
225 | return nil | ||
226 | } | ||
227 | |||
228 | func cleanPath(u *url.URL) { | ||
229 | hasSlash := strings.HasSuffix(u.Path, "/") | ||
230 | |||
231 | // clean up path, removing duplicate `/` | ||
232 | u.Path = path.Clean(u.Path) | ||
233 | u.RawPath = path.Clean(u.RawPath) | ||
234 | |||
235 | if hasSlash && !strings.HasSuffix(u.Path, "/") { | ||
236 | u.Path += "/" | ||
237 | u.RawPath += "/" | ||
238 | } | ||
239 | } | ||
240 | |||
241 | // EscapePath escapes part of a URL path in Amazon style | ||
242 | func EscapePath(path string, encodeSep bool) string { | ||
243 | var buf bytes.Buffer | ||
244 | for i := 0; i < len(path); i++ { | ||
245 | c := path[i] | ||
246 | if noEscape[c] || (c == '/' && !encodeSep) { | ||
247 | buf.WriteByte(c) | ||
248 | } else { | ||
249 | fmt.Fprintf(&buf, "%%%02X", c) | ||
250 | } | ||
251 | } | ||
252 | return buf.String() | ||
253 | } | ||
254 | |||
255 | func convertType(v reflect.Value, tag reflect.StructTag) (string, error) { | ||
256 | v = reflect.Indirect(v) | ||
257 | if !v.IsValid() { | ||
258 | return "", errValueNotSet | ||
259 | } | ||
260 | |||
261 | var str string | ||
262 | switch value := v.Interface().(type) { | ||
263 | case string: | ||
264 | str = value | ||
265 | case []byte: | ||
266 | str = base64.StdEncoding.EncodeToString(value) | ||
267 | case bool: | ||
268 | str = strconv.FormatBool(value) | ||
269 | case int64: | ||
270 | str = strconv.FormatInt(value, 10) | ||
271 | case float64: | ||
272 | str = strconv.FormatFloat(value, 'f', -1, 64) | ||
273 | case time.Time: | ||
274 | str = value.UTC().Format(RFC822) | ||
275 | case aws.JSONValue: | ||
276 | b, err := json.Marshal(value) | ||
277 | if err != nil { | ||
278 | return "", err | ||
279 | } | ||
280 | if tag.Get("location") == "header" { | ||
281 | str = base64.StdEncoding.EncodeToString(b) | ||
282 | } else { | ||
283 | str = string(b) | ||
284 | } | ||
285 | default: | ||
286 | err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) | ||
287 | return "", err | ||
288 | } | ||
289 | return str, nil | ||
290 | } | ||
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go new file mode 100644 index 0000000..4366de2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go | |||
@@ -0,0 +1,45 @@ | |||
1 | package rest | ||
2 | |||
3 | import "reflect" | ||
4 | |||
5 | // PayloadMember returns the payload field member of i if there is one, or nil. | ||
6 | func PayloadMember(i interface{}) interface{} { | ||
7 | if i == nil { | ||
8 | return nil | ||
9 | } | ||
10 | |||
11 | v := reflect.ValueOf(i).Elem() | ||
12 | if !v.IsValid() { | ||
13 | return nil | ||
14 | } | ||
15 | if field, ok := v.Type().FieldByName("_"); ok { | ||
16 | if payloadName := field.Tag.Get("payload"); payloadName != "" { | ||
17 | field, _ := v.Type().FieldByName(payloadName) | ||
18 | if field.Tag.Get("type") != "structure" { | ||
19 | return nil | ||
20 | } | ||
21 | |||
22 | payload := v.FieldByName(payloadName) | ||
23 | if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) { | ||
24 | return payload.Interface() | ||
25 | } | ||
26 | } | ||
27 | } | ||
28 | return nil | ||
29 | } | ||
30 | |||
31 | // PayloadType returns the type of a payload field member of i if there is one, or "". | ||
32 | func PayloadType(i interface{}) string { | ||
33 | v := reflect.Indirect(reflect.ValueOf(i)) | ||
34 | if !v.IsValid() { | ||
35 | return "" | ||
36 | } | ||
37 | if field, ok := v.Type().FieldByName("_"); ok { | ||
38 | if payloadName := field.Tag.Get("payload"); payloadName != "" { | ||
39 | if member, ok := v.Type().FieldByName(payloadName); ok { | ||
40 | return member.Tag.Get("type") | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | return "" | ||
45 | } | ||
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go new file mode 100644 index 0000000..7a779ee --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go | |||
@@ -0,0 +1,227 @@ | |||
1 | package rest | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "encoding/base64" | ||
6 | "encoding/json" | ||
7 | "fmt" | ||
8 | "io" | ||
9 | "io/ioutil" | ||
10 | "net/http" | ||
11 | "reflect" | ||
12 | "strconv" | ||
13 | "strings" | ||
14 | "time" | ||
15 | |||
16 | "github.com/aws/aws-sdk-go/aws" | ||
17 | "github.com/aws/aws-sdk-go/aws/awserr" | ||
18 | "github.com/aws/aws-sdk-go/aws/request" | ||
19 | ) | ||
20 | |||
21 | // UnmarshalHandler is a named request handler for unmarshaling rest protocol requests | ||
22 | var UnmarshalHandler = request.NamedHandler{Name: "awssdk.rest.Unmarshal", Fn: Unmarshal} | ||
23 | |||
24 | // UnmarshalMetaHandler is a named request handler for unmarshaling rest protocol request metadata | ||
25 | var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.rest.UnmarshalMeta", Fn: UnmarshalMeta} | ||
26 | |||
27 | // Unmarshal unmarshals the REST component of a response in a REST service. | ||
28 | func Unmarshal(r *request.Request) { | ||
29 | if r.DataFilled() { | ||
30 | v := reflect.Indirect(reflect.ValueOf(r.Data)) | ||
31 | unmarshalBody(r, v) | ||
32 | } | ||
33 | } | ||
34 | |||
35 | // UnmarshalMeta unmarshals the REST metadata of a response in a REST service | ||
36 | func UnmarshalMeta(r *request.Request) { | ||
37 | r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") | ||
38 | if r.RequestID == "" { | ||
39 | // Alternative version of request id in the header | ||
40 | r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id") | ||
41 | } | ||
42 | if r.DataFilled() { | ||
43 | v := reflect.Indirect(reflect.ValueOf(r.Data)) | ||
44 | unmarshalLocationElements(r, v) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | func unmarshalBody(r *request.Request, v reflect.Value) { | ||
49 | if field, ok := v.Type().FieldByName("_"); ok { | ||
50 | if payloadName := field.Tag.Get("payload"); payloadName != "" { | ||
51 | pfield, _ := v.Type().FieldByName(payloadName) | ||
52 | if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { | ||
53 | payload := v.FieldByName(payloadName) | ||
54 | if payload.IsValid() { | ||
55 | switch payload.Interface().(type) { | ||
56 | case []byte: | ||
57 | defer r.HTTPResponse.Body.Close() | ||
58 | b, err := ioutil.ReadAll(r.HTTPResponse.Body) | ||
59 | if err != nil { | ||
60 | r.Error = awserr.New("SerializationError", "failed to decode REST response", err) | ||
61 | } else { | ||
62 | payload.Set(reflect.ValueOf(b)) | ||
63 | } | ||
64 | case *string: | ||
65 | defer r.HTTPResponse.Body.Close() | ||
66 | b, err := ioutil.ReadAll(r.HTTPResponse.Body) | ||
67 | if err != nil { | ||
68 | r.Error = awserr.New("SerializationError", "failed to decode REST response", err) | ||
69 | } else { | ||
70 | str := string(b) | ||
71 | payload.Set(reflect.ValueOf(&str)) | ||
72 | } | ||
73 | default: | ||
74 | switch payload.Type().String() { | ||
75 | case "io.ReadCloser": | ||
76 | payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) | ||
77 | case "io.ReadSeeker": | ||
78 | b, err := ioutil.ReadAll(r.HTTPResponse.Body) | ||
79 | if err != nil { | ||
80 | r.Error = awserr.New("SerializationError", | ||
81 | "failed to read response body", err) | ||
82 | return | ||
83 | } | ||
84 | payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b)))) | ||
85 | default: | ||
86 | io.Copy(ioutil.Discard, r.HTTPResponse.Body) | ||
87 | defer r.HTTPResponse.Body.Close() | ||
88 | r.Error = awserr.New("SerializationError", | ||
89 | "failed to decode REST response", | ||
90 | fmt.Errorf("unknown payload type %s", payload.Type())) | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | |||
99 | func unmarshalLocationElements(r *request.Request, v reflect.Value) { | ||
100 | for i := 0; i < v.NumField(); i++ { | ||
101 | m, field := v.Field(i), v.Type().Field(i) | ||
102 | if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { | ||
103 | continue | ||
104 | } | ||
105 | |||
106 | if m.IsValid() { | ||
107 | name := field.Tag.Get("locationName") | ||
108 | if name == "" { | ||
109 | name = field.Name | ||
110 | } | ||
111 | |||
112 | switch field.Tag.Get("location") { | ||
113 | case "statusCode": | ||
114 | unmarshalStatusCode(m, r.HTTPResponse.StatusCode) | ||
115 | case "header": | ||
116 | err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag) | ||
117 | if err != nil { | ||
118 | r.Error = awserr.New("SerializationError", "failed to decode REST response", err) | ||
119 | break | ||
120 | } | ||
121 | case "headers": | ||
122 | prefix := field.Tag.Get("locationName") | ||
123 | err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) | ||
124 | if err != nil { | ||
125 | r.Error = awserr.New("SerializationError", "failed to decode REST response", err) | ||
126 | break | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | if r.Error != nil { | ||
131 | return | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | |||
136 | func unmarshalStatusCode(v reflect.Value, statusCode int) { | ||
137 | if !v.IsValid() { | ||
138 | return | ||
139 | } | ||
140 | |||
141 | switch v.Interface().(type) { | ||
142 | case *int64: | ||
143 | s := int64(statusCode) | ||
144 | v.Set(reflect.ValueOf(&s)) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error { | ||
149 | switch r.Interface().(type) { | ||
150 | case map[string]*string: // we only support string map value types | ||
151 | out := map[string]*string{} | ||
152 | for k, v := range headers { | ||
153 | k = http.CanonicalHeaderKey(k) | ||
154 | if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) { | ||
155 | out[k[len(prefix):]] = &v[0] | ||
156 | } | ||
157 | } | ||
158 | r.Set(reflect.ValueOf(out)) | ||
159 | } | ||
160 | return nil | ||
161 | } | ||
162 | |||
163 | func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) error { | ||
164 | isJSONValue := tag.Get("type") == "jsonvalue" | ||
165 | if isJSONValue { | ||
166 | if len(header) == 0 { | ||
167 | return nil | ||
168 | } | ||
169 | } else if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) { | ||
170 | return nil | ||
171 | } | ||
172 | |||
173 | switch v.Interface().(type) { | ||
174 | case *string: | ||
175 | v.Set(reflect.ValueOf(&header)) | ||
176 | case []byte: | ||
177 | b, err := base64.StdEncoding.DecodeString(header) | ||
178 | if err != nil { | ||
179 | return err | ||
180 | } | ||
181 | v.Set(reflect.ValueOf(&b)) | ||
182 | case *bool: | ||
183 | b, err := strconv.ParseBool(header) | ||
184 | if err != nil { | ||
185 | return err | ||
186 | } | ||
187 | v.Set(reflect.ValueOf(&b)) | ||
188 | case *int64: | ||
189 | i, err := strconv.ParseInt(header, 10, 64) | ||
190 | if err != nil { | ||
191 | return err | ||
192 | } | ||
193 | v.Set(reflect.ValueOf(&i)) | ||
194 | case *float64: | ||
195 | f, err := strconv.ParseFloat(header, 64) | ||
196 | if err != nil { | ||
197 | return err | ||
198 | } | ||
199 | v.Set(reflect.ValueOf(&f)) | ||
200 | case *time.Time: | ||
201 | t, err := time.Parse(RFC822, header) | ||
202 | if err != nil { | ||
203 | return err | ||
204 | } | ||
205 | v.Set(reflect.ValueOf(&t)) | ||
206 | case aws.JSONValue: | ||
207 | b := []byte(header) | ||
208 | var err error | ||
209 | if tag.Get("location") == "header" { | ||
210 | b, err = base64.StdEncoding.DecodeString(header) | ||
211 | if err != nil { | ||
212 | return err | ||
213 | } | ||
214 | } | ||
215 | |||
216 | m := aws.JSONValue{} | ||
217 | err = json.Unmarshal(b, &m) | ||
218 | if err != nil { | ||
219 | return err | ||
220 | } | ||
221 | v.Set(reflect.ValueOf(m)) | ||
222 | default: | ||
223 | err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) | ||
224 | return err | ||
225 | } | ||
226 | return nil | ||
227 | } | ||