-
Notifications
You must be signed in to change notification settings - Fork 1
/
router.go
74 lines (63 loc) · 1.7 KB
/
router.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
package goa
import (
"bytes"
"net/http"
"reflect"
"runtime"
"github.com/lovego/regex_tree"
)
type Router struct {
beforeLookup func(rw http.ResponseWriter, req *http.Request)
RouterGroup
notFound []func(*Context)
}
func New() *Router {
return &Router{
RouterGroup: RouterGroup{routes: make(map[string]*regex_tree.Node)},
notFound: []func(*Context){defaultNotFound},
}
}
func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if r.beforeLookup != nil {
r.beforeLookup(rw, req)
}
handlers, params := r.Lookup(req.Method, req.URL.Path)
c := &Context{Request: req, ResponseWriter: rw, handlers: handlers, params: params, index: -1}
if len(handlers) == 0 {
c.handlers = r.notFound
}
c.Next()
}
func (r *Router) BeforeLookup(fun func(rw http.ResponseWriter, req *http.Request)) {
r.beforeLookup = fun
}
func (r *Router) Use(handlers ...func(*Context)) {
r.RouterGroup.Use(handlers...)
last := len(r.notFound) - 1
notFound := r.notFound[last]
r.notFound = append(r.notFound[:last], handlers...)
r.notFound = append(r.notFound, notFound)
}
func (r *Router) NotFound(handler func(*Context)) {
last := len(r.notFound) - 1
r.notFound[last] = handler
}
func defaultNotFound(c *Context) {
if c.ResponseWriter != nil {
c.WriteHeader(404)
c.Write([]byte(`{"code":"404","message":"Not Found."}`))
}
}
func (r *Router) String() string {
var buf bytes.Buffer
buf.WriteString("{\n")
buf.WriteString(r.RoutesString())
if len(r.notFound) > 0 {
buf.WriteString(" notFound: " + funcName(r.notFound[len(r.notFound)-1]) + "\n")
}
buf.WriteString("}\n")
return buf.String()
}
func funcName(fun interface{}) string {
return runtime.FuncForPC(reflect.ValueOf(fun).Pointer()).Name()
}