Skip to content

Commit 7fb91c6

Browse files
authored
Merge pull request #97 from devfeel/develop
Develop - dotweb新增ExcludeUse接口,重构Middleware实现
2 parents d4e05e6 + 1daf7df commit 7fb91c6

File tree

10 files changed

+247
-70
lines changed

10 files changed

+247
-70
lines changed

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: 43 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)
147+
if m != nil {
148+
m.Exclude(routers...)
149+
if middlewareLen > 0 {
150+
app.Middlewares[middlewareLen-1].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,23 @@ 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+
for _, m := range node.appMiddlewares {
400+
if m.HasExclude() && m.ExistsExcludeRouter(node.fullPath) {
401+
node.hasExcludeMiddleware = true
402+
}
403+
}
404+
}
405+
}
406+
374407
// init inner routers
375408
func (app *DotWeb) initInnerRouter() {
376409
//默认支持pprof信息查看
@@ -416,9 +449,6 @@ func (app *DotWeb) initServerEnvironment() {
416449
app.HttpServer.SetRenderer(NewInnerRenderer())
417450
}
418451

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

example/middleware/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ func main() {
2727

2828
//InitModule(app)
2929

30-
app.UseRequestLog()
30+
//app.UseRequestLog()
3131
app.Use(
3232
NewAccessFmtLog("app"),
33-
//NewSimpleAuth("admin"),
3433
)
34+
app.ExcludeUse(NewAccessFmtLog("appex"), "/", "/")
3535

3636
//启动 监控服务
3737
app.SetPProfConfig(true, 8081)
@@ -51,6 +51,7 @@ func Index(ctx dotweb.Context) error {
5151
ctx.Response().Header().Set("Content-Type", "text/html; charset=utf-8")
5252
//fmt.Println(time.Now(), "Index Handler")
5353
_, err := ctx.WriteString("index => ", fmt.Sprint(ctx.RouterNode().Middlewares()))
54+
fmt.Println(ctx.RouterNode().GroupMiddlewares())
5455
return err
5556
}
5657

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: 84 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,105 @@ 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)
28+
HasExclude() bool
29+
ExistsExcludeRouter(router string) bool
1730
}
1831

1932
//middleware 基础类,应用可基于此实现完整Moddleware
2033
type BaseMiddlware struct {
21-
next Middleware
34+
next Middleware
35+
excludeRouters map[string]struct{}
2236
}
2337

2438
func (bm *BaseMiddlware) SetNext(m Middleware) {
2539
bm.next = m
2640
}
2741

2842
func (bm *BaseMiddlware) Next(ctx Context) error {
29-
return bm.next.Handle(ctx)
43+
httpCtx := ctx.(*HttpContext)
44+
if httpCtx.middlewareStep == "" {
45+
httpCtx.middlewareStep = middleware_App
46+
}
47+
if bm.next == nil {
48+
if httpCtx.middlewareStep == middleware_App {
49+
httpCtx.middlewareStep = middleware_Group
50+
if len(httpCtx.RouterNode().GroupMiddlewares()) > 0 {
51+
return httpCtx.RouterNode().GroupMiddlewares()[0].Handle(ctx)
52+
}
53+
}
54+
if httpCtx.middlewareStep == middleware_Group {
55+
httpCtx.middlewareStep = middleware_Router
56+
if len(httpCtx.RouterNode().Middlewares()) > 0 {
57+
return httpCtx.RouterNode().Middlewares()[0].Handle(ctx)
58+
}
59+
}
60+
61+
if httpCtx.middlewareStep == middleware_Router {
62+
return httpCtx.Handler()(ctx)
63+
}
64+
} else {
65+
//check exclude config
66+
if ctx.RouterNode().Node().hasExcludeMiddleware && bm.next.HasExclude() {
67+
if bm.next.ExistsExcludeRouter(ctx.RouterNode().Node().fullPath) {
68+
return bm.next.Next(ctx)
69+
}
70+
}
71+
return bm.next.Handle(ctx)
72+
}
73+
return nil
74+
}
75+
76+
// Exclude Exclude this middleware with router
77+
func (bm *BaseMiddlware) Exclude(routers ...string) {
78+
if bm.excludeRouters == nil {
79+
bm.excludeRouters = make(map[string]struct{})
80+
}
81+
for _, v := range routers {
82+
bm.excludeRouters[v] = struct{}{}
83+
}
84+
}
85+
86+
// HasExclude check has set exclude router
87+
func (bm *BaseMiddlware) HasExclude() bool {
88+
if bm.excludeRouters == nil {
89+
return false
90+
}
91+
if len(bm.excludeRouters) > 0 {
92+
return true
93+
} else {
94+
return false
95+
}
96+
}
97+
98+
// ExistsExcludeRouter check is exists router in exclude map
99+
func (bm *BaseMiddlware) ExistsExcludeRouter(router string) bool {
100+
if bm.excludeRouters == nil {
101+
return false
102+
}
103+
_, exists := bm.excludeRouters[router]
104+
return exists
30105
}
31106

32107
type xMiddleware struct {
@@ -35,24 +110,14 @@ type xMiddleware struct {
35110
}
36111

37112
func (x *xMiddleware) Handle(ctx Context) error {
38-
len := len(ctx.RouterNode().Middlewares())
113+
httpCtx := ctx.(*HttpContext)
114+
if httpCtx.middlewareStep == "" {
115+
httpCtx.middlewareStep = middleware_App
116+
}
39117
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-
}
118+
return httpCtx.Handler()(ctx)
54119
}
55-
120+
return x.Next(ctx)
56121
}
57122

58123
//请求日志中间件

0 commit comments

Comments
 (0)