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