How do you let a call through in varnish when a cookie "lang" is not set?
Solution 1:
Bypassing the cache when a lang cookie was not set
In its most basic form, this is the VCL code you need to pass requests to the backend that don't contain a lang
cookie:
sub vcl_recv {
if(req.http.Cookie !~ "(^|([^;]*;)+)\s*lang=([^;]*)\s*($|(;[^;]*)+)") {
return(pass);
}
}
However, you'll probably need to define some logic in case the lang
cookie was set.
Using the value of the lang cookie
The following VCL snippet extracts the language that was set by the lang
cookie and stores it in req.http.lang
.
This value is used to create a cache variation per language:
sub vcl_recv {
if(req.http.Cookie !~ "(^|([^;]*;)+)\s*lang=([^;]*)\s*($|(;[^;]*)+)") {
return(pass);
}
set req.http.lang = regsub(req.http.Cookie,"(^|([^;]*;)+)\s*lang=([^;]*)\s*($|(;[^;]*)+)","\3");
//Some other logic
return(hash);
}
sub vcl_hash {
if(req.http.lang) {
hash_data(req.http.lang);
}
}
The snippet above also explicitly calls return(hash)
. At some point you will need to force Varnish to cache when the lang
cookie is set, because the standard Varnish behavior cache anything when cookies are present.
I added a //Some other logic
comment, because I'm assuming there will be more logic to bypass the cache. For example when request methods other than GET
and HEAD
are used, or for custom URL patterns that need to bypass the cache.
Avoiding too many cache variations
The hash_data(req.http.lang)
statement will ensure that a cache variation is created for every value that the lang
cookie may have.
The danger with that is that users with bad intentions start adding random values to the lang
cookie to fill the cache.
Keeping this risk in mind, it would make sense to explicitly list the supported languages in your regular expression.
Here's the initial regex:
(^|([^;]*;)+)\s*lang=([^;]*)\s*($|(;[^;]*)+)
Here's an example with hardcoded supported languages:
(^|([^;]*;)+)\s*lang=(en|es|de|it|es|fr|nl)\s*($|(;[^;]*)+)
Just tailor this regex to your needs and the languages your web platform supports.