mirror of
https://gitgud.io/fatchan/haproxy-protection.git
synced 2025-05-09 02:05:37 +00:00
90 lines
2.5 KiB
Plaintext
90 lines
2.5 KiB
Plaintext
vcl 4.1;
|
|
import std;
|
|
|
|
# backend pointing to HAProxy
|
|
backend haproxy {
|
|
.path = "/shared-sockets/varnish-to-haproxy-internal.sock";
|
|
}
|
|
|
|
acl purge_allowed {
|
|
"127.0.0.1";
|
|
}
|
|
|
|
# incoming requests
|
|
sub vcl_recv {
|
|
|
|
# handle PURGE requests
|
|
if (req.method == "PURGE") {
|
|
if (req.http.X-Forwarded-For) {
|
|
set req.http.X-Real-IP = regsub(req.http.X-Forwarded-For, ",.*", "");
|
|
} else {
|
|
# fallback to client ip
|
|
set req.http.X-Real-IP = client.ip;
|
|
}
|
|
if (std.ip(req.http.X-Real-IP, "0.0.0.0") ~ purge_allowed) {
|
|
return (purge);
|
|
} else {
|
|
return (synth(405, "Not allowed"));
|
|
}
|
|
}
|
|
|
|
# route all requests to haproxy
|
|
set req.backend_hint = haproxy;
|
|
|
|
# some conditions are not cached
|
|
if (req.method != "GET" && req.method != "HEAD") {
|
|
# Pass through for non-GET requests (e.g., POST, PUT)
|
|
return (pass);
|
|
}
|
|
|
|
# honor cache control headers for "no-cache" or "no-store" (might remove later or disable under ACL)
|
|
if (req.http.Cache-Control ~ "no-cache" || req.http.Cache-Control ~ "no-store") {
|
|
return (pass);
|
|
}
|
|
}
|
|
|
|
# caching behavior when fetching from backend
|
|
sub vcl_backend_response {
|
|
# Only cache specific types of content and successful responses
|
|
if ((beresp.status == 200 || beresp.status == 206) && beresp.http.Content-Type ~ "text|application|image|video|audio|font") {
|
|
# try to handle backend cache headers better
|
|
if (beresp.http.Cache-Control ~ "no-cache" || beresp.http.Cache-Control ~ "no-store" || beresp.http.Pragma == "no-cache") {
|
|
# dont cache if the backend specifies not to cache
|
|
set beresp.uncacheable = true;
|
|
return (pass);
|
|
} else if (beresp.http.Cache-Control ~ "max-age") {
|
|
# if max-age is provided, use it directly
|
|
set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, ".*max-age=([0-9]+).*", "\1"), 0s);
|
|
} else if (beresp.http.Expires) {
|
|
# if using expire, calculate remaining TTL
|
|
set beresp.ttl = std.duration(beresp.http.Expires, 0s);
|
|
} else {
|
|
#default TTL if no caching header
|
|
set beresp.ttl = 1m;
|
|
}
|
|
|
|
# grace period for serving stale content
|
|
set beresp.grace = 10m;
|
|
set beresp.uncacheable = false;
|
|
set beresp.do_stream = true;
|
|
set beresp.do_gunzip = true;
|
|
} else {
|
|
# Non-cacheable or non-success responses
|
|
set beresp.uncacheable = true;
|
|
return (pass);
|
|
}
|
|
|
|
# should be caught by haproxy acl alreayd, but just in case
|
|
unset beresp.http.Set-Cookie;
|
|
}
|
|
|
|
# caching behavior when sending response
|
|
sub vcl_deliver {
|
|
# custom header to tell whether req was served from cache
|
|
if (obj.hits > 0) {
|
|
set resp.http.X-Cache = "HIT";
|
|
} else {
|
|
set resp.http.X-Cache = "MISS";
|
|
}
|
|
}
|