improve route priority handling for ghttp.Server

This commit is contained in:
John
2019-12-02 21:26:12 +08:00
parent fcba650348
commit 108ced2b0b
3 changed files with 59 additions and 25 deletions

View File

@ -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()

View File

@ -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更精准的优先级更高

View File

@ -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}")
})
}