Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ncserny/49a2a821f048859c50c4 to your computer and use it in GitHub Desktop.
Save ncserny/49a2a821f048859c50c4 to your computer and use it in GitHub Desktop.
Varnish 3 VCL for Cloudflare + WordPress + W3 Total Cache
# Backend Server
backend default {
.host = "XXX.XXX.XXX.XXX"; # IP Address of your Web Server
.port = "80"; # Port of your Web Server
}
# Hosts allowed to purge Varnish
acl purge {
"localhost"; # Allow varnish to be purged from the same server it is running on
"XXX.XXX.XXX.XXX"/24; # IP of your web server that is allowed to purge the cache
}
sub vcl_recv {
# Get Varnish to pass a header to Apache with the client IP
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 Request Denied or fullfilled
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return (lookup);
}
# Pipe if the request method is non-standard
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
return (pipe);
}
# Bypass cache if the request method is not GET or HEAD
if (!(req.request == "GET" || req.request == "HEAD")) {
return (pass);
}
# Bypass cache if the request goes to administration URLs
if (req.url ~ "wp-(login|admin|cron|includes)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
return (pass);
}
# Remove has_js and CloudFlare/Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
# Remove cookies from static assets
if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.*$", "");
}
# Remove Parameters from capaign urls, etc.
if (req.url ~ "\?(utm_(campaign|medium|source|term)|adParams|client|cx|eid|fbid|feed|ref(id|src)?|v(er|iew))=") {
set req.url = regsub(req.url, "\?.*$", "");
}
if (req.http.cookie) {
if (req.http.cookie ~ "(wordpress_|wp-settings-)") {
return(pass);
} else {
unset req.http.cookie;
}
}
}
sub vcl_fetch {
if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true") {
return (hit_for_pass);
}
# Get rid of User Agent to improve caching
if (beresp.http.Vary ~ "User-Agent") {
set beresp.http.Vary = regsub(beresp.http.Vary, ",? *User-Agent *", "");
set beresp.http.Vary = regsub(beresp.http.Vary, "^, *", "");
if (beresp.http.Vary == "") {
unset beresp.http.Vary;
}
}
# Cache 301 and 302 and set a lifetime of 1 day
if (beresp.status == 301 || beresp.status == 302) {
set beresp.ttl = 1d;
return (deliver);
}
# Only allow cookies to be set if we're in admin area
if (!(bereq.url ~ "(wp-login|wp-admin|preview=true)")) {
unset beresp.http.set-cookie;
}
}
sub vcl_deliver {
# Send headers in order to know if cache has been hit or missed
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "OK";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 404 "Not cached";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment