-
Notifications
You must be signed in to change notification settings - Fork 414
/
router_util.go
186 lines (160 loc) · 4.63 KB
/
router_util.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package api
import (
"context"
"fmt"
"net/http"
"reflect"
"strconv"
"strings"
"github.com/gorilla/mux"
"github.com/rockbears/log"
"github.com/ovh/cds/engine/service"
"github.com/ovh/cds/sdk"
)
// writeNoContentPostMiddleware writes StatusNoContent (204) for each response with No Header Content-Type
// this is a PostMiddlewaare, launch if there no error in handler.
// If there is no Content-Type, it's because there is no body return. In CDS, we
// always use service.WriteJSON to send body or explicitly write Content-TYpe as application/octet-stream
// So, if there is No Content-Type, we return 204 with content type to json
func writeNoContentPostMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, error) {
for headerName := range w.Header() {
if headerName == "Content-Type" {
return ctx, nil
}
if headerName == "Location" {
return ctx, nil
}
}
service.WriteProcessTime(ctx, w)
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusNoContent)
return ctx, nil
}
func (r *Router) getRoute(method string, p1 uintptr, routeName string, vars map[string]string) string {
var url string
for uri, routerConfig := range r.mapRouterConfigs {
rc := routerConfig.Config[method]
if rc == nil {
continue
}
if strings.HasPrefix(uri, r.Prefix) {
sf2 := reflect.ValueOf(rc.Handler)
if p1 == sf2.Pointer() {
url = uri
break
}
}
}
for k, v := range vars {
url = strings.Replace(url, "{"+k+"}", v, -1)
}
if url == "" {
log.Debug(context.Background(), "Cant find route for Handler %s %v", method, routeName)
}
return url
}
func (r *Router) GetRouteV2(method string, handler service.HandlerFuncV2, vars map[string]string) string {
_, routeHandler := handler()
p1 := reflect.ValueOf(routeHandler).Pointer()
routeName := sdk.GetFuncName(routeHandler)
return r.getRoute(method, p1, routeName, vars)
}
// GetRoute returns the routes given a handler
func (r *Router) GetRoute(method string, handler service.HandlerFunc, vars map[string]string) string {
p1 := reflect.ValueOf(handler()).Pointer()
routeName := sdk.GetFuncName(handler)
return r.getRoute(method, p1, routeName, vars)
}
// FormString return a string
func FormString(r *http.Request, s string) string {
return r.FormValue(s)
}
// QueryString return a string from a query parameter
func QueryString(r *http.Request, s string) string {
return r.FormValue(s)
}
// QueryBool return a boolean from a query parameter
func QueryBool(r *http.Request, s string) bool {
return service.FormBool(r, s)
}
// QueryStrings returns the list of values for given query param key or nil if key no values.
func QueryStrings(r *http.Request, key string) ([]string, error) {
if err := r.ParseForm(); err != nil {
return nil, err
}
if v, ok := r.Form[key]; ok {
return v, nil
}
return nil, nil
}
// SortOrder constant.
type SortOrder string
// SortOrders.
const (
ASC SortOrder = "asc"
DESC SortOrder = "desc"
)
func validateSortOrder(s string) bool {
switch SortOrder(s) {
case ASC, DESC:
return true
}
return false
}
// SortCompareInt returns the result of the right compare equation depending of given sort order.
func SortCompareInt(i, j int, o SortOrder) bool {
if o == ASC {
return i < j
}
return i > j
}
// QuerySort returns the a of key found in sort query param or nil if sort param not found.
func QuerySort(r *http.Request) (map[string]SortOrder, error) {
if err := r.ParseForm(); err != nil {
return nil, err
}
v, ok := r.Form["sort"]
if !ok {
return nil, nil
}
res := map[string]SortOrder{}
for _, item := range strings.Split(v[0], ",") {
if item == "" {
return nil, sdk.NewError(sdk.ErrWrongRequest, fmt.Errorf("invalid given sort key"))
}
s := strings.Split(item, ":")
if len(s) > 1 {
if !validateSortOrder(s[1]) {
return nil, sdk.NewError(sdk.ErrWrongRequest, fmt.Errorf("invalid given sort param"))
}
res[s[0]] = SortOrder(s[1])
} else {
res[s[0]] = ASC
}
}
return res, nil
}
// requestVarInt return int value for a var in Request
func requestVarInt(r *http.Request, s string) (int64, error) {
vars := mux.Vars(r)
// Check ID Job
id, err := strconv.ParseInt(vars[s], 10, 64)
if err != nil {
err = sdk.WrapError(err, "%s is not an integer: %s", s, vars[s])
if s == "id" {
return 0, sdk.NewErrorWithStack(err, sdk.ErrInvalidID)
}
return 0, sdk.NewErrorWithStack(err, sdk.ErrWrongRequest)
}
return id, nil
}
func translate(msgList []sdk.Message) []string {
msgListString := []string{}
for _, m := range msgList {
s := m.String()
if s != "" {
msgListString = append(msgListString, s)
}
}
return msgListString
}