Files
fiber/middleware/compress/compress.go
zeekayandHanzo Dev f60e254acb module: rename to github.com/zap-proto/fiber/v3
Fork of gofiber/fiber v3 based on the v3.2.0 tag. Rewrites all self-imports
github.com/gofiber/fiber/v3 -> github.com/zap-proto/fiber/v3. Upstream
gofiber/schema and gofiber/utils/v2 dependencies are left untouched.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-10 12:49:35 -07:00

126 lines
2.9 KiB
Go

package compress
import (
"strings"
"github.com/zap-proto/fiber/v3"
"github.com/zap-proto/fiber/v3/middleware/etag"
"github.com/gofiber/utils/v2"
"github.com/valyala/fasthttp"
)
func hasToken(header, token string) bool {
for part := range strings.SplitSeq(header, ",") {
if utils.EqualFold(utils.TrimSpace(part), token) {
return true
}
}
return false
}
func shouldSkip(c fiber.Ctx) bool {
if c.Method() == fiber.MethodHead {
return true
}
status := c.Response().StatusCode()
if status < 200 ||
status == fiber.StatusNoContent ||
status == fiber.StatusResetContent ||
status == fiber.StatusNotModified ||
status == fiber.StatusPartialContent ||
len(c.Response().Body()) == 0 ||
c.Get(fiber.HeaderRange) != "" ||
hasToken(c.Get(fiber.HeaderCacheControl), "no-transform") ||
hasToken(c.GetRespHeader(fiber.HeaderCacheControl), "no-transform") {
return true
}
return false
}
func appendVaryAcceptEncoding(c fiber.Ctx) {
vary := c.GetRespHeader(fiber.HeaderVary)
if vary == "" {
c.Set(fiber.HeaderVary, fiber.HeaderAcceptEncoding)
return
}
if hasToken(vary, "*") || hasToken(vary, fiber.HeaderAcceptEncoding) {
return
}
c.Set(fiber.HeaderVary, vary+", "+fiber.HeaderAcceptEncoding)
}
// New creates a new middleware handler
func New(config ...Config) fiber.Handler {
// Set default config
cfg := configDefault(config...)
// Setup request handlers
var (
fctx = func(_ *fasthttp.RequestCtx) {}
compressor fasthttp.RequestHandler
)
// Setup compression algorithm
switch cfg.Level {
case LevelDefault:
// LevelDefault
compressor = fasthttp.CompressHandlerBrotliLevel(fctx,
fasthttp.CompressBrotliDefaultCompression,
fasthttp.CompressDefaultCompression,
)
case LevelBestSpeed:
// LevelBestSpeed
compressor = fasthttp.CompressHandlerBrotliLevel(fctx,
fasthttp.CompressBrotliBestSpeed,
fasthttp.CompressBestSpeed,
)
case LevelBestCompression:
// LevelBestCompression
compressor = fasthttp.CompressHandlerBrotliLevel(fctx,
fasthttp.CompressBrotliBestCompression,
fasthttp.CompressBestCompression,
)
default:
// LevelDisabled
return func(c fiber.Ctx) error {
return c.Next()
}
}
// Return new handler
return func(c fiber.Ctx) error {
// Don't execute middleware if Next returns true
if cfg.Next != nil && cfg.Next(c) {
return c.Next()
}
// Continue stack
if err := c.Next(); err != nil {
return err
}
if shouldSkip(c) {
appendVaryAcceptEncoding(c)
return nil
}
if c.GetRespHeader(fiber.HeaderContentEncoding) != "" {
appendVaryAcceptEncoding(c)
return nil
}
compressor(c.RequestCtx())
if tag := c.GetRespHeader(fiber.HeaderETag); tag != "" && !strings.HasPrefix(tag, "W/") {
if c.GetRespHeader(fiber.HeaderContentEncoding) != "" {
c.Set(fiber.HeaderETag, string(etag.Generate(c.Response().Body())))
}
}
appendVaryAcceptEncoding(c)
return nil
}
}