From 918b1a506a6a91c969a66568ddbd1c9e5e0c1568 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Thu, 11 Jun 2026 03:17:46 +0900 Subject: [PATCH] fix(middleware): reset ContentLength after gzip decompression --- middleware/body_limit_test.go | 25 +++++++++++++++++++++++++ middleware/decompress.go | 1 + middleware/decompress_test.go | 4 ++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/middleware/body_limit_test.go b/middleware/body_limit_test.go index 5529f5d84..68d904da8 100644 --- a/middleware/body_limit_test.go +++ b/middleware/body_limit_test.go @@ -68,6 +68,31 @@ func TestBodyLimitConfig_ToMiddleware(t *testing.T) { assert.Equal(t, http.StatusRequestEntityTooLarge, he.StatusCode()) } +func TestBodyLimitAfterDecompressUsesDecodedSize(t *testing.T) { + e := echo.New() + body := "ok" + gz, err := gzipString(body) + assert.NoError(t, err) + assert.Greater(t, len(gz), len(body)) + + req := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(gz)) + req.Header.Set(echo.HeaderContentEncoding, GZIPEncoding) + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + err = Decompress()(BodyLimit(int64(len(body)))(func(c *echo.Context) error { + body, readErr := io.ReadAll(c.Request().Body) + if readErr != nil { + return readErr + } + return c.String(http.StatusOK, string(body)) + }))(c) + + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, rec.Code) + assert.Equal(t, body, rec.Body.String()) +} + func TestBodyLimitReader(t *testing.T) { hw := []byte("Hello, World!") diff --git a/middleware/decompress.go b/middleware/decompress.go index a384af2ea..501ee6c5b 100644 --- a/middleware/decompress.go +++ b/middleware/decompress.go @@ -120,6 +120,7 @@ func (config DecompressConfig) ToMiddleware() (echo.MiddlewareFunc, error) { // -1 means explicitly unlimited (not recommended) c.Request().Body = gr } + c.Request().ContentLength = -1 return next(c) } diff --git a/middleware/decompress_test.go b/middleware/decompress_test.go index 1823e94bb..8dc3057ba 100644 --- a/middleware/decompress_test.go +++ b/middleware/decompress_test.go @@ -215,8 +215,6 @@ func BenchmarkDecompress(b *testing.B) { e := echo.New() body := `{"name": "echo"}` gz, _ := gzipString(body) - req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(string(gz))) - req.Header.Set(echo.HeaderContentEncoding, GZIPEncoding) h := Decompress()(func(c *echo.Context) error { c.Response().Write([]byte(body)) // For Content-Type sniffing @@ -228,6 +226,8 @@ func BenchmarkDecompress(b *testing.B) { for i := 0; i < b.N; i++ { // Decompress + req := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(gz)) + req.Header.Set(echo.HeaderContentEncoding, GZIPEncoding) rec := httptest.NewRecorder() c := e.NewContext(req, rec) h(c)