mirror of
https://github.com/gogf/gf.git
synced 2025-04-05 11:18:50 +08:00
fix duplicated route dump for package ghttp (#3116)
This commit is contained in:
parent
e2e12fadb0
commit
cbea89e6f7
@ -24,13 +24,13 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
// Client is a http client for SDK.
|
||||
// Client is an http client for SDK.
|
||||
type Client struct {
|
||||
*gclient.Client
|
||||
config Config
|
||||
}
|
||||
|
||||
// New creates and returns a http client for SDK.
|
||||
// New creates and returns an http client for SDK.
|
||||
func New(config Config) *Client {
|
||||
client := config.Client
|
||||
if client == nil {
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"github.com/olekukonko/tablewriter"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
"github.com/gogf/gf/v2/container/gtype"
|
||||
"github.com/gogf/gf/v2/debug/gdebug"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
@ -340,8 +341,9 @@ func (s *Server) GetOpenApi() *goai.OpenApiV3 {
|
||||
// GetRoutes retrieves and returns the router array.
|
||||
func (s *Server) GetRoutes() []RouterItem {
|
||||
var (
|
||||
m = make(map[string]*garray.SortedArray)
|
||||
address = s.GetListenedAddress()
|
||||
m = make(map[string]*garray.SortedArray)
|
||||
routeFilterSet = gset.NewStrSet()
|
||||
address = s.GetListenedAddress()
|
||||
)
|
||||
if s.config.HTTPSAddr != "" {
|
||||
if len(address) > 0 {
|
||||
@ -351,18 +353,21 @@ func (s *Server) GetRoutes() []RouterItem {
|
||||
}
|
||||
for k, handlerItems := range s.routesMap {
|
||||
array, _ := gregex.MatchString(`(.*?)%([A-Z]+):(.+)@(.+)`, k)
|
||||
for index, handlerItem := range handlerItems {
|
||||
item := RouterItem{
|
||||
Server: s.config.Name,
|
||||
Address: address,
|
||||
Domain: array[4],
|
||||
Type: handlerItem.Type,
|
||||
Middleware: array[1],
|
||||
Method: array[2],
|
||||
Route: array[3],
|
||||
Priority: len(handlerItems) - index - 1,
|
||||
Handler: handlerItem,
|
||||
}
|
||||
for index := len(handlerItems) - 1; index >= 0; index-- {
|
||||
var (
|
||||
handlerItem = handlerItems[index]
|
||||
item = RouterItem{
|
||||
Server: s.config.Name,
|
||||
Address: address,
|
||||
Domain: array[4],
|
||||
Type: handlerItem.Type,
|
||||
Middleware: array[1],
|
||||
Method: array[2],
|
||||
Route: array[3],
|
||||
Priority: index,
|
||||
Handler: handlerItem,
|
||||
}
|
||||
)
|
||||
switch item.Handler.Type {
|
||||
case HandlerTypeObject, HandlerTypeHandler:
|
||||
item.IsServiceHandler = true
|
||||
@ -370,6 +375,14 @@ func (s *Server) GetRoutes() []RouterItem {
|
||||
case HandlerTypeMiddleware:
|
||||
item.Middleware = "GLOBAL MIDDLEWARE"
|
||||
}
|
||||
// Repeated route filtering for dump.
|
||||
var setKey = fmt.Sprintf(
|
||||
`%s|%s|%s|%s`,
|
||||
item.Method, item.Route, item.Domain, item.Type,
|
||||
)
|
||||
if !routeFilterSet.AddIfNotExist(setKey) {
|
||||
continue
|
||||
}
|
||||
if len(item.Handler.Middleware) > 0 {
|
||||
for _, v := range item.Handler.Middleware {
|
||||
if item.Middleware != "" {
|
||||
|
@ -169,8 +169,12 @@ func (g *RouterGroup) Bind(handlerOrObject ...interface{}) *RouterGroup {
|
||||
"/",
|
||||
item,
|
||||
)
|
||||
|
||||
default:
|
||||
g.server.Logger().Fatalf(ctx, "invalid bind parameter type: %v", originValueAndKind.InputValue.Type())
|
||||
g.server.Logger().Fatalf(
|
||||
ctx, "invalid bind parameter type: %v, should be route function or struct object",
|
||||
originValueAndKind.InputValue.Type(),
|
||||
)
|
||||
}
|
||||
}
|
||||
return group
|
||||
|
@ -187,6 +187,8 @@ func (s *Server) searchHandlers(method, path, domain string) (parsedItems []*Han
|
||||
repeatHandlerCheckMap[item.Id] = struct{}{}
|
||||
}
|
||||
// Serving handler can only be added to the handler array just once.
|
||||
// The first route item in the list has the most priority than the rest.
|
||||
// This ignoring can implement route overwritten feature.
|
||||
if hasServe {
|
||||
switch item.Type {
|
||||
case HandlerTypeHandler, HandlerTypeObject:
|
||||
|
@ -7,13 +7,17 @@
|
||||
package ghttp_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/guid"
|
||||
)
|
||||
|
||||
@ -177,3 +181,55 @@ func Test_Router_Group_Map(t *testing.T) {
|
||||
t.Assert(c.PostContent(ctx, "/test"), "post")
|
||||
})
|
||||
}
|
||||
|
||||
type SafeBuffer struct {
|
||||
buffer *bytes.Buffer
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (b *SafeBuffer) Write(p []byte) (n int, err error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.buffer.Write(p)
|
||||
}
|
||||
|
||||
func (b *SafeBuffer) String() string {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.buffer.String()
|
||||
}
|
||||
|
||||
func Test_Router_OverWritten(t *testing.T) {
|
||||
var (
|
||||
s = g.Server(guid.S())
|
||||
obj = new(GroupObject)
|
||||
buf = &SafeBuffer{
|
||||
buffer: bytes.NewBuffer(nil),
|
||||
mu: sync.Mutex{},
|
||||
}
|
||||
logger = glog.NewWithWriter(buf)
|
||||
)
|
||||
logger.SetStdoutPrint(false)
|
||||
s.SetLogger(logger)
|
||||
s.SetRouteOverWrite(true)
|
||||
s.Group("/api", func(group *ghttp.RouterGroup) {
|
||||
group.ALLMap(g.Map{
|
||||
"/obj": obj,
|
||||
})
|
||||
group.ALLMap(g.Map{
|
||||
"/obj": obj,
|
||||
})
|
||||
})
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
dumpContent := buf.String()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
t.Assert(gstr.Count(dumpContent, `/api/obj `), 1)
|
||||
t.Assert(gstr.Count(dumpContent, `/api/obj/index`), 1)
|
||||
t.Assert(gstr.Count(dumpContent, `/api/obj/show`), 1)
|
||||
t.Assert(gstr.Count(dumpContent, `/api/obj/delete`), 1)
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user