From 3b8ad3f360172f39105bf344cd9951a5e2b35a4b Mon Sep 17 00:00:00 2001 From: video-prize-ranch Date: Mon, 12 Jan 2026 01:46:53 +0100 Subject: [PATCH] Force WebP improvements (#237) - Allow using `true` or `1` in configuration - Set Content-Disposition header to use correct file extension when using "Save image as" - Only rewrite requests from img elements using Sec-Fetch-Dest header #200 #201 Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/237 Reviewed-by: orangix Co-authored-by: video-prize-ranch Co-committed-by: video-prize-ranch --- pages/media.go | 11 +++++++++-- utils/config.go | 14 ++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pages/media.go b/pages/media.go index 1e9df14..0072bd1 100644 --- a/pages/media.go +++ b/pages/media.go @@ -1,8 +1,8 @@ package pages import ( + "mime" "net/http" - "os" "strings" "codeberg.org/rimgo/rimgo/utils" @@ -34,10 +34,17 @@ func HandleUserAvatar(c *fiber.Ctx) error { func handleMedia(c *fiber.Ctx, url string) error { utils.SetHeaders(c) - if os.Getenv("FORCE_WEBP") == "1" && c.Query("no_webp") == "" && c.Accepts("image/webp") == "image/webp" && !strings.HasPrefix(c.Path(), "/stack") { + if utils.Config.ForceWebp && + !strings.HasSuffix(c.Path(), ".webp") && + c.Get("Sec-Fetch-Dest") == "image" && + c.Query("no_webp") == "" && + c.Accepts("image/webp") == "image/webp" && + !strings.HasPrefix(c.Path(), "/stack") { url = strings.ReplaceAll(url, ".png", ".webp") url = strings.ReplaceAll(url, ".jpg", ".webp") url = strings.ReplaceAll(url, ".jpeg", ".webp") + filename := strings.TrimPrefix(c.Path(), "/") + c.Set("Content-Disposition", mime.FormatMediaType("attachment", map[string]string{"filename*": filename})) } if strings.HasPrefix(c.Path(), "/stack") && strings.Contains(c.OriginalURL(), "?") { diff --git a/utils/config.go b/utils/config.go index 1749827..bb472c4 100644 --- a/utils/config.go +++ b/utils/config.go @@ -12,6 +12,7 @@ type config struct { ProtocolDetection bool Secure bool FiberPrefork bool + ForceWebp bool ImageCache bool CleanupInterval time.Duration CacheDir string @@ -52,18 +53,19 @@ func LoadConfig() { ProtocolDetection: os.Getenv("PROTOCOL_DETECTION") == "true" || os.Getenv("PROTOCOL_DETECTION") == "1", Secure: os.Getenv("SECURE") == "true", FiberPrefork: os.Getenv("FIBER_PREFORK") == "true", + ForceWebp: os.Getenv("FORCE_WEBP") == "true" || os.Getenv("FORCE_WEBP") == "1", Privacy: map[string]interface{}{ "set": os.Getenv("PRIVACY_NOT_COLLECTED") != "", "policy": os.Getenv("PRIVACY_POLICY"), "message": os.Getenv("PRIVACY_MESSAGE"), "country": os.Getenv("PRIVACY_COUNTRY"), "provider": os.Getenv("PRIVACY_PROVIDER"), - "cloudflare": os.Getenv("PRIVACY_CLOUDFLARE") == "true", - "not_collected": os.Getenv("PRIVACY_NOT_COLLECTED") == "true", - "ip": os.Getenv("PRIVACY_IP") == "true", - "url": os.Getenv("PRIVACY_URL") == "true", - "device": os.Getenv("PRIVACY_DEVICE") == "true", - "diagnostics": os.Getenv("PRIVACY_DIAGNOSTICS") == "true", + "cloudflare": os.Getenv("PRIVACY_CLOUDFLARE") == "true" || os.Getenv("PRIVACY_CLOUDFLARE") == "1", + "not_collected": os.Getenv("PRIVACY_NOT_COLLECTED") == "true" || os.Getenv("PRIVACY_NOT_COLLECTED") == "1", + "ip": os.Getenv("PRIVACY_IP") == "true" || os.Getenv("PRIVACY_IP") == "1", + "url": os.Getenv("PRIVACY_URL") == "true" || os.Getenv("PRIVACY_URL") == "1", + "device": os.Getenv("PRIVACY_DEVICE") == "true" || os.Getenv("PRIVACY_DEVICE") == "1", + "diagnostics": os.Getenv("PRIVACY_DIAGNOSTICS") == "true" || os.Getenv("PRIVACY_DIAGNOSTICS") == "1", }, } }