Skip to content

Instantly share code, notes, and snippets.

@cmejo
Created May 28, 2014 18:16
Show Gist options
  • Save cmejo/ee549b7bb0d8f0d88cfd to your computer and use it in GitHub Desktop.
Save cmejo/ee549b7bb0d8f0d88cfd to your computer and use it in GitHub Desktop.

Revisions

  1. cmejo created this gist May 28, 2014.
    302 changes: 302 additions & 0 deletions default.vcl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,302 @@
    # 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 {"
    <?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_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);
    }