# This is a basic VCL configuration file for varnish. See the vcl(7) main page for details on VCL syntax and semantics. # # Default backend definition. Set this to point to your content server. # backend default { .host = "127.0.0.1"; .port = "8080"; .connect_timeout = 600s; .first_byte_timeout = 600s; .between_bytes_timeout = 600s; } # Detect the device sub detect_device { # define the 'desktop' device set req.http.X-Device = "desktop"; if (req.http.User-Agent ~ "iP(hone|od)" || req.http.User-Agent ~ "Android" || req.http.User-Agent ~ "Windows Phone" || req.http.User-Agent ~ "Symbian" || req.http.User-Agent ~ "webOS" || req.http.User-Agent ~ "Blackberry") { # Define smartphones and tablets set req.http.X-Device = "mobile"; } } # Respond to incoming requests. sub vcl_recv { # bypass varnish for dev sites if ( req.http.host ~ "^dev-assets.*$" ) { return (pass); } if ( req.http.host ~ "^dev-new.*$" ) { return (pass); } if ( req.http.host ~ "^mobiledev.*$" ) { return (pass); } #redirect non-www to www, four domains if ( req.http.host == "universitybusiness.com") { set req.http.host = "www.universitybusiness.com"; error 750 "http://" + req.http.host + req.url; } if ( req.http.host == "districtadministration.com") { set req.http.host = "www.districtadministration.com"; error 750 "http://" + req.http.host + req.url; } if ( req.http.host == "ubtechconference.com") { set req.http.host = "www.ubtechconference.com"; error 750 "http://" + req.http.host + req.url; } if ( req.http.host == "daleadershipinstitute.com") { set req.http.host = "www.daleadershipinstitute.com"; error 750 "http://" + req.http.host + req.url; } #custom redirects for jobs landing pages if (req.http.host ~ "^jobs\.universitybusiness\.com$") { error 750 "http://www.universitybusiness.com/jobs-interest"; } else if (req.http.host ~ "^jobs\.districtadministration\.com$") { error 750 "http://www.districtadministration.com/jobs-interest"; } call detect_device; 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.url ~ "^/varnishcheck$") { error 200 "Varnish is Ready"; } # Allow the backend to serve up stale content if it is responding slowly. if (!req.backend.healthy) { # Use anonymous, cached pages if all backends are down. unset req.http.Cookie; if (req.http.X-Forwarded-Proto == "https") { set req.http.X-Forwarded-Proto = "http"; } set req.grace = 30m; } else { set req.grace = 15s; } # 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. 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 ~ "^.*/ahah/.*$") { return (pass); } # Pipe these paths directly to Apache for streaming. if (req.url ~ "^/admin/content/backup_migrate/export") { return (pipe); } # Do not allow outside access to cron.php or install.php. #if (req.url ~ "^/(cron|install)\.php$" && !client.ip ~ internal) { # Have Varnish throw the error directly. #error 404 "Page not found."; # Use a custom error page that you've defined in Drupal at the path "404". # set req.url = "/404"; #} # 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|css|js)(\?[a-z0-9]+)?$") { unset req.http.Cookie; } # 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)=", "; \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.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 ") { # unset req.http.Authorization; #} if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } return (lookup); } # 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"; } # don't send a cache header down to the browser # make them always get it from Varnish remove resp.http.Cache-Control; } # In the event of an error, show friendlier messages. sub vcl_error { # handle simple redirects directly if (obj.status == 750) { set obj.http.Location = obj.response; set obj.status = 301; return (deliver); } set obj.http.Content-Type = "text/html; charset=utf-8"; set obj.http.Retry-After = "5"; synthetic {" "} + obj.status + " " + obj.response + {"

Error "} + obj.status + " " + obj.response + {"

"} + obj.response + {"

Guru Meditation:

XID: "} + req.xid + {"


Varnish cache server

"}; return (deliver); } sub vcl_hash { #Existing hash configuration hash_data(req.url); if(req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } # And then add the device to the hash (if its a mobile device) if (req.http.X-Device ~ "mobile") { hash_data(req.http.X-Device); } return (hash); }