Skip to content

Instantly share code, notes, and snippets.

@etcook
Created February 26, 2015 00:03
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save etcook/7a11504ac728e416f294 to your computer and use it in GitHub Desktop.
Save etcook/7a11504ac728e416f294 to your computer and use it in GitHub Desktop.
# Called after a document has been successfully retrieved from the backend.
sub vcl_fetch {
# Uncomment to make the default cache "time to live" is 5 minutes, handy
# but it may cache stale pages unless purged. (TODO)
# By default Varnish will use the headers sent to it by Apache (the backend server)
# to figure out the correct TTL.
# WP Super Cache sends a TTL of 3 seconds, set in wp-content/cache/.htaccess
set beresp.ttl = 300s;
set beresp.http.X-Node = "ONE";
# Strip cookies for static files and set a long cache expiry time.
if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$") {
unset beresp.http.set-cookie;
set beresp.ttl = 24h;
} elseif (beresp.status != 302 && beresp.status != 301) {
remove beresp.http.Cache-Control;
remove beresp.http.pragma;
}
# Dump the PHPSESSID cookie - WP uses cookie based sessions
set beresp.http.cookie = regsuball(beresp.http.cookie, "PHPSESSID=[^;]+(; )?", "");
#set beresp.http.set-cookie = regsuball(beresp.http.set-cookie, "PHPSESSID=[^;]+(; )?", "");
# Varnish determined the object was not cacheable
if (beresp.ttl == 0s) {
set beresp.http.X-Cacheable = "NO:Not Cacheable";
} else if (req.http.Cookie ~"(wp-postpass|wordpress_logged_in|comment_author_|_password_protected_auth)") {
# You don't wish to cache content for logged in users
set beresp.http.X-Cacheable = "NO:Got Session";
set beresp.ttl = 0s;
return(hit_for_pass);
} else if (beresp.http.cache-control ~ "(no-cache|private)" || beresp.http.pragma ~ "no-cache") {
# You are respecting the Cache-Control=private header from the backend
set beresp.http.X-Cacheable = "NO:Cache-Control=private";
set beresp.ttl = 0s;
return(hit_for_pass);
} else if (beresp.ttl < 1s) {
# You are extending the lifetime of the object artificially
set beresp.ttl = 300s;
set beresp.grace = 300s;
set beresp.http.X-Cacheable = "YES:Forced";
} else {
# Varnish determined the object was cacheable
set beresp.http.X-Cacheable = "YES";
unset beresp.http.set-cookie;
}
if (beresp.status == 404 || beresp.status >= 500) {
set beresp.ttl = 0s;
}
# Fix a strange problem: HTTP 301 redirects to the same page sometimes go in
if (beresp.http.Location == req.proto + "://" + req.http.host + req.url
|| beresp.http.Location == req.http.X-Forwarded-Proto + "://" + req.http.host + req.url
) {
if (req.restarts > 2) {
unset beresp.http.Location;
# set beresp.http.X-Restarts = req.restarts;
} else {
return(restart);
}
}
# Deliver the content
return(deliver);
}
sub vcl_hash {
if (req.http.X-Forwarded-Proto) {
hash_data(req.http.X-Forwarded-Proto);
}
# Each cached page has to be identified by a key that unlocks it.
# Add the browser cookie only if a WordPress cookie found.
if (req.http.Cookie ~ "(wp-postpass|wordpress_logged_in|comment_author_|_password_protected_auth)") {
hash_data(req.http.Cookie);
}
hash_data(req.http.host);
hash_data(req.url);
hash_data(req.http.X-Forwarded-Proto);
hash_data(req.http.PS-CapabilityList);
return(hash);
}
# 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-ClientIP = req.http.x-reqip;
if(!req.http.x-debug){
remove resp.http.X-Varnish;
remove resp.http.Via;
remove resp.http.Age;
remove resp.http.X-Powered-By;
remove resp.http.X-Cacheable;
remove resp.http.X-Cache;
remove resp.http.X-Pingback;
remove resp.http.x-page-speed;
}
set resp.http.X-Forwarded-For = req.http.X-Forwarded-For;
set resp.http.X-Mission = "Do well. Do good. Godspeed.";
}
# vcl_recv is called whenever a request is received
sub vcl_recv {
#return(pipe);
#if (req.url~ "^/wp/") {
# set req.url = regsub(req.url, "^/wp/", "/");
#}
#if (req.url~ "^//") {
# set req.url = regsub(req.url, "^//", "/");
#}
if(req.url ~ "(wp-config.php|setup.php|xmlrpc.php)" || req.http.host == "jimandchels.com") {
error 404 "Sorry.";
return(lookup);
}
if(client.ip ~ upstream_proxy && req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For;
} else {
set req.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
}
set req.http.x-reqip = regsub(req.http.X-Forwarded-For,",\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b","");
if( req.http.x-reqip == "173.173.69.105" || client.ip ~ debug ){
set req.http.x-debug = "debug";
}
#set req.http.x-clientip = regsub(req.http.X-Forwarded-For,",\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b","");
#set req.http.x-clientip = client.ip;
if ((req.request == "POST" || req.request == "PUT") &&
req.http.transfer-encoding ~ "chunked") {
return(pipe);
}
if (req.http.Accept-Encoding !~ "gzip") {
return (pass);
}
if (req.url ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+") {
# Skip the cache for .pagespeed. resource. PageSpeed has its own
# cache for these, and these could bloat up the caching layer.
return (pass);
}
call generate_user_agent_based_key;
# Block 3d: Verify the ACL for an incoming purge request and handle it.
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return (lookup);
}
# remove ?ver=xxxxx strings from urls so css and js files are cached.
# Watch out when upgrading WordPress, need to restart Varnish or flush cache.
set req.url = regsub(req.url, "\?ver=.*$", "");
# Remove "replytocom" from requests to make caching better.
set req.url = regsub(req.url, "\?replytocom=.*$", "");
# Overwrite X-Forwarded-For header with client's IP
#remove req.http.X-Forwarded-For;
#set req.http.X-Forwarded-For = client.ip;
# OR append the forwarded ip in the header
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;
}
# Exclude this site because it breaks if cached
#if (req.http.host == "example.com") {
# return(pass);
#}
# Serve objects up to 2 minutes past their expiry if the backend is slow to respond.
set req.grace = 120s;
# Strip cookies for static files:
if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$") {
unset req.http.Cookie;
return(lookup);
}
# Remove has_js and 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 empty cookies.
if (req.http.Cookie ~ "^\s*$") {
unset req.http.Cookie;
}
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return(lookup);
error 200 "Purged.";
}
# Pass anything other than GET and HEAD directly.
if (req.request != "GET" && req.request != "HEAD") {
return(pass);
} /* We only deal with GET and HEAD by default */
# remove cookies for comments cookie to make caching better.
set req.http.cookie = regsub(req.http.cookie, "1231111111111111122222222333333=[^;]+(; )?", "");
# never cache the admin pages, or the server-status page
if (req.request == "GET" && (req.url ~ "(wp-admin|bb-admin|server-status)")) {
return(pipe);
}
# don't cache authenticated sessions
if (req.http.Cookie && req.http.Cookie ~ "(wordpress_|_password_protected_auth)") {
return(pipe);
}
# don't cache ajax requests
if(req.http.X-Requested-With == "XMLHttpRequest" || req.url ~ "nocache" || req.url ~ "(control.php|wp-comments-post.php|wp-login.php|bb-login.php|bb-reset-password.php|register.php|admin-ajax.php|customize.php)") {
return(pipe);
}
return(lookup);
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment