fix(net/ghttp): skip common response body in common response handler for streaming content types (#3762)

This commit is contained in:
wwwfeng
2024-09-12 17:50:43 +08:00
committed by GitHub
parent 9b318bb57f
commit 3d63ebfe81
2 changed files with 63 additions and 0 deletions

View File

@ -7,6 +7,7 @@
package ghttp
import (
"mime"
"net/http"
"github.com/gogf/gf/v2/errors/gcode"
@ -20,6 +21,17 @@ type DefaultHandlerResponse struct {
Data interface{} `json:"data" dc:"Result data for certain request according API definition"`
}
const (
contentTypeEventStream = "text/event-stream"
contentTypeOctetStream = "application/octet-stream"
contentTypeMixedReplace = "multipart/x-mixed-replace"
)
var (
// streamContentType is the content types for stream response.
streamContentType = []string{contentTypeEventStream, contentTypeOctetStream, contentTypeMixedReplace}
)
// MiddlewareHandlerResponse is the default middleware handling handler response object and its error.
func MiddlewareHandlerResponse(r *Request) {
r.Middleware.Next()
@ -29,6 +41,14 @@ func MiddlewareHandlerResponse(r *Request) {
return
}
// It does not output common response content if it is stream response.
mediaType, _, _ := mime.ParseMediaType(r.Response.Header().Get("Content-Type"))
for _, ct := range streamContentType {
if mediaType == ct {
return
}
}
var (
msg string
err = r.GetError()

View File

@ -772,6 +772,49 @@ func Test_MiddlewareHandlerGzipResponse(t *testing.T) {
})
}
func Test_MiddlewareHandlerStreamResponse(t *testing.T) {
s := g.Server(guid.S())
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.GET("/stream/event", func(r *ghttp.Request) {
r.Response.Header().Set("Content-Type", "text/event-stream")
})
group.GET("/stream/octet", func(r *ghttp.Request) {
r.Response.Header().Set("Content-Type", "application/octet-stream")
})
group.GET("/stream/mixed", func(r *ghttp.Request) {
r.Response.Header().Set("Content-Type", "multipart/x-mixed-replace")
})
})
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()))
rsp, err := client.Get(ctx, "/stream/event")
t.AssertNil(err)
t.Assert(rsp.StatusCode, http.StatusOK)
t.Assert(rsp.ReadAllString(), "")
rsp, err = client.Get(ctx, "/stream/octet")
t.AssertNil(err)
t.Assert(rsp.StatusCode, http.StatusOK)
t.Assert(rsp.ReadAllString(), "")
rsp, err = client.Get(ctx, "/stream/mixed")
t.AssertNil(err)
t.Assert(rsp.StatusCode, http.StatusOK)
t.Assert(rsp.ReadAllString(), "")
})
}
type testTracerProvider struct{}
var _ trace.TracerProvider = &testTracerProvider{}