if (req.http.Cookie !~ "(^|;\s*)(province=(.*?))(;|$)") {
return (pass);
}
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed-products)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
}
I need to prevent the first cookie to get deleted, I noticed varnish kept removing all of my cookies for some reason, so I was wondering what the hell was happening, so I checked and I think the latter part is at fault, so do I need to prevent set and unset from happening by doing the following?
if (req.http.Cookie !~ "(^|;\s*)(province=(.*?))(;|$)") {
return (pass);
}
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed-products|province)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
}
Here's the snippet I would use in your case to prevent the following cookies from being removed:
sub vcl_recv {
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed\-products|province)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.cookie ~ "^\s*$") {
unset req.http.cookie;
}
}
}
In the end after all the cookie substitutions took place and the cookie is just a collection of whitespace characters, or if the cookie is an empty string, we remove the entire cookie header.
Of course that won't be the case if any of the above cookies are present.
That should really do the trick. However I see a lot of confusion regarding this approach, and rightfully so, because these regular expression substitutions are ugly and hard to interpret.
An alternative is to use vmod_cookie
and leverage the clean cookie management API it offers. See http://varnish-cache.org/docs/6.6/reference/vmod_cookie.html for docs.
vmod_cookie
is a native Varnish VMOD as of version6.4
. This means that versions6.4
,6.5
and6.6
ship it by default. If you're on an older version, you can compile the module from source by using https://github.com/varnish/varnish-modules
Here's the how you use it in your case:
import cookie;
sub vcl_recv {
if (req.http.Cookie) {
cookie.parse(req.http.cookie);
cookie.keep("allgroups,view-products,province");
set req.http.cookie = cookie.get_string();
if (req.http.cookie ~ "^\s*$") {
unset req.http.cookie;
}
}
}
See what works best for you, but you have to admit that vmod_cookie
is easier to use and understand than the regsub()
calls.