diff --git a/net/ghttp/ghttp_server_domain.go b/net/ghttp/ghttp_server_domain.go index 10a98d780..1e49a4529 100644 --- a/net/ghttp/ghttp_server_domain.go +++ b/net/ghttp/ghttp_server_domain.go @@ -32,7 +32,7 @@ func (s *Server) Domain(domains string) *Domain { // BindHandler binds the handler for the specified pattern. func (d *Domain) BindHandler(pattern string, handler any) { for domain := range d.domains { - d.server.BindHandler(pattern+"@"+domain, handler) + d.server.BindHandler(patternBindDomain(pattern, domain), handler) } } @@ -40,7 +40,7 @@ func (d *Domain) doBindHandler(ctx context.Context, in doBindHandlerInput) { for domain := range d.domains { d.server.doBindHandler(ctx, doBindHandlerInput{ Prefix: in.Prefix, - Pattern: in.Pattern + "@" + domain, + Pattern: patternBindDomain(in.Pattern, domain), FuncInfo: in.FuncInfo, Middleware: in.Middleware, Source: in.Source, @@ -51,7 +51,7 @@ func (d *Domain) doBindHandler(ctx context.Context, in doBindHandlerInput) { // BindObject binds the object for the specified pattern. func (d *Domain) BindObject(pattern string, obj any, methods ...string) { for domain := range d.domains { - d.server.BindObject(pattern+"@"+domain, obj, methods...) + d.server.BindObject(patternBindDomain(pattern, domain), obj, methods...) } } @@ -59,7 +59,7 @@ func (d *Domain) doBindObject(ctx context.Context, in doBindObjectInput) { for domain := range d.domains { d.server.doBindObject(ctx, doBindObjectInput{ Prefix: in.Prefix, - Pattern: in.Pattern + "@" + domain, + Pattern: patternBindDomain(in.Pattern, domain), Object: in.Object, Method: in.Method, Middleware: in.Middleware, @@ -71,7 +71,7 @@ func (d *Domain) doBindObject(ctx context.Context, in doBindObjectInput) { // BindObjectMethod binds the method for the specified pattern. func (d *Domain) BindObjectMethod(pattern string, obj any, method string) { for domain := range d.domains { - d.server.BindObjectMethod(pattern+"@"+domain, obj, method) + d.server.BindObjectMethod(patternBindDomain(pattern, domain), obj, method) } } @@ -79,7 +79,7 @@ func (d *Domain) doBindObjectMethod(ctx context.Context, in doBindObjectMethodIn for domain := range d.domains { d.server.doBindObjectMethod(ctx, doBindObjectMethodInput{ Prefix: in.Prefix, - Pattern: in.Pattern + "@" + domain, + Pattern: patternBindDomain(in.Pattern, domain), Object: in.Object, Method: in.Method, Middleware: in.Middleware, @@ -91,7 +91,7 @@ func (d *Domain) doBindObjectMethod(ctx context.Context, in doBindObjectMethodIn // BindObjectRest binds the RESTful API for the specified pattern. func (d *Domain) BindObjectRest(pattern string, obj any) { for domain := range d.domains { - d.server.BindObjectRest(pattern+"@"+domain, obj) + d.server.BindObjectRest(patternBindDomain(pattern, domain), obj) } } @@ -99,7 +99,7 @@ func (d *Domain) doBindObjectRest(ctx context.Context, in doBindObjectInput) { for domain := range d.domains { d.server.doBindObjectRest(ctx, doBindObjectInput{ Prefix: in.Prefix, - Pattern: in.Pattern + "@" + domain, + Pattern: patternBindDomain(in.Pattern, domain), Object: in.Object, Method: in.Method, Middleware: in.Middleware, @@ -111,7 +111,7 @@ func (d *Domain) doBindObjectRest(ctx context.Context, in doBindObjectInput) { // BindHookHandler binds the hook handler for the specified pattern. func (d *Domain) BindHookHandler(pattern string, hook HookName, handler HandlerFunc) { for domain := range d.domains { - d.server.BindHookHandler(pattern+"@"+domain, hook, handler) + d.server.BindHookHandler(patternBindDomain(pattern, domain), hook, handler) } } @@ -119,7 +119,7 @@ func (d *Domain) doBindHookHandler(ctx context.Context, in doBindHookHandlerInpu for domain := range d.domains { d.server.doBindHookHandler(ctx, doBindHookHandlerInput{ Prefix: in.Prefix, - Pattern: in.Pattern + "@" + domain, + Pattern: patternBindDomain(in.Pattern, domain), HookName: in.HookName, Handler: in.Handler, Source: in.Source, @@ -130,7 +130,7 @@ func (d *Domain) doBindHookHandler(ctx context.Context, in doBindHookHandlerInpu // BindHookHandlerByMap binds the hook handler for the specified pattern. func (d *Domain) BindHookHandlerByMap(pattern string, hookMap map[HookName]HandlerFunc) { for domain := range d.domains { - d.server.BindHookHandlerByMap(pattern+"@"+domain, hookMap) + d.server.BindHookHandlerByMap(patternBindDomain(pattern, domain), hookMap) } } @@ -151,14 +151,14 @@ func (d *Domain) BindStatusHandlerByMap(handlerMap map[int]HandlerFunc) { // BindMiddleware binds the middleware for the specified pattern. func (d *Domain) BindMiddleware(pattern string, handlers ...HandlerFunc) { for domain := range d.domains { - d.server.BindMiddleware(pattern+"@"+domain, handlers...) + d.server.BindMiddleware(patternBindDomain(pattern, domain), handlers...) } } // BindMiddlewareDefault binds the default middleware for the specified pattern. func (d *Domain) BindMiddlewareDefault(handlers ...HandlerFunc) { for domain := range d.domains { - d.server.BindMiddleware(defaultMiddlewarePattern+"@"+domain, handlers...) + d.server.BindMiddleware(patternBindDomain(defaultMiddlewarePattern, domain), handlers...) } } @@ -166,3 +166,10 @@ func (d *Domain) BindMiddlewareDefault(handlers ...HandlerFunc) { func (d *Domain) Use(handlers ...HandlerFunc) { d.BindMiddlewareDefault(handlers...) } + +func patternBindDomain(pattern, domain string) string { + if domain != "" { + return pattern + "@" + domain + } + return pattern +} diff --git a/net/ghttp/ghttp_z_unit_feature_router_domain_basic_test.go b/net/ghttp/ghttp_z_unit_feature_router_domain_basic_test.go index d9c91428f..f0c1f36b3 100644 --- a/net/ghttp/ghttp_z_unit_feature_router_domain_basic_test.go +++ b/net/ghttp/ghttp_z_unit_feature_router_domain_basic_test.go @@ -363,3 +363,37 @@ func Test_Router_DomainGroup(t *testing.T) { t.Assert(client2.DeleteContent(ctx, "/app/comment/20"), "Not Found") }) } + +// issue#4100 +func TestIssue4100(t *testing.T) { + s := g.Server(guid.S()) + d := s.Domain("") + d.BindHandler("/:name", func(r *ghttp.Request) { + r.Response.Write("/:name") + }) + d.BindHandler("/:name/update", func(r *ghttp.Request) { + r.Response.Write(r.Get("name")) + }) + d.BindHandler("/:name/:action", func(r *ghttp.Request) { + r.Response.Write(r.Get("action")) + }) + d.BindHandler("/:name/*any", func(r *ghttp.Request) { + r.Response.Write(r.Get("any")) + }) + d.BindHandler("/user/list/{field}.html", func(r *ghttp.Request) { + r.Response.Write(r.Get("field")) + }) + s.SetDumpRouterMap(false) + s.Start() + defer s.Shutdown() + + time.Sleep(100 * time.Millisecond) + gtest.C(t, func(t *gtest.T) { + client := g.Client() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort())) + t.Assert(client.GetContent(ctx, "/john"), "") + t.Assert(client.GetContent(ctx, "/john/update"), "john") + t.Assert(client.GetContent(ctx, "/john/edit"), "edit") + t.Assert(client.GetContent(ctx, "/user/list/100.html"), "100") + }) +}