fix: 修复gzip中间件ERR_INCOMPLETE_CHUNKED_ENCODING
- 首次Write时删除Content-Length头(压缩后大小不同) - 非压缩类型直接透传,不经过gzip writer - 移除有问题的noopWriter方案
This commit is contained in:
+31
-36
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user