# VCL configuration file for Varnish # Define which IP addresses or hosts have access to files that are # blocked from the public internet acl internal { "localhost"; } # Define origin servers backend web { .host = "1.2.3.4"; .port = "80"; } backend web_ssl { .host = "1.2.3.4"; .port = "443"; } # Uncomment to support Munin graphs # backend monitoring { .host = "127.0.0.1"; .port = "8081"; } # Uncomment to include Security.VCL module # @see: https://github.com/comotion/security.vcl # include "/etc/varnish/security/main.vcl"; # Respond to incoming requests sub vcl_recv { # Uncomment to support Munin graphs. Access is granted if visitor is coming # from a whitelisted IP address and secret token is provided. # e.g. http://www.example.com/munin?your-secret-token # if (req.url ~ "^/munin" && client.ip ~ internal # && (req.url ~ "\?your-secret-token" # || req.http.referer ~ "(www\.)?example\.com")) { # set req.backend = monitoring; # return (pipe); # } # Uncomment to have New Relic track queue times # C{ # #include # }C # Handle HTTPS connection if (server.port == 443) { set req.backend = web_ssl; } else { set req.backend = web; } 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; } } # Normalize requests sent via curls -X mode and LWP if (req.url ~ "^http://") { set req.url = regsub(req.url, "http://[^/]*", ""); } # Normalize hostname to avoid double caching set req.http.host = regsub(req.http.host, "^example\.com$", "www.example.com"); # Uncomment to support shared hosting when testing through staging server # set req.http.host = regsub(req.http.host, "^cache\.example\.com$", # "www.example.com"); # Use anonymous, cached pages if all backends are down if (!req.backend.healthy) { unset req.http.Cookie; } # Allow the backend to serve up stale content if it is responding slowly set req.grace = 6h; # Do not cache these paths if (req.url ~ "^/status\.php$" || req.url ~ "^/administrator") { return (pass); } # Do not cache authenticated sessions if (req.http.Cookie && req.http.Cookie ~ "authtoken=") { return (pipe); } # Do not allow outside access to configuration.php if (req.url ~ "^/configuration\.php$" && !client.ip ~ internal) { # Have Varnish throw the error directly # error 404 "Page not found."; # Use a custom error page set req.url = "/"; } # Allow purge only from internal users if (req.request == "PURGE") { if (!client.ip ~ internal) { error 405 "Not allowed."; } return (lookup); } # 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; } } # Always cache the following file types for all users if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|pdf|txt|css|js|html|htm|gz|xml)(\?[a-z0-9]+)?$") { unset req.http.Cookie; } 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") { return (pass); } # We cache requests with cookies too (e.g. Google Analytics) # Original: if (req.http.Authenticate || req.http.Authorization # || req.http.Cookie) { if (req.http.Authenticate || req.http.Authorization) { 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); # } # Determine the cache key when storing/retrieving a cached page sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } # Don't include cookie in hash # if (req.http.Cookie) { # hash_data(req.http.Cookie); # } return (hash); } sub vcl_hit { if (req.request == "PURGE") { purge; error 200 "Purged."; } if (obj.ttl <= 0s) { return (pass); } return (deliver); } sub vcl_miss { if (req.request == "PURGE") { error 404 "Not in cache."; } return (fetch); } # Called when the requested object has been retrieved from the backend, or the # request to the backend has failed; "beresp" stands for back-end response sub vcl_fetch { # Don't allow static files to set cookies if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|pdf|txt|css|js|html|htm|gz|xml)(\?[a-z0-9]+)?$") { unset beresp.http.Set-cookie; } # Allow items to be stale if needed set beresp.grace = 6h; if (beresp.ttl <= 0s) { set beresp.http.X-Cacheable = "NO:Not Cacheable"; return (hit_for_pass); } else if (req.http.Cookie ~"(UserID|_session)") { # Don't cache content for logged in users set beresp.http.X-Cacheable = "NO:Got Session"; return (hit_for_pass); } else if (beresp.http.Cache-Control ~ "private") { # Respect the Cache-Control=private header from the backend set beresp.http.X-Cacheable = "NO:Cache-Control=private"; return (hit_for_pass); } else if (beresp.ttl < 1s) { # Extend 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"; # Uncomment to have Varnish cache objects longer than the clients do. # Cache must be purged manually when the site changes, so don't use with # frequently changing content - comments, visitor counters etc. # @see: https://www.varnish-cache.org/trac/wiki/VCLExampleLongerCaching # unset beresp.http.expires; # set beresp.ttl = 1w; # set beresp.http.magicmarker = "1"; } return (deliver); } sub vcl_deliver { # Uncomment to add hostname to headers # set resp.http.X-Served-By = server.hostname; # Identify which Varnish handled the request if (obj.hits > 0) { set resp.http.X-Cache = "HIT from Tokyo"; set resp.http.X-Cache-Hits = obj.hits; } else { set resp.http.X-Cache = "MISS from Tokyo"; } # Remove version number sometimes set by CMS if (resp.http.X-Content-Encoded-By) { unset resp.http.X-Content-Encoded-By; } if (resp.http.magicmarker) { # Remove the magic marker, see vcl_fetch unset resp.http.magicmarker; # By definition we have a fresh object set resp.http.Age = "0"; } return (deliver); } sub vcl_error { # Redirect to some other URL in case of root page failure # if (req.url ~ "^/?$") { # set obj.status = 302; # set obj.http.Location = "http://backup.example.com/"; # } # Otherwise redirect to root, which will likely be in the cache set obj.http.Content-Type = "text/html; charset=utf-8"; synthetic {" Page Unavailable

Page Unavailable

The page you requested is temporarily unavailable.

We're redirecting you to the homepage in 3 seconds.

(Error "} + obj.status + " " + obj.response + {")
"}; return (deliver); }