0

Situation::

  1. Varnish needs to cache even in the presence of cookies on the request.
  2. The request may contain N arbitrary cookies of which certain known cookies must not form part of the cache key. The arbitrary cookies don't contain any user sensitive data, eg. they are cosmetic helpers like is_authenticated=1.
  3. The actual backend must receive the original set of cookies unmolested in the case of a cache miss.
  4. I don't want to check for URL patterns in the VCL because that assumes too much knowledge of the backend.

This is surprisingly hard to solve. All solutions I've found so far assumes a whitelist for (2) whereas I need a blacklist. And most solutions delete cookies which are supposed to go through to the backend.

hedleyroos
  • 320
  • 3
  • 9

1 Answers1

1

So how about (untested):

# We use builtin.vcl logic and 'return' from our vcl_recv in order 
# to prevent default Varnish behaviour of not caching with cookies present
sub vcl_recv {
    # your vcl_recv starts here
    # ...
    # your vcl_recv ends here

    if (req.method == "PRI") {
    /* We do not support SPDY or HTTP/2.0 */
        return (synth(405));
    }
    if (req.method != "GET" &&
      req.method != "HEAD" &&
      req.method != "PUT" &&
      req.method != "POST" &&
      req.method != "TRACE" &&
      req.method != "OPTIONS" &&
      req.method != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }

    if (req.method != "GET" && req.method != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }
    if (req.http.Authorization) {
        /* Not cacheable by default */
        return (pass);
    }
    return (hash);
}

sub vcl_hash {
    set req.http.X-Cookie-Hash = regsub(req.http.cookie, "KNOWN1=[^;]+;", "");
    set req.http.X-Cookie-Hash = regsub(req.http.X-Cookie-Hash, "KNOWN2=[^;]+;", "");
    hash_data(req.http.X-Cookie-Hash);
}

Which removes each known cookie and hashes on the remainders :) Not ideal, because it can't guarantee the order of cookies in the header, but other from that should work.

Danila Vershinin
  • 8,725
  • 2
  • 29
  • 35
  • That certainly looks correct but one problem remains - Varnish still sees the presence of cookies and thus refuses to cache. Is there a way to alter that behavior? – hedleyroos Apr 09 '17 at 10:22
  • Wow, that is very impressive. My testing so far indicates that it works perfectly. I'm going to mark your answer as the solution. – hedleyroos Apr 09 '17 at 11:07