Skip to content

Commit 1dbd538

Browse files
author
pzrr@qq.com
committed
#### Version 1.4.1
* 优化dotweb结构,调整部分内部函数名称,增加initBindMiddleware * 重构Middleware实现 * Node新增AppMiddlewares与GroupMiddlewares,用于存储App级、Group级的中间件实例 * Middleware新增Exclude(routers ...string)函数,用于指定不生效的路由 * middleware执行优先级: - 优先级1:app级别middleware - 优先级2:group级别middleware - 优先级:router级别middleware * 更新example/middleware * 2018-01-01 23:00:00
1 parent a598a24 commit 1dbd538

10 files changed

Lines changed: 209 additions & 69 deletions

File tree

‎context.go‎

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,24 +87,25 @@ type (
8787
HttpContext struct {
8888
context context.Context
8989
//暂未启用
90-
cancle context.CancelFunc
91-
request *Request
92-
routerNode RouterNode
93-
routerParams Params
94-
response *Response
95-
webSocket *WebSocket
96-
hijackConn *HijackConn
97-
isWebSocket bool
98-
isHijack bool
99-
isEnd bool //表示当前处理流程是否需要终止
100-
httpServer *HttpServer
101-
sessionID string
102-
innerItems *core.ItemContext
103-
items *core.ItemContext
104-
viewData *core.ItemContext
105-
features *xFeatureTools
106-
handler HttpHandle
107-
startTime time.Time
90+
cancle context.CancelFunc
91+
middlewareStep string
92+
request *Request
93+
routerNode RouterNode
94+
routerParams Params
95+
response *Response
96+
webSocket *WebSocket
97+
hijackConn *HijackConn
98+
isWebSocket bool
99+
isHijack bool
100+
isEnd bool //表示当前处理流程是否需要终止
101+
httpServer *HttpServer
102+
sessionID string
103+
innerItems *core.ItemContext
104+
items *core.ItemContext
105+
viewData *core.ItemContext
106+
features *xFeatureTools
107+
handler HttpHandle
108+
startTime time.Time
108109
}
109110
)
110111

@@ -129,6 +130,7 @@ func (ctx *HttpContext) reset(res *Response, r *Request, server *HttpServer, nod
129130
func (ctx *HttpContext) release() {
130131
ctx.request = nil
131132
ctx.response = nil
133+
ctx.middlewareStep = ""
132134
ctx.routerNode = nil
133135
ctx.routerParams = nil
134136
ctx.webSocket = nil

‎dotweb.go‎

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ const (
5454
RunMode_Production = "production"
5555
)
5656

57-
5857
//New create and return DotApp instance
5958
func New() *DotWeb {
6059
app := &DotWeb{
@@ -141,6 +140,19 @@ func (app *DotWeb) SetProductionMode() {
141140
logger.SetEnabledConsole(false)
142141
}
143142

143+
// ExcludeUse registers a middleware exclude routers
144+
// like exclude /index or /query/:id
145+
func (app *DotWeb) ExcludeUse(m Middleware, routers ...string) {
146+
middlewareLen := len(app.Middlewares) - 1
147+
if m != nil {
148+
m.Exclude(routers...)
149+
if middlewareLen >= 0 {
150+
app.Middlewares[middlewareLen].SetNext(m)
151+
}
152+
app.Middlewares = append(app.Middlewares, m)
153+
}
154+
}
155+
144156
// Use registers a middleware
145157
func (app *DotWeb) Use(m ...Middleware) {
146158
step := len(app.Middlewares) - 1
@@ -244,10 +256,14 @@ func (app *DotWeb) MustStart() {
244256
// not support pprof server auto start
245257
func (app *DotWeb) ListenAndServe(addr string) error {
246258
app.initAppConfig()
247-
app.initRegisterMiddleware()
248-
app.initRegisterRoute()
249-
app.initRegisterGroup()
259+
app.initRegisterConfigMiddleware()
260+
app.initRegisterConfigRoute()
261+
app.initRegisterConfigGroup()
262+
250263
app.initServerEnvironment()
264+
265+
app.initBindMiddleware()
266+
251267
app.initInnerRouter()
252268

253269
if app.HttpServer.ServerConfig().EnabledTLS {
@@ -300,8 +316,8 @@ func (app *DotWeb) initAppConfig() {
300316
}
301317
}
302318

303-
// init register Middleware
304-
func (app *DotWeb) initRegisterMiddleware() {
319+
// init register config's Middleware
320+
func (app *DotWeb) initRegisterConfigMiddleware() {
305321
config := app.Config
306322
//register app's middleware
307323
for _, m := range config.Middlewares {
@@ -314,8 +330,8 @@ func (app *DotWeb) initRegisterMiddleware() {
314330
}
315331
}
316332

317-
// init register route
318-
func (app *DotWeb) initRegisterRoute() {
333+
// init register config's route
334+
func (app *DotWeb) initRegisterConfigRoute() {
319335
config := app.Config
320336
//load router and register
321337
for _, r := range config.Routers {
@@ -335,8 +351,8 @@ func (app *DotWeb) initRegisterRoute() {
335351
}
336352
}
337353

338-
// init register route
339-
func (app *DotWeb) initRegisterGroup() {
354+
// init register config's route
355+
func (app *DotWeb) initRegisterConfigGroup() {
340356
config := app.Config
341357
//support group
342358
for _, v := range config.Groups {
@@ -371,6 +387,19 @@ func (app *DotWeb) initRegisterGroup() {
371387
}
372388
}
373389

390+
// init bind app's middleware to router node
391+
func (app *DotWeb) initBindMiddleware() {
392+
//add default httphandler with middlewares
393+
app.Use(&xMiddleware{})
394+
395+
router := app.HttpServer.Router().(*router)
396+
for path, node := range router.allNodeMap {
397+
logger.Logger().Debug("DotWeb initBindMiddleware "+path+" "+fmt.Sprint(node), LogTarget_HttpServer)
398+
node.appMiddlewares = app.Middlewares
399+
400+
}
401+
}
402+
374403
// init inner routers
375404
func (app *DotWeb) initInnerRouter() {
376405
//默认支持pprof信息查看
@@ -416,9 +445,6 @@ func (app *DotWeb) initServerEnvironment() {
416445
app.HttpServer.SetRenderer(NewInnerRenderer())
417446
}
418447

419-
//add default httphandler with middlewares
420-
app.Use(&xMiddleware{})
421-
422448
//start pprof server
423449
if app.Config.App.EnabledPProf {
424450
logger.Logger().Debug("DotWeb:StartPProfServer["+strconv.Itoa(app.Config.App.PProfPort)+"] Begin", LogTarget_HttpServer)

‎example/middleware/main.go‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ func main() {
2727

2828
//InitModule(app)
2929

30-
app.UseRequestLog()
30+
//app.UseRequestLog()
3131
app.Use(
3232
NewAccessFmtLog("app"),
33+
NewAccessFmtLog("app2"),
3334
//NewSimpleAuth("admin"),
3435
)
3536

@@ -51,6 +52,7 @@ func Index(ctx dotweb.Context) error {
5152
ctx.Response().Header().Set("Content-Type", "text/html; charset=utf-8")
5253
//fmt.Println(time.Now(), "Index Handler")
5354
_, err := ctx.WriteString("index => ", fmt.Sprint(ctx.RouterNode().Middlewares()))
55+
fmt.Println(ctx.RouterNode().GroupMiddlewares())
5456
return err
5557
}
5658

‎group.go‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,19 @@ func NewGroup(prefix string, server *HttpServer) Group {
3030

3131
// Use implements `Router#Use()` for sub-routes within the Group.
3232
func (g *xGroup) Use(m ...Middleware) Group {
33-
g.middlewares = append(g.middlewares, m...)
33+
if len(m) <= 0 {
34+
return g
35+
}
36+
step := len(g.middlewares) - 1
37+
for i := range m {
38+
if m[i] != nil {
39+
if step >= 0 {
40+
g.middlewares[step].SetNext(m[i])
41+
}
42+
g.middlewares = append(g.middlewares, m[i])
43+
step++
44+
}
45+
}
3446
return g
3547
}
3648

@@ -79,6 +91,7 @@ func (g *xGroup) RegisterRoute(method, path string, handler HttpHandle) RouterNo
7991
}
8092

8193
func (g *xGroup) add(method, path string, handler HttpHandle) RouterNode {
82-
node := g.server.Router().RegisterRoute(method, g.prefix+path, handler).Use(g.middlewares...)
94+
node := g.server.Router().RegisterRoute(method, g.prefix+path, handler)
95+
node.Node().groupMiddlewares = g.middlewares
8396
return node
8497
}

‎middleware.go‎

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,78 @@ package dotweb
33
import (
44
"github.com/devfeel/dotweb/framework/convert"
55
"github.com/devfeel/dotweb/logger"
6-
"reflect"
76
"time"
87
)
98

9+
const (
10+
middleware_App = "app"
11+
middleware_Group = "group"
12+
middleware_Router = "router"
13+
)
14+
1015
type MiddlewareFunc func() Middleware
1116

17+
//middleware执行优先级:
18+
//优先级1:app级别middleware
19+
//优先级2:group级别middleware
20+
//优先级3:router级别middleware
21+
1222
// Middleware middleware interface
1323
type Middleware interface {
1424
Handle(ctx Context) error
1525
SetNext(m Middleware)
1626
Next(ctx Context) error
27+
Exclude(routers ...string)
1728
}
1829

1930
//middleware 基础类,应用可基于此实现完整Moddleware
2031
type BaseMiddlware struct {
21-
next Middleware
32+
next Middleware
33+
excludeRouters map[string]struct{}
2234
}
2335

2436
func (bm *BaseMiddlware) SetNext(m Middleware) {
2537
bm.next = m
2638
}
2739

2840
func (bm *BaseMiddlware) Next(ctx Context) error {
29-
return bm.next.Handle(ctx)
41+
httpCtx := ctx.(*HttpContext)
42+
if httpCtx.middlewareStep == "" {
43+
httpCtx.middlewareStep = middleware_App
44+
}
45+
if bm.next == nil {
46+
if httpCtx.middlewareStep == middleware_App {
47+
httpCtx.middlewareStep = middleware_Group
48+
if len(httpCtx.RouterNode().GroupMiddlewares()) > 0 {
49+
return httpCtx.RouterNode().GroupMiddlewares()[0].Handle(ctx)
50+
}
51+
}
52+
if httpCtx.middlewareStep == middleware_Group {
53+
httpCtx.middlewareStep = middleware_Router
54+
if len(httpCtx.RouterNode().Middlewares()) > 0 {
55+
return httpCtx.RouterNode().Middlewares()[0].Handle(ctx)
56+
}
57+
}
58+
59+
if httpCtx.middlewareStep == middleware_Router {
60+
return httpCtx.Handler()(ctx)
61+
}
62+
} else {
63+
return bm.next.Handle(ctx)
64+
}
65+
return nil
66+
}
67+
68+
// Exclude Exclude this middleware with router
69+
func (bm *BaseMiddlware) Exclude(routers ...string) {
70+
if bm.excludeRouters == nil {
71+
bm.excludeRouters = make(map[string]struct{})
72+
}
73+
for _, v := range routers {
74+
if _, exists := bm.excludeRouters[v]; !exists {
75+
bm.excludeRouters[v] = struct{}{}
76+
}
77+
}
3078
}
3179

3280
type xMiddleware struct {
@@ -35,24 +83,14 @@ type xMiddleware struct {
3583
}
3684

3785
func (x *xMiddleware) Handle(ctx Context) error {
38-
len := len(ctx.RouterNode().Middlewares())
86+
httpCtx := ctx.(*HttpContext)
87+
if httpCtx.middlewareStep == "" {
88+
httpCtx.middlewareStep = middleware_App
89+
}
3990
if x.IsEnd {
40-
return ctx.Handler()(ctx)
41-
} else {
42-
if x.next == nil {
43-
if len <= 0 {
44-
return ctx.Handler()(ctx)
45-
} else {
46-
if reflect.TypeOf(ctx.RouterNode().Middlewares()[len-1]).String() != "*dotweb.xMiddleware" {
47-
ctx.RouterNode().Use(&xMiddleware{IsEnd: true})
48-
}
49-
return ctx.RouterNode().Middlewares()[0].Handle(ctx)
50-
}
51-
} else {
52-
return x.Next(ctx)
53-
}
91+
return httpCtx.Handler()(ctx)
5492
}
55-
93+
return x.Next(ctx)
5694
}
5795

5896
//请求日志中间件

‎router.go‎

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ type (
8080

8181
RouterNode interface {
8282
Use(m ...Middleware) *Node
83+
AppMiddlewares() []Middleware
84+
GroupMiddlewares() []Middleware
8385
Middlewares() []Middleware
8486
Node() *Node
8587
}
@@ -93,8 +95,8 @@ type (
9395
// router is a http.Handler which can be used to dispatch requests to different
9496
// handler functions via configurable routes
9597
router struct {
96-
Nodes map[string]*Node
97-
98+
Nodes map[string]*Node
99+
allNodeMap map[string]*Node
98100
server *HttpServer
99101
handlerMap map[string]HttpHandle
100102
handlerMutex *sync.RWMutex
@@ -157,6 +159,7 @@ func NewRouter(server *HttpServer) *router {
157159
RedirectTrailingSlash: true,
158160
RedirectFixedPath: true,
159161
HandleOPTIONS: true,
162+
allNodeMap: make(map[string]*Node),
160163
server: server,
161164
handlerMap: make(map[string]HttpHandle),
162165
handlerMutex: new(sync.RWMutex),
@@ -309,11 +312,18 @@ func (r *router) wrapRouterHandle(handler HttpHandle, isHijack bool) RouterHandl
309312

310313
//处理用户handle
311314
var ctxErr error
312-
if len(r.server.DotApp.Middlewares) > 0 {
313-
ctxErr = r.server.DotApp.Middlewares[0].Handle(httpCtx)
315+
//if len(r.server.DotApp.Middlewares) > 0 {
316+
// ctxErr = r.server.DotApp.Middlewares[0].Handle(httpCtx)
317+
//} else {
318+
// ctxErr = handler(httpCtx)
319+
//}
320+
321+
if len(httpCtx.routerNode.AppMiddlewares()) > 0 {
322+
ctxErr = httpCtx.routerNode.AppMiddlewares()[0].Handle(httpCtx)
314323
} else {
315324
ctxErr = handler(httpCtx)
316325
}
326+
317327
if ctxErr != nil {
318328
//handler the exception
319329
if r.server.DotApp.ExceptionHandler != nil {
@@ -481,6 +491,7 @@ func (r *router) add(method, path string, handle RouterHandle, m ...Middleware)
481491
}
482492
//fmt.Println("Handle => ", method, " - ", *root, " - ", path)
483493
outnode = root.addRoute(path, handle, m...)
494+
r.allNodeMap[method+"_"+path] = outnode
484495
return
485496
}
486497

0 commit comments

Comments
 (0)