1
9
10 package openapi
11
12 import (
13 "encoding/json"
14 "errors"
15 "io/ioutil"
16 "mime/multipart"
17 "net/http"
18 "os"
19 "strconv"
20 "strings"
21
22 "github.com/gorilla/mux"
23 )
24
25
26 type Route struct {
27 Name string
28 Method string
29 Pattern string
30 HandlerFunc http.HandlerFunc
31 }
32
33
34 type Routes []Route
35
36
37 type Router interface {
38 Routes() Routes
39 }
40
41 const errMsgRequiredMissing = "required parameter is missing"
42
43
44 func NewRouter(routers ...Router) *mux.Router {
45 router := mux.NewRouter().StrictSlash(true)
46 for _, api := range routers {
47 for _, route := range api.Routes() {
48 var handler http.Handler
49 handler = route.HandlerFunc
50 handler = Logger(handler, route.Name)
51
52 router.
53 Methods(route.Method).
54 Path(route.Pattern).
55 Name(route.Name).
56 Handler(handler)
57 }
58 }
59
60 return router
61 }
62
63
64 func EncodeJSONResponse(i interface{}, status *int, w http.ResponseWriter) error {
65 w.Header().Set("Content-Type", "application/json; charset=UTF-8")
66 if status != nil {
67 w.WriteHeader(*status)
68 } else {
69 w.WriteHeader(http.StatusOK)
70 }
71
72 if i != nil {
73 return json.NewEncoder(w).Encode(i)
74 }
75
76 return nil
77 }
78
79
80 func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) {
81 _, fileHeader, err := r.FormFile(key)
82 if err != nil {
83 return nil, err
84 }
85
86 return readFileHeaderToTempFile(fileHeader)
87 }
88
89
90 func ReadFormFilesToTempFiles(r *http.Request, key string) ([]*os.File, error) {
91 if err := r.ParseMultipartForm(32 << 20); err != nil {
92 return nil, err
93 }
94
95 files := make([]*os.File, 0, len(r.MultipartForm.File[key]))
96
97 for _, fileHeader := range r.MultipartForm.File[key] {
98 file, err := readFileHeaderToTempFile(fileHeader)
99 if err != nil {
100 return nil, err
101 }
102
103 files = append(files, file)
104 }
105
106 return files, nil
107 }
108
109
110 func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error) {
111 formFile, err := fileHeader.Open()
112 if err != nil {
113 return nil, err
114 }
115
116 defer formFile.Close()
117
118 fileBytes, err := ioutil.ReadAll(formFile)
119 if err != nil {
120 return nil, err
121 }
122
123 file, err := ioutil.TempFile("", fileHeader.Filename)
124 if err != nil {
125 return nil, err
126 }
127
128 defer func() {
129 _ = file.Close()
130 }()
131
132 file.Write(fileBytes)
133
134 return file, nil
135 }
136
137
138 func parseFloatParameter(param string, bitSize int, required bool) (float64, error) {
139 if param == "" {
140 if required {
141 return 0, errors.New(errMsgRequiredMissing)
142 }
143
144 return 0, nil
145 }
146
147 return strconv.ParseFloat(param, bitSize)
148 }
149
150
151 func parseFloat64Parameter(param string, required bool) (float64, error) {
152 return parseFloatParameter(param, 64, required)
153 }
154
155
156 func parseFloat32Parameter(param string, required bool) (float32, error) {
157 val, err := parseFloatParameter(param, 32, required)
158 return float32(val), err
159 }
160
161
162 func parseIntParameter(param string, bitSize int, required bool) (int64, error) {
163 if param == "" {
164 if required {
165 return 0, errors.New(errMsgRequiredMissing)
166 }
167
168 return 0, nil
169 }
170
171 return strconv.ParseInt(param, 10, bitSize)
172 }
173
174
175 func parseInt64Parameter(param string, required bool) (int64, error) {
176 return parseIntParameter(param, 64, required)
177 }
178
179
180 func parseInt32Parameter(param string, required bool) (int32, error) {
181 val, err := parseIntParameter(param, 32, required)
182 return int32(val), err
183 }
184
185
186 func parseBoolParameter(param string, required bool) (bool, error) {
187 if param == "" {
188 if required {
189 return false, errors.New(errMsgRequiredMissing)
190 }
191
192 return false, nil
193 }
194
195 val, err := strconv.ParseBool(param)
196 if err != nil {
197 return false, err
198 }
199
200 return bool(val), nil
201 }
202
203
204 func parseFloat64ArrayParameter(param, delim string, required bool) ([]float64, error) {
205 if param == "" {
206 if required {
207 return nil, errors.New(errMsgRequiredMissing)
208 }
209
210 return nil, nil
211 }
212
213 str := strings.Split(param, delim)
214 floats := make([]float64, len(str))
215
216 for i, s := range str {
217 if v, err := strconv.ParseFloat(s, 64); err != nil {
218 return nil, err
219 } else {
220 floats[i] = v
221 }
222 }
223
224 return floats, nil
225 }
226
227
228 func parseFloat32ArrayParameter(param, delim string, required bool) ([]float32, error) {
229 if param == "" {
230 if required {
231 return nil, errors.New(errMsgRequiredMissing)
232 }
233
234 return nil, nil
235 }
236
237 str := strings.Split(param, delim)
238 floats := make([]float32, len(str))
239
240 for i, s := range str {
241 if v, err := strconv.ParseFloat(s, 32); err != nil {
242 return nil, err
243 } else {
244 floats[i] = float32(v)
245 }
246 }
247
248 return floats, nil
249 }
250
251
252 func parseInt64ArrayParameter(param, delim string, required bool) ([]int64, error) {
253 if param == "" {
254 if required {
255 return nil, errors.New(errMsgRequiredMissing)
256 }
257
258 return nil, nil
259 }
260
261 str := strings.Split(param, delim)
262 ints := make([]int64, len(str))
263
264 for i, s := range str {
265 if v, err := strconv.ParseInt(s, 10, 64); err != nil {
266 return nil, err
267 } else {
268 ints[i] = v
269 }
270 }
271
272 return ints, nil
273 }
274
275
276 func parseInt32ArrayParameter(param, delim string, required bool) ([]int32, error) {
277 if param == "" {
278 if required {
279 return nil, errors.New(errMsgRequiredMissing)
280 }
281
282 return nil, nil
283 }
284
285 str := strings.Split(param, delim)
286 ints := make([]int32, len(str))
287
288 for i, s := range str {
289 if v, err := strconv.ParseInt(s, 10, 32); err != nil {
290 return nil, err
291 } else {
292 ints[i] = int32(v)
293 }
294 }
295
296 return ints, nil
297 }
298
View as plain text