To serve different content based on the device type, add the following VCL::
Here are a few examples on how to serve different content to the client based on device classification.
include "devicedetect.vcl";
sub vcl_recv { call devicedetect; }
sub vcl_hash {
# add the device classification to the hash, so clients get the correct cached object
if (req.http.X-hash-input) { hash_data(req.http.X-hash-input); }
}
This will make a different set of cache objects based on what the client is identified as.
Different backend for mobile clients
------------------------------------
If you have a different backend that serves pages for mobile clients, or any special needs in VCL, you can use the X-UA-Device header like this::
include "devicedetect.vcl";
backend mobile {
.host = "10.0.0.1";
.port = "80";
}
The tricks involved are:
1. Detect the client (pretty simple, just include devicedetect.vcl and call it)
2. Figure out how to signal the backend what client class this is. This includes for example setting a header, changing a header or even changing the backend request URL.
3. Modify any response from the backend to add missing Vary headers, so Varnish' internal handling of this kicks in.
4. Modify output sent to the client so any caches outside our control don't serve the wrong content.
sub vcl_recv {
call devicedetect;
All this while still making sure that we only get 1 cache object per URL per device class.
if (req.http.X-UA-Device ~ "^mobile" || req.http.X-UA-device ~ "^tablet") {
set req.backend = mobile;
}
}
Redirecting mobile clients
--------------------------
If you want to redirect mobile clients you can use the following snippet.
.. 065-redir-mobile-start
VCL::
include "devicedetect.vcl";
sub vcl_recv {
call devicedetect;
if (req.http.X-UA-Device ~ "^mobile" || req.http.X-UA-device ~ "^tablet") {
error 750 "Moved Temporarily";
}
}
sub vcl_error {
if (obj.status == 750) {
set obj.http.Location = "http://m.example.com" + req.url;
set obj.status = 302;
return(deliver);
}
}
.. 065-redir-mobile-end
Signaling device type to the backend
------------------------------------
Except where redirection is used, the backend needs to be told what kind of
client the content is meant to be served to.
Example 1: Send HTTP header to backend
''''''''''''''''''''''''''''''''''''''
The basic case is that Varnish add the X-UA-Device HTTP header on the
backend requests, and the backend mentions in the response Vary header that the
content is dependant on this header. Everything works out of the box from
Varnish's perspective.
content is dependant on this header.
Everything works out of the box from Varnish' perspective.
.. 071-example1-start
Example VCL::
...
...
@@ -95,10 +41,8 @@ Example VCL::
# completed.
sub vcl_miss { call add_x-ua-device; }
sub vcl_pass { call add_x-ua-device; }
.. 071-example1-end
Please remember that the backend must send a Vary header on User-Agent, or you will need to add that manually. See below for an example.
.. 071-example1-end
Example 2: Normalize the User-Agent string
''''''''''''''''''''''''''''''''''''''''''
...
...
@@ -125,44 +69,17 @@ VCL::
sub vcl_miss { if (req.http.X-UA-Device) { set bereq.http.User-Agent = req.http.X-UA-Device; } }
sub vcl_pass { if (req.http.X-UA-Device) { set bereq.http.User-Agent = req.http.X-UA-Device; } }
# so, this is a bit conterintuitive. The backend creates content based on the normalized User-Agent,
# but we use Vary on X-UA-Device so Varnish will use the same cached object for all U-As that map to
# the same X-UA-Device.
# if the backend does not mention in Vary that it has crafted special
# content based on the User-Agent (==X-UA-Device), add it.
# If your backend does set Vary: User-Agent, you may have to remove that here.