1
0
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:
John Guo 2023-11-02 09:48:39 +08:00 committed by GitHub
parent e2e12fadb0
commit cbea89e6f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 17 deletions

View File

@ -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 {

View File

@ -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 != "" {

View File

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

View File

@ -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:

View File

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