-
Notifications
You must be signed in to change notification settings - Fork 28
/
router.go
162 lines (136 loc) · 3.76 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
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
package ace
import (
"github.com/julienschmidt/httprouter"
"log"
"net/http"
)
var defaultPanic = func(c *C, rcv interface{}) {
stack := Stack()
log.Printf("PANIC: %s\n%s", rcv, stack)
c.String(500, "<pre>%s\n%s</pre>", rcv, stack)
}
var defaultNotfound = func(c *C) {
c.String(404, "not found")
}
//Router http router
type Router struct {
handlers []HandlerFunc
prefix string
ace *Ace
}
//Use register middleware
func (r *Router) Use(middlewares ...HandlerFunc) {
for _, handler := range middlewares {
r.handlers = append(r.handlers, handler)
}
}
//GET handle GET method
func (r *Router) GET(path string, handlers ...HandlerFunc) {
r.Handle("GET", path, handlers)
}
//POST handle POST method
func (r *Router) POST(path string, handlers ...HandlerFunc) {
r.Handle("POST", path, handlers)
}
//PATCH handle PATCH method
func (r *Router) PATCH(path string, handlers ...HandlerFunc) {
r.Handle("PATCH", path, handlers)
}
//PUT handle PUT method
func (r *Router) PUT(path string, handlers ...HandlerFunc) {
r.Handle("PUT", path, handlers)
}
//DELETE handle DELETE method
func (r *Router) DELETE(path string, handlers ...HandlerFunc) {
r.Handle("DELETE", path, handlers)
}
//HEAD handle HEAD method
func (r *Router) HEAD(path string, handlers ...HandlerFunc) {
r.Handle("HEAD", path, handlers)
}
//OPTIONS handle OPTIONS method
func (r *Router) OPTIONS(path string, handlers ...HandlerFunc) {
r.Handle("OPTIONS", path, handlers)
}
//Group group route
func (r *Router) Group(path string, handlers ...HandlerFunc) *Router {
handlers = r.combineHandlers(handlers)
return &Router{
handlers: handlers,
prefix: r.path(path),
ace: r.ace,
}
}
//RouteNotFound call when route does not match
func (r *Router) RouteNotFound(h HandlerFunc) {
r.ace.notfoundFunc = h
}
//Panic call when panic was called
func (r *Router) Panic(h PanicHandler) {
r.ace.panicFunc = h
}
//Handler convert ace.HandlerFunc to http.Handler
// func (r *Router) HandlerFunc(h HandlerFunc) http.Handler {
// handlers := r.combineHandlers([]HandlerFunc{h})
// return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// c := r.ace.CreateContext(w, req)
// c.handlers = handlers
// c.Next()
// r.ace.pool.Put(c)
// })
// }
//HandlerFunc convert http.HandlerFunc to ace.HandlerFunc
func (r *Router) HTTPHandlerFunc(h http.HandlerFunc) HandlerFunc {
return func(c *C) {
h(c.Writer, c.Request)
}
}
//Static server static file
//path is url path
//root is root directory
func (r *Router) Static(path string, root http.Dir, handlers ...HandlerFunc) {
path = r.path(path)
fileServer := http.StripPrefix(path, http.FileServer(root))
handlers = append(handlers, func(c *C) {
fileServer.ServeHTTP(c.Writer, c.Request)
})
r.ace.httprouter.Handle("GET", r.staticPath(path), func(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
c := r.ace.createContext(w, req)
c.handlers = handlers
c.Next()
r.ace.pool.Put(c)
})
}
//Handle handle with specific method
func (r *Router) Handle(method, path string, handlers []HandlerFunc) {
handlers = r.combineHandlers(handlers)
r.ace.httprouter.Handle(method, r.path(path), func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
c := r.ace.createContext(w, req)
c.params = params
c.handlers = handlers
c.Next()
r.ace.pool.Put(c)
})
}
func (r *Router) staticPath(p string) string {
if p == "/" {
return "/*filepath"
}
return concat(p, "/*filepath")
}
func (r *Router) path(p string) string {
if r.prefix == "/" {
return p
}
return concat(r.prefix, p)
}
func (r *Router) combineHandlers(handlers []HandlerFunc) []HandlerFunc {
aLen := len(r.handlers)
hLen := len(handlers)
h := make([]HandlerFunc, aLen+hLen)
copy(h, r.handlers)
for i := 0; i < hLen; i++ {
h[aLen+i] = handlers[i]
}
return h
}