Search code examples
varnish-vclvarnish-4

Varnish caching with cookies


Just new to Varnish. It's getting hard, more than expected :-(

I'm trying to improve some php code, developed some time ago, using varnish. This code uses just two cookies: PHPSESSID and LANGUAGE

All pages set PHPSESSID cookie if it's not defined. However this cookie for anonymous sessions it's only used in one page.

Let's say I have Page1, Page2, Page3 and Page4. My configuration should be as follows:

Page1, Page2 and Page3 need LANGUAGE cookie and should be cached with that cookie: one cache for each language and page.

Page4 needs PHPSESSID and LANGUAGE cookies, and shouldn't be cached as it's specific for each user.

My default.vlc is not working properly, so any orientation would be really apreciated. Maybe I've missunderstood some concepts.

    sub vcl_init {

    # When requests come to Varnish I need to remove PHPSESSID so it's not used for the hash in caching. Page4 doesn't need caching as it's specific for each user:
       if (req.http.host ~ "Page4") {
         return(pass);
       }

    # remove PHPSESSID so pages1, 2, and 3 get cached just once for everyuser but in all languages.

       if ((req.url !~ "page4")) {
          set req.http.Cookie = regsuball(req.http.Cookie, "PHPSESSID=[^;]+(; )?", "");
       }

   return (hash);


    }

I need to cache webpages with LANGUAGE cookie so I include it in vcl_hash:

sub vcl_hash {
  hash_data(req.url);
  if (req.http.host) {
    hash_data(req.http.host);
  } else {
    hash_data(server.ip);
  }

  # hash cookies for requests that have them
  if (req.http.Cookie) {
    hash_data(req.http.Cookie);
  }
}

How can I remove just PHPSESSIONID?

sub vcl_backend_response {
  # Called after the response headers has been successfully retrieved from the backend.

  if (!(bereq.url ~ "Page4"))  {
     unset beresp.http.set-cookie;
  }
  return (deliver);

}

Solution

  • You are on the right track. If I understand your question, the thing that does not work is that you remove all cookies server response (if it's not Page4) instead of just removing PHPSESSID.

    You can do a regexp in your sub vcl_backend_response to remove only phpsessionid if url is not Page4.

    beresp.http.set-cookie = regsuball(beresp.http.set-cookie, "PHPSESSID=[^;]+(; )?", "")
    

    Alternatively, if you use varnish 4 or above, you should use the vmod cookie which makes cookie handling much easier (no more need for regexp).