Question

I am using Varnish 3.0.5 and Apache 2.4.6 with PHP 5.4.21

I have read the documentation here which says

Varnish will, in the default configuration, not cache a object coming from the backend with a Set-Cookie header present. Also, if the client sends a Cookie header, Varnish will bypass the cache and go directly to the backend.

So, in an effort to have Varnish cash pages, I need to remove the non-important cookies being sent to Varnish from the client. At present, there is only one cookie being sent as depicted here:enter image description here

My default.vcl file has the following code, which is supposed to remove the cookie(s) whose name starts with the underscore character, or whose name is "has_js":

 sub vcl_recv {
 #       //Remove all cookies that begin with an underscore
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_\.a-z0-9]+|has_js)=[^;]*", "");
 #       //Remove a ";" prefix, if present.
    set req.http.Cookie = regsub(req.http.Cookie, "^;\s", "");

 #       unset req.http.Cookie;
 ...

I have tested the regex from this application and it finds a match for the cookie being sent from the client as noted in the image above.

When I run

 ]# varnishes

from the command line, I find that I have no "hits" only "misses". However, if I uncomment the

 unset req.http.Cookie;

line, so that it removes all the Cookies (of which there should be only one, I assume from the image above) I get the hits I'd expect.

I'm hoping someone can point me in the right direction as to what I may be missing?

Thanks.

Was it helpful?

Solution

The problem with the code above is this line in the default.vcl that gets called later on:

 if (req.http.Authorization || req.http.Cookie) {
 #         /* Not cacheable by default */
           return (pass);
 }

It is commented out, but still gets called as part of the default behavior of Varnish. As you can see, it is asking if

 req.http.Cookie

exists. In the code provided in the question, the variable will still exist, but will be an empty string. This empty string will still pass the logical test in the default Varnish behavior. As a result, the following code must be added after the code which removes the undesirable cookies:

 set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_\.a-z0-9]+|has_js)=[^;]*", "");
 #       //Remove a ";" prefix, if present.
 set req.http.Cookie = regsub(req.http.Cookie, "^;\s", "");

 if (req.http.Cookie == "") {
         unset req.http.Cookie;
 }

Now, if the req.http.Cookie is empty, the object will be removed and Varnish will cache as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top