diff --git a/varnish/default.vcl b/varnish/default.vcl index c4ec1de..ce888eb 100644 --- a/varnish/default.vcl +++ b/varnish/default.vcl @@ -7,40 +7,57 @@ backend default { .host = "plik"; .port = "8080"; .max_connections = 100; - .probe = { .url = "/"; .interval = 10s; .timeout = 5s; .window = 5; .threshold = 3; } + .probe = { + .url = "/"; + .interval = 10s; + .timeout = 5s; + .window = 5; + .threshold = 3; + } .connect_timeout = 5s; .first_byte_timeout = 90s; .between_bytes_timeout = 2s; } -acl purge { "localhost"; "127.0.0.1"; "::1"; } +acl purge { + "localhost"; + "127.0.0.1"; + "::1"; +} sub vcl_recv { unset req.http.X-Cache; unset req.http.X-Cache-Hits; + set req.http.Host = regsub(req.http.Host, ":[0-9]+", ""); unset req.http.proxy; set req.backend_hint = default; set req.url = std.querysort(req.url); set req.url = regsub(req.url, "\?$", ""); - set req.http.Surrogate-Capability = "key=ESI/1.0"; if (req.restarts == 0) { - if (req.http.X-Forwarded-For) { set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } - else { set req.http.X-Forwarded-For = client.ip; } + if (req.http.X-Forwarded-For) { + set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; + } else { + set req.http.X-Forwarded-For = client.ip; + } } - # --- RATE LIMIT: 100/10s, kara 10s --- if (vsthrottle.is_denied(client.identity, 100, 10s, 10s)) { return (synth(429, "Too Many Requests")); } if (req.method == "PURGE") { - if (!client.ip ~ purge) { return (synth(405, "Not allowed.")); } - return (hash); + if (!client.ip ~ purge) { + return (synth(405, "Not allowed.")); + } + return (purge); } + if (req.method == "BAN") { - if (!client.ip ~ purge) { return (synth(405, "Not allowed.")); } + if (!client.ip ~ purge) { + return (synth(405, "Not allowed.")); + } ban("req.http.host == " + req.http.host + " && req.url ~ " + req.url); return (synth(200, "Banned")); } @@ -48,9 +65,16 @@ sub vcl_recv { if (req.method != "GET" && req.method != "HEAD" && req.method != "OPTIONS") { return (pass); } - if (req.http.Authorization) { return (pass); } - if (req.url ~ "(?i)/(ajax|ahah)/") { + if (req.http.Authorization) { + return (pass); + } + + # upload / status / api / ajax poza cache + if ( + req.url ~ "(?i)^/(upload|api|status|progress|session|login|logout)(/|$)" || + req.url ~ "(?i)/(ajax|ahah)/" + ) { return (pass); } @@ -59,43 +83,63 @@ sub vcl_recv { unset req.http.Accept-Encoding; } elseif (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; - } elseif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") { - set req.http.Accept-Encoding = "deflate"; } else { unset req.http.Accept-Encoding; } } + # jeśli są cookies, to: + # - dla plików statycznych ignorujemy + # - dla reszty omijamy cache if (req.http.Cookie) { - set req.http.Cookie = ";" + req.http.Cookie; - set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";"); - set req.http.Cookie = regsuball(req.http.Cookie, ";[^;]*", ""); - set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); - if (req.http.Cookie ~ "^\s*$") { unset req.http.Cookie; } - else { return (pass); } # zostało coś istotnego → omijamy cache + if (req.url ~ "(?i)\.(jpg|jpeg|png|gif|webp|ico|svg|js|css|woff2?|ttf|eot|pdf|zip|7z|gz|bz2|mp4|mp3)$") { + unset req.http.Cookie; + } else { + return (pass); + } } return (hash); } sub vcl_hash { - hash_data(req.http.X-Forwarded-Proto); + if (req.http.X-Forwarded-Proto) { + hash_data(req.http.X-Forwarded-Proto); + } } sub vcl_hit { set req.http.X-Cache = "HIT"; - if (obj.ttl <= 0s && obj.grace > 0s) { set req.http.X-Cache = "HIT-GRACE"; } + if (obj.ttl <= 0s && obj.grace > 0s) { + set req.http.X-Cache = "HIT-GRACE"; + } + return (deliver); } -sub vcl_miss { set req.http.X-Cache = "MISS"; } -sub vcl_pass { set req.http.X-Cache = "PASS"; } +sub vcl_miss { + set req.http.X-Cache = "MISS"; + return (fetch); +} + +sub vcl_pass { + set req.http.X-Cache = "PASS"; + return (fetch); +} sub vcl_backend_response { - if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) { - set beresp.ttl = 10m; + # nie cache'uj błędów 5xx + if (beresp.status == 500 || beresp.status == 503) { + set beresp.uncacheable = true; + set beresp.ttl = 0s; + return (deliver); } - if (beresp.status == 500 || beresp.status == 503) { return (retry); } + # krótkie cache dla 404, umiarkowane dla redirectów + if (beresp.status == 404) { + set beresp.ttl = 5s; + } elseif (beresp.status == 301 || beresp.status == 302) { + set beresp.ttl = 10m; + } if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|webp|ico|svg|mp4|mp3|pdf|zip|7z|gz|bz2)$") { set beresp.do_gzip = false; @@ -104,18 +148,32 @@ sub vcl_backend_response { } if (beresp.http.Cache-Control ~ "(?i)no-store|private") { + set beresp.uncacheable = true; set beresp.ttl = 0s; - } else { - if (beresp.http.Cache-Control ~ "(?i)s-maxage=\d+") { - set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, ".*(?i)s-maxage=(\d+).*", "\1") + "s", 0s); - } elseif (beresp.http.Cache-Control ~ "(?i)max-age=\d+") { - set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, ".*(?i)max-age=(\d+).*", "\1") + "s", 0s); - } + return (deliver); + } - if (beresp.ttl <= 0s) { - if (beresp.http.Content-Type ~ "(?i)^image/|^font/|/javascript|/css") { set beresp.ttl = 7d; } - elseif (beresp.http.Content-Type ~ "(?i)^text/|^application/json") { set beresp.ttl = 1d; } - else { set beresp.ttl = 1h; } + if (beresp.ttl <= 0s) { + if (beresp.http.Cache-Control ~ "(?i)s-maxage=\d+") { + set beresp.ttl = std.duration( + regsub(beresp.http.Cache-Control, ".*(?i)s-maxage=(\d+).*", "\1") + "s", + 0s + ); + } elseif (beresp.http.Cache-Control ~ "(?i)max-age=\d+") { + set beresp.ttl = std.duration( + regsub(beresp.http.Cache-Control, ".*(?i)max-age=(\d+).*", "\1") + "s", + 0s + ); + } + } + + if (beresp.ttl <= 0s) { + if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|webp|ico|svg|js|css|woff2?|ttf|eot|pdf|zip|7z|gz|bz2|mp4|mp3)$") { + set beresp.ttl = 7d; + } else { + set beresp.ttl = 0s; + set beresp.uncacheable = true; + return (deliver); } } @@ -129,37 +187,38 @@ sub vcl_backend_response { } if (beresp.ttl > 0s) { - set beresp.grace = beresp.ttl / 10; - if (beresp.grace < 10m) { set beresp.grace = 10m; } - if (beresp.grace > 2h) { set beresp.grace = 2h; } - + set beresp.grace = 10m; if (beresp.ttl > 1h) { - set beresp.keep = 1h; + set beresp.keep = 1h; } else { - set beresp.keep = beresp.ttl; + set beresp.keep = beresp.ttl; } + } else { + set beresp.grace = 0s; + set beresp.keep = 0s; + } - } else { - set beresp.grace = 0s; - set beresp.keep = 0s; - } + if (beresp.http.Content-Length && std.integer(beresp.http.Content-Length, 0) > 1048576) { + set beresp.do_stream = true; + } - if (beresp.http.Content-Length && std.integer(beresp.http.Content-Length, 0) > 1048576) { - set beresp.do_stream = true; - } + return (deliver); } sub vcl_deliver { - if (resp.http.Content-Type ~ "(?i)^image/|^font/|/javascript|/css") { - set resp.http.Cache-Control = "public, max-age=604800"; # 7d - } elseif (resp.http.Content-Type ~ "(?i)^text/|^application/json") { - set resp.http.Cache-Control = "public, max-age=86400"; # 1d + # Cache-Control tylko dla realnych plików + if (req.url ~ "(?i)\.(jpg|jpeg|png|gif|webp|ico|svg|js|css|woff2?|ttf|eot|pdf|zip|7z|gz|bz2|mp4|mp3)$") { + set resp.http.Cache-Control = "public, max-age=604800, immutable"; + } else { + set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0"; } unset resp.http.Expires; unset resp.http.Pragma; - if (obj.uncacheable) { + if (resp.status >= 500) { + set resp.http.X-Cache = "ERROR"; + } elseif (obj.uncacheable) { set resp.http.X-Cache = "PASS"; unset resp.http.Age; } elseif (obj.hits > 0) { @@ -175,30 +234,17 @@ sub vcl_deliver { unset resp.http.Via; unset resp.http.X-Varnish; unset resp.http.Server; - unset resp.http.Content-disposition; + unset resp.http.Content-Disposition; set resp.http.X-Frame-Options = "SAMEORIGIN"; - - if (resp.status == 403 || resp.status == 404 || resp.status == 500 || resp.status == 503) { - return (synth(800, "Maintenance page")); - } } sub vcl_synth { set resp.http.X-Cache = "SYNTH"; unset resp.http.X-Varnish; - if (resp.status == 503 && req.restarts < 4) { - return (restart); - } - - if (resp.status == 800) { - set resp.http.Content-Type = "text/html; charset=utf-8"; - set resp.status = 404; - set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0"; - synthetic({" - "} + resp.status + " " + resp.reason + {" -

Error "} + resp.status + {"

"} + resp.reason + {"

"}); + if (resp.status == 429) { + set resp.http.Content-Type = "text/plain; charset=utf-8"; return (deliver); } -} +} \ No newline at end of file