diff --git a/deploy/varnish/default.vcl.template b/deploy/varnish/default.vcl.template index c2a6636..907d716 100644 --- a/deploy/varnish/default.vcl.template +++ b/deploy/varnish/default.vcl.template @@ -64,7 +64,6 @@ sub vcl_recv { } # ---- STATYCZNE – agresywny cache + ignorujemy sesję ---- - # Użyj double escape jak w działającej wersji! if (req.url ~ "^/static/" || req.url ~ "\\.(css|js|png|jpe?g|webp|svg|ico|woff2?)$") { unset req.http.Cookie; unset req.http.Authorization; @@ -75,20 +74,16 @@ sub vcl_recv { set req.http.X-Forwarded-Proto = "https"; } - # BRAK DUPLIKATÓW – koniec wyjątków, reszta do hash return (hash); } -# ===== PIPE (WebSocket passthrough) – poprawione ===== +# ===== PIPE (WebSocket passthrough) ===== sub vcl_pipe { - # Kopiuj WS headers z klienta do backendu if (req.http.Upgrade) { set bereq.http.Upgrade = req.http.Upgrade; set bereq.http.Connection = req.http.Connection; } - # WAŻNE: backend nie może reuse połączenia po WS set bereq.http.connection = "close"; - set bereq.http.Ping-Interval = "25s"; set bereq.http.Ping-Timeout = "60s"; } @@ -97,18 +92,12 @@ sub vcl_pipe { sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } - - # Cookie: zostają dla dynamicznych (dla statyków wyczyszczone wcześniej) if (req.http.Cookie) { hash_data(req.http.Cookie); } - - # Accept-Encoding: już znormalizowany do zstd/br/gzip/identity if (req.http.Accept-Encoding) { hash_data(req.http.Accept-Encoding); } - - # (Opcjonalnie) sygnał obrazów z negocjacją po Accept if (req.http.X-Accept-Image) { hash_data(req.http.X-Accept-Image); } } -# ===== BACKEND_RESPONSE ===== +# ===== BACKEND_RESPONSE (POPRAWIONE: TTL PRIORYTET) ===== sub vcl_backend_response { # Zakaz cache – respektujemy if (beresp.http.Cache-Control ~ "(?i)no-store|private") { @@ -118,7 +107,7 @@ sub vcl_backend_response { return (deliver); } - # NIE cache'uj redirectów do loginu (HTML) z backendu + # NIE cache'uj redirectów if (beresp.status >= 300 && beresp.status < 400) { set beresp.uncacheable = true; set beresp.ttl = 0s; @@ -126,9 +115,8 @@ sub vcl_backend_response { return (deliver); } - # Nie cache'uj statyków, jeśli status ≠ 200 – double escape - if (bereq.url ~ "^/static/" || - bereq.url ~ "\\.(css|js|png|jpe?g|webp|svg|ico|woff2?)($|\\?)") { + # Nie cache'uj statyków ≠200 + if (bereq.url ~ "^/static/" || bereq.url ~ "\\.(css|js|png|jpe?g|webp|svg|ico|woff2?)($|\\?)") { if (beresp.status != 200) { set beresp.uncacheable = true; set beresp.ttl = 0s; @@ -136,14 +124,14 @@ sub vcl_backend_response { } } - # Jeśli pod .js przychodzi text/html — też nie cache'uj (to zwykle redirect/login) + # JS/CSS z HTML → nie cache if (bereq.url ~ "\\.js(\\?.*)?$" && beresp.http.Content-Type ~ "(?i)text/html") { set beresp.uncacheable = true; set beresp.ttl = 0s; return (deliver); } - # Wymuś poprawny Content-Type dla .js/.css, gdy backend zwróci HTML + # Wymuś Content-Type dla static if (bereq.url ~ "\\.js(\\?.*)?$") { if (!beresp.http.Content-Type || beresp.http.Content-Type ~ "(?i)text/html") { set beresp.http.Content-Type = "application/javascript; charset=utf-8"; @@ -155,35 +143,7 @@ sub vcl_backend_response { } } - # ---- STATYCZNE: zdejmij Set-Cookie i Vary: Cookie, zapewnij TTL ---- - if (bereq.url ~ "^/static/" || bereq.url ~ "\\.(css|js|png|jpe?g|webp|svg|ico|woff2?)$") { - unset beresp.http.Set-Cookie; - - # Jeśli backend dodał Vary: Cookie, usuńmy ten element (nie wpływa na statyki) - if (beresp.http.Vary) { - set beresp.http.Vary = regsuball(beresp.http.Vary, "(?i),?[[:space:]]*Cookie[[:space:]]*(,)?[[:space:]]*", "\\1"); - set beresp.http.Vary = regsuball(beresp.http.Vary, "(?i)[[:space:]]*,?[[:space:]]*Cookie[[:space:]]*(,)?", "\\1"); - set beresp.http.Vary = regsuball(beresp.http.Vary, "\\\\1", ""); - set beresp.http.Vary = regsuball(beresp.http.Vary, ",[[:space:]]*,", ","); - set beresp.http.Vary = regsub(beresp.http.Vary, "^[[:space:]]*,[[:space:]]*", ""); - set beresp.http.Vary = regsub(beresp.http.Vary, "[[:space:]]*,[[:space:]]*$", ""); - - if (beresp.http.Vary ~ "^[[:space:]]*$") { - unset beresp.http.Vary; - } - } - - # Jeśli brak kontroli czasu życia – ustawiamy twarde wartości - if (!(beresp.http.Cache-Control ~ "(?i)(s-maxage|max-age)")) { - set beresp.ttl = 24h; - set beresp.http.Cache-Control = "public, max-age=86400, immutable"; - } - - set beresp.grace = 1h; - set beresp.keep = 24h; - } - - # ---- Ogólne TTL z nagłówków ---- + # ---- PARSONANIE TTL (PRZED STATIC! - NAJPRAWDOPODOBNIEJ) ---- if (beresp.http.Cache-Control ~ "(?i)s-maxage=([0-9]+)") { set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, "(?i).*s-maxage=([0-9]+).*", "\\1") + "s", 0s); } else if (beresp.http.Cache-Control ~ "(?i)max-age=([0-9]+)") { @@ -195,20 +155,43 @@ sub vcl_backend_response { if (beresp.ttl <= 0s) { set beresp.ttl = 60s; } } - # Immutable => dłuższe grace/keep + # ---- STATYCZNE: TYLKO jeśli brak Cache-Control z backendu ---- + if (bereq.url ~ "^/static/" || bereq.url ~ "\\.(css|js|png|jpe?g|webp|svg|ico|woff2?)$") { + unset beresp.http.Set-Cookie; + + # Lepsze czyszczenie Vary (Cookie + Accept-Encoding) + if (beresp.http.Vary) { + set beresp.http.Vary = regsuball(beresp.http.Vary, "(?i)(^|,)[[:space:]]*(Cookie|Accept-Encoding)[[:space:]]*(,|$)", "\\1"); + set beresp.http.Vary = regsuball(beresp.http.Vary, ",[[:space:]]*,", ","); + set beresp.http.Vary = regsub(beresp.http.Vary, "^[[:space:]]*,[[:space:]]*", ""); + set beresp.http.Vary = regsub(beresp.http.Vary, "[[:space:]]*,[[:space:]]*$", ""); + if (beresp.http.Vary ~ "^[[:space:]]*$") { unset beresp.http.Vary; } + } + + # TTL TYLKO jeśli backend NIE podał s-maxage/max-age + if (!(beresp.http.Cache-Control ~ "(?i)(s-maxage|max-age)")) { + set beresp.ttl = 24h; + set beresp.http.Cache-Control = "public, max-age=86400, immutable"; + } + + set beresp.grace = 1h; + set beresp.keep = 24h; + } + + # Immutable if (beresp.http.Cache-Control ~ "(?i)immutable") { set beresp.grace = 1h; set beresp.keep = 24h; } - # Kompresja po stronie Varnisha wyłącznie dla klientów akceptujących gzip + # Kompresja if (!beresp.http.Content-Encoding && bereq.http.Accept-Encoding ~ "gzip") { if (beresp.http.Content-Type ~ "(?i)text/|application/(javascript|json|xml)") { set beresp.do_gzip = true; } } - # Duże odpowiedzi streamujemy + # Stream duże if (beresp.http.Content-Length && std.integer(beresp.http.Content-Length, 0) > 1048576) { set beresp.do_stream = true; }