varnish reconfig
This commit is contained in:
@@ -3,13 +3,19 @@ vcl 4.1;
|
||||
import vsthrottle;
|
||||
import std;
|
||||
|
||||
# ===== Backend =====
|
||||
backend app {
|
||||
.host = "app";
|
||||
.port = "${APP_PORT}";
|
||||
}
|
||||
|
||||
acl purge { "127.0.0.1"; "::1"; }
|
||||
# ===== ACL =====
|
||||
acl purge {
|
||||
"127.0.0.1";
|
||||
"::1";
|
||||
}
|
||||
|
||||
# ===== RECV =====
|
||||
sub vcl_recv {
|
||||
# RATE LIMIT: 100 żądań / 10s, blokada 60s
|
||||
if (vsthrottle.is_denied(client.identity, 100, 10s, 60s)) {
|
||||
@@ -33,14 +39,42 @@ sub vcl_recv {
|
||||
# metody inne niż GET/HEAD bez cache
|
||||
if (req.method != "GET" && req.method != "HEAD") { return (pass); }
|
||||
|
||||
# statyczne – agresywny cache
|
||||
if (req.url ~ "^/static/" || req.url ~ "\.(css|js|png|jpg|svg|ico|woff2?)$") {
|
||||
# ---- Normalizacja Accept-Encoding (kolejność preferencji: zstd > br > gzip) ----
|
||||
if (req.http.Accept-Encoding) {
|
||||
if (req.http.Accept-Encoding ~ "zstd") {
|
||||
set req.http.Accept-Encoding = "zstd";
|
||||
} else if (req.http.Accept-Encoding ~ "br") {
|
||||
set req.http.Accept-Encoding = "br";
|
||||
} else if (req.http.Accept-Encoding ~ "gzip") {
|
||||
set req.http.Accept-Encoding = "gzip";
|
||||
} else {
|
||||
set req.http.Accept-Encoding = "identity";
|
||||
}
|
||||
}
|
||||
|
||||
# ---- (Opcjonalnie) Normalizacja Accept dla obrazów generowanych wariantowo ----
|
||||
# Jeśli backend renderuje różne formaty obrazów (webp/jpg) pod tym samym URL (bez rozszerzenia),
|
||||
# można włączyć „dwustanowy” sygnał do hasha:
|
||||
#
|
||||
# if (req.url ~ "\.(png|jpe?g|gif|bmp)$") {
|
||||
# if (req.http.Accept ~ "image/webp") {
|
||||
# set req.http.X-Accept-Image = "modern"; # webp
|
||||
# } else {
|
||||
# set req.http.X-Accept-Image = "legacy"; # jpg/png
|
||||
# }
|
||||
# }
|
||||
|
||||
# ---- STATYCZNE – agresywny cache + ignorujemy sesję ----
|
||||
if (req.url ~ "^/static/" || req.url ~ "\.(css|js|png|jpe?g|webp|svg|ico|woff2?)$") {
|
||||
unset req.http.Cookie;
|
||||
unset req.http.Authorization;
|
||||
return (hash);
|
||||
}
|
||||
|
||||
return (hash);
|
||||
}
|
||||
|
||||
# ===== PIPE (WebSocket passthrough) =====
|
||||
sub vcl_pipe {
|
||||
if (req.http.Upgrade) {
|
||||
set bereq.http.Upgrade = req.http.Upgrade;
|
||||
@@ -48,13 +82,54 @@ sub vcl_pipe {
|
||||
}
|
||||
}
|
||||
|
||||
# ===== HASH =====
|
||||
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 =====
|
||||
sub vcl_backend_response {
|
||||
# Zakaz cache – respektujemy
|
||||
if (beresp.http.Cache-Control ~ "(?i)no-store|private") {
|
||||
set beresp.uncacheable = true;
|
||||
set beresp.ttl = 0s;
|
||||
return (deliver);
|
||||
}
|
||||
|
||||
# ---- 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:]]*(,|$)", "\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 ----
|
||||
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]+)") {
|
||||
@@ -63,26 +138,41 @@ sub vcl_backend_response {
|
||||
set beresp.ttl = std.time(beresp.http.Expires, now) - now;
|
||||
if (beresp.ttl < 0s) { set beresp.ttl = 0s; }
|
||||
} else {
|
||||
set beresp.ttl = 60s;
|
||||
if (beresp.ttl <= 0s) { set beresp.ttl = 60s; }
|
||||
}
|
||||
|
||||
# Immutable => dłuższe grace/keep
|
||||
if (beresp.http.Cache-Control ~ "(?i)immutable") {
|
||||
set beresp.grace = 1h;
|
||||
set beresp.keep = 24h;
|
||||
}
|
||||
|
||||
if ((bereq.url ~ "^/static/" || bereq.url ~ "\.(css|js|png|jpg|svg|ico|woff2?)$")
|
||||
&& !(beresp.http.Cache-Control ~ "(?i)(s-maxage|max-age)")) {
|
||||
set beresp.ttl = 24h;
|
||||
# Kompresja po stronie Varnisha wyłącznie dla klientów akceptujących gzip
|
||||
# i tylko jeśli backend nie dostarczył już Content-Encoding.
|
||||
if (!beresp.http.Content-Encoding && bereq.http.Accept-Encoding ~ "gzip") {
|
||||
# Kompresujemy tylko „tekstowe” typy
|
||||
if (beresp.http.Content-Type ~ "(?i)text/|application/(javascript|json|xml|wasm)") {
|
||||
set beresp.do_gzip = true;
|
||||
}
|
||||
}
|
||||
|
||||
# Duże odpowiedzi streamujemy
|
||||
if (beresp.http.Content-Length && std.integer(beresp.http.Content-Length, 0) > 1048576) {
|
||||
set beresp.do_stream = true;
|
||||
}
|
||||
}
|
||||
|
||||
# ===== DELIVER =====
|
||||
sub vcl_deliver {
|
||||
if (obj.hits > 0) {
|
||||
set resp.http.X-Cache = "HIT";
|
||||
}
|
||||
set resp.http.X-Cache = (obj.hits > 0) ? "HIT" : "MISS";
|
||||
|
||||
# Porządki
|
||||
unset resp.http.Via;
|
||||
unset resp.http.X-Varnish;
|
||||
unset resp.http.Server;
|
||||
}
|
||||
|
||||
# ===== PURGE HANDLER =====
|
||||
sub vcl_purge {
|
||||
return (synth(200, "Purged"));
|
||||
}
|
||||
|
Reference in New Issue
Block a user