Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'Vary: If-None-Match' to cache mobile and desktop requests separately

Note: Please correct me if any of my assumptions are wrong. I'm not very sure of any of this...

I have been playing around with HTTP caching on Heroku and trying to work out a nice way to differentiate between mobile and desktop requests when caching using Varnish on Heroku.

My first idea was that I could set a Vary header so the cache is Varied on If-None-Match. As Rails automatically sends back etags generated from a hash of the content the etag would vary between desktop and mobile requests (different templates) and so it would eventually cache two versions (not fact, just my original thoughts). I have been playing around with this but I don't think it works.

Firstly, I can't wrap my head around when/if anything gets cached as surely requests with If-None-Match will be conditional gets anyway? Secondly, in practice fresh requests (ones without If-None-Match) sometimes receive the mobile site. Is this because the cache doesn't know whether to serve up the mobile or desktop cached version as the If-None-Match header isn't there?

As it probably sounds, I am rather confused. Will this approach work in any way or am I being silly? Also, is there anyway to achieve separate cached versions if I am unable to reach the Varnish config at all (as I am on Heroku)?

The exact code I am using in Rails to set the cache headers is:

response.headers['Cache-Control'] = 'public, max-age=86400'
response.headers['Vary'] = 'If-None-Match'

Edit: I am aware I can use Vary: User-Agent but trying to avoid it if possible due to it have a high miss rate (many, many user agents).

like image 910
seadowg Avatar asked Oct 25 '22 03:10

seadowg


1 Answers

You could try Vary: User-Agent. However you'll have many cached versions of a single page (one for each user agent).

An other solution may be to detect mobile browsers directly in the reverse proxy, set a X-Is-Mobile-Browser client header before the reverse proxy attempts to find a cached page, set a Vary: X-Is-Mobile-Browser on the backend server (so that the reverse proxy will only cache 2 versions of the same page) and replace that header with Vary: User-Agent before sending to client.

like image 102
Arnaud Le Blanc Avatar answered Oct 27 '22 10:10

Arnaud Le Blanc