Varnish mobile redirection
First published on September 2, 2012
If you have separate mobile and main sites, you usually want to implement automatic redirection from the main site to the mobile site for mobile visitors. Redirection based on the user agent string is the current standard and is relatively straightforward. If your web server directly serves pages, you can implement the logic at the Apache level, either through rewrite conditions and rules or through an Apache module, both of which were discussed here.
If your website is behind a reverse proxy such as Varnish, you do not want Apache to perform such redirections, because you don’t want Varnish to cache the redirect responses. In other words, if the first visitor is a non-mobile user, all subsequent mobile visitors for a certain period of time will get that cached, non-redirected response; if the first visitor is a mobile user, everybody will get redirected for a certain period of time. Therefore, the redirection logic is best placed at the Varnish level.
The example Varnish configuration below, to be placed in the VCL file, redirects mobile users based on a list of mobile user agent strings from detectmobilebrowsers.com. It allows users to return to the full site and remain there, bypassing the redirection logic. Of course, this is just a general example that you can tweak depending on your exact use cases. You might have slightly different requirements on allowing users to manually go between the mobile and main sites.
In vcl_recv() to determine whether to redirect:
# Only redirect if we do not force the full browser using a GET parameter or COOKIE if( !( req.url ~ "\?fullbrowser$" || req.http.Cookie ~ "fullbrowser=1" ) ) { # Check for mobile device if( req.http.User-Agent ~ "(?i)android.+mobile|avantgo|bada\/|blac kberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge | maemo|meego.+mobile|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re) \/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap| windows (ce|phone)|xda|xiino" ) { error 750 "Moved Temporarily"; } }
In vcl_error() to perform the redirection:
if( obj.status == 750) { set obj.http.Location = "http://m.yoursite.com" + req.url; set obj.status = 302; return(deliver); }
In vcl_fetch() to allow a mobile user to stay on the main site via a link that has “?fullbrowser” appended to it:
# Cookie handling for mobile redirects # Assumes no other GET parameters; modify to match "fullbrowser" anywhere in the string or if there are other GET parameters if( req.url ~ "\?fullbrowser$" ) { set beresp.http.Set-Cookie = "fullbrowser=1; domain=.yoursite.com; path=/"; }
For a more general overview of things to consider when implementing Varnish on a website, see this post.