2

I'm using Django with Varnish 4.

I'm trying to achieve that:

  • If the request is not for the home page, pass (I'm trying to only cache the home page at the moment to test it, etc.)
  • If the cookie 'sessionid' is present, pass or cache for each sessions
  • Anything else: pass

Here's the configuration of sub vcl_recv:

# cache only home page
    if (! req.url == "/") {
            return(pass);
    }

    # not caching if cookie sessionid is present
    if (req.http.Cookie ~ "sessionid") {
            return(pass);
    }

    unset req.http.cookie;

So far, Varnish seems to always generate a new page for each it when calling the home page as anonymous. I can tell using the headers Varnish send (the 'age' is always 0 and 'X-Varnish' is always a different number).

It's either that my configuration is missing something, or is it because Django sends a 'Vary: Cookie' in the response? If it's the case, how can I 'hide' cookies from Varnish in this case (only for anonymous users)?

1

1 Answer 1

2

The 'problem' was that Django sent a 'Vary: Cookie' header all the time. I think it's because of the 'auth' plugin, but I didn't investigate that, I just deleted the header when the response came back from the server.

Here's what Varnish's doc has to say about 'vary: cookie':

Another example of bad usage is when using only Vary: Cookie to differentiate a response. Again, there could be a very large number of cookies and hence a very large number of cached objects, which are going to be retrieved most likely only by their original requesters.

Source: https://www.varnish-software.com/book/4.0/chapters/HTTP.html#vary

Here's what my VCL config looks like (I removed the upper part which is simply server configuration):

sub vcl_recv
{
        # caching only home page
        if (! req.url == "/") {
                return(pass);
        }

        # not caching if cookie sessionid present
        if (req.http.Cookie ~ "sessionid") {
                return(pass);
        }

        unset req.http.cookie;

}

sub vcl_backend_response
{

        if (bereq.url == "/") {
                unset beresp.http.Vary;
                return(deliver);
        }
}

You must log in to answer this question.

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