Created
February 10, 2011 19:01
-
-
Save samsoir/821104 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
C{ | |
#include <limits.h> | |
#include <errno.h> | |
}C | |
backend default { | |
.host = "192.168.192.134"; | |
.port = "80"; | |
} | |
/* Called when request arrives */ | |
sub vcl_recv | |
{ | |
#call strip_ZDEDebugger_cookies; | |
// Clear out cache pass header if it's set | |
unset req.http.X-Cache-Pass; | |
// clean out requests sent via curls -X mode and LWP | |
if (req.url ~ "^http://") { | |
set req.url = regsub(req.url, "http://[^/]*", ""); | |
} | |
if (req.request != "GET" && req.request != "HEAD" && | |
req.request != "PUT" && req.request != "POST" && | |
req.request != "TRACE" && req.request != "OPTIONS" && | |
req.request != "DELETE") { | |
/* Non-RFC2616 or CONNECT which is weird. */ | |
return (pipe); | |
} | |
/* Actively purge cache on updates */ | |
if (req.request == "PUT" || req.request == "POST" || req.request == "DELETE") { | |
call purge_updated_entries; | |
} | |
/* We can pipe form posts, no need to interfere */ | |
if (req.request == "POST" && | |
(req.http.Transfer-Encoding == "chunked" || | |
req.http.Transfer-Encoding == "multipart/form-data")) { | |
return (pipe); | |
} | |
/* Bypass Varnish completely when this cookie is set */ | |
if (req.http.Cookie ~ "CW-Varnish-Bypass") { | |
return (pipe); | |
} | |
/* Normalise the accept encoding header */ | |
call normalise_accept_encoding; | |
if (req.request == "GET" || req.request == "HEAD") { | |
/* stale-while-(revalidate|error) */ | |
set req.grace = 10s; | |
} | |
} | |
/* Forces every pipe to be a new connection. | |
Otherwise pipelined requests might fall into the same pipe */ | |
sub vcl_pipe { | |
set bereq.http.Connection = "Close"; | |
} | |
/* Called when item is fetched, decide whether to cache or not */ | |
sub vcl_fetch { | |
/* Strip cookies from static assets */ | |
if (req.url ~ "\.(png|gif|jpg|css)$") { | |
unset beresp.http.set-cookie; | |
set beresp.ttl = 1h; | |
} | |
/* Grace for longer period */ | |
set beresp.grace = 10s; | |
/* Indicate that we passed on vcl_fetch */ | |
if (req.http.X-Cache-Pass) { | |
set beresp.http.X-Cache-Pass = req.http.X-Cache-Pass; | |
return (pass); | |
} | |
call strip_ZDEDebugger_cookies_beresp; | |
/* Do not cache requests that set cookies */ | |
if (beresp.http.Set-Cookie) { | |
set beresp.http.X-Cache-Pass = "21"; | |
return (pass); | |
} | |
/* Do NOT cache requests with HTTP Authentication on, unless a special cookie is set (needed to load-test Varnish) */ | |
if (req.http.Authorization && !(req.http.Cookie ~ "CW-Varnish-No-Http-Auth")) { | |
set beresp.http.X-Cache-Pass = "HTTP Auth"; | |
//set obj.http.X-Cacheable = "NO: HTTP Authentication " obj.http.X-Cacheable; | |
return (pass); | |
} | |
/* Cache 2xx codes only for now */ | |
if (beresp.status < 200 || beresp.status > 299) { | |
set beresp.http.X-Cache-Pass = "22"; | |
return (pass); | |
} | |
/* Handle the X-Cache-Control header */ | |
if (beresp.http.X-Cache-Control) { | |
call x_cache_control; | |
} | |
/* Cache hits for pass objects. If page is not cacheable (for example Set-Cookie: XXX) | |
it's marked to pass during the lifetime of the object. Here we set the lifetime to very | |
low in order to get away from having cacheable-objects pass */ | |
if (!beresp.cacheable) { | |
if (beresp.ttl > 3s) { | |
set beresp.ttl = 3s; | |
} | |
set beresp.http.X-Cache-Pass = "24"; | |
return (pass); | |
} | |
/* Specific responses from backend cause us not to cache the page */ | |
if ((beresp.http.Cache-Control && beresp.http.Cache-Control ~ "no-cache|private|no-store|max-age=0|s-maxage=0") || | |
(beresp.http.Pragma && beresp.http.Pragma ~ "no-cache|private")) { | |
set beresp.http.X-Cache-Pass = "25"; | |
return (pass); | |
} else { | |
/* No backend cache control. Save item for 10s and send private headers so that | |
upstream doesn't pick up the cached copy */ | |
if (!beresp.http.Cache-Control) { | |
set beresp.ttl = 10s; | |
set beresp.http.Cache-Control = "private, max-age=0, no-store"; | |
} | |
} | |
return (deliver); | |
} | |
/* Add information about whether request hit cache or not */ | |
sub vcl_deliver { | |
/* PASS happens in cases where we actively pass the request */ | |
if (resp.http.X-Cache-Pass) { | |
set resp.http.X-Cache-Action = "PASS (" resp.http.X-Cache-Pass ")"; | |
unset resp.http.X-Cache-Pass; | |
} else { | |
if (obj.hits > 0) { | |
set resp.http.X-Cache-Action = "HIT"; | |
set resp.http.X-Cache-Hits = obj.hits; | |
} else { | |
set resp.http.X-Cache-Action = "MISS"; | |
} | |
} | |
/* Rename the Age header to X-Cache-Age to avoid | |
the age to invalidate legimite client caches */ | |
set resp.http.X-Cache-Age = resp.http.Age; | |
/* remove some outgoing headers */ | |
#unset resp.http.Age; | |
#unset resp.http.Via; | |
#unset resp.http.X-Varnish; | |
#unset resp.http.X-Cache-Control; | |
} | |
/* Cache configurations based on layout cookie */ | |
sub vcl_hash { | |
} | |
/* Customize error page to show simple error message */ | |
sub vcl_error { | |
/* __monitoring_check.html */ | |
if (obj.status == 200) { | |
set obj.http.Content-Type = "text/html"; | |
set obj.http.Cache-Control = "max-age=0"; | |
synthetic obj.status " " obj.response; | |
return (deliver); | |
} | |
/* Possible redirects */ | |
if (obj.status == 302 && req.url != obj.response) { | |
set obj.http.Location = "http://" req.http.Host obj.response; | |
synthetic obj.response; | |
return (deliver); | |
} | |
/* Only restart in case there was server error */ | |
if (req.restarts == 0 && obj.status >= 500 && obj.status <= 599) { | |
return (restart); | |
} else { | |
set obj.http.Content-Type = "text/html; charset=utf-8"; | |
set obj.http.Cache-Control = "private, max-age=0"; | |
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>"} obj.status " " obj.response {"</title> | |
</head> | |
<body> | |
<h1>Error "} obj.status " " obj.response {"</h1> | |
</body> | |
</html>"}; // " | |
return (deliver); | |
} | |
} | |
/* ---- Function definitions ---- */ | |
/** | |
* {{{ sub x_cache_control | |
* | |
* X-Cache-Control handling. This function can be called from vcl_fetch | |
* | |
* We support the following directives in X-Cache-Control header: | |
* - no-cache Causes varnish to pass this object (no caching made) | |
* - no-store Causes varnish to pass this object (no caching made) | |
* - max-age Allows to define custom max-age for the varnish. | |
* | |
* Note that X-Cache-Control takes precedence when it comes caching | |
* objects in the varnish cache | |
*/ | |
sub x_cache_control | |
{ | |
if (beresp.http.X-Cache-Control ~ "no-cache|no-store") { | |
set beresp.http.X-Cache-Pass = "23"; | |
unset beresp.http.X-Cache-Control; | |
return (pass); | |
} | |
if (beresp.http.X-Cache-Control ~ "max-age=[0-9]+") { | |
/* Copy the ttl from the original header so that it's easier to handle in inline C */ | |
set beresp.http.X-Cache-Control-TTL = regsub(beresp.http.X-Cache-Control, ".*max-age=([0-9]+).*", "\1"); | |
C{ | |
{ | |
const char *hdr_val = 0; | |
char *end = 0; | |
/* Get the temporary header set earlier */ | |
hdr_val = VRT_GetHdr(sp, HDR_BERESP, "\024X-Cache-Control-TTL:"); | |
if (hdr_val != (void *)0) { | |
/* Get the time to live from header value */ | |
long cache_ttl = strtol(hdr_val, &end, 0); | |
/* Make sure that it was a valid number and in range that we expect */ | |
if (ERANGE != errno && end != hdr_val && cache_ttl >= 0 && cache_ttl < INT_MAX) { | |
/* At this point we have a suitable header */ | |
VRT_l_beresp_ttl(sp, (cache_ttl * 1)); | |
} | |
} | |
} | |
}C | |
/* Do not send X-Cache-Control outside */ | |
unset beresp.http.X-Cache-Control; | |
unset beresp.http.X-Cache-Control-TTL; | |
return (deliver); | |
} | |
} | |
/* }}} */ | |
/** | |
* {{{ sub normalise_accept_encoding | |
* | |
* Normalise the accept-encoding header so that we don't | |
* cache too many copies of each page. | |
*/ | |
sub normalise_accept_encoding { | |
/* Normalise accept-encoding header */ | |
if (req.http.Accept-Encoding) { | |
if (req.http.Accept-Encoding ~ "gzip") { | |
set req.http.Accept-Encoding = "gzip"; | |
} elsif (req.http.Accept-Encoding ~ "deflate") { | |
set req.http.Accept-Encoding = "deflate"; | |
} else { | |
// unkown algorithm | |
unset req.http.Accept-Encoding; | |
} | |
} | |
} | |
/* }}} */ | |
/** | |
* {{{ sub strip_ZDEDebugger_cookies | |
* | |
* Strip the Zend Debugger cookies | |
sub strip_ZDEDebugger_cookies { | |
set req.http.Cookie = regsuball(req.http.Cookie, "ZDEDebuggerPresent[^;]+(; )?", ""); | |
set req.http.Cookie = regsub(req.http.Cookie, "; $", ""); | |
if (req.http.Cookie ~ "^ *$") { | |
remove req.http.Cookie; | |
} | |
} | |
*/ | |
/* }}} */ | |
/** | |
* {{{ sub strip_ZDEDebugger_cookies_beresp | |
* | |
* Strip the Zend Debugger cookies from beresp | |
*/ | |
sub strip_ZDEDebugger_cookies_beresp { | |
set beresp.http.Set-Cookie = regsuball(beresp.http.Set-Cookie, "ZDEDebuggerPresent[^;]+(; )?", ""); | |
set beresp.http.Set-Cookie = regsub(beresp.http.Set-Cookie, "; $", ""); | |
set beresp.http.Set-Cookie = regsub(beresp.http.Set-Cookie, "^path=/$", ""); | |
if (beresp.http.Set-Cookie ~ "^ *$") { | |
remove beresp.http.Set-Cookie; | |
} | |
} | |
/* }}} */ | |
/** | |
* {{{ sub purge_updated_entries | |
* | |
* Purge the cache when there's an UPDATE action | |
*/ | |
sub purge_updated_entries { | |
// Purge the cache for the Favourites toolbar when the user adds a new favourite | |
call get_user_id_from_url; | |
if (req.http.X-Varnish-SL-Userid) { | |
purge("req.url ~ " req.http.X-Varnish-SL-Userid); | |
} | |
} | |
/* }}} */ | |
/** | |
* {{{ sub get_user_id_from_url | |
* | |
* Get the User ID from the URL | |
* and store it into the req.http.X-Varnish-SL-Userid header | |
*/ | |
sub get_user_id_from_url { | |
if (req.url ~ "^/customer/") { | |
set req.http.X-Varnish-SL-Userid = regsub(req.url, "^/customer/([^/]+)/", "\1"); | |
} | |
} | |
/* }}} */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment