Created
February 7, 2013 18:30
-
-
Save daniel-nelson/4733045 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
backend example { | |
.host = "<%=http_endpoint%>"; | |
.port = "<%=http_port%>"; | |
} | |
backend s3 { | |
.host = "assets.example.me"; | |
.port = "80"; | |
} | |
backend s3staging { | |
.host = "stagingassets.example.me"; | |
.port = "80"; | |
} | |
sub vcl_deliver { | |
# This just inserts a diagnostic header to let us know if the content | |
# was served via a cache hit, or whether it was a miss. | |
if (obj.hits > 0) { | |
set resp.http.X-Cache = "HIT"; | |
} else { | |
set resp.http.X-Cache = "MISS"; | |
} | |
} | |
sub vcl_recv { | |
# if request is a purge then allow it through without doing redirects or ssl checks (it's purpose is clear) | |
if (req.request == "PURGE") { | |
if (!req.http.X-Purge-Token ~ "xxxxxxxxxxxxxxx") { | |
error 405 "Not allowed."; | |
} | |
return(lookup); | |
} | |
# if it matches our domains and is not secure then redirect | |
if ( (req.http.host ~ "^(www\.)?example\.me\.?" || req.http.host ~ "^(www\.)?examplestaging\.com\.?") | |
&& req.http.X-Forwarded-Proto !~ "(?i)https" | |
&& req.url !~ "/(images|assets|javascripts|stylesheets|themes|vendor)") { | |
# If we are insecure and also have the www. then strip that as well (avoiding double redirect below) | |
# This is done here instead of below to improve user experience. | |
# If this wasn't here, it would redirect with www then hit a second redirect | |
set req.http.host = regsub(req.http.host, "^www\.", ""); | |
set req.http.host = regsub(req.http.host, "\.$", ""); | |
set req.http.x-Redir-Url = "https://" + req.http.host + req.url; | |
error 750 req.http.x-Redir-Url; # throw exception which is caught in vcl_error and turned into redirect | |
} | |
# If we are correctly using https but we have the www. or we have a trailing period, strip it off | |
if ( req.http.host ~ "^www\.example\.me" || req.http.host ~ "^www\.examplestaging\.com" || req.http.host ~ "example\.me\.$" || req.http.host ~ "examplestaging\.com\.$") { | |
set req.http.host = regsub(req.http.host, "^www\.", ""); | |
set req.http.host = regsub(req.http.host, "\.$", ""); | |
set req.http.x-Redir-Url = "https://" + req.http.host + req.url; | |
error 750 req.http.x-Redir-Url; # throw exception which is caught in vcl_error and turned into redirect | |
} | |
# pass asset data on to s3. append gz to appropriate content so that we store gz content in cache. | |
# varnish will decompress it if the browser doesn't support it. | |
if ( req.http.host ~ "^s3assets.example.me$") { | |
set req.url = regsub(req.url, "(css|js)$", "\1.gz"); | |
set req.http.host = "assets.example.me"; | |
set req.backend = s3; | |
} else if (req.http.host ~ "^s3assets.examplestaging.com$") { | |
set req.url = regsub(req.url, "(css|js)$", "\1.gz"); | |
set req.http.host = "stagingassets.example.me"; | |
set req.backend = s3staging; | |
} else { | |
set req.backend = example; | |
} | |
if (req.request != "GET") { | |
return(pass); | |
} | |
# force to a single encoding type so that order in list doesn't break our caches | |
# disable ie6 from receiving compression, even if it says it supports it. ie6 has many bugs around this | |
if (req.http.Accept-Encoding) { | |
if (req.http.User-Agent ~ "MSIE 6") { | |
unset req.http.Accept-Encoding; | |
} elsif (req.http.Accept-Encoding ~ "gzip") { | |
set req.http.Accept-Encoding = "gzip"; | |
} elsif (req.http.Accept-Encoding ~ "deflate") { | |
set req.http.Accept-Encoding = "deflate"; | |
} else { | |
unset req.http.Accept-Encoding; | |
} | |
} | |
return(lookup); | |
} | |
sub vcl_hit { | |
if (req.request == "PURGE") { | |
purge; # Varnish 3.0.x | |
error 200 "Purged."; | |
} | |
} | |
sub vcl_miss { | |
if (req.request == "PURGE") { | |
error 200 "Not in cache."; | |
} | |
} | |
sub vcl_fetch { | |
if (beresp.http.Server ~ "AmazonS3") { | |
# if it is coming from amazon then it would have the header Server: AmazonS3 | |
# we don't want to cache this as it is going to be cached by cloudfront | |
# remove cookies from all publicly cacheable resources | |
remove beresp.http.Set-Cookie; | |
# save the decision that this request can not be cached by creating a hit_for_pass object | |
# http://stackoverflow.com/questions/12691489/varnish-hit-for-pass-means | |
return(hit_for_pass); | |
} else if (beresp.http.Cache-Control ~ "public") { | |
# remove cookies from all publicly cacheable resources | |
remove beresp.http.Set-Cookie; | |
if (beresp.http.X-Public-ExampleDoc ~ "true") { | |
remove beresp.http.X-Public-ExampleDoc; | |
# this is a publicly published doc. set cache-control in such a way as to force | |
# browser to check with Varnish to see whether the doc has been modified (which | |
# happens when changes or published or the doc is no longer publicly published | |
# at this url) on all subsequent requests | |
set beresp.http.Cache-Control = "public, max-age=0, must-revalidate"; | |
} | |
return(deliver); | |
} | |
# do NOT cache this. the previous conditional already checked the cache control header for 'public', | |
# so this document does not include a public cache control | |
# save the decision that this request can not be cached by creating a hit_for_pass object | |
# http://stackoverflow.com/questions/12691489/varnish-hit-for-pass-means | |
return(hit_for_pass); | |
} | |
sub vcl_error { | |
if (obj.status == 200) { | |
# purge errors with 200 | |
return (deliver); | |
} | |
if (obj.status == 750) { | |
#catch errors to handle redirect scenarios. used for redirecting to ssl | |
set obj.http.Location = obj.response; | |
set obj.status = 302; | |
return (deliver); | |
} | |
return (deliver); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment