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