Created
October 9, 2013 20:48
-
-
Save wwhurley/6908087 to your computer and use it in GitHub Desktop.
VCL
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
# This is a basic VCL configuration file for varnish. See the vcl(7) | |
# man page for details on VCL syntax and semantics. | |
# | |
# Default backend definition. Set this to point to your content | |
# server. | |
# | |
include "acl.vcl"; | |
include "backends.vcl"; | |
# Respond to incoming requests. | |
sub vcl_recv { | |
if (req.request == "GET" && req.url ~ "^/varnishcheck$") { | |
error 200 "Varnish is Ready"; | |
} | |
# nginx status checks | |
if (req.url ~ "^/nginx_status") { | |
if ( !client.ip ~ internal) { | |
error 405 "Not allowed."; | |
} else { | |
return (pass); | |
} | |
} | |
# Allow PURGE from localhost and 192.168.0.0/24 | |
if (req.request == "PURGE") { | |
if (!client.ip ~ purge) { | |
error 405 "Not allowed."; | |
} | |
return (lookup); | |
} | |
# Get ride of progress.js query params | |
if (req.url ~ "^/misc/progress\.js\?[0-9]+$") { | |
set req.url = "/misc/progress.js"; | |
} | |
# If global redirect is on | |
#if (req.url ~ "node\?page=[0-9]+$") { | |
# set req.url = regsub(req.url, "node(\?page=[0-9]+$)", "\1"); | |
# return (lookup); | |
#} | |
# Do not cache these paths. | |
# Drupal: | |
if (req.url ~ "^/status\.php$" || | |
req.url ~ "^/update\.php$" || | |
req.url ~ "^/ooyala/ping$" || | |
req.url ~ "^/admin" || | |
req.url ~ "^/admin/.*$" || | |
req.url ~ "^/user" || | |
req.url ~ "^/user/.*$" || | |
req.url ~ "^/users/.*$" || | |
req.url ~ "^/info/.*$" || | |
req.url ~ "^/flag/.*$" || | |
req.url ~ "^.*/ajax/.*$" || | |
req.url ~ "^.*/phpmyadmin/.*$" || | |
req.url ~ "^.*/ahah/.*$") { | |
return (pass); | |
} | |
# Pipe these paths directly to Apache for streaming. | |
if (req.url ~ "^/admin/content/backup_migrate/export") { | |
return (pipe); | |
} | |
# Handle compression correctly. Different browsers send different | |
# "Accept-Encoding" headers, even though they mostly all support the same | |
# compression mechanisms. By consolidating these compression headers into | |
# a consistent format, we can reduce the size of the cache and get more hits.= | |
# @see: http:// varnish.projects.linpro.no/wiki/FAQ/Compression | |
if (req.http.Accept-Encoding) { | |
if (req.http.Accept-Encoding ~ "gzip") { | |
# If the browser supports it, we'll use gzip. | |
set req.http.Accept-Encoding = "gzip"; | |
} | |
else if (req.http.Accept-Encoding ~ "deflate") { | |
# Next, try deflate if it is supported. | |
set req.http.Accept-Encoding = "deflate"; | |
} | |
else { | |
# Unknown algorithm. Remove it and send unencoded. | |
unset req.http.Accept-Encoding; | |
} | |
} | |
# Remove all cookies that Drupal doesn't need to know about. ANY remaining | |
# cookie will cause the request to pass-through to a backend. For the most part | |
# we always set the NO_CACHE cookie after any POST request, disabling the | |
# Varnish cache temporarily. The session cookie allows all authenticated users | |
# to pass through as long as they're logged in. | |
# | |
# 1. Append a semi-colon to the front of the cookie string. | |
# 2. Remove all spaces that appear after semi-colons. | |
# 3. Match the cookies we want to keep, adding the space we removed | |
# previously, back. (\1) is first matching group in the regsuball. | |
# 4. Remove all other cookies, identifying them by the fact that they have | |
# no space after the preceding semi-colon. | |
# 5. Remove all spaces and semi-colons from the beginning and end of the | |
# cookie string. | |
if (req.http.Cookie) { | |
set req.http.Cookie = ";" + req.http.Cookie; | |
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";"); | |
set req.http.Cookie = regsuball(req.http.Cookie, ";(S{1,2}ESS[a-z0-9]+|NO_CACHE|PHPSESS|cfs_session|wordpress_logged_in_[a-z0-9]+|wordpress_[a-z0-9]+|wordpress_test_cookie.*+)=", "; \1="); | |
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", ""); | |
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); | |
if (req.http.Cookie == "") { | |
# If there are no remaining cookies, remove the cookie header. If there | |
# aren't any cookie headers, Varnish's default behavior will be to cache | |
# the page. | |
unset req.http.Cookie; | |
} | |
else { | |
# If there is any cookies left (a session or NO_CACHE cookie), do not | |
# cache the page. Pass it on to Apache directly. | |
return (pass); | |
} | |
} | |
## From default below ## | |
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; | |
} | |
} | |
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); | |
} | |
if (req.request != "GET" && req.request != "HEAD") { | |
/* We only deal with GET and HEAD by default */ | |
return (pass); | |
} | |
## Unset Authorization header if it has the correct details... | |
if (req.http.Authorization == "Basic Zm9ydW1vbmU6ZjFkZXY=") { | |
unset req.http.Authorization; | |
} | |
if (req.http.Authorization || req.http.Cookie) { | |
#if (req.http.Cookie) { | |
/* Not cacheable by default */ | |
return (pass); | |
} | |
return (lookup); | |
} | |
sub vcl_pipe { | |
# Note that only the first request to the backend will have | |
# X-Forwarded-For set. If you use X-Forwarded-For and want to | |
# have it set for all requests, make sure to have: | |
set bereq.http.connection = "close"; | |
# here. It is not set by default as it might break some broken web | |
# applications, like IIS with NTLM authentication. | |
} | |
# Routine used to determine the cache key if storing/retrieving a cached page. | |
sub vcl_hash { | |
if (req.http.X-Forwarded-Proto == "https") { | |
hash_data(req.http.X-Forwarded-Proto); | |
} | |
} | |
sub vcl_hit { | |
if (req.request == "PURGE") { | |
ban("obj.http.x-url ~ " + req.url); | |
error 200 "Purged."; | |
} | |
} | |
sub vcl_miss { | |
if (req.request == "PURGE") { | |
ban("obj.http.x-url ~ " + req.url); | |
error 200 "Purged."; | |
} | |
} | |
# Code determining what to do when serving items from the Apache servers. | |
sub vcl_fetch { | |
# Don't allow static files to set cookies. | |
if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js)(\?[a-z0-9]+)?$") { | |
# beresp == Back-end response from the web server. | |
unset beresp.http.set-cookie; | |
} | |
else if (beresp.http.Cache-Control) { | |
unset beresp.http.Expires; | |
} | |
if (beresp.status == 301) { | |
set beresp.ttl = 1h; | |
return(deliver); | |
} | |
## Doesn't seem to work as expected | |
#if (beresp.status == 500) { | |
# set beresp.saintmode = 10s; | |
# return(restart); | |
#} | |
# Allow items to be stale if needed. | |
set beresp.grace = 1h; | |
} | |
# Set a header to track a cache HIT/MISS. | |
sub vcl_deliver { | |
if (obj.hits > 0) { | |
set resp.http.X-Varnish-Cache = "HIT"; | |
} | |
else { | |
set resp.http.X-Varnish-Cache = "MISS"; | |
} | |
} | |
# In the event of an error, show friendlier messages. | |
sub vcl_error { | |
# Throw 401 for unauth requests | |
if (obj.status == 401) { | |
set obj.http.Content-Type = "text/html; charset=utf-8"; | |
set obj.http.WWW-Authenticate = "Basic realm=Secured"; | |
synthetic {" | |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"> | |
<HTML> | |
<HEAD> | |
<TITLE>Error</TITLE> | |
<META HTTP-EQUIV='Content-Type' CONTENT='text/html;'> | |
</HEAD> | |
<BODY><H1>401 Unauthorized (varnish)</H1></BODY> | |
</HTML> | |
"}; | |
return (deliver); | |
} | |
set obj.http.Content-Type = "text/html; charset=utf-8"; | |
set obj.http.Retry-After = "5"; | |
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> | |
<p>"} + obj.response + {"</p> | |
<h3>Guru Meditation:</h3> | |
<p>XID: "} + req.xid + {"</p> | |
<hr> | |
<p>Varnish cache server</p> | |
</body> | |
</html> | |
"}; | |
return (deliver); | |
} | |
# | |
# Below is a commented-out copy of the default VCL logic. If you | |
# redefine any of these subroutines, the built-in logic will be | |
# appended to your code. | |
# sub vcl_recv { | |
# 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; | |
# } | |
# } | |
# 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); | |
# } | |
# if (req.request != "GET" && req.request != "HEAD") { | |
# /* We only deal with GET and HEAD by default */ | |
# return (pass); | |
# } | |
# if (req.http.Authorization || req.http.Cookie) { | |
# /* Not cacheable by default */ | |
# return (pass); | |
# } | |
# return (lookup); | |
# } | |
# | |
# sub vcl_pipe { | |
# # Note that only the first request to the backend will have | |
# # X-Forwarded-For set. If you use X-Forwarded-For and want to | |
# # have it set for all requests, make sure to have: | |
# # set bereq.http.connection = "close"; | |
# # here. It is not set by default as it might break some broken web | |
# # applications, like IIS with NTLM authentication. | |
# return (pipe); | |
# } | |
# | |
# sub vcl_pass { | |
# return (pass); | |
# } | |
# | |
# sub vcl_hash { | |
# hash_data(req.url); | |
# if (req.http.host) { | |
# hash_data(req.http.host); | |
# } else { | |
# hash_data(server.ip); | |
# } | |
# return (hash); | |
# } | |
# | |
# sub vcl_hit { | |
# return (deliver); | |
# } | |
# | |
# sub vcl_miss { | |
# return (fetch); | |
# } | |
# | |
# sub vcl_fetch { | |
# if (beresp.ttl <= 0s || | |
# beresp.http.Set-Cookie || | |
# beresp.http.Vary == "*") { | |
# /* | |
# * Mark as "Hit-For-Pass" for the next 2 minutes | |
# */ | |
# set beresp.ttl = 120 s; | |
# return (hit_for_pass); | |
# } | |
# return (deliver); | |
# } | |
# | |
# sub vcl_deliver { | |
# return (deliver); | |
# } | |
# | |
# sub vcl_error { | |
# set obj.http.Content-Type = "text/html; charset=utf-8"; | |
# set obj.http.Retry-After = "5"; | |
# 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> | |
# <p>"} + obj.response + {"</p> | |
# <h3>Guru Meditation:</h3> | |
# <p>XID: "} + req.xid + {"</p> | |
# <hr> | |
# <p>Varnish cache server</p> | |
# </body> | |
# </html> | |
# "}; | |
# return (deliver); | |
# } | |
# | |
# sub vcl_init { | |
# return (ok); | |
# } | |
# | |
# sub vcl_fini { | |
# return (ok); | |
# } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment