From 0f9f668c6076214680f87e89a88a426cb08228ad Mon Sep 17 00:00:00 2001 From: Seefs <40468931+seefs001@users.noreply.github.com> Date: Fri, 31 Jul 2026 11:17:55 +0800 Subject: [PATCH] feat: support zstd request decompression (#6545) --- go.mod | 2 +- middleware/gzip.go | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fa0632bc..b0642f16 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/jfreymuth/oggvorbis v1.0.5 github.com/jinzhu/copier v0.4.0 github.com/joho/godotenv v1.5.1 + github.com/klauspost/compress v1.18.0 github.com/mewkiz/flac v1.0.13 github.com/nicksnyder/go-i18n/v2 v2.6.1 github.com/pkg/errors v0.9.1 @@ -126,7 +127,6 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/middleware/gzip.go b/middleware/gzip.go index 5e568253..05853e5a 100644 --- a/middleware/gzip.go +++ b/middleware/gzip.go @@ -8,6 +8,7 @@ import ( "github.com/QuantumNous/new-api/constant" "github.com/andybalholm/brotli" "github.com/gin-gonic/gin" + "github.com/klauspost/compress/zstd" ) type readCloser struct { @@ -38,6 +39,7 @@ func DecompressRequestMiddleware() gin.HandlerFunc { wrapMaxBytes := func(body io.ReadCloser) io.ReadCloser { return http.MaxBytesReader(c.Writer, body, maxBytes) } + decompressed := false switch c.GetHeader("Content-Encoding") { case "gzip": @@ -55,7 +57,7 @@ func DecompressRequestMiddleware() gin.HandlerFunc { return origBody.Close() }, }) - c.Request.Header.Del("Content-Encoding") + decompressed = true case "br": reader := brotli.NewReader(origBody) c.Request.Body = wrapMaxBytes(&readCloser{ @@ -64,12 +66,31 @@ func DecompressRequestMiddleware() gin.HandlerFunc { return origBody.Close() }, }) - c.Request.Header.Del("Content-Encoding") + decompressed = true + case "zstd": + reader, err := zstd.NewReader(origBody) + if err != nil { + _ = origBody.Close() + c.AbortWithStatus(http.StatusBadRequest) + return + } + c.Request.Body = wrapMaxBytes(&readCloser{ + Reader: reader, + closeFn: func() error { + reader.Close() + return origBody.Close() + }, + }) + decompressed = true default: // Even for uncompressed bodies, enforce a max size to avoid huge request allocations. c.Request.Body = wrapMaxBytes(origBody) } + if decompressed { + c.Request.Header.Del("Content-Encoding") + } + // Continue processing the request c.Next() }