Skip to content

Instantly share code, notes, and snippets.

@cloudmanic
Created November 30, 2018 03:12
Show Gist options
  • Save cloudmanic/dae4eb6ada2274b3654349f351f1bb33 to your computer and use it in GitHub Desktop.
Save cloudmanic/dae4eb6ada2274b3654349f351f1bb33 to your computer and use it in GitHub Desktop.
vcl 4.0;
import directors;
acl purge {
"localhost";
}
backend server1 {
.host = "XXXXXXX.compute-1.amazonaws.com";
.port = "6080";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
backend server2 {
.host = "XXXXXXX.compute-1.amazonaws.com";
.port = "6080";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
sub vcl_init {
new vdir = directors.round_robin();
vdir.add_backend(server1);
vdir.add_backend(server2);
}
sub vcl_recv {
# send all traffic to the bar director:
set req.backend_hint = vdir.backend();
if(req.http.host == "admin.XXXXXX.org") {
return (pass);
}
// Since we do not have a way to purge site maps we do not cache them.
if (req.url ~ "\.xml(\.gz)?$") {
return (pass);
}
# allow PURGE from acl list
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return(synth(405,"Purging not allowed for " + client.ip));
}
return (purge);
}
# allow BAN from acl list
if (req.method == "BAN") {
if (!client.ip ~ purge) {
return(synth(405,"Purging not allowed for " + client.ip));
}
ban("obj.http.x-depends-on ~ .+(" + req.http.X-Depends-On-Ban + ").+");
return(synth(200, "Ban added - " + req.http.X-Depends-On-Ban));
}
# Only deal with "normal" types
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "PATCH" &&
req.method != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# Only cache GET or HEAD requests. This makes sure the POST requests are always passed.
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Some generic URL manipulation, useful for all templates that follow
# First remove the Google Analytics added parameters, useless for our backend
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, "\?$", "");
}
# Strip hash, server doesn't need it.
if (req.url ~ "\#") {
set req.url = regsub(req.url, "\#.*$", "");
}
# Strip a trailing ? if it exists
if (req.url ~ "\?$") {
set req.url = regsub(req.url, "\?$", "");
}
# Some generic cookie manipulation, useful for all templates that follow
# Remove the "has_js" cookie
set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
# Remove any Google Analytics based cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "_gat=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");
# Remove DoubleClick offensive cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", "");
# Remove the Quant Capital cookies (added by some plugin, all __qca)
set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
# Remove the AddThis cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", "");
# Remove a ";" prefix in the cookie if present
set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
# Are there cookies left with only spaces or that are empty?
if (req.http.cookie ~ "^\s*$") {
unset req.http.cookie;
}
# Large static files are delivered directly to the end-user without
# waiting for Varnish to fully read the file first.
# Varnish 4 fully supports Streaming, so set do_stream in vcl_backend_response()
if (req.url ~ "^[^?]*\.(7z|avi|bz2|flac|flv|gz|mka|mkv|mov|mp3|mp4|mpeg|mpg|ogg|ogm|opus|rar|tar|tgz|tbz|txz|wav|webm|xz|zip)(\?.*)?$") {
unset req.http.Cookie;
return (hash);
}
# Not cacheable by default
if (req.http.Authorization) {
return (pass);
}
# Do not cache login page.
if(req.url ~ "(login)") {
return (pass);
}
# Do not cache search page.
if(req.url ~ "(search)") {
return (pass);
}
# Do not cache register page.
if(req.url ~ "(register)") {
return (pass);
}
# Do not cache jta page.
if(req.url ~ "(jta)") {
return (pass);
}
# Do not cache preview attempts
if(req.url ~ "^/\?preview" ) {
return (pass);
}
# Do not cache requests with a cookie
if(req.http.Cookie ~ "(^|;\s*)(PageCacheAllowed=no)(;|$)") {
return (pass);
}
return (hash);
}
sub vcl_backend_response {
# Do not cache non-200 responses
if (beresp.status != 200) {
set beresp.ttl = 2s;
set beresp.uncacheable = true;
return(deliver);
}
# Do nothing if this is the admin panel
if(bereq.http.host == "www.XXXXX.org") {
return (deliver);
}
if(bereq.http.host == "www.stage.XXXXX.org") {
return (deliver);
}
if(bereq.http.host == "www.test.XXXXXX.org") {
return (deliver);
}
# Do nothing if this is a login request
if(bereq.url ~ "(login)") {
return (deliver);
}
# Do nothing if this is a logout request
if(bereq.url ~ "(logout)") {
return (deliver);
}
if(bereq.http.Cookie ~ "(^|;\s*)(PageCacheAllowed=no)(;|$)") {
return (deliver);
}
unset beresp.http.pragma;
unset beresp.http.expires;
unset beresp.http.Cache-Control;
# This is Laravel specific, we have session-monster which sets a no-session header if we do not really need the set session cookie.
# Check for this and unset the cookies if not required
# Except if its a POST request
if (beresp.http.X-No-Session ~ "yes") {
unset beresp.http.set-cookie;
}
# Set default cache
set beresp.ttl = 1d;
# Allow stale content, in case the backend goes down.
set beresp.grace = 1h;
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
set resp.http.X-Count = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
# Remove some headers: Nginx version & OS
unset resp.http.Server;
unset resp.http.X-Powered-By;
unset resp.http.X-Varnish;
unset resp.http.Via;
unset resp.http.Link;
unset resp.http.X-Depends-On;
unset resp.http.X-No-Session;
unset resp.http.X-Generator;
unset resp.http.X-Clockwork-Id;
unset resp.http.X-Clockwork-Version;
return (deliver);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment