From b9fbfb91bdca0e4b0fcb41002e58bf9bf96585f9 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 19 Sep 2019 19:44:46 +0800 Subject: [PATCH] improve middleware feature of ghttp.Server; add MapStrAny function for gmap/gtree --- .../ghttp/server/middleware/auth_exception.go | 44 +++++++++++++++++++ .example/other/test.go | 14 +++--- container/gmap/gmap_hash_any_any_map.go | 11 +++++ container/gmap/gmap_link_map.go | 14 ++++++ container/gtree/gtree_avltree.go | 12 +++++ container/gtree/gtree_btree.go | 12 +++++ container/gtree/gtree_redblacktree.go | 12 +++++ net/ghttp/ghttp_request_router.go | 6 ++- net/ghttp/ghttp_server_router_group.go | 8 ++++ net/ghttp/ghttp_server_router_middleware.go | 2 +- 10 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 .example/net/ghttp/server/middleware/auth_exception.go diff --git a/.example/net/ghttp/server/middleware/auth_exception.go b/.example/net/ghttp/server/middleware/auth_exception.go new file mode 100644 index 000000000..99c924908 --- /dev/null +++ b/.example/net/ghttp/server/middleware/auth_exception.go @@ -0,0 +1,44 @@ +package main + +import ( + "net/http" + + "github.com/gogf/gf/frame/g" + "github.com/gogf/gf/net/ghttp" +) + +func MiddlewareAuth(r *ghttp.Request) { + token := r.Get("token") + if token == "123456" { + r.Middleware.Next() + } else { + r.Response.WriteStatus(http.StatusForbidden) + } +} + +func main() { + s := g.Server() + s.Group("/admin", func(g *ghttp.RouterGroup) { + g.MiddlewarePattern("/*action", func(r *ghttp.Request) { + if action := r.GetRouterString("action"); action != "" { + switch action { + case "login": + r.Middleware.Next() + return + } + } + MiddlewareAuth(r) + }) + g.ALL("/login", func(r *ghttp.Request) { + r.Response.Write("login") + }) + g.ALL("/dashboard", func(r *ghttp.Request) { + r.Response.Write("dashboard") + }) + g.ALL("/user", func(r *ghttp.Request) { + r.Response.Write("user") + }) + }) + s.SetPort(8199) + s.Run() +} diff --git a/.example/other/test.go b/.example/other/test.go index ed808bf92..3089d5cea 100644 --- a/.example/other/test.go +++ b/.example/other/test.go @@ -1,16 +1,12 @@ package main import ( - "fmt" - "reflect" - - "github.com/gogf/gf/frame/g" - - "github.com/gogf/gf/text/gstr" + "github.com/gogf/gf/os/gcmd" + "github.com/gogf/gf/os/glog" ) func main() { - m, _ := gstr.Parse("map[a]=1&map[b]=2") - g.Dump(m) - fmt.Println(reflect.TypeOf(m["map"].(map[string]interface{})["b"])) + glog.SetFlags(glog.F_TIME_DATE | glog.F_TIME_TIME | glog.F_FILE_SHORT) + glog.Debug("dd") + glog.Println("timeout", gcmd.GetOpt("timeout")) } diff --git a/container/gmap/gmap_hash_any_any_map.go b/container/gmap/gmap_hash_any_any_map.go index 8b4c35ffc..dd6818d1f 100644 --- a/container/gmap/gmap_hash_any_any_map.go +++ b/container/gmap/gmap_hash_any_any_map.go @@ -68,6 +68,17 @@ func (m *AnyAnyMap) Map() map[interface{}]interface{} { return data } +// MapStrAny returns a copy of the data of the map as map[string]interface{}. +func (m *AnyAnyMap) MapStrAny() map[string]interface{} { + m.mu.RLock() + data := make(map[string]interface{}, len(m.data)) + for k, v := range m.data { + data[gconv.String(k)] = v + } + m.mu.RUnlock() + return data +} + // Set sets key-value to the hash map. func (m *AnyAnyMap) Set(key interface{}, val interface{}) { m.mu.Lock() diff --git a/container/gmap/gmap_link_map.go b/container/gmap/gmap_link_map.go index 2d0512ada..f45c03588 100644 --- a/container/gmap/gmap_link_map.go +++ b/container/gmap/gmap_link_map.go @@ -104,6 +104,20 @@ func (m *ListMap) Map() map[interface{}]interface{} { return data } +// MapStrAny returns a copy of the data of the map as map[string]interface{}. +func (m *ListMap) MapStrAny() map[string]interface{} { + m.mu.RLock() + node := (*gListMapNode)(nil) + data := make(map[string]interface{}, len(m.data)) + m.list.IteratorAsc(func(e *glist.Element) bool { + node = e.Value.(*gListMapNode) + data[gconv.String(node.key)] = node.value + return true + }) + m.mu.RUnlock() + return data +} + // Set sets key-value to the map. func (m *ListMap) Set(key interface{}, value interface{}) { m.mu.Lock() diff --git a/container/gtree/gtree_avltree.go b/container/gtree/gtree_avltree.go index 18783dcc6..848e6099a 100644 --- a/container/gtree/gtree_avltree.go +++ b/container/gtree/gtree_avltree.go @@ -10,6 +10,8 @@ import ( "encoding/json" "fmt" + "github.com/gogf/gf/util/gconv" + "github.com/gogf/gf/container/gvar" "github.com/gogf/gf/internal/rwmutex" ) @@ -408,6 +410,16 @@ func (tree *AVLTree) Map() map[interface{}]interface{} { return m } +// MapStrAny returns all key-value items as map[string]interface{}. +func (tree *AVLTree) MapStrAny() map[string]interface{} { + m := make(map[string]interface{}, tree.Size()) + tree.IteratorAsc(func(key, value interface{}) bool { + m[gconv.String(key)] = value + return true + }) + return m +} + // Flip exchanges key-value of the tree to value-key. // Note that you should guarantee the value is the same type as key, // or else the comparator would panic. diff --git a/container/gtree/gtree_btree.go b/container/gtree/gtree_btree.go index 32e67b5ae..fb264b82e 100644 --- a/container/gtree/gtree_btree.go +++ b/container/gtree/gtree_btree.go @@ -12,6 +12,8 @@ import ( "fmt" "strings" + "github.com/gogf/gf/util/gconv" + "github.com/gogf/gf/container/gvar" "github.com/gogf/gf/internal/rwmutex" ) @@ -302,6 +304,16 @@ func (tree *BTree) Map() map[interface{}]interface{} { return m } +// MapStrAny returns all key-value items as map[string]interface{}. +func (tree *BTree) MapStrAny() map[string]interface{} { + m := make(map[string]interface{}, tree.Size()) + tree.IteratorAsc(func(key, value interface{}) bool { + m[gconv.String(key)] = value + return true + }) + return m +} + // Clear removes all nodes from the tree. func (tree *BTree) Clear() { tree.mu.Lock() diff --git a/container/gtree/gtree_redblacktree.go b/container/gtree/gtree_redblacktree.go index 32c980b6f..a7b9e6597 100644 --- a/container/gtree/gtree_redblacktree.go +++ b/container/gtree/gtree_redblacktree.go @@ -10,6 +10,8 @@ import ( "encoding/json" "fmt" + "github.com/gogf/gf/util/gconv" + "github.com/gogf/gf/container/gvar" "github.com/gogf/gf/internal/rwmutex" ) @@ -345,6 +347,16 @@ func (tree *RedBlackTree) Map() map[interface{}]interface{} { return m } +// MapStrAny returns all key-value items as map[string]interface{}. +func (tree *RedBlackTree) MapStrAny() map[string]interface{} { + m := make(map[string]interface{}, tree.Size()) + tree.IteratorAsc(func(key, value interface{}) bool { + m[gconv.String(key)] = value + return true + }) + return m +} + // Left returns the left-most (min) node or nil if tree is empty. func (tree *RedBlackTree) Left() *RedBlackTreeNode { tree.mu.RLock() diff --git a/net/ghttp/ghttp_request_router.go b/net/ghttp/ghttp_request_router.go index 70e85f693..53235d53e 100644 --- a/net/ghttp/ghttp_request_router.go +++ b/net/ghttp/ghttp_request_router.go @@ -23,7 +23,11 @@ func (r *Request) GetRouterValue(key string, def ...interface{}) interface{} { return nil } -// 获得路由解析参数, gvar.Var +// 获得路由解析参数 func (r *Request) GetRouterVar(key string, def ...interface{}) *gvar.Var { return gvar.New(r.GetRouterValue(key, def...)) } + +func (r *Request) GetRouterString(key string, def ...interface{}) string { + return r.GetRouterVar(key, def...).String() +} diff --git a/net/ghttp/ghttp_server_router_group.go b/net/ghttp/ghttp_server_router_group.go index 976a0b91d..1486401d2 100644 --- a/net/ghttp/ghttp_server_router_group.go +++ b/net/ghttp/ghttp_server_router_group.go @@ -216,6 +216,14 @@ func (g *RouterGroup) Middleware(handlers ...HandlerFunc) *RouterGroup { return group } +func (g *RouterGroup) MiddlewarePattern(pattern string, handlers ...HandlerFunc) *RouterGroup { + group := g.Clone() + for _, handler := range handlers { + group.preBind("MIDDLEWARE", pattern, handler) + } + return group +} + func (g *RouterGroup) preBind(bindType string, pattern string, object interface{}, params ...interface{}) *RouterGroup { preBindItems = append(preBindItems, groupPreBindItem{ group: g, diff --git a/net/ghttp/ghttp_server_router_middleware.go b/net/ghttp/ghttp_server_router_middleware.go index cf355a52c..2f169ef57 100644 --- a/net/ghttp/ghttp_server_router_middleware.go +++ b/net/ghttp/ghttp_server_router_middleware.go @@ -27,7 +27,7 @@ func (s *Server) BindMiddleware(pattern string, handlers ...HandlerFunc) { } // 注册中间件,绑定到全局路由规则("/*")上,中间件参数支持多个。 -func (s *Server) AddMiddleware(handlers ...HandlerFunc) { +func (s *Server) BindMiddlewareDefault(handlers ...HandlerFunc) { for _, handler := range handlers { s.setHandler(gDEFAULT_MIDDLEWARE_PATTERN, &handlerItem{ itemType: gHANDLER_TYPE_MIDDLEWARE,