1
10
11 package unannotatedecho
12
13 import (
14 "bytes"
15 "context"
16 "encoding/json"
17 "encoding/xml"
18 "errors"
19 "fmt"
20 "io"
21 "mime/multipart"
22 "net/http"
23 "net/url"
24 "os"
25 "path/filepath"
26 "reflect"
27 "regexp"
28 "strconv"
29 "strings"
30 "time"
31 "unicode/utf8"
32
33 "golang.org/x/oauth2"
34 )
35
36 var (
37 jsonCheck = regexp.MustCompile("(?i:[application|text]/json)")
38 xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)")
39 )
40
41
42
43 type APIClient struct {
44 cfg *Configuration
45 common service
46
47
48
49 UnannotatedEchoServiceApi *UnannotatedEchoServiceApiService
50 }
51
52 type service struct {
53 client *APIClient
54 }
55
56
57
58 func NewAPIClient(cfg *Configuration) *APIClient {
59 if cfg.HTTPClient == nil {
60 cfg.HTTPClient = http.DefaultClient
61 }
62
63 c := &APIClient{}
64 c.cfg = cfg
65 c.common.client = c
66
67
68 c.UnannotatedEchoServiceApi = (*UnannotatedEchoServiceApiService)(&c.common)
69
70 return c
71 }
72
73 func atoi(in string) (int, error) {
74 return strconv.Atoi(in)
75 }
76
77
78 func selectHeaderContentType(contentTypes []string) string {
79 if len(contentTypes) == 0 {
80 return ""
81 }
82 if contains(contentTypes, "application/json") {
83 return "application/json"
84 }
85 return contentTypes[0]
86 }
87
88
89 func selectHeaderAccept(accepts []string) string {
90 if len(accepts) == 0 {
91 return ""
92 }
93
94 if contains(accepts, "application/json") {
95 return "application/json"
96 }
97
98 return strings.Join(accepts, ",")
99 }
100
101
102 func contains(haystack []string, needle string) bool {
103 for _, a := range haystack {
104 if strings.ToLower(a) == strings.ToLower(needle) {
105 return true
106 }
107 }
108 return false
109 }
110
111
112 func typeCheckParameter(obj interface{}, expected string, name string) error {
113
114 if obj == nil {
115 return nil
116 }
117
118
119 if reflect.TypeOf(obj).String() != expected {
120 return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String())
121 }
122 return nil
123 }
124
125
126 func parameterToString(obj interface{}, collectionFormat string) string {
127 var delimiter string
128
129 switch collectionFormat {
130 case "pipes":
131 delimiter = "|"
132 case "ssv":
133 delimiter = " "
134 case "tsv":
135 delimiter = "\t"
136 case "csv":
137 delimiter = ","
138 }
139
140 if reflect.TypeOf(obj).Kind() == reflect.Slice {
141 return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
142 }
143
144 return fmt.Sprintf("%v", obj)
145 }
146
147
148 func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
149 return c.cfg.HTTPClient.Do(request)
150 }
151
152
153 func (c *APIClient) ChangeBasePath(path string) {
154 c.cfg.BasePath = path
155 }
156
157
158 func (c *APIClient) prepareRequest(
159 ctx context.Context,
160 path string, method string,
161 postBody interface{},
162 headerParams map[string]string,
163 queryParams url.Values,
164 formParams url.Values,
165 fileName string,
166 fileBytes []byte) (localVarRequest *http.Request, err error) {
167
168 var body *bytes.Buffer
169
170
171 if postBody != nil {
172 contentType := headerParams["Content-Type"]
173 if contentType == "" {
174 contentType = detectContentType(postBody)
175 headerParams["Content-Type"] = contentType
176 }
177
178 body, err = setBody(postBody, contentType)
179 if err != nil {
180 return nil, err
181 }
182 }
183
184
185 if len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") {
186 if body != nil {
187 return nil, errors.New("Cannot specify postBody and multipart form at the same time.")
188 }
189 body = &bytes.Buffer{}
190 w := multipart.NewWriter(body)
191
192 for k, v := range formParams {
193 for _, iv := range v {
194 if strings.HasPrefix(k, "@") {
195 err = addFile(w, k[1:], iv)
196 if err != nil {
197 return nil, err
198 }
199 } else {
200 w.WriteField(k, iv)
201 }
202 }
203 }
204 if len(fileBytes) > 0 && fileName != "" {
205 w.Boundary()
206
207 part, err := w.CreateFormFile("file", filepath.Base(fileName))
208 if err != nil {
209 return nil, err
210 }
211 _, err = part.Write(fileBytes)
212 if err != nil {
213 return nil, err
214 }
215
216 headerParams["Content-Type"] = w.FormDataContentType()
217 }
218
219
220 headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
221 w.Close()
222 }
223
224
225 url, err := url.Parse(path)
226 if err != nil {
227 return nil, err
228 }
229
230
231 query := url.Query()
232 for k, v := range queryParams {
233 for _, iv := range v {
234 query.Add(k, iv)
235 }
236 }
237
238
239 url.RawQuery = query.Encode()
240
241
242 if body != nil {
243 localVarRequest, err = http.NewRequest(method, url.String(), body)
244 } else {
245 localVarRequest, err = http.NewRequest(method, url.String(), nil)
246 }
247 if err != nil {
248 return nil, err
249 }
250
251
252 if len(headerParams) > 0 {
253 headers := http.Header{}
254 for h, v := range headerParams {
255 headers.Set(h, v)
256 }
257 localVarRequest.Header = headers
258 }
259
260
261 if c.cfg.Host != "" {
262 localVarRequest.Host = c.cfg.Host
263 }
264
265
266 localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
267
268 if ctx != nil {
269
270 localVarRequest = localVarRequest.WithContext(ctx)
271
272
273
274
275 if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok {
276
277 var latestToken *oauth2.Token
278 if latestToken, err = tok.Token(); err != nil {
279 return nil, err
280 }
281
282 latestToken.SetAuthHeader(localVarRequest)
283 }
284
285
286 if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok {
287 localVarRequest.SetBasicAuth(auth.UserName, auth.Password)
288 }
289
290
291 if auth, ok := ctx.Value(ContextAccessToken).(string); ok {
292 localVarRequest.Header.Add("Authorization", "Bearer "+auth)
293 }
294 }
295
296 for header, value := range c.cfg.DefaultHeader {
297 localVarRequest.Header.Add(header, value)
298 }
299
300 return localVarRequest, nil
301 }
302
303 func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
304 if strings.Contains(contentType, "application/xml") {
305 if err = xml.Unmarshal(b, v); err != nil {
306 return err
307 }
308 return nil
309 } else if strings.Contains(contentType, "application/json") {
310 if err = json.Unmarshal(b, v); err != nil {
311 return err
312 }
313 return nil
314 }
315 return errors.New("undefined response type")
316 }
317
318
319 func addFile(w *multipart.Writer, fieldName, path string) error {
320 file, err := os.Open(path)
321 if err != nil {
322 return err
323 }
324 defer file.Close()
325
326 part, err := w.CreateFormFile(fieldName, filepath.Base(path))
327 if err != nil {
328 return err
329 }
330 _, err = io.Copy(part, file)
331
332 return err
333 }
334
335
336 func reportError(format string, a ...interface{}) error {
337 return fmt.Errorf(format, a...)
338 }
339
340
341 func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
342 if bodyBuf == nil {
343 bodyBuf = &bytes.Buffer{}
344 }
345
346 if reader, ok := body.(io.Reader); ok {
347 _, err = bodyBuf.ReadFrom(reader)
348 } else if b, ok := body.([]byte); ok {
349 _, err = bodyBuf.Write(b)
350 } else if s, ok := body.(string); ok {
351 _, err = bodyBuf.WriteString(s)
352 } else if s, ok := body.(*string); ok {
353 _, err = bodyBuf.WriteString(*s)
354 } else if jsonCheck.MatchString(contentType) {
355 err = json.NewEncoder(bodyBuf).Encode(body)
356 } else if xmlCheck.MatchString(contentType) {
357 xml.NewEncoder(bodyBuf).Encode(body)
358 }
359
360 if err != nil {
361 return nil, err
362 }
363
364 if bodyBuf.Len() == 0 {
365 err = fmt.Errorf("Invalid body type %s\n", contentType)
366 return nil, err
367 }
368 return bodyBuf, nil
369 }
370
371
372 func detectContentType(body interface{}) string {
373 contentType := "text/plain; charset=utf-8"
374 kind := reflect.TypeOf(body).Kind()
375
376 switch kind {
377 case reflect.Struct, reflect.Map, reflect.Ptr:
378 contentType = "application/json; charset=utf-8"
379 case reflect.String:
380 contentType = "text/plain; charset=utf-8"
381 default:
382 if b, ok := body.([]byte); ok {
383 contentType = http.DetectContentType(b)
384 } else if kind == reflect.Slice {
385 contentType = "application/json; charset=utf-8"
386 }
387 }
388
389 return contentType
390 }
391
392
393 type cacheControl map[string]string
394
395 func parseCacheControl(headers http.Header) cacheControl {
396 cc := cacheControl{}
397 ccHeader := headers.Get("Cache-Control")
398 for _, part := range strings.Split(ccHeader, ",") {
399 part = strings.Trim(part, " ")
400 if part == "" {
401 continue
402 }
403 if strings.ContainsRune(part, '=') {
404 keyval := strings.Split(part, "=")
405 cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
406 } else {
407 cc[part] = ""
408 }
409 }
410 return cc
411 }
412
413
414 func CacheExpires(r *http.Response) time.Time {
415
416 var expires time.Time
417 now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
418 if err != nil {
419 return time.Now()
420 }
421 respCacheControl := parseCacheControl(r.Header)
422
423 if maxAge, ok := respCacheControl["max-age"]; ok {
424 lifetime, err := time.ParseDuration(maxAge + "s")
425 if err != nil {
426 expires = now
427 }
428 expires = now.Add(lifetime)
429 } else {
430 expiresHeader := r.Header.Get("Expires")
431 if expiresHeader != "" {
432 expires, err = time.Parse(time.RFC1123, expiresHeader)
433 if err != nil {
434 expires = now
435 }
436 }
437 }
438 return expires
439 }
440
441 func strlen(s string) int {
442 return utf8.RuneCountInString(s)
443 }
444
445
446 type GenericSwaggerError struct {
447 body []byte
448 error string
449 model interface{}
450 }
451
452
453 func (e GenericSwaggerError) Error() string {
454 return e.error
455 }
456
457
458 func (e GenericSwaggerError) Body() []byte {
459 return e.body
460 }
461
462
463 func (e GenericSwaggerError) Model() interface{} {
464 return e.model
465 }
View as plain text