mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
remove returning error of Write* functions for ghttp.Server; add UT cases for gclient.Client.DoRequestObj
This commit is contained in:
@ -11,13 +11,14 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/debug/gdebug"
|
||||
"github.com/gogf/gf/v2/net/gclient"
|
||||
"github.com/gogf/gf/v2/net/gtcp"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
|
||||
78
net/gclient/gclient_z_unit_feature_trace_test.go
Normal file
78
net/gclient/gclient_z_unit_feature_trace_test.go
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gclient_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/internal/tracing"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/net/gtcp"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"go.opentelemetry.io/otel"
|
||||
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type CustomProvider struct {
|
||||
*sdkTrace.TracerProvider
|
||||
}
|
||||
|
||||
func NewCustomProvider() *CustomProvider {
|
||||
return &CustomProvider{
|
||||
TracerProvider: sdkTrace.NewTracerProvider(
|
||||
sdkTrace.WithIDGenerator(NewCustomIDGenerator()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type CustomIDGenerator struct{}
|
||||
|
||||
func NewCustomIDGenerator() *CustomIDGenerator {
|
||||
return &CustomIDGenerator{}
|
||||
}
|
||||
|
||||
func (id *CustomIDGenerator) NewIDs(ctx context.Context) (traceID trace.TraceID, spanID trace.SpanID) {
|
||||
return tracing.NewIDs()
|
||||
}
|
||||
|
||||
func (id *CustomIDGenerator) NewSpanID(ctx context.Context, traceID trace.TraceID) (spanID trace.SpanID) {
|
||||
return tracing.NewSpanID()
|
||||
}
|
||||
|
||||
func TestClient_CustomProvider(t *testing.T) {
|
||||
provider := otel.GetTracerProvider()
|
||||
defer otel.SetTracerProvider(provider)
|
||||
|
||||
otel.SetTracerProvider(NewCustomProvider())
|
||||
|
||||
p, _ := gtcp.GetFreePort()
|
||||
s := g.Server(p)
|
||||
s.BindHandler("/hello", func(r *ghttp.Request) {
|
||||
r.Response.WriteHeader(200)
|
||||
r.Response.WriteJson(g.Map{"field": "test_for_response_body"})
|
||||
})
|
||||
s.SetPort(p)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
c := g.Client()
|
||||
url := fmt.Sprintf("127.0.0.1:%d/hello", p)
|
||||
resp, err := c.DoRequest(ctx, http.MethodGet, url)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(resp, nil)
|
||||
t.Assert(resp.ReadAllString(), "{\"field\":\"test_for_response_body\"}")
|
||||
})
|
||||
}
|
||||
78
net/gclient/gclient_z_unit_request_obj_test.go
Normal file
78
net/gclient/gclient_z_unit_request_obj_test.go
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gclient_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/net/gtcp"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
)
|
||||
|
||||
func Test_Client_DoRequestObj(t *testing.T) {
|
||||
type UserCreateReq struct {
|
||||
g.Meta `path:"/user" method:"post"`
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
type UserCreateRes struct {
|
||||
Id int
|
||||
}
|
||||
type UserQueryReq struct {
|
||||
g.Meta `path:"/user" method:"get"`
|
||||
}
|
||||
type UserQueryRes struct {
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
p, _ := gtcp.GetFreePort()
|
||||
s := g.Server(p)
|
||||
s.Group("/user", func(group *ghttp.RouterGroup) {
|
||||
group.GET("/", func(r *ghttp.Request) {
|
||||
r.Response.WriteJson(g.Map{"id": 1, "name": "john"})
|
||||
})
|
||||
group.POST("/", func(r *ghttp.Request) {
|
||||
r.Response.WriteJson(g.Map{"id": r.Get("Id")})
|
||||
})
|
||||
})
|
||||
s.SetPort(p)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d", p)
|
||||
client := g.Client().SetPrefix(url).ContentJson()
|
||||
var (
|
||||
createRes *UserCreateRes
|
||||
createReq = UserCreateReq{
|
||||
Id: 1,
|
||||
Name: "john",
|
||||
}
|
||||
)
|
||||
err := client.DoRequestObj(ctx, createReq, &createRes)
|
||||
t.AssertNil(err)
|
||||
t.Assert(createRes.Id, 1)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d", p)
|
||||
client := g.Client().SetPrefix(url).ContentJson()
|
||||
var (
|
||||
queryRes *UserQueryRes
|
||||
queryReq = UserQueryReq{}
|
||||
)
|
||||
err := client.DoRequestObj(ctx, queryReq, &queryRes)
|
||||
t.AssertNil(err)
|
||||
t.Assert(queryRes.Id, 1)
|
||||
t.Assert(queryRes.Name, "john")
|
||||
})
|
||||
}
|
||||
@ -11,16 +11,13 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/debug/gdebug"
|
||||
"github.com/gogf/gf/v2/internal/tracing"
|
||||
"go.opentelemetry.io/otel"
|
||||
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/debug/gdebug"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/gclient"
|
||||
@ -643,58 +640,3 @@ func TestClient_RequestVar(t *testing.T) {
|
||||
t.AssertNE(users, nil)
|
||||
})
|
||||
}
|
||||
|
||||
type CustomProvider struct {
|
||||
*sdkTrace.TracerProvider
|
||||
}
|
||||
|
||||
func NewCustomProvider() *CustomProvider {
|
||||
return &CustomProvider{
|
||||
TracerProvider: sdkTrace.NewTracerProvider(
|
||||
sdkTrace.WithIDGenerator(NewCustomIDGenerator()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type CustomIDGenerator struct{}
|
||||
|
||||
func NewCustomIDGenerator() *CustomIDGenerator {
|
||||
return &CustomIDGenerator{}
|
||||
}
|
||||
|
||||
func (id *CustomIDGenerator) NewIDs(ctx context.Context) (traceID trace.TraceID, spanID trace.SpanID) {
|
||||
return tracing.NewIDs()
|
||||
}
|
||||
|
||||
func (id *CustomIDGenerator) NewSpanID(ctx context.Context, traceID trace.TraceID) (spanID trace.SpanID) {
|
||||
return tracing.NewSpanID()
|
||||
}
|
||||
|
||||
func TestClient_CustomProvider(t *testing.T) {
|
||||
provider := otel.GetTracerProvider()
|
||||
defer otel.SetTracerProvider(provider)
|
||||
|
||||
otel.SetTracerProvider(NewCustomProvider())
|
||||
|
||||
p, _ := gtcp.GetFreePort()
|
||||
s := g.Server(p)
|
||||
s.BindHandler("/hello", func(r *ghttp.Request) {
|
||||
r.Response.WriteHeader(200)
|
||||
r.Response.WriteJson(g.Map{"field": "test_for_response_body"})
|
||||
})
|
||||
s.SetPort(p)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
c := g.Client()
|
||||
url := fmt.Sprintf("127.0.0.1:%d/hello", p)
|
||||
resp, err := c.DoRequest(ctx, http.MethodGet, url)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(resp, nil)
|
||||
t.Assert(resp.ReadAllString(), "{\"field\":\"test_for_response_body\"}")
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
)
|
||||
|
||||
// DefaultHandlerResponse is the default implementation of HandlerResponse.
|
||||
@ -32,7 +31,6 @@ func MiddlewareHandlerResponse(r *Request) {
|
||||
|
||||
var (
|
||||
msg string
|
||||
ctx = r.Context()
|
||||
err = r.GetError()
|
||||
res = r.GetHandlerResponse()
|
||||
code = gerror.Code(err)
|
||||
@ -55,12 +53,9 @@ func MiddlewareHandlerResponse(r *Request) {
|
||||
} else {
|
||||
code = gcode.CodeOK
|
||||
}
|
||||
internalErr := r.Response.WriteJson(DefaultHandlerResponse{
|
||||
r.Response.WriteJson(DefaultHandlerResponse{
|
||||
Code: code.Code(),
|
||||
Message: msg,
|
||||
Data: res,
|
||||
})
|
||||
if internalErr != nil {
|
||||
intlog.Errorf(ctx, `%+v`, internalErr)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
@ -102,48 +103,42 @@ func (r *Response) WriteflnExit(format string, params ...interface{}) {
|
||||
}
|
||||
|
||||
// WriteJson writes `content` to the response with JSON format.
|
||||
func (r *Response) WriteJson(content interface{}) error {
|
||||
func (r *Response) WriteJson(content interface{}) {
|
||||
r.Header().Set("Content-Type", contentTypeJson)
|
||||
// If given string/[]byte, response it directly to the client.
|
||||
switch content.(type) {
|
||||
case string, []byte:
|
||||
r.Write(gconv.String(content))
|
||||
return nil
|
||||
}
|
||||
// Else use json.Marshal function to encode the parameter.
|
||||
if b, err := json.Marshal(content); err != nil {
|
||||
return err
|
||||
panic(gerror.Wrap(err, `WriteJson failed`))
|
||||
} else {
|
||||
r.Write(b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteJsonExit writes `content` to the response with JSON format and exits executing
|
||||
// of current handler if success. The "Exit" feature is commonly used to replace usage of
|
||||
// return statements in the handler, for convenience.
|
||||
func (r *Response) WriteJsonExit(content interface{}) error {
|
||||
if err := r.WriteJson(content); err != nil {
|
||||
return err
|
||||
}
|
||||
func (r *Response) WriteJsonExit(content interface{}) {
|
||||
r.WriteJson(content)
|
||||
r.Request.Exit()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteJsonP writes `content` to the response with JSONP format.
|
||||
//
|
||||
// Note that there should be a "callback" parameter in the request for JSONP format.
|
||||
func (r *Response) WriteJsonP(content interface{}) error {
|
||||
func (r *Response) WriteJsonP(content interface{}) {
|
||||
r.Header().Set("Content-Type", contentTypeJson)
|
||||
// If given string/[]byte, response it directly to client.
|
||||
switch content.(type) {
|
||||
case string, []byte:
|
||||
r.Write(gconv.String(content))
|
||||
return nil
|
||||
}
|
||||
// Else use json.Marshal function to encode the parameter.
|
||||
if b, err := json.Marshal(content); err != nil {
|
||||
return err
|
||||
panic(gerror.Wrap(err, `WriteJsonP failed`))
|
||||
} else {
|
||||
// r.Header().Set("Content-Type", "application/json")
|
||||
if callback := r.Request.Get("callback").String(); callback != "" {
|
||||
@ -156,7 +151,6 @@ func (r *Response) WriteJsonP(content interface{}) error {
|
||||
r.Write(b)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteJsonPExit writes `content` to the response with JSONP format and exits executing
|
||||
@ -164,40 +158,32 @@ func (r *Response) WriteJsonP(content interface{}) error {
|
||||
// return statements in the handler, for convenience.
|
||||
//
|
||||
// Note that there should be a "callback" parameter in the request for JSONP format.
|
||||
func (r *Response) WriteJsonPExit(content interface{}) error {
|
||||
if err := r.WriteJsonP(content); err != nil {
|
||||
return err
|
||||
}
|
||||
func (r *Response) WriteJsonPExit(content interface{}) {
|
||||
r.WriteJsonP(content)
|
||||
r.Request.Exit()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteXml writes `content` to the response with XML format.
|
||||
func (r *Response) WriteXml(content interface{}, rootTag ...string) error {
|
||||
func (r *Response) WriteXml(content interface{}, rootTag ...string) {
|
||||
r.Header().Set("Content-Type", contentTypeXml)
|
||||
// If given string/[]byte, response it directly to clients.
|
||||
switch content.(type) {
|
||||
case string, []byte:
|
||||
r.Write(gconv.String(content))
|
||||
return nil
|
||||
}
|
||||
if b, err := gjson.New(content).ToXml(rootTag...); err != nil {
|
||||
return err
|
||||
panic(gerror.Wrap(err, `WriteXml failed`))
|
||||
} else {
|
||||
r.Write(b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteXmlExit writes `content` to the response with XML format and exits executing
|
||||
// of current handler if success. The "Exit" feature is commonly used to replace usage
|
||||
// of return statements in the handler, for convenience.
|
||||
func (r *Response) WriteXmlExit(content interface{}, rootTag ...string) error {
|
||||
if err := r.WriteXml(content, rootTag...); err != nil {
|
||||
return err
|
||||
}
|
||||
func (r *Response) WriteXmlExit(content interface{}, rootTag ...string) {
|
||||
r.WriteXml(content, rootTag...)
|
||||
r.Request.Exit()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteStatus writes HTTP `status` and `content` to the response.
|
||||
|
||||
@ -9,7 +9,6 @@ package ghttp
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
"github.com/gogf/gf/v2/net/goai"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
)
|
||||
@ -48,16 +47,9 @@ func (s *Server) initOpenApi() {
|
||||
|
||||
// openapiSpec is a build-in handler automatic producing for openapi specification json file.
|
||||
func (s *Server) openapiSpec(r *Request) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
if s.config.OpenApiPath == "" {
|
||||
r.Response.Write(`OpenApi specification file producing is disabled`)
|
||||
} else {
|
||||
err = r.Response.WriteJson(s.openapi)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
intlog.Errorf(r.Context(), `%+v`, err)
|
||||
r.Response.WriteJson(s.openapi)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user