radchat/server/middleware.go
2025-09-04 19:42:02 -05:00

56 lines
1.4 KiB
Go

package server
// HTTP middleware for gzip compression and cache control.
import (
"compress/gzip"
"io"
"net/http"
"strings"
)
// MiddlewareChain composes multiple middleware into a single http.Handler wrapper.
func MiddlewareChain(middlewares ...func(http.Handler) http.Handler) func(http.Handler) http.Handler {
return func(final http.Handler) http.Handler {
for _, middleware := range middlewares {
final = middleware(final)
}
return final
}
}
// gzipResponseWriter wraps http.ResponseWriter to write gzipped data.
type gzipResponseWriter struct {
http.ResponseWriter
io.Writer
}
func (g *gzipResponseWriter) Write(data []byte) (int, error) {
return g.Writer.Write(data)
}
func CacheDisableMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Set("Pragma", "no-cache")
w.Header().Set("Expires", "0")
next.ServeHTTP(w, r)
})
}
func GzipMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
next.ServeHTTP(w, r)
return
}
gz := gzip.NewWriter(w)
defer func(gz *gzip.Writer) {
_ = gz.Close()
}(gz)
w.Header().Set("Content-Encoding", "gzip")
next.ServeHTTP(&gzipResponseWriter{ResponseWriter: w, Writer: gz}, r)
})
}