forked from loafle/openapi-generator-original
* Fix some go client formatting issues * Fix go client go imports * Run `goimports -w .` on examples directory * Sort imports in api * Add new line between each property Before secret feature was used to add new line using two property declaration in the same line. There should be no new line before first property. The easiest way is to use `-first` special property https://github.com/samskivert/jmustache#-first-and--last New line are required so `goimports` won't reformat whitespaces between property name and type. * Change whitespaces to tabs * Fix whitespaces in api_client There is a new line between each service to prevent `goimports` from adding whitespaces between types and names * Fix more whitespaces There was a need to set special delimeter for formatting in the commit. Go slices use curly braces and `jmustache` got confused when found triple curly braces. * Fix whitespaces in configuration.mustache * Fix whitespaces for api response * Support for optional description Do not add whitespace if description is missing * Add new lines between enum values to prevent formatting * Generate go code from current code - imports are not sorted :( - there are extra whitespaces for different languages. I don't know why * Run generate for security tests
427 lines
10 KiB
Go
427 lines
10 KiB
Go
/*
|
|
* Swagger Petstore *_/ ' \" =end -- \\r\\n \\n \\r
|
|
*
|
|
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end --
|
|
*
|
|
* API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r
|
|
* Contact: apiteam@swagger.io *_/ ' \" =end -- \\r\\n \\n \\r
|
|
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
|
*/
|
|
|
|
package swagger
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"encoding/xml"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"unicode/utf8"
|
|
|
|
"golang.org/x/net/context"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
var (
|
|
jsonCheck = regexp.MustCompile("(?i:[application|text]/json)")
|
|
xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)")
|
|
)
|
|
|
|
// APIClient manages communication with the Swagger Petstore *_/ ' \" =end -- \\r\\n \\n \\r API v1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r
|
|
// In most cases there should be only one, shared, APIClient.
|
|
type APIClient struct {
|
|
cfg *Configuration
|
|
common service // Reuse a single struct instead of allocating one for each service on the heap.
|
|
|
|
// API Services
|
|
|
|
FakeApi *FakeApiService
|
|
}
|
|
|
|
type service struct {
|
|
client *APIClient
|
|
}
|
|
|
|
// NewAPIClient creates a new API client. Requires a userAgent string describing your application.
|
|
// optionally a custom http.Client to allow for advanced features such as caching.
|
|
func NewAPIClient(cfg *Configuration) *APIClient {
|
|
if cfg.HTTPClient == nil {
|
|
cfg.HTTPClient = http.DefaultClient
|
|
}
|
|
|
|
c := &APIClient{}
|
|
c.cfg = cfg
|
|
c.common.client = c
|
|
|
|
// API Services
|
|
c.FakeApi = (*FakeApiService)(&c.common)
|
|
|
|
return c
|
|
}
|
|
|
|
func atoi(in string) (int, error) {
|
|
return strconv.Atoi(in)
|
|
}
|
|
|
|
// selectHeaderContentType select a content type from the available list.
|
|
func selectHeaderContentType(contentTypes []string) string {
|
|
if len(contentTypes) == 0 {
|
|
return ""
|
|
}
|
|
if contains(contentTypes, "application/json") {
|
|
return "application/json"
|
|
}
|
|
return contentTypes[0] // use the first content type specified in 'consumes'
|
|
}
|
|
|
|
// selectHeaderAccept join all accept types and return
|
|
func selectHeaderAccept(accepts []string) string {
|
|
if len(accepts) == 0 {
|
|
return ""
|
|
}
|
|
|
|
if contains(accepts, "application/json") {
|
|
return "application/json"
|
|
}
|
|
|
|
return strings.Join(accepts, ",")
|
|
}
|
|
|
|
// contains is a case insenstive match, finding needle in a haystack
|
|
func contains(haystack []string, needle string) bool {
|
|
for _, a := range haystack {
|
|
if strings.ToLower(a) == strings.ToLower(needle) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Verify optional parameters are of the correct type.
|
|
func typeCheckParameter(obj interface{}, expected string, name string) error {
|
|
// Make sure there is an object.
|
|
if obj == nil {
|
|
return nil
|
|
}
|
|
|
|
// Check the type is as expected.
|
|
if reflect.TypeOf(obj).String() != expected {
|
|
return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// parameterToString convert interface{} parameters to string, using a delimiter if format is provided.
|
|
func parameterToString(obj interface{}, collectionFormat string) string {
|
|
var delimiter string
|
|
|
|
switch collectionFormat {
|
|
case "pipes":
|
|
delimiter = "|"
|
|
case "ssv":
|
|
delimiter = " "
|
|
case "tsv":
|
|
delimiter = "\t"
|
|
case "csv":
|
|
delimiter = ","
|
|
}
|
|
|
|
if reflect.TypeOf(obj).Kind() == reflect.Slice {
|
|
return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
|
|
}
|
|
|
|
return fmt.Sprintf("%v", obj)
|
|
}
|
|
|
|
// callAPI do the request.
|
|
func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
|
|
return c.cfg.HTTPClient.Do(request)
|
|
}
|
|
|
|
// Change base path to allow switching to mocks
|
|
func (c *APIClient) ChangeBasePath(path string) {
|
|
c.cfg.BasePath = path
|
|
}
|
|
|
|
// prepareRequest build the request
|
|
func (c *APIClient) prepareRequest(
|
|
ctx context.Context,
|
|
path string, method string,
|
|
postBody interface{},
|
|
headerParams map[string]string,
|
|
queryParams url.Values,
|
|
formParams url.Values,
|
|
fileName string,
|
|
fileBytes []byte) (localVarRequest *http.Request, err error) {
|
|
|
|
var body *bytes.Buffer
|
|
|
|
// Detect postBody type and post.
|
|
if postBody != nil {
|
|
contentType := headerParams["Content-Type"]
|
|
if contentType == "" {
|
|
contentType = detectContentType(postBody)
|
|
headerParams["Content-Type"] = contentType
|
|
}
|
|
|
|
body, err = setBody(postBody, contentType)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// add form parameters and file if available.
|
|
if len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") {
|
|
if body != nil {
|
|
return nil, errors.New("Cannot specify postBody and multipart form at the same time.")
|
|
}
|
|
body = &bytes.Buffer{}
|
|
w := multipart.NewWriter(body)
|
|
|
|
for k, v := range formParams {
|
|
for _, iv := range v {
|
|
if strings.HasPrefix(k, "@") { // file
|
|
err = addFile(w, k[1:], iv)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else { // form value
|
|
w.WriteField(k, iv)
|
|
}
|
|
}
|
|
}
|
|
if len(fileBytes) > 0 && fileName != "" {
|
|
w.Boundary()
|
|
//_, fileNm := filepath.Split(fileName)
|
|
part, err := w.CreateFormFile("file", filepath.Base(fileName))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, err = part.Write(fileBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Set the Boundary in the Content-Type
|
|
headerParams["Content-Type"] = w.FormDataContentType()
|
|
}
|
|
|
|
// Set Content-Length
|
|
headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
|
|
w.Close()
|
|
}
|
|
|
|
// Setup path and query parameters
|
|
url, err := url.Parse(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Adding Query Param
|
|
query := url.Query()
|
|
for k, v := range queryParams {
|
|
for _, iv := range v {
|
|
query.Add(k, iv)
|
|
}
|
|
}
|
|
|
|
// Encode the parameters.
|
|
url.RawQuery = query.Encode()
|
|
|
|
// Generate a new request
|
|
if body != nil {
|
|
localVarRequest, err = http.NewRequest(method, url.String(), body)
|
|
} else {
|
|
localVarRequest, err = http.NewRequest(method, url.String(), nil)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// add header parameters, if any
|
|
if len(headerParams) > 0 {
|
|
headers := http.Header{}
|
|
for h, v := range headerParams {
|
|
headers.Set(h, v)
|
|
}
|
|
localVarRequest.Header = headers
|
|
}
|
|
|
|
// Override request host, if applicable
|
|
if c.cfg.Host != "" {
|
|
localVarRequest.Host = c.cfg.Host
|
|
}
|
|
|
|
// Add the user agent to the request.
|
|
localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
|
|
|
|
if ctx != nil {
|
|
// add context to the request
|
|
localVarRequest = localVarRequest.WithContext(ctx)
|
|
|
|
// Walk through any authentication.
|
|
|
|
// OAuth2 authentication
|
|
if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok {
|
|
// We were able to grab an oauth2 token from the context
|
|
var latestToken *oauth2.Token
|
|
if latestToken, err = tok.Token(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
latestToken.SetAuthHeader(localVarRequest)
|
|
}
|
|
|
|
// Basic HTTP Authentication
|
|
if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok {
|
|
localVarRequest.SetBasicAuth(auth.UserName, auth.Password)
|
|
}
|
|
|
|
// AccessToken Authentication
|
|
if auth, ok := ctx.Value(ContextAccessToken).(string); ok {
|
|
localVarRequest.Header.Add("Authorization", "Bearer "+auth)
|
|
}
|
|
}
|
|
|
|
for header, value := range c.cfg.DefaultHeader {
|
|
localVarRequest.Header.Add(header, value)
|
|
}
|
|
|
|
return localVarRequest, nil
|
|
}
|
|
|
|
// Add a file to the multipart request
|
|
func addFile(w *multipart.Writer, fieldName, path string) error {
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = io.Copy(part, file)
|
|
|
|
return err
|
|
}
|
|
|
|
// Prevent trying to import "fmt"
|
|
func reportError(format string, a ...interface{}) error {
|
|
return fmt.Errorf(format, a...)
|
|
}
|
|
|
|
// Set request body from an interface{}
|
|
func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
|
|
if bodyBuf == nil {
|
|
bodyBuf = &bytes.Buffer{}
|
|
}
|
|
|
|
if reader, ok := body.(io.Reader); ok {
|
|
_, err = bodyBuf.ReadFrom(reader)
|
|
} else if b, ok := body.([]byte); ok {
|
|
_, err = bodyBuf.Write(b)
|
|
} else if s, ok := body.(string); ok {
|
|
_, err = bodyBuf.WriteString(s)
|
|
} else if jsonCheck.MatchString(contentType) {
|
|
err = json.NewEncoder(bodyBuf).Encode(body)
|
|
} else if xmlCheck.MatchString(contentType) {
|
|
xml.NewEncoder(bodyBuf).Encode(body)
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if bodyBuf.Len() == 0 {
|
|
err = fmt.Errorf("Invalid body type %s\n", contentType)
|
|
return nil, err
|
|
}
|
|
return bodyBuf, nil
|
|
}
|
|
|
|
// detectContentType method is used to figure out `Request.Body` content type for request header
|
|
func detectContentType(body interface{}) string {
|
|
contentType := "text/plain; charset=utf-8"
|
|
kind := reflect.TypeOf(body).Kind()
|
|
|
|
switch kind {
|
|
case reflect.Struct, reflect.Map, reflect.Ptr:
|
|
contentType = "application/json; charset=utf-8"
|
|
case reflect.String:
|
|
contentType = "text/plain; charset=utf-8"
|
|
default:
|
|
if b, ok := body.([]byte); ok {
|
|
contentType = http.DetectContentType(b)
|
|
} else if kind == reflect.Slice {
|
|
contentType = "application/json; charset=utf-8"
|
|
}
|
|
}
|
|
|
|
return contentType
|
|
}
|
|
|
|
// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
|
|
type cacheControl map[string]string
|
|
|
|
func parseCacheControl(headers http.Header) cacheControl {
|
|
cc := cacheControl{}
|
|
ccHeader := headers.Get("Cache-Control")
|
|
for _, part := range strings.Split(ccHeader, ",") {
|
|
part = strings.Trim(part, " ")
|
|
if part == "" {
|
|
continue
|
|
}
|
|
if strings.ContainsRune(part, '=') {
|
|
keyval := strings.Split(part, "=")
|
|
cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
|
|
} else {
|
|
cc[part] = ""
|
|
}
|
|
}
|
|
return cc
|
|
}
|
|
|
|
// CacheExpires helper function to determine remaining time before repeating a request.
|
|
func CacheExpires(r *http.Response) time.Time {
|
|
// Figure out when the cache expires.
|
|
var expires time.Time
|
|
now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
|
|
if err != nil {
|
|
return time.Now()
|
|
}
|
|
respCacheControl := parseCacheControl(r.Header)
|
|
|
|
if maxAge, ok := respCacheControl["max-age"]; ok {
|
|
lifetime, err := time.ParseDuration(maxAge + "s")
|
|
if err != nil {
|
|
expires = now
|
|
}
|
|
expires = now.Add(lifetime)
|
|
} else {
|
|
expiresHeader := r.Header.Get("Expires")
|
|
if expiresHeader != "" {
|
|
expires, err = time.Parse(time.RFC1123, expiresHeader)
|
|
if err != nil {
|
|
expires = now
|
|
}
|
|
}
|
|
}
|
|
return expires
|
|
}
|
|
|
|
func strlen(s string) int {
|
|
return utf8.RuneCountInString(s)
|
|
}
|