From 37717fec6906512557d171ec81b498381260a9f3 Mon Sep 17 00:00:00 2001 From: mkelvers Date: Fri, 3 Jul 2026 02:59:28 +0200 Subject: [PATCH] feat: add compression middleware --- internal/server/static_delivery.go | 44 ++++++++++++++---------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/internal/server/static_delivery.go b/internal/server/static_delivery.go index a677079e..fd4ca7a0 100644 --- a/internal/server/static_delivery.go +++ b/internal/server/static_delivery.go @@ -148,19 +148,16 @@ func StaticCacheMiddleware() gin.HandlerFunc { } } -//nolint:unused type compressionMode uint8 const ( - compressionUndecided compressionMode = iota //nolint:unused - compressionPlain //nolint:unused - compressionGzip //nolint:unused + compressionUndecided compressionMode = iota + compressionPlain + compressionGzip ) -//nolint:unused const compressionMinLength = 1024 -//nolint:unused func acceptsGzip(value string) bool { wildcard := false for _, part := range strings.Split(value, ",") { @@ -189,7 +186,6 @@ func acceptsGzip(value string) bool { return wildcard } -//nolint:unused func canNegotiateCompression(r *http.Request) bool { if r.Method == http.MethodHead || r.Header.Get("Range") != "" { return false @@ -203,7 +199,6 @@ func canNegotiateCompression(r *http.Request) bool { return !isCompressedPath(r.URL.Path) } -//nolint:unused type compressionWriter struct { gin.ResponseWriter buffer bytes.Buffer @@ -214,14 +209,12 @@ type compressionWriter struct { 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() @@ -229,12 +222,10 @@ func (w *compressionWriter) WriteHeaderNow() { } } -//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 @@ -242,7 +233,6 @@ func (w *compressionWriter) Status() int { return w.ResponseWriter.Status() } -//nolint:unused func (w *compressionWriter) Size() int { if size := w.ResponseWriter.Size(); size >= 0 { return size @@ -253,12 +243,10 @@ func (w *compressionWriter) Size() int { 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 @@ -267,7 +255,6 @@ func (w *compressionWriter) startPlain() { w.ResponseWriter.WriteHeader(w.Status()) } -//nolint:unused func (w *compressionWriter) flushBuffer() error { if w.buffer.Len() == 0 { return nil @@ -284,7 +271,6 @@ func (w *compressionWriter) flushBuffer() error { return err } -//nolint:unused func (w *compressionWriter) writePlain(data []byte) (int, error) { w.startPlain() if err := w.flushBuffer(); err != nil { @@ -294,7 +280,6 @@ func (w *compressionWriter) writePlain(data []byte) (int, error) { return w.ResponseWriter.Write(data) } -//nolint:unused func (w *compressionWriter) startGzip() { if w.mode != compressionUndecided { return @@ -310,7 +295,6 @@ func (w *compressionWriter) startGzip() { w.gzip = gzip.NewWriter(w.ResponseWriter) } -//nolint:unused func (w *compressionWriter) knownContentLength() (compress, known bool) { contentLength := w.Header().Get("Content-Length") if contentLength == "" { @@ -323,7 +307,6 @@ func (w *compressionWriter) knownContentLength() (compress, known bool) { return length >= compressionMinLength, true } -//nolint:unused func (w *compressionWriter) canCompress(data []byte) bool { status := w.Status() if status < http.StatusOK || status == http.StatusNoContent || status == http.StatusPartialContent || status == http.StatusNotModified { @@ -345,7 +328,6 @@ func (w *compressionWriter) canCompress(data []byte) bool { return w.acceptsGzip } -//nolint:unused func (w *compressionWriter) Write(data []byte) (int, error) { w.wroteBody = true @@ -380,7 +362,6 @@ func (w *compressionWriter) Write(data []byte) (int, error) { return w.gzip.Write(data) } -//nolint:unused func (w *compressionWriter) Flush() { if w.mode == compressionUndecided { if w.canCompress(w.buffer.Bytes()) { @@ -397,7 +378,6 @@ func (w *compressionWriter) Flush() { w.ResponseWriter.Flush() } -//nolint:unused func (w *compressionWriter) finish() error { if w.mode == compressionUndecided { if w.Status() == http.StatusNotModified { @@ -420,3 +400,21 @@ func (w *compressionWriter) finish() error { } return w.gzip.Close() } + +func CompressionMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + if !canNegotiateCompression(c.Request) { + return + } + + writer := &compressionWriter{ + ResponseWriter: c.Writer, + acceptsGzip: acceptsGzip(c.Request.Header.Get("Accept-Encoding")), + } + c.Writer = writer + c.Next() + if err := writer.finish(); err != nil { + _ = c.Error(err) + } + } +}