From 7619287206784f15b0fbd954e855b9ec2f234231 Mon Sep 17 00:00:00 2001 From: John Guo Date: Thu, 21 Sep 2023 20:17:50 +0800 Subject: [PATCH] fix isue #2976, to be compatible with bad response type definition for strict route function --- net/ghttp/ghttp_server_service_handler.go | 10 +++++-- ...ghttp_z_unit_feature_router_strict_test.go | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/net/ghttp/ghttp_server_service_handler.go b/net/ghttp/ghttp_server_service_handler.go index a1d56f2f80e..5c41dcfe0a3 100644 --- a/net/ghttp/ghttp_server_service_handler.go +++ b/net/ghttp/ghttp_server_service_handler.go @@ -214,11 +214,15 @@ func (s *Server) checkAndCreateFuncInfo(f interface{}, pkgPath, structName, meth // trimGeneric removes type definitions string from response type name if generic func trimGeneric(structName string) string { var ( - leftBraceIndex = strings.LastIndex(structName, "[") + leftBraceIndex = strings.LastIndex(structName, "[") // for generic, it is faster to start at the end than at the beginning rightBraceIndex = strings.LastIndex(structName, "]") ) - if leftBraceIndex == -1 && rightBraceIndex == -1 { - // no generic type usage. + if leftBraceIndex == -1 || rightBraceIndex == -1 { + // not found '[' or ']' + return structName + } else if leftBraceIndex+1 == rightBraceIndex { + // may be a slice, because generic is '[X]', not '[]' + // to be compatible with bad return parameter type: []XxxRes return structName } return structName[:leftBraceIndex] diff --git a/net/ghttp/ghttp_z_unit_feature_router_strict_test.go b/net/ghttp/ghttp_z_unit_feature_router_strict_test.go index ac041454b79..b3f1479ba9a 100644 --- a/net/ghttp/ghttp_z_unit_feature_router_strict_test.go +++ b/net/ghttp/ghttp_z_unit_feature_router_strict_test.go @@ -323,12 +323,29 @@ func Test_Router_Handler_Strict_WithGeneric(t *testing.T) { }, }, nil }) + s.BindHandler("/test1_slice", func(ctx context.Context, req *TestReq) (res []Test1Res, err error) { + return []Test1Res{ + Test1Res{ + Age: TestGeneric[int]{ + Test: req.Age, + }, + }, + }, nil + }) s.BindHandler("/test2", func(ctx context.Context, req *TestReq) (res *Test2Res, err error) { return &Test2Res{ Test: req.Age, }, nil }) + s.BindHandler("/test2_slice", func(ctx context.Context, req *TestReq) (res []Test2Res, err error) { + return []Test2Res{ + Test2Res{ + Test: req.Age, + }, + }, nil + }) + s.BindHandler("/test3", func(ctx context.Context, req *TestReq) (res *TestGenericRes[int], err error) { return &TestGenericRes[int]{ Test: req.Age, @@ -339,13 +356,24 @@ func Test_Router_Handler_Strict_WithGeneric(t *testing.T) { s.Start() defer s.Shutdown() + s.BindHandler("/test3_slice", func(ctx context.Context, req *TestReq) (res []TestGenericRes[int], err error) { + return []TestGenericRes[int]{ + TestGenericRes[int]{ + Test: req.Age, + }, + }, nil + }) + 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, "/test1?age=1"), `{"code":0,"message":"","data":{"Age":{"Test":1}}}`) + t.Assert(client.GetContent(ctx, "/test1_slice?age=1"), `{"code":0,"message":"","data":[{"Age":{"Test":1}}]}`) t.Assert(client.GetContent(ctx, "/test2?age=2"), `{"code":0,"message":"","data":{"Test":2}}`) + t.Assert(client.GetContent(ctx, "/test2_slice?age=2"), `{"code":0,"message":"","data":[{"Test":2}]}`) t.Assert(client.GetContent(ctx, "/test3?age=3"), `{"code":0,"message":"","data":{"Test":3}}`) + t.Assert(client.GetContent(ctx, "/test3_slice?age=3"), `{"code":0,"message":"","data":[{"Test":3}]}`) }) }