3

I have the following situation:

On my site, javascript sets a cookie that contains relevant information for generating the markup.

I therefore want Varnish to cache each page separately for each value of said cookie.

All the documentation I have found says that Varnish will not cache if any cookie is present, and explains how to remove cookies in Varnish preprocessing.

This is obviously not what I want, I want to cache, even if a certain cookie is present, but seperately for each value of the cookie.

Any way to achieve this?

2 Answers 2

3

This is possible

For example:

sub vcl_recv {
        set req.http.X-COOKIEHASH = "";
        if (req.http.Cookie ~ "COOKIEHASH=") {
                set req.http.X-COOKIEHASH = regsub(req.http.Cookie,"^.*?COOKIEHASH=([^;]*);*.*$", "\1");
                /* to prevent default action when cookies are present */
                /* this is shortcut - you should adjust this to your VCL logic */
                return (lookup);
        }
}
sub vcl_hash {
        hash_data(req.http.X-COOKIEHASH);
}
sub vcl_miss {
        unset bereq.http.X-COOKIEHASH;
}
sub vcl_pass {
        unset bereq.http.X-COOKIEHASH;
}

In vcl_recv() we extract value for cookie (with the name COOKIEHASH) and in vcl_hash() we add this value to the hash function.

This is example for one cookie. But it's easy to add more cookie names. You must also remember to deal with other cookies (discard them or ignore).

1

This started off as a comment on RJS's answer - but it's getting a bit long...

IIRC (don't do a lot stuff with Varnish) you need to specify all the determinants of uniqueness in vcl_hash - hence RJS's answer might be wrong - indeed the examples in the manual explicitly use the URL as well as other indicators.

I think there's also some problems with the way RJS extracts the cookie. Assuming that the cookie value is in req.http.X-COOKIEHASH, the solution would be:

sub vcl_hash {
    hash_data(req.url);
    hash_data(req.http.X-COOKIEHASH);
}

A consequence of this is that Varnish will start caching copies of content which is not varying with the cookie - hence you might want to exclude static content URLs from using the cookie(s) to determine the hash.

However this doesn't help to solve the problem for other caches - both intermediate and browser. The content should be served up with a Vary: Cookie header. See also discussion here

2
  • hash_data(req.url) is included in default vcl. There is no return(hash) in my function so default code will be added.
    – RJS
    Mar 21, 2013 at 20:52
  • Good point about Vary. If he use cookies to generate diffrent contenet for one url he must sent Vary header from backend. This could be added to vcl but much better plece for this is a backend.
    – RJS
    Mar 21, 2013 at 20:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .