-
Notifications
You must be signed in to change notification settings - Fork 1
/
handler.go
61 lines (56 loc) · 1.55 KB
/
handler.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
package pick
import (
"encoding/json"
"github.com/hopeio/context/httpctx"
"github.com/hopeio/utils/net/http/binding"
"net/http"
"reflect"
)
var (
HttpContextType = reflect.TypeOf((*httpctx.Context)(nil))
)
// Param is a single URL parameter, consisting of a key and a value.
type Param struct {
Key string
Value string
}
// Params is a Param-slice, as returned by the router.
// The slice is ordered, the first URL parameter is also the first slice value.
// It is therefore safe to read values by the index.
type Params []Param
func CommonHandler(w http.ResponseWriter, req *http.Request, handle *reflect.Value, ps *Params) {
handleTyp := handle.Type()
handleNumIn := handleTyp.NumIn()
if handleNumIn != 0 {
params := make([]reflect.Value, handleNumIn)
ctxi := httpctx.FromRequest(httpctx.RequestCtx{
Request: req,
Response: w,
})
defer ctxi.RootSpan().End()
for i := 0; i < handleNumIn; i++ {
if handleTyp.In(i).ConvertibleTo(HttpContextType) {
params[i] = reflect.ValueOf(ctxi)
} else {
params[i] = reflect.New(handleTyp.In(i).Elem())
if ps != nil || req.URL.RawQuery != "" {
src := req.URL.Query()
if ps != nil {
pathParam := *ps
if len(pathParam) > 0 {
for i := range pathParam {
src.Set(pathParam[i].Key, pathParam[i].Value)
}
}
}
binding.Decode(params[i], src)
}
if req.Method != http.MethodGet {
json.NewDecoder(req.Body).Decode(params[i].Interface())
}
}
}
result := handle.Call(params)
ResWriteReflect(w, ctxi.TraceID(), result)
}
}