SmartPixels
Got an idea?

Smart Varnish Cache Bypass With Cookies

Varnish is an extremely easy to use high performance HTTP reverse proxy that caches your content thereby accelerating content delivery and minimising resource usage. However, the default Varnish configurations doesn’t always work well, you would require some custom modifications based on your website.

Handling cookies and headers varies vastly from websites and that could be the difference in getting the best out of your varnish installation. By default Varnish will ignore all requests with cookies and if you are passing up all your request then you might as well not use Varnish. Everyone might already know that most websites use cookies to track and store data.

Ofcourse, you could always configure Varnish to ignore all the cookies but you would end up caching guests and users alike, which would cause problems if you want to show user-specific or real-time content based on users.

If you do want to serve uncached content to users then these two lines of code in your default varnish configuration file under the vcl_recv section would do the trick.

     if( req.request == "POST" ||  req.http.cookie ~ "smart_varnish_bypass" )
  {
    return( pass );
  }

The above code is just an example of how you could use the cookies to bypass varnish thereby serving uncached content to users. Remember, Varnish being a reverse proxy would pass the request on to your server.

WordPress Plugin

Caching WordPress with Varnish can be made easy with our plugin Smart Varnish For WordPress. It creates a cookie when a user logs into your WordPress powered site there by allowing us to bypass varnish caching.

Joomla Plugin

We have also developed a Smart Varnish For Joomla plugin, compatible with both Joomla 2.5 and 3.0. Works exactly like the WordPress plugin and you need to follow the same procedure while configuring varnish.

Sample Varnish vcl_recv Configuration

# Handle the HTTP request received

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;
        }
    }

    # remove the port
    set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");

    # Allow purging
    if (req.request == "PURGE") {
        if (!client.ip ~ purge) {
            # Not from an allowed IP? Then die with an error.
            error 405 "This IP is not allowed to send PURGE requests.";
        }


        return (lookup);
    }

    # Only deal with "normal" types
    if (req.request != "GET" &&
            req.request != "HEAD" &&
            req.request != "PUT" &&
            req.request != "POST" &&
            req.request != "TRACE" &&
            req.request != "OPTIONS" &&
            req.request != "PATCH" &&
            req.request != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }

    # don't cache ajax requests.
    if(req.http.X-Requested-With == "XMLHttpRequest" || req.url ~ "nocache") {
        return (pass);
    }



# Using the cookie in our reverse proxy (pass) request that goes to the backend admin,
    if( req.url ~ "^/administrator" || req.url ~ "^/wp-admin" || req.url ~ "^/wp-login.php" || req.request == "POST" ||  req.http.cookie ~ "smart_varnish_bypass" )
    {
     return( pass );
    }

    # Configure grace period
    set req.grace = 15s;
    if (req.backend.healthy) {
        set req.grace = 30s;
    } else {
        unset req.http.Cookie;
        set req.grace = 6h;
    }


    # Remove all cookies for static files

    if (req.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|pdf|png|rtf|swf|txt|woff|xml)(\?.*)?$") {
        unset req.http.Cookie;
        return (lookup);
    }

    return (lookup);
}

🚀 Launch Your MVP in Weeks — Not Months

Got a startup idea? We help founders turn concepts into reality with lean, production-ready MVPs.

Get a Free MVP Strategy Call