diff --git a/.example/other/test.go b/.example/other/test.go index 5ca4e66de..ab245dc5d 100644 --- a/.example/other/test.go +++ b/.example/other/test.go @@ -1,35 +1,22 @@ package main import ( - "github.com/gogf/gf/frame/g" "github.com/gogf/gf/net/ghttp" ) -// 前置中间件1 -func MiddlewareBefore1(r *ghttp.Request) { - r.SetParam("name", "GoFrame") - r.Response.Writeln("set name") - r.Middleware.Next() -} - -// 前置中间件2 -func MiddlewareBefore2(r *ghttp.Request) { - r.SetParam("site", "https://goframe.org") - r.Response.Writeln("set site") - r.Middleware.Next() -} - func main() { - s := g.Server() - s.Group("/", func(group *ghttp.RouterGroup) { - group.Middleware(MiddlewareBefore1, MiddlewareBefore2) - group.ALL("/user", func(r *ghttp.Request) { - r.Response.Writefln( - "%s: %s", - r.GetParamVar("name").String(), - r.GetParamVar("site").String(), - ) - }) + s := ghttp.GetServer() + s.BindHandler("/admin", func(r *ghttp.Request) { + r.Response.Write("admin") + }) + s.BindHandler("/admin-{page}", func(r *ghttp.Request) { + r.Response.Write("admin-{page}", r.GetInt("page")) + }) + s.BindHandler("/admin-goods", func(r *ghttp.Request) { + r.Response.Write("admin-goods") + }) + s.BindHandler("/admin-goods-{page}", func(r *ghttp.Request) { + r.Response.Write("admin-goods-{page}", r.GetInt("page")) }) s.SetPort(8199) s.Run() diff --git a/net/ghttp/ghttp_server_router.go b/net/ghttp/ghttp_server_router.go index bbc95c0cc..e71b2277e 100644 --- a/net/ghttp/ghttp_server_router.go +++ b/net/ghttp/ghttp_server_router.go @@ -236,6 +236,21 @@ func (s *Server) compareRouterPriority(newItem *handlerItem, oldItem *handlerIte return false } + /** 比较路由规则长度,越长的规则优先级越高,模糊/命名规则不算长度 **/ + var uriNew, uriOld string + uriNew, _ = gregex.ReplaceString(`\{[^/]+\}`, "", newItem.router.Uri) + uriNew, _ = gregex.ReplaceString(`:[^/]+`, "", uriNew) + uriNew, _ = gregex.ReplaceString(`\*[^/]+`, "", uriNew) + uriOld, _ = gregex.ReplaceString(`\{[^/]+\}`, "", oldItem.router.Uri) + uriOld, _ = gregex.ReplaceString(`:[^/]+`, "", uriOld) + uriOld, _ = gregex.ReplaceString(`\*[^/]+`, "", uriOld) + if len(uriNew) > len(uriOld) { + return true + } + if len(uriNew) < len(uriOld) { + return false + } + /* 模糊规则数量相等,后续不用再判断*规则的数量比较了 */ // 比较HTTP METHOD,更精准的优先级更高 diff --git a/net/ghttp/ghttp_unit_router_basic_test.go b/net/ghttp/ghttp_unit_router_basic_test.go index 4afca7aed..fddbe88bc 100644 --- a/net/ghttp/ghttp_unit_router_basic_test.go +++ b/net/ghttp/ghttp_unit_router_basic_test.go @@ -198,3 +198,35 @@ func Test_Router_404(t *testing.T) { gtest.Assert(resp.StatusCode, 404) }) } + +func Test_Router_Priority(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.BindHandler("/admin", func(r *ghttp.Request) { + r.Response.Write("admin") + }) + s.BindHandler("/admin-{page}", func(r *ghttp.Request) { + r.Response.Write("admin-{page}") + }) + s.BindHandler("/admin-goods", func(r *ghttp.Request) { + r.Response.Write("admin-goods") + }) + s.BindHandler("/admin-goods-{page}", func(r *ghttp.Request) { + r.Response.Write("admin-goods-{page}") + }) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + time.Sleep(100 * time.Millisecond) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/admin"), "admin") + gtest.Assert(client.GetContent("/admin-1"), "admin-{page}") + gtest.Assert(client.GetContent("/admin-goods"), "admin-goods") + gtest.Assert(client.GetContent("/admin-goods-2"), "admin-goods-{page}") + }) +}