Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@brunobbbs
Last active July 5, 2020 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brunobbbs/1dd690fa2691e5fef6de134bd9b6ef86 to your computer and use it in GitHub Desktop.
Save brunobbbs/1dd690fa2691e5fef6de134bd9b6ef86 to your computer and use it in GitHub Desktop.
Varnish example file for Plone installation
# VCL file optimized for plone.app.caching. See vcl(7) for details
vcl 4.0;
import directors;
import std;
probe healthcheck {
.interval = 10s;
.request = "HEAD / HTTP/1.1";
.timeout = 2s;
.threshold = 3;
.window = 5;
}
backend client1 {
.host = "127.0.0.1";
.port = "8081";
.connect_timeout = 0.4s;
.first_byte_timeout = 2m;
.between_bytes_timeout = 60s;
.probe = healthcheck;
.max_connections = 32;
}
backend client2 {
.host = "127.0.0.1";
.port = "8082";
.connect_timeout = 0.4s;
.first_byte_timeout = 2m;
.between_bytes_timeout = 60s;
.probe = healthcheck;
.max_connections = 32;
}
backend client3 {
.host = "127.0.0.1";
.port = "8083";
.connect_timeout = 0.4s;
.first_byte_timeout = 2m;
.between_bytes_timeout = 60s;
.probe = healthcheck;
.max_connections = 32;
}
backend client4 {
.host = "127.0.0.1";
.port = "8084";
.connect_timeout = 0.4s;
.first_byte_timeout = 2m;
.between_bytes_timeout = 60s;
.probe = healthcheck;
.max_connections = 32;
}
# For now, we'll only allow purges coming from localhost
acl purge {
"127.0.0.1";
"localhost";
}
sub vcl_init {
new cluster = directors.round_robin();
cluster.add_backend(client1);
cluster.add_backend(client2);
cluster.add_backend(client3);
cluster.add_backend(client4);
}
sub vcl_recv {
if (req.http.host ~ "^(www\.)?seuportal.com$") {
set req.backend_hint = cluster.backend();
set req.url = "/VirtualHostBase/http/" + req.http.host + ":80/Plone/VirtualHostRoot" + req.url;
}
if (req.http.host ~ "^localhost$") {
set req.http.host = "seuportal.com";
set req.url = "/VirtualHostBase/http/" + req.http.host + ":80/Plone/VirtualHostRoot" + req.url;
}
#
# Do Plone cookie sanitization, so cookies do not destroy cacheable anonymous pages
#
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, ";(statusmessages|__ac|_ZopeId|__cp)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
}
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return(synth(403, "Not allowed"));
}
return (purge);
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.method != "GET" && req.method != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.url ~ "\.(jpe?g|png|gif|pdf|gz|tgz|bz2|tbz|tar|zip|tiff|tif)$" || req.url ~ "/(image|(image_(?:[^/]|(?!view.*).+)))$") {
return (hash);
}
if (req.url ~ "\.(svg|swf|ico|mp3|mp4|m4a|ogg|mov|avi|wmv|flv)$") {
return (hash);
}
if (req.url ~ "\.(xls|vsd|doc|ppt|pps|vsd|doc|ppt|pps|xls|pdf|sxw|rar|odc|odb|odf|odg|odi|odp|ods|odt|sxc|sxd|sxi|sxw|dmg|torrent|deb|msi|iso|rpm)$") {
return (hash);
}
if (req.url ~ "\.(css|js)$") {
return (hash);
}
if (req.http.Authorization || req.http.Cookie ~ "(^|; )(__ac=|_ZopeId=)") {
/* Not cacheable by default */
return (pass);
}
return (hash);
}
sub vcl_backend_response {
# Here we could unset cookies explicitly,
# but we assume plone.app.caching extension does it jobs
# and no extra cookies fall through for HTTP responses we'd like to cache
# (like images)
if (beresp.status >= 500 && beresp.status < 600) {
unset beresp.http.Cache-Control;
set beresp.http.Cache-Control = "no-cache, max-age=0, must-revalidate";
set beresp.ttl = 0s;
set beresp.http.Pragma = "no-cache";
set beresp.uncacheable = true;
return(deliver);
}
if (beresp.ttl <= 0s
|| beresp.http.Set-Cookie
|| beresp.http.Surrogate-control ~ "no-store"
|| (!beresp.http.Surrogate-Control && beresp.http.Cache-Control ~ "no-cache|no-store|private")
|| beresp.http.Vary == "*") {
/* * Mark as "Hit-For-Pass" for the next 2 minutes */
set beresp.ttl = 120s;
set beresp.uncacheable = true;
}
set beresp.grace = 120s;
return (deliver);
}
sub vcl_hash {
hash_data(req.url);
# if (req.http.host) {
# hash_data(req.http.host);
# } else {
# hash_data(server.ip);
# }
return (lookup);
}
# error() is now synth()
sub vcl_synth {
if (resp.status == 720) {
# We use this special error status 720 to force redirects with 301 (permanent) redirects
# To use this, call the following from anywhere in vcl_recv: error 720 "http://host/new.html"
set resp.status = 301;
set resp.http.Location = resp.reason;
return (deliver);
} elseif (resp.status == 721) {
# And we use error status 721 to force redirects with a 302 (temporary) redirect
# To use this, call the following from anywhere in vcl_recv: error 720 "http://host/new.html"
set resp.status = 302;
set resp.http.Location = resp.reason;
return (deliver);
}
return (deliver);
}
sub vcl_synth {
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.Retry-After = "5";
synthetic( {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>"} + resp.status + " " + resp.reason + {"</title>
</head>
<body>
<h1>Error "} + resp.status + " " + resp.reason + {"</h1>
<p>"} + resp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} + req.xid + {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"} );
return (deliver);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
set resp.http.X-Cache-Hits = obj.hits;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment