1
9
10 package openapi
11
12 import (
13 "encoding/json"
14 "errors"
15 "github.com/gorilla/mux"
16 "io/ioutil"
17 "mime/multipart"
18 "net/http"
19 "os"
20 "strconv"
21 "strings"
22 )
23
24
25 type Route struct {
26 Name string
27 Method string
28 Pattern string
29 HandlerFunc http.HandlerFunc
30 }
31
32
33 type Routes []Route
34
35
36 type Router interface {
37 Routes() Routes
38 }
39
40 const errMsgRequiredMissing = "required parameter is missing"
41
42
43 func NewRouter(routers ...Router) *mux.Router {
44 router := mux.NewRouter().StrictSlash(true)
45 for _, api := range routers {
46 for _, route := range api.Routes() {
47 var handler http.Handler
48 handler = route.HandlerFunc
49 handler = Logger(handler, route.Name)
50
51 router.
52 Methods(route.Method).
53 Path(route.Pattern).
54 Name(route.Name).
55 Handler(handler)
56 }
57 }
58
59 return router
60 }
61
62
63 func EncodeJSONResponse(i interface{}, status *int, w http.ResponseWriter) error {
64 w.Header().Set("Content-Type", "application/json; charset=UTF-8")
65 if status != nil {
66 w.WriteHeader(*status)
67 } else {
68 w.WriteHeader(http.StatusOK)
69 }
70
71 return json.NewEncoder(w).Encode(i)
72 }
73
74
75 func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) {
76 _, fileHeader, err := r.FormFile(key)
77 if err != nil {
78 return nil, err
79 }
80
81 return readFileHeaderToTempFile(fileHeader)
82 }
83
84
85 func ReadFormFilesToTempFiles(r *http.Request, key string) ([]*os.File, error) {
86 if err := r.ParseMultipartForm(32 << 20); err != nil {
87 return nil, err
88 }
89
90 files := make([]*os.File, 0, len(r.MultipartForm.File[key]))
91
92 for _, fileHeader := range r.MultipartForm.File[key] {
93 file, err := readFileHeaderToTempFile(fileHeader)
94 if err != nil {
95 return nil, err
96 }
97
98 files = append(files, file)
99 }
100
101 return files, nil
102 }
103
104
105 func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error) {
106 formFile, err := fileHeader.Open()
107 if err != nil {
108 return nil, err
109 }
110
111 defer formFile.Close()
112
113 fileBytes, err := ioutil.ReadAll(formFile)
114 if err != nil {
115 return nil, err
116 }
117
118 file, err := ioutil.TempFile("", fileHeader.Filename)
119 if err != nil {
120 return nil, err
121 }
122
123 defer file.Close()
124
125 file.Write(fileBytes)
126
127 return file, nil
128 }
129
130
131 func parseInt64Parameter(param string, required bool) (int64, error) {
132 if param == "" {
133 if required {
134 return 0, errors.New(errMsgRequiredMissing)
135 }
136
137 return 0, nil
138 }
139
140 return strconv.ParseInt(param, 10, 64)
141 }
142
143
144 func parseInt32Parameter(param string, required bool) (int32, error) {
145 if param == "" {
146 if required {
147 return 0, errors.New(errMsgRequiredMissing)
148 }
149
150 return 0, nil
151 }
152
153 val, err := strconv.ParseInt(param, 10, 32)
154 if err != nil {
155 return -1, err
156 }
157
158 return int32(val), nil
159 }
160
161
162 func parseBoolParameter(param string) (bool, error) {
163 val, err := strconv.ParseBool(param)
164 if err != nil {
165 return false, err
166 }
167
168 return bool(val), nil
169 }
170
171
172 func parseInt64ArrayParameter(param, delim string, required bool) ([]int64, error) {
173 if param == "" {
174 if required {
175 return nil, errors.New(errMsgRequiredMissing)
176 }
177
178 return nil, nil
179 }
180
181 str := strings.Split(param, delim)
182 ints := make([]int64, len(str))
183
184 for i, s := range str {
185 if v, err := strconv.ParseInt(s, 10, 64); err != nil {
186 return nil, err
187 } else {
188 ints[i] = v
189 }
190 }
191
192 return ints, nil
193 }
194
195
196 func parseInt32ArrayParameter(param, delim string, required bool) ([]int32, error) {
197 if param == "" {
198 if required {
199 return nil, errors.New(errMsgRequiredMissing)
200 }
201
202 return nil, nil
203 }
204
205 str := strings.Split(param, delim)
206 ints := make([]int32, len(str))
207
208 for i, s := range str {
209 if v, err := strconv.ParseInt(s, 10, 32); err != nil {
210 return nil, err
211 } else {
212 ints[i] = int32(v)
213 }
214 }
215
216 return ints, nil
217 }
View as plain text