diff --git a/rest/handler/loghandler.go b/rest/handler/loghandler.go index 62f48c56b..e6552fc02 100644 --- a/rest/handler/loghandler.go +++ b/rest/handler/loghandler.go @@ -24,8 +24,9 @@ import ( ) const ( - limitBodyBytes = 1024 - defaultSlowThreshold = time.Millisecond * 500 + limitBodyBytes = 1024 + limitDetailedBodyBytes = 4096 + defaultSlowThreshold = time.Millisecond * 500 ) var slowThreshold = syncx.ForAtomicDuration(defaultSlowThreshold) @@ -94,7 +95,8 @@ func DetailedLogHandler(next http.Handler) http.Handler { lrw := newDetailLoggedResponseWriter(rw, &buf) var dup io.ReadCloser - r.Body, dup = iox.DupReadCloser(r.Body) + // https://github.com/zeromicro/go-zero/issues/3564 + r.Body, dup = iox.LimitDupReadCloser(r.Body, limitDetailedBodyBytes) logs := new(internal.LogCollector) next.ServeHTTP(lrw, r.WithContext(internal.WithLogCollector(r.Context(), logs))) r.Body = dup diff --git a/rest/handler/loghandler_test.go b/rest/handler/loghandler_test.go index b6f81e1d9..85afcfe84 100644 --- a/rest/handler/loghandler_test.go +++ b/rest/handler/loghandler_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/zeromicro/go-zero/core/logx/logtest" "github.com/zeromicro/go-zero/rest/internal" "github.com/zeromicro/go-zero/rest/internal/response" ) @@ -86,6 +87,26 @@ func TestLogHandlerSlow(t *testing.T) { assert.Equal(t, http.StatusOK, resp.Code) } } + +func TestDetailedLogHandler_LargeBody(t *testing.T) { + lbuf := logtest.NewCollector(t) + + var buf bytes.Buffer + for i := 0; i < limitDetailedBodyBytes<<2; i++ { + buf.WriteByte('a') + } + + req := httptest.NewRequest(http.MethodPost, "http://localhost", &buf) + h := DetailedLogHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(io.Discard, r.Body) + })) + resp := httptest.NewRecorder() + h.ServeHTTP(resp, req) + + // extra 200 for the length of POST request headers + assert.True(t, len(lbuf.Content()) < limitDetailedBodyBytes+200) +} + func TestDetailedLogHandler_Hijack(t *testing.T) { resp := httptest.NewRecorder() writer := &detailLoggedResponseWriter{ @@ -111,6 +132,7 @@ func TestDetailedLogHandler_Hijack(t *testing.T) { _, _, _ = writer.Hijack() }) } + func TestSetSlowThreshold(t *testing.T) { assert.Equal(t, defaultSlowThreshold, slowThreshold.Load()) SetSlowThreshold(time.Second)