Monday, November 11, 2013

Varnish infinite redirect loop for naked domain redirect to www

You might face an infinite redirect loop with varnish if your backend server does a redirect for a naked domain or for that matter any domain.

Problem is that varnish by default uses a combination of hostname  and url  to create a cache key. This becomes a problem when your varnish server's hostname is not the same as the served domain (which is the case most of the times).

This leads to varnish caching a 301/302 redirect in itself. So if I hit example.com and my backend throws a 301 to www.example.com the key generated in varnish would be hostname_url and not HOST_url. So now if I hit www.example.com I am provided a 302 to the same url as lookup does not take into account the HOST which is different for example.com and www.example.com. To overcome this update the VCL to include HOST in the cache key. I have added req.http.X-Forwarded-Prot also to the hash to overcome https redirect that we face with ELB and varnish when the SSL terminates at ELB and the backend has been coded to do a redirect from non secure url (http) to secure urls (https).


sub vcl_hash {
    hash_data(req.http.host);
    hash_data(req.url);
    hash_data(req.http.X-Forwarded-Proto);
    return(hash);
}

If you are facing infinite redirect loop for https pages behind ELB read this.