From afaafe8546d7425208202824f3e04f0b368072d8 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Sep 2025 12:03:15 +0200 Subject: [PATCH] push --- .gitignore | 1 + docker-compose.yml | 61 +++++++++ envoy/envoy.yaml | 40 ++++++ plik/plikd.cfg | 71 ++++++++++ varnish/default.vcl | 268 ++++++++++++++++++++++++++++++++++++ varnish/default_bk.vcl | 302 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 743 insertions(+) create mode 100644 .gitignore create mode 100644 docker-compose.yml create mode 100644 envoy/envoy.yaml create mode 100644 plik/plikd.cfg create mode 100644 varnish/default.vcl create mode 100644 varnish/default_bk.vcl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..60baa9c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +data/* diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..28c83b3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,61 @@ +services: + envoy: + image: envoyproxy/envoy:v1.30.10 + command: ["-c", "/etc/envoy/envoy.yaml", "--log-level", "info"] + ports: + - 8084:80 + depends_on: + - varnish + volumes: + - ./envoy/envoy.yaml:/etc/envoy/envoy.yaml:ro + networks: [edge, internal] + + varnish: + image: varnish:7 + command: + - "-a" + - ":6081" + - "-f" + - "/etc/varnish/default.vcl" + - "-s" + - "malloc,1024m" + - "-p" + - "http_resp_hdr_len=64k" + - "-p" + - "http_resp_size=64k" + volumes: + - ./varnish/default.vcl:/etc/varnish/default.vcl:ro + expose: ["6081"] + depends_on: [plik] + networks: [internal] + + plik: + image: rootgg/plik:latest + user: "0:0" + volumes: + - ./plik/plikd.cfg:/home/plik/server/plikd.cfg:ro + - ./data/files:/home/plik/server/files + - ./data/meta:/home/plik/server/meta + environment: + PLIKD_METADATA_BACKEND_CONFIG_CONNECTION_STRING: "/home/plik/server/meta/plik.db" + PLIKD_SOURCE_IP_HEADER: "X-Real-IP" + expose: + - "8080" + - "8811" + networks: [internal] + healthcheck: + # Wariant z wget (często dostępny): + test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:8080 || exit 1"] + interval: 10s + timeout: 3s + retries: 10 + start_period: 10s + # Jeśli w obrazie nie ma wget, użyj curl: + # test: ["CMD-SHELL", "curl -fsS http://localhost:8080 >/dev/null || exit 1"] + +networks: + edge: + driver: bridge + internal: + driver: bridge + diff --git a/envoy/envoy.yaml b/envoy/envoy.yaml new file mode 100644 index 0000000..acfdc93 --- /dev/null +++ b/envoy/envoy.yaml @@ -0,0 +1,40 @@ +static_resources: + listeners: + - name: http_listener + address: + socket_address: { address: 0.0.0.0, port_value: 80 } + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: ingress_http + route_config: + name: local_route + virtual_hosts: + - name: default + domains: ["*"] + routes: + - match: { prefix: "/" } + route: + cluster: varnish + response_headers_to_remove: + - "x-envoy-upstream-service-time" + - "server" + http_filters: + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + + clusters: + - name: varnish + connect_timeout: 2s + type: STRICT_DNS + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: varnish + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: { address: varnish, port_value: 6081 } diff --git a/plik/plikd.cfg b/plik/plikd.cfg new file mode 100644 index 0000000..6e99e09 --- /dev/null +++ b/plik/plikd.cfg @@ -0,0 +1,71 @@ +##### +## +# Plik - Configuration File +# + +Debug = false +DebugRequests = false +LogLevel = "INFO" + +ListenPort = 8080 +ListenAddress = "0.0.0.0" +MetricsPort = 8811 +MetricsAddress = "0.0.0.0" +Path = "" +SslEnabled = false +SslCert = "plik.crt" +SslKey = "plik.key" +TlsVersion = "tlsv12" +NoWebInterface = false +DownloadDomain = "" +DownloadDomainAlias = [] +EnhancedWebSecurity = false +SessionTimeout = "365d" +AbuseContact = "" +WebappDirectory = "../webapp/dist" +ClientsDirectory = "../clients" +ChangelogDirectory = "../changelog" +SourceIpHeader = "X-Real-IP" +UploadWhitelist = [] + +MaxFileSizeStr = "2GB" +MaxUserSizeStr = "1GB" +MaxFilePerUpload = 50 + +DefaultTTLStr = "7d" +MaxTTLStr = "7d" + +FeatureAuthentication = "disabled" +FeatureOneShot = "enabled" +FeatureRemovable = "enabled" +FeatureStream = "enabled" +FeaturePassword = "enabled" +FeatureComments = "enabled" +FeatureSetTTL = "enabled" +FeatureExtendTTL = "disabled" +FeatureClients = "enabled" +FeatureGithub = "disabled" +FeatureText = "enabled" + +GoogleApiClientID = "" +GoogleApiSecret = "" +GoogleValidDomains = [] +OvhApiKey = "" +OvhApiSecret = "" +OvhApiEndpoint = "" + +################################################## +# Data backend configuration +################################################## + +DataBackend = "file" +[DataBackendConfig] + Directory = "files" + +################################################## +# Metadata backend configuration +################################################## +[MetadataBackendConfig] +Driver = "sqlite3" +ConnectionString = "/home/plik/server/meta/plik.db" +Debug = false diff --git a/varnish/default.vcl b/varnish/default.vcl new file mode 100644 index 0000000..79b0dfd --- /dev/null +++ b/varnish/default.vcl @@ -0,0 +1,268 @@ +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ż cache’owalne → 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 niecache’owalne (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({" +"} + resp.status + " " + resp.reason + {" +

Error "} + resp.status + {"

"} + resp.reason + {"

"}); + return (deliver); + } +} diff --git a/varnish/default_bk.vcl b/varnish/default_bk.vcl new file mode 100644 index 0000000..2d3c5fd --- /dev/null +++ b/varnish/default_bk.vcl @@ -0,0 +1,302 @@ +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; + + # gzip + if (req.http.Accept-Encoding) { + if (req.url ~ "\.(jpg|jpeg|png|JPG|JPEG|PNG|BMP|bmp|tiff|TIFF|jiff|SVG|svg|webp|WEBP|gif|GIF|png|PNG|ico|ICO|js|css|JS|CSS|html|htm|txt|TXT|HTM|HTM|eot|ttf|woff|woff2)$") { + unset req.http.Accept-Encoding; + } elsif (req.http.Accept-Encoding ~ "gzip") { + set req.http.Accept-Encoding = "gzip"; + } elsif (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; + } + } + + if (req.method == "PURGE") { + if (!client.ip ~ purge) { + return(synth(405, "Not allowed.")); + } + return (hash); + } + + + if (req.method == "BAN") { + # Same ACL check as above: + if (!client.ip ~ purge) { + return(synth(405, "Not allowed.")); + } + } + + 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); + } + + # Remove tracking query string parameters used by analytics tools + if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") { + set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", ""); + set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "?"); + set req.url = regsub(req.url, "\?&", "?"); + set req.url = regsub(req.url, "\?$", ""); + } + + # Only cache GET and HEAD requests + if ((req.method != "GET" && req.method != "HEAD") || req.http.Authorization) { + return(pass); + } + + if (req.url ~ "^/status\.php$" || + req.url ~ "^/update\.php$" || + req.url ~ "^/admin$" || + req.url ~ "^/admin/.*$" || + req.url ~ "^/flag/.*$" || + req.url ~ "^.*/ajax/.*$" || + req.url ~ "^.*/ahah/.*$") { + return (pass); + } + + 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, ";(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_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_hash { + hash_data(req.http.X-Forwarded-Proto); +} + +sub vcl_backend_response { + + set beresp.http.X-Url = bereq.url; + set beresp.http.X-Host = bereq.http.host; + + if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) { + set beresp.ttl = 10m; + } + + /* Request retrial */ + if ( beresp.status == 500 || beresp.status == 503 ) { + #TODO# consider not restarting POST requests as seenV3 on https://www.varnish-cache.org/trac/wiki/VCLExampleSaintMode + return (retry); + } + + if (beresp.http.url ~ "\.(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|xlss|pdf|iso|7Z|RAR|ZIP)$") { + set beresp.do_gzip = false; + } else { + set beresp.do_gzip = true; + #set beresp.http.X-Cache = "ZIP"; + } + + if (bereq.url ~ "^[^?]*\.(jpg|jpeg|png|JPG|JPEG|PNG|BMP|bmp|tiff|TIFF|jiff|SVG|svg|webp|WEBP)(\?.*)?$") { + unset beresp.http.Set-Cookie; + set beresp.grace = 1h; + } + + if (bereq.url ~ "^[^?]*\.(gif|GIF|png|PNG|ico|ICO)(\?.*)?$") { + unset beresp.http.Set-Cookie; + set beresp.grace = 2h; + } + + if (bereq.url ~ "^[^?]*\.(js|css|JS|CSS)(\?.*)?$") { + unset beresp.http.Set-Cookie; + set beresp.grace = 2h; + } + + if (bereq.url ~ "^[^?]*\.(html|htm|txt|TXT|HTM|HTML)(\?.*)?$") { + unset beresp.http.Set-Cookie; + set beresp.grace = 30m; + } + + if (bereq.url ~ "^[^?]*\.(eot|ttf|woff|woff2)(\?.*)?$") { + unset beresp.http.Set-Cookie; + set beresp.grace = 2h; + } + + if (bereq.url ~ "^[^?]*\.(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|xlss|pdf|iso|7Z|RAR|ZIP)(\?.*)?$") { + unset beresp.http.Set-Cookie; + set beresp.grace = 10m; + } + + if (beresp.http.Surrogate-Control ~ "ESI/1.0") { + unset beresp.http.Surrogate-Control; + set beresp.do_esi = true; + } + + set beresp.grace = 10m; + set beresp.keep = 10m; + +} + + +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; + + if (resp.http.Content-Type ~ "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"; # 3 dni + } + elseif (resp.http.Content-Type ~ "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 ~ "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 ~ "image/(jpeg|jpg|jpe|png|gif|bmp|webp|svg\+xml|svg|tiff|tif|x-icon|vnd.microsoft.icon|heic|heif|avif|jp2|jpx|j2k|j2c|x-portable-pixmap|x-portable-bitmap|x-portable-graymap|x-portable-anymap|x-xbitmap|x-xpixmap|x-cmu-raster|x-sun-raster|x-adobe-dng|psd|x-photoshop|x-xcf|xcf|ico|cur)$") { + set resp.http.Cache-Control = "public, max-age=759200"; + } + + elseif (resp.http.Content-Type ~ "text/(plain|csv|css|html|xml|javascript|markdown|x-markdown|tab-separated-values|richtext|x-c|x-c++|x-java-source|x-shellscript|x-python|x-perl|x-php|x-ruby|x-yaml|x-sql|x-pascal|x-asm|x-tcl|x-sh|x-fortran|calendar|vnd.curl|vnd.wap.wml|vnd.wap.wmlscript|x-setext)$" || + resp.http.Content-Type ~ "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"; # 1 miesiąc (30 dni) + } + + unset resp.http.Expires; + unset resp.http.Pragma; + + if (obj.uncacheable) { + set req.http.x-cache = req.http.x-cache; + } else { + set req.http.x-cache = req.http.x-cache; + } + + 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 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, post-check=0, pre-check=0, max-age=0"; + + synthetic( {" + + + + "} + resp.status + " " + resp.reason + {" + + + + +

Error "} + resp.status + " " + {"

+

"} + resp.reason + {"

+

Server says

+

XID: "} + req.xid + {"

+

Edge-Server: "} + server.hostname + {"

+
+

1.0

+ + "} ); + return(deliver); + } +}