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
+31 -36
View File
@@ -4,7 +4,6 @@ import (
"compress/gzip"
"embed"
"fmt"
"io"
"io/fs"
"log"
"mime"
@@ -370,54 +369,50 @@ func gzipMiddleware() gin.HandlerFunc {
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()
if gw, ok := c.Writer.(*gzipWriter); ok {
contentType := c.Writer.Header().Get("Content-Type")
if !isCompressibleContentType(contentType) {
gw.ResponseWriter = &noopWriter{}
gw.Writer.Close()
c.Writer = gw.ResponseWriter
return
}
gw.Writer.Close()
if gw.compressed {
gw.writer.Close()
}
}
}
type gzipWriter struct {
type gzipResponseWriter struct {
gin.ResponseWriter
Writer *gzip.Writer
writer *gzip.Writer
compressed bool
}
func (w *gzipWriter) Write(data []byte) (int, error) {
contentType := w.Header().Get("Content-Type")
if !isCompressibleContentType(contentType) {
return w.ResponseWriter.Write(data)
func (w *gzipResponseWriter) Write(data []byte) (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.compressed = true
}
}
if w.Header().Get("Content-Encoding") == "" {
w.Header().Set("Content-Encoding", "gzip")
if w.compressed {
return w.writer.Write(data)
}
return w.Writer.Write(data)
return w.ResponseWriter.Write(data)
}
func (w *gzipWriter) WriteString(s string) (int, error) {
contentType := w.Header().Get("Content-Type")
if !isCompressibleContentType(contentType) {
return w.ResponseWriter.WriteString(s)
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.compressed = true
}
}
if w.Header().Get("Content-Encoding") == "" {
w.Header().Set("Content-Encoding", "gzip")
if w.compressed {
return w.writer.Write([]byte(s))
}
return io.WriteString(w.Writer, s)
}
type noopWriter struct {
gin.ResponseWriter
}
func (w *noopWriter) Write(data []byte) (int, error) {
return len(data), nil
return w.ResponseWriter.WriteString(s)
}