-
Notifications
You must be signed in to change notification settings - Fork 180
Expand file tree
/
Copy pathgroup.go
More file actions
148 lines (129 loc) · 5.47 KB
/
group.go
File metadata and controls
148 lines (129 loc) · 5.47 KB
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
package dotweb
import "reflect"
// Group is the interface that wraps the group router methods.
// A Group allows you to create routes with a common prefix and middleware chain.
type Group interface {
// Use registers middleware(s) to the group.
Use(m ...Middleware) Group
// Group creates a new sub-group with prefix and optional sub-group-level middleware.
Group(prefix string, m ...Middleware) Group
// DELETE registers a new DELETE route with the given path and handler.
DELETE(path string, h HttpHandle) RouterNode
// GET registers a new GET route with the given path and handler.
GET(path string, h HttpHandle) RouterNode
// HEAD registers a new HEAD route with the given path and handler.
HEAD(path string, h HttpHandle) RouterNode
// OPTIONS registers a new OPTIONS route with the given path and handler.
OPTIONS(path string, h HttpHandle) RouterNode
// PATCH registers a new PATCH route with the given path and handler.
PATCH(path string, h HttpHandle) RouterNode
// POST registers a new POST route with the given path and handler.
POST(path string, h HttpHandle) RouterNode
// PUT registers a new PUT route with the given path and handler.
PUT(path string, h HttpHandle) RouterNode
// ServerFile registers a file server route with the given path and file root.
ServerFile(path string, fileroot string) RouterNode
// RegisterRoute registers a new route with the given HTTP method, path and handler.
RegisterRoute(method, path string, h HttpHandle) RouterNode
// SetNotFoundHandle sets a custom 404 handler for this group.
SetNotFoundHandle(handler StandardHandle) Group
}
// xGroup is the implementation of Group interface.
type xGroup struct {
prefix string
middlewares []Middleware
allRouterExpress map[string]struct{}
server *HttpServer
notFoundHandler StandardHandle
}
func NewGroup(prefix string, server *HttpServer) Group {
g := &xGroup{prefix: prefix, server: server, allRouterExpress: make(map[string]struct{})}
server.groups = append(server.groups, g)
server.Logger().Debug("DotWeb:Group NewGroup ["+prefix+"]", LogTarget_HttpServer)
return g
}
// Use implements `Router#Use()` for sub-routes within the Group.
func (g *xGroup) Use(ms ...Middleware) Group {
if len(ms) <= 0 {
return g
}
// deepcopy middleware structs to avoid middleware chain misbehaving
m := []Middleware{}
for _, om := range ms {
//newM := reflect.New(reflect.ValueOf(om).Elem().Type()).Interface().(Middleware)
newElem := reflect.New(reflect.TypeOf(om).Elem())
newElem.Elem().Set(reflect.ValueOf(om).Elem())
newM := newElem.Interface().(Middleware)
newM.SetNext(nil)
m = append(m, newM)
}
step := len(g.middlewares) - 1
for i := range m {
if m[i] != nil {
if step >= 0 {
g.middlewares[step].SetNext(m[i])
}
g.middlewares = append(g.middlewares, m[i])
step++
}
}
return g
}
// DELETE implements `Router#DELETE()` for sub-routes within the Group.
func (g *xGroup) DELETE(path string, h HttpHandle) RouterNode {
return g.add(RouteMethod_DELETE, path, h)
}
// GET implements `Router#GET()` for sub-routes within the Group.
func (g *xGroup) GET(path string, h HttpHandle) RouterNode {
return g.add(RouteMethod_GET, path, h)
}
// HEAD implements `Router#HEAD()` for sub-routes within the Group.
func (g *xGroup) HEAD(path string, h HttpHandle) RouterNode {
return g.add(RouteMethod_HEAD, path, h)
}
// OPTIONS implements `Router#OPTIONS()` for sub-routes within the Group.
func (g *xGroup) OPTIONS(path string, h HttpHandle) RouterNode {
return g.add(RouteMethod_OPTIONS, path, h)
}
// PATCH implements `Router#PATCH()` for sub-routes within the Group.
func (g *xGroup) PATCH(path string, h HttpHandle) RouterNode {
return g.add(RouteMethod_PATCH, path, h)
}
// POST implements `Router#POST()` for sub-routes within the Group.
func (g *xGroup) POST(path string, h HttpHandle) RouterNode {
return g.add(RouteMethod_POST, path, h)
}
// PUT implements `Router#PUT()` for sub-routes within the Group.
func (g *xGroup) PUT(path string, h HttpHandle) RouterNode {
return g.add(RouteMethod_PUT, path, h)
}
// PUT implements `Router#PUT()` for sub-routes within the Group.
func (g *xGroup) ServerFile(path string, fileroot string) RouterNode {
g.allRouterExpress[RouteMethod_GET+routerExpressSplit+g.prefix+path] = struct{}{}
node := g.server.Router().ServerFile(g.prefix+path, fileroot)
node.Node().groupMiddlewares = g.middlewares
return node
}
// Group creates a new sub-group with prefix and optional sub-group-level middleware.
func (g *xGroup) Group(prefix string, m ...Middleware) Group {
return NewGroup(g.prefix+prefix, g.server).Use(g.middlewares...).Use(m...)
}
func (g *xGroup) RegisterRoute(method, path string, handler HttpHandle) RouterNode {
return g.add(method, path, handler)
}
func (g *xGroup) add(method, path string, handler HttpHandle) RouterNode {
node := g.server.Router().RegisterRoute(method, g.prefix+path, handler)
g.allRouterExpress[method+routerExpressSplit+g.prefix+path] = struct{}{}
node.Node().groupMiddlewares = g.middlewares
return node
}
// SetNotFoundHandle sets a custom 404 handler for this group.
// This handler takes priority over the app-level NotFoundHandler.
// If a request path starts with the group's prefix but no route matches,
// this handler will be called instead of the global NotFoundHandler.
// SetNotFoundHandle sets custom 404 handler for this group.
// This handler takes priority over the app-level NotFoundHandler.
func (g *xGroup) SetNotFoundHandle(handler StandardHandle) Group {
g.notFoundHandler = handler
return g
}