fix: 修复gzip中间件ERR_INCOMPLETE_CHUNKED_ENCODING

- 首次Write时删除Content-Length头(压缩后大小不同)
- 非压缩类型直接透传,不经过gzip writer
- 移除有问题的noopWriter方案
This commit is contained in:
2026-05-05 14:58:47 +08:00
parent d584b578f1
commit 6c99256e71
+29 -34
View File
@@ -4,7 +4,6 @@ import (
"compress/gzip" "compress/gzip"
"embed" "embed"
"fmt" "fmt"
"io"
"io/fs" "io/fs"
"log" "log"
"mime" "mime"
@@ -370,54 +369,50 @@ func gzipMiddleware() gin.HandlerFunc {
c.Header("Vary", "Accept-Encoding") c.Header("Vary", "Accept-Encoding")
c.Writer = &gzipWriter{Writer: gzip.NewWriter(c.Writer), ResponseWriter: c.Writer} gw := &gzipResponseWriter{ResponseWriter: c.Writer, writer: gzip.NewWriter(c.Writer)}
c.Writer = gw
c.Next() c.Next()
if gw, ok := c.Writer.(*gzipWriter); ok { if gw.compressed {
contentType := c.Writer.Header().Get("Content-Type") gw.writer.Close()
if !isCompressibleContentType(contentType) {
gw.ResponseWriter = &noopWriter{}
gw.Writer.Close()
c.Writer = gw.ResponseWriter
return
}
gw.Writer.Close()
} }
} }
} }
type gzipWriter struct { type gzipResponseWriter struct {
gin.ResponseWriter gin.ResponseWriter
Writer *gzip.Writer writer *gzip.Writer
compressed bool
} }
func (w *gzipWriter) Write(data []byte) (int, error) { func (w *gzipResponseWriter) Write(data []byte) (int, error) {
if !w.compressed {
contentType := w.Header().Get("Content-Type") contentType := w.Header().Get("Content-Type")
if !isCompressibleContentType(contentType) { if isCompressibleContentType(contentType) {
w.Header().Del("Content-Length")
w.Header().Set("Content-Encoding", "gzip")
w.compressed = true
}
}
if w.compressed {
return w.writer.Write(data)
}
return w.ResponseWriter.Write(data) return w.ResponseWriter.Write(data)
} }
if w.Header().Get("Content-Encoding") == "" {
func (w *gzipResponseWriter) WriteString(s string) (int, error) {
if !w.compressed {
contentType := w.Header().Get("Content-Type")
if isCompressibleContentType(contentType) {
w.Header().Del("Content-Length")
w.Header().Set("Content-Encoding", "gzip") w.Header().Set("Content-Encoding", "gzip")
w.compressed = true
} }
return w.Writer.Write(data)
} }
func (w *gzipWriter) WriteString(s string) (int, error) { if w.compressed {
contentType := w.Header().Get("Content-Type") return w.writer.Write([]byte(s))
if !isCompressibleContentType(contentType) { }
return w.ResponseWriter.WriteString(s) return w.ResponseWriter.WriteString(s)
} }
if w.Header().Get("Content-Encoding") == "" {
w.Header().Set("Content-Encoding", "gzip")
}
return io.WriteString(w.Writer, s)
}
type noopWriter struct {
gin.ResponseWriter
}
func (w *noopWriter) Write(data []byte) (int, error) {
return len(data), nil
}