feat: add compression writer struct and basic methods

This commit is contained in:
2026-07-03 02:57:07 +02:00
parent ba0e5c6d21
commit 89447cbc15

View File

@@ -2,6 +2,8 @@ package server
import ( import (
"bufio" "bufio"
"bytes"
"compress/gzip"
"mime" "mime"
"net" "net"
"net/http" "net/http"
@@ -156,6 +158,9 @@ const (
compressionGzip //nolint:unused compressionGzip //nolint:unused
) )
//nolint:unused
const compressionMinLength = 1024
//nolint:unused //nolint:unused
func acceptsGzip(value string) bool { func acceptsGzip(value string) bool {
wildcard := false wildcard := false
@@ -198,3 +203,94 @@ func canNegotiateCompression(r *http.Request) bool {
} }
return !isCompressedPath(r.URL.Path) return !isCompressedPath(r.URL.Path)
} }
//nolint:unused
type compressionWriter struct {
gin.ResponseWriter
buffer bytes.Buffer
gzip *gzip.Writer
mode compressionMode
status int
wroteBody bool
acceptsGzip bool
}
//nolint:unused
func (w *compressionWriter) WriteHeader(status int) {
if status > 0 && w.mode == compressionUndecided && !w.wroteBody {
w.status = status
}
}
//nolint:unused
func (w *compressionWriter) WriteHeaderNow() {
if w.mode == compressionUndecided {
w.startPlain()
_ = w.flushBuffer()
}
}
//nolint:unused
func (w *compressionWriter) WriteString(data string) (int, error) {
return w.Write([]byte(data))
}
//nolint:unused
func (w *compressionWriter) Status() int {
if w.status != 0 {
return w.status
}
return w.ResponseWriter.Status()
}
//nolint:unused
func (w *compressionWriter) Size() int {
if size := w.ResponseWriter.Size(); size >= 0 {
return size
}
if w.buffer.Len() > 0 {
return w.buffer.Len()
}
return -1
}
//nolint:unused
func (w *compressionWriter) Written() bool {
return w.wroteBody || w.ResponseWriter.Written()
}
//nolint:unused
func (w *compressionWriter) startPlain() {
if w.mode != compressionUndecided {
return
}
w.mode = compressionPlain
w.ResponseWriter.WriteHeader(w.Status())
}
//nolint:unused
func (w *compressionWriter) flushBuffer() error {
if w.buffer.Len() == 0 {
return nil
}
data := w.buffer.Bytes()
w.buffer.Reset()
var err error
if w.mode == compressionGzip {
_, err = w.gzip.Write(data)
} else {
//nolint:staticcheck
_, err = w.ResponseWriter.Write(data)
}
return err
}
//nolint:unused
func (w *compressionWriter) writePlain(data []byte) (int, error) {
w.startPlain()
if err := w.flushBuffer(); err != nil {
return 0, err
}
//nolint:staticcheck
return w.ResponseWriter.Write(data)
}