resolve response is gzip in internalMiddlewareServerTracing (#3055)

This commit is contained in:
ltp217 2023-10-17 20:35:56 +08:00 committed by GitHub
parent 7c92c2f7e8
commit 34e522306d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 0 deletions

View File

@ -7,9 +7,12 @@
package ghttp
import (
"compress/gzip"
"context"
"fmt"
"io"
"net/http"
"strings"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
@ -110,9 +113,34 @@ func internalMiddlewareServerTracing(r *Request) {
}
// Response content logging.
var resBodyContent = gstr.StrLimit(r.Response.BufferString(), gtrace.MaxContentLogSize(), "...")
if gzipAccepted(r.Response.Header()) {
reader, err := gzip.NewReader(strings.NewReader(r.Response.BufferString()))
if err != nil {
span.SetStatus(codes.Error, fmt.Sprintf(`read gzip response err:%+v`, err))
}
defer reader.Close()
uncompressed, err := io.ReadAll(reader)
if err != nil {
span.SetStatus(codes.Error, fmt.Sprintf(`get uncompress value err:%+v`, err))
}
resBodyContent = gstr.StrLimit(string(uncompressed), gtrace.MaxContentLogSize(), "...")
}
span.AddEvent(tracingEventHttpResponse, trace.WithAttributes(
attribute.String(tracingEventHttpResponseHeaders, gconv.String(httputil.HeaderToMap(r.Response.Header()))),
attribute.String(tracingEventHttpResponseBody, resBodyContent),
))
}
// gzipAccepted returns whether the client will accept gzip-encoded content.
func gzipAccepted(header http.Header) bool {
a := header.Get("Content-Encoding")
parts := strings.Split(a, ",")
for _, part := range parts {
part = strings.TrimSpace(part)
if part == "gzip" || strings.HasPrefix(part, "gzip;") {
return true
}
}
return false
}

View File

@ -7,8 +7,10 @@
package ghttp_test
import (
"compress/gzip"
"fmt"
"net/http"
"strings"
"testing"
"time"
@ -17,6 +19,8 @@ import (
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/guid"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
)
func Test_BindMiddleware_Basic1(t *testing.T) {
@ -736,3 +740,43 @@ func Test_MiddlewareHandlerResponse(t *testing.T) {
t.Assert(rsp.StatusCode, http.StatusInternalServerError)
})
}
func Test_MiddlewareHandlerGzipResponse(t *testing.T) {
tp := testTracerProvider{}
otel.SetTracerProvider(&tp)
s := g.Server(guid.S())
s.Group("/", func(group *ghttp.RouterGroup) {
group.GET("/default", func(r *ghttp.Request) {
var buffer strings.Builder
gzipWriter := gzip.NewWriter(&buffer)
defer gzipWriter.Close()
_, _ = gzipWriter.Write([]byte("hello"))
// 设置响应头,表明内容使用 gzip 压缩
r.Response.Header().Set("Content-Encoding", "gzip")
r.Response.Header().Set("Content-Encoding", "gzip")
r.Response.Header().Set("Content-Type", "text/plain")
r.Response.Header().Set("Content-Length", fmt.Sprint(buffer.Len()))
// 写入压缩后的内容
r.Response.Write(buffer.String())
})
})
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, "/default")
t.AssertNil(err)
t.Assert(rsp.StatusCode, http.StatusOK)
})
}
type testTracerProvider struct{}
var _ trace.TracerProvider = &testTracerProvider{}
func (*testTracerProvider) Tracer(_ string, _ ...trace.TracerOption) trace.Tracer {
return trace.NewNoopTracerProvider().Tracer("")
}