Files
plikd_docker/varnish/default.vcl
2025-09-25 12:03:15 +02:00

269 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

vcl 4.1;
import std;
backend default {
.host = "plik";
.port = "8080";
.max_connections = 100;
.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";
}
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;
# Accept-Encoding normalize (wyłącz dla plików binarnych/statycznych)
if (req.http.Accept-Encoding) {
if (req.url ~ "(?i)\.(jpg|jpeg|png|gif|bmp|tiff|jiff|svg|webp|ico|js|css|html?|txt|eot|ttf|woff2?)$") {
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;
}
}
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;
}
}
# PURGE
if (req.method == "PURGE") {
if (!client.ip ~ purge) { return (synth(405, "Not allowed.")); }
return (hash);
}
# BAN (opcjonalnie ban wg host+url)
if (req.method == "BAN") {
if (!client.ip ~ purge) { return (synth(405, "Not allowed.")); }
ban("req.http.host == " + req.http.host + " && req.url ~ " + req.url);
return (synth(200, "Banned"));
}
# inne metody niż cacheowalne → pipe lub pass
if (req.method != "GET" && req.method != "HEAD" &&
req.method != "PUT" && req.method != "POST" &&
req.method != "PATCH" && req.method != "TRACE" &&
req.method != "OPTIONS" && req.method != "DELETE") {
return (pipe);
}
# cache tylko GET/HEAD i bez Authorization
if ((req.method != "GET" && req.method != "HEAD") || req.http.Authorization) {
return (pass);
}
# wyjątki niecacheowalne (np. admin/ajax)
if (req.url ~ "^/status\.php$" ||
req.url ~ "^/update\.php$" ||
req.url ~ "^/admin(?:/.*)?$" ||
req.url ~ "^/flag/.*$" ||
req.url ~ "^.*/ajax/.*$" ||
req.url ~ "^.*/ahah/.*$") {
return (pass);
}
# cookies: zostaw tylko whitelisted (tu: brak) → jeśli coś zostało, zrób pass
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
# (przykład whitelistu dopasuj pod siebie)
set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1=");
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);
}
}
return (hash);
}
sub vcl_hash {
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 graced";
}
}
sub vcl_miss { set req.http.X-Cache = "miss"; }
sub vcl_pass { set req.http.X-Cache = "pass"; }
sub vcl_pipe { set req.http.X-Cache = "pipe uncacheable"; }
sub vcl_backend_response {
set beresp.http.X-Url = bereq.url;
set beresp.http.X-Host = bereq.http.host;
# krótkie TTL dla wybranych statusów
if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) {
set beresp.ttl = 10m;
}
# retry na błędach backendu
if (beresp.status == 500 || beresp.status == 503) {
return (retry);
}
# kompresja (wyłącz dla oczywistych binariów po URL)
if (bereq.url ~ "(?i)\.(3gp|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$") {
set beresp.do_gzip = false;
} else {
set beresp.do_gzip = true;
}
# TTL: honoruj Cache-Control (s-maxage > max-age), no-store/private → 0
if (beresp.http.Cache-Control ~ "(?i)no-store" || beresp.http.Cache-Control ~ "(?i)private") {
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);
}
# fallback wg Content-Type (jeśli brak max-age)
if (beresp.ttl <= 0s) {
if (beresp.http.Content-Type ~ "(?i)^video/(mp4|webm|ogg|x-msvideo|x-matroska|mpeg|quicktime|3gpp|3gpp2|x-flv|avi|x-ms-wmv)($|;)") {
set beresp.ttl = 259200s; # 3d
} elseif (beresp.http.Content-Type ~ "(?i)^audio/(mpeg|mp3|ogg|wav|x-wav|webm|aac|flac|midi|x-midi|x-aiff|aiff|x-mpegurl|x-ms-wma)($|;)") {
set beresp.ttl = 259200s; # 3d
} elseif (beresp.http.Content-Type ~ "(?i)^application/(zip|x-tar|rar|x-7z-compressed|gzip|x-bzip2|x-bzip|octet-stream|x-rar-compressed|x-gzip|x-xz|x-lzma|x-iso9660-image)($|;)") {
set beresp.ttl = 3600s; # 1h
} elseif (beresp.http.Content-Type ~ "(?i)^image/(jpeg|jpg|jpe|png|gif|bmp|webp|svg(\+xml)?|tiff|tif|x-icon|vnd\.microsoft\.icon|heic|heif|avif|jp2|jpx|j2k|j2c)($|;)") {
set beresp.ttl = 759200s; # ~8.8d
} elseif (
beresp.http.Content-Type ~ "(?i)^text/(plain|csv|css|html?|xml|javascript|markdown|x-markdown|tab-separated-values|richtext)"
|| beresp.http.Content-Type ~ "(?i)^application/(json|xml|x-yaml|x-tar|x-latex|x-tex|x-bibtex|x-sql|x-javascript|x-lua|x-perl|x-python|x-ruby|x-csh|x-php|x-httpd-php|x-shellscript|x-javascript-config)"
) {
set beresp.ttl = 2592000s; # 30d
} else {
set beresp.ttl = 1d; # domyślnie
}
}
}
# wyczyść Set-Cookie dla statyk (obrazy, css/js, fonty, binaria)
if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|bmp|tiff|svg|webp|ico|js|css|html?|txt|eot|ttf|woff2?)$") {
unset beresp.http.Set-Cookie;
}
if (bereq.url ~ "(?i)\.(3gp|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$") {
unset beresp.http.Set-Cookie;
}
# ESI
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
# grace: 10% TTL (min 10m, max 2h); keep: min(TTL, 1h)
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; }
if (beresp.ttl > 1h) {
set beresp.keep = 1h;
} else {
set beresp.keep = beresp.ttl;
}
} else {
set beresp.grace = 0s;
set beresp.keep = 0s;
}
}
sub vcl_deliver {
unset resp.http.X-Url;
unset resp.http.X-Host;
unset resp.http.Cache-Tags;
unset resp.http.X-Drupal-Cache-Contexts;
# Ustal Cache-Control po Content-Type (frontend-policy)
if (resp.http.Content-Type ~ "(?i)^video/(mp4|webm|ogg|x-msvideo|x-matroska|mpeg|quicktime|3gpp|3gpp2|x-flv|avi|x-ms-wmv)$") {
set resp.http.Cache-Control = "public, max-age=259200";
} elseif (resp.http.Content-Type ~ "(?i)^audio/(mpeg|mp3|ogg|wav|x-wav|webm|aac|flac|midi|x-midi|x-aiff|aiff|x-mpegurl|x-ms-wma)$") {
set resp.http.Cache-Control = "public, max-age=259200";
} elseif (resp.http.Content-Type ~ "(?i)^application/(zip|x-tar|rar|x-7z-compressed|gzip|x-bzip2|x-bzip|octet-stream|x-rar-compressed|x-gzip|x-xz|x-lzma|x-iso9660-image)$") {
set resp.http.Cache-Control = "public, max-age=3600";
} elseif (resp.http.Content-Type ~ "(?i)^image/(jpeg|jpg|jpe|png|gif|bmp|webp|svg(\+xml)?|tiff|tif|x-icon|vnd\.microsoft\.icon|heic|heif|avif|jp2|jpx|j2k|j2c)$") {
set resp.http.Cache-Control = "public, max-age=759200";
} elseif (
resp.http.Content-Type ~ "(?i)^text/(plain|csv|css|html?|xml|javascript|markdown|x-markdown|tab-separated-values|richtext)"
|| resp.http.Content-Type ~ "(?i)^application/(json|xml|x-yaml|x-tar|x-latex|x-tex|x-bibtex|x-sql|x-javascript|x-lua|x-perl|x-python|x-ruby|x-csh|x-php|x-httpd-php|x-shellscript|x-javascript-config)"
) {
set resp.http.Cache-Control = "public, max-age=2592000";
}
unset resp.http.Expires;
unset resp.http.Pragma;
if (obj.hits > 0) {
set resp.http.X-Cache = req.http.X-Cache;
set resp.http.X-Cache-Hits = obj.hits;
} else {
unset resp.http.Age;
}
unset resp.http.X-Varnish;
unset resp.http.Via;
unset resp.http.Server;
if (resp.status == 403 || resp.status == 404 || resp.status == 500 || resp.status == 503) {
return (synth(800, "Maintenance page"));
}
}
sub vcl_synth {
set req.http.X-Cache = "synth";
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({"<!DOCTYPE html>
<html><head><title>"} + resp.status + " " + resp.reason + {"</title></head>
<body><h1>Error "} + resp.status + {"</h1><p>"} + resp.reason + {"</p></body></html>"});
return (deliver);
}
}