diff --git a/encoding/gjson/gjson.go b/encoding/gjson/gjson.go index 23e685fa3..e1f512067 100644 --- a/encoding/gjson/gjson.go +++ b/encoding/gjson/gjson.go @@ -40,7 +40,7 @@ const ( // Json is the customized JSON struct. type Json struct { - mu *rwmutex.RWMutex + mu rwmutex.RWMutex p *interface{} // Pointer for hierarchical data access, it's the root of data in default. c byte // Char separator('.' in default). vc bool // Violence Check(false in default), which is used to access data when the hierarchical data key contains separator char. @@ -358,6 +358,9 @@ func (j *Json) setPointerWithValue(pointer *interface{}, key string, value inter // getPointerByPattern returns a pointer to the value by specified `pattern`. func (j *Json) getPointerByPattern(pattern string) *interface{} { + if j.p == nil { + return nil + } if j.vc { return j.getPointerByPatternWithViolenceCheck(pattern) } else { diff --git a/encoding/gjson/gjson_api.go b/encoding/gjson/gjson_api.go index e3773f121..5accf4606 100644 --- a/encoding/gjson/gjson_api.go +++ b/encoding/gjson/gjson_api.go @@ -22,6 +22,9 @@ func (j *Json) Interface() interface{} { } j.mu.RLock() defer j.mu.RUnlock() + if j.p == nil { + return nil + } return *(j.p) } diff --git a/encoding/gjson/gjson_api_new_load.go b/encoding/gjson/gjson_api_new_load.go index 5d6dfd910..ec45f55df 100644 --- a/encoding/gjson/gjson_api_new_load.go +++ b/encoding/gjson/gjson_api_new_load.go @@ -95,7 +95,7 @@ func NewWithOptions(data interface{}, options Options) *Json { vc: false, } } - j.mu = rwmutex.New(options.Safe) + j.mu = rwmutex.Create(options.Safe) return j } diff --git a/encoding/gjson/gjson_implements.go b/encoding/gjson/gjson_implements.go index 2e9b547dc..cde121924 100644 --- a/encoding/gjson/gjson_implements.go +++ b/encoding/gjson/gjson_implements.go @@ -37,10 +37,16 @@ func (j *Json) UnmarshalValue(value interface{}) error { // MapStrAny implements interface function MapStrAny(). func (j *Json) MapStrAny() map[string]interface{} { + if j == nil { + return nil + } return j.Map() } // Interfaces implements interface function Interfaces(). func (j *Json) Interfaces() []interface{} { + if j == nil { + return nil + } return j.Array() } diff --git a/net/ghttp/ghttp_server_graceful.go b/net/ghttp/ghttp_server_graceful.go index 073f9f867..306b8e38b 100644 --- a/net/ghttp/ghttp_server_graceful.go +++ b/net/ghttp/ghttp_server_graceful.go @@ -198,13 +198,13 @@ func (s *gracefulServer) getNetListener() (net.Listener, error) { f := os.NewFile(s.fd, "") ln, err = net.FileListener(f) if err != nil { - err = gerror.Wrapf(err, "%d: net.FileListener failed", gproc.Pid()) + err = gerror.Wrap(err, "net.FileListener failed") return nil, err } } else { ln, err = net.Listen("tcp", s.httpServer.Addr) if err != nil { - err = gerror.Wrapf(err, "%d: net.Listen failed", gproc.Pid()) + err = gerror.Wrapf(err, `net.Listen address "%s" failed`, s.httpServer.Addr) } } return ln, err diff --git a/net/ghttp/ghttp_z_unit_issue_test.go b/net/ghttp/ghttp_z_unit_issue_test.go index 0e5a1ca5f..0eefcef8b 100644 --- a/net/ghttp/ghttp_z_unit_issue_test.go +++ b/net/ghttp/ghttp_z_unit_issue_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/test/gtest" @@ -223,3 +224,43 @@ func Test_Issue662(t *testing.T) { t.Assert(c.PostContent(ctx, "/boot/test", dataReq), `{"code":51,"message":"The code is required","data":null}`) }) } + +type DemoReq struct { + g.Meta `path:"/demo" method:"post"` + Data *gjson.Json +} + +type DemoRes struct { + Content string +} + +type Api struct{} + +func (a *Api) Demo(ctx context.Context, req *DemoReq) (res *DemoRes, err error) { + return &DemoRes{ + Content: req.Data.MustToJsonString(), + }, err +} + +var api = Api{} + +// https://github.com/gogf/gf/issues/2172 +func Test_Issue2172(t *testing.T) { + s := g.Server(guid.S()) + s.Use(ghttp.MiddlewareHandlerResponse) + s.Group("/", func(group *ghttp.RouterGroup) { + group.Bind(api) + }) + s.SetPort(8888) + s.SetDumpRouterMap(false) + s.Start() + defer s.Shutdown() + time.Sleep(1000 * time.Millisecond) + + gtest.C(t, func(t *gtest.T) { + c := g.Client() + c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort())) + dataReq := `{"data":{"asd":1}}` + t.Assert(c.PostContent(ctx, "/demo", dataReq), `{"code":0,"message":"","data":{"Content":"{\"asd\":1}"}}`) + }) +}