-
Notifications
You must be signed in to change notification settings - Fork 0
/
kira_router.go
156 lines (130 loc) · 4.17 KB
/
kira_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
package kira
import (
"github.com/julienschmidt/httprouter"
"net/http"
)
// Route represent a route.
type Route struct {
Method string
Path string
HandlerFunc HandlerFunc
Middlewares []Middleware
}
// Middleware add a middleware to the route.
func (r *Route) Middleware(midd ...Middleware) {
r.Middlewares = append(r.Middlewares, midd...)
}
// Use is an alias of Middleware method.
func (r *Route) Use(midd ...Middleware) {
r.Middleware(midd...)
}
// RegisterRoutes it's simply register the routes into the router.
func (app *App) RegisterRoutes() *httprouter.Router {
// build the routes and attach the middlewares to every route.
for _, route := range app.Routes {
// Register the route.
app.Router.Handler(
// Method
route.Method,
// Path
route.Path,
// Handler
buildRoute(app, route.HandlerFunc, route.Middlewares),
)
}
// 404
if app.NotFoundHandler == nil {
app.Router.NotFound = buildRoute(app, defaultNotFound, nil)
} else {
app.Router.NotFound = buildRoute(app, app.NotFoundHandler, nil)
}
// Handle panic
app.Router.PanicHandler = func(w http.ResponseWriter, r *http.Request, err interface{}) {
var panicHandler = func(ctx *Context) {
defaultPanic(ctx, err)
}
buildRoute(app, panicHandler, nil)(w, r)
}
return app.Router
}
// Change the middleware to support middleware chain.
// This function will take the middleware and the next handler as a parameters.
// Then return a handler that accept the next handler as a parameter.
func buildMiddleware(middleware Middleware, next HandlerFunc) HandlerFunc {
return func(ctx *Context) {
middleware.Middleware(ctx, next)
}
}
// buildRoute create the context for the route and attach the middlewares to it if exists.
func buildRoute(app *App, handler HandlerFunc, rm []Middleware) http.HandlerFunc {
// Route middlewares
if len(rm) > 0 {
for _, m := range rm {
handler = buildMiddleware(m, handler)
}
}
// Assign default middlewares to all handlers.
for _, defaultMiddleware := range defaultMiddlewares() {
handler = buildMiddleware(defaultMiddleware, handler)
}
// Global Middlewares
if len(app.Middlewares) > 0 {
for _, m := range app.Middlewares {
handler = buildMiddleware(m, handler)
}
}
return func(w http.ResponseWriter, r *http.Request) {
// Root context.
ctx := app.pool.Get().(*Context)
ctx.response = &responseWriter{w, ctx}
ctx.request = r
// Run the chain
handler(ctx)
// Release the pool
app.pool.Put(ctx)
}
}
// create new route instance.
func createRoute(app *App, method string, path string, handler HandlerFunc, middlewares ...Middleware) *Route {
route := &Route{
Method: method,
Path: path,
Middlewares: middlewares,
HandlerFunc: handler,
}
// Append the route
app.Routes = append(app.Routes, route)
return route
}
// Get Handle GET requests.
func (app *App) Get(path string, ctx HandlerFunc, middlewares ...Middleware) *Route {
return createRoute(app, "GET", path, ctx, middlewares...)
}
// Head Handle HEAD requests.
func (app *App) Head(path string, ctx HandlerFunc, middlewares ...Middleware) *Route {
return createRoute(app, "HEAD", path, ctx, middlewares...)
}
// Post Handle POST requests.
func (app *App) Post(path string, ctx HandlerFunc, middlewares ...Middleware) *Route {
return createRoute(app, "POST", path, ctx, middlewares...)
}
// Put Handle PUT requests.
func (app *App) Put(path string, ctx HandlerFunc, middlewares ...Middleware) *Route {
return createRoute(app, "PUT", path, ctx, middlewares...)
}
// Patch Handle PATCH requests.
func (app *App) Patch(path string, ctx HandlerFunc, middlewares ...Middleware) *Route {
return createRoute(app, "PATCH", path, ctx, middlewares...)
}
// Delete Handle DELETE requests.
func (app *App) Delete(path string, ctx HandlerFunc, middlewares ...Middleware) *Route {
return createRoute(app, "DELETE", path, ctx, middlewares...)
}
// Options Handle OPTIONS requests.
func (app *App) Options(path string, ctx HandlerFunc, middlewares ...Middleware) *Route {
return createRoute(app, "OPTIONS", path, ctx, middlewares...)
}
// ServeFiles serve files in the given root.
func (app *App) ServeFiles(path string, root http.FileSystem) {
app.Router.ServeFiles(path, root)
}