/
routers.go
159 lines (130 loc) · 3.92 KB
/
routers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
* novellia
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 0.9.2
* Contact: contact@rektangularstudios.com
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package novellia
import (
"encoding/json"
"io/ioutil"
"net/http"
"os"
"strconv"
"mime/multipart"
"github.com/gorilla/mux"
)
// A Route defines the parameters for an api endpoint
type Route struct {
Name string
Method string
Pattern string
HandlerFunc http.HandlerFunc
}
// Routes are a collection of defined api endpoints
type Routes []Route
// Router defines the required methods for retrieving api routes
type Router interface {
Routes() Routes
}
func CORSMiddleware(r *mux.Router) mux.MiddlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if origin := req.Header.Get("Origin"); origin != "" {
rw.Header().Set("Access-Control-Allow-Origin", origin)
rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
rw.Header().Set("Access-Control-Allow-Headers", "Accept, Accept-Language, Content-Type")
}
// Stop here if its Preflighted OPTIONS request
if req.Method == "OPTIONS" {
return
}
next.ServeHTTP(rw, req)
})
}
}
// NewRouter creates a new router for any number of api routers
func NewRouter(routers ...Router) *mux.Router {
router := mux.NewRouter().StrictSlash(true)
router.Use(CORSMiddleware(router))
for _, api := range routers {
for _, route := range api.Routes() {
var handler http.Handler
handler = route.HandlerFunc
handler = Logger(handler, route.Name)
router.
Methods(route.Method, "OPTIONS").
Path(route.Pattern).
Name(route.Name).
Handler(handler)
}
}
return router
}
// EncodeJSONResponse uses the json encoder to write an interface to the http response with an optional status code
func EncodeJSONResponse(i interface{}, status *int, w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
if status != nil {
w.WriteHeader(*status)
} else {
w.WriteHeader(http.StatusOK)
}
return json.NewEncoder(w).Encode(i)
}
// ReadFormFileToTempFile reads file data from a request form and writes it to a temporary file
func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) {
_, fileHeader, err := r.FormFile(key)
if err != nil {
return nil, err
}
return readFileHeaderToTempFile(fileHeader)
}
// ReadFormFilesToTempFiles reads files array data from a request form and writes it to a temporary files
func ReadFormFilesToTempFiles(r *http.Request, key string) ([]*os.File, error) {
if err := r.ParseMultipartForm(32 << 20); err != nil {
return nil, err
}
files := make([]*os.File, 0, len(r.MultipartForm.File[key]))
for _, fileHeader := range r.MultipartForm.File[key] {
file, err := readFileHeaderToTempFile(fileHeader)
if err != nil {
return nil, err
}
files = append(files, file)
}
return files, nil
}
// readFileHeaderToTempFile reads multipart.FileHeader and writes it to a temporary file
func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error) {
formFile, err := fileHeader.Open()
if err != nil {
return nil, err
}
defer formFile.Close()
fileBytes, err := ioutil.ReadAll(formFile)
if err != nil {
return nil, err
}
file, err := ioutil.TempFile("", fileHeader.Filename)
if err != nil {
return nil, err
}
defer file.Close()
file.Write(fileBytes)
return file, nil
}
// parseInt64Parameter parses a sting parameter to an int64
func parseInt64Parameter(param string) (int64, error) {
return strconv.ParseInt(param, 10, 64)
}
// parseInt32Parameter parses a sting parameter to an int32
func parseInt32Parameter(param string) (int32, error) {
val, err := strconv.ParseInt(param, 10, 32)
if err != nil {
return -1, err
}
return int32(val), nil
}