Just for the record, I finally came up with a VCL script that solves this problem using custom headers and restarting the request:
backend default
{
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv
{
if(req.http.X-Force-Backend)
{
return(pass);
}
if(req.http.Cookie && req.request ~ "(GET|HEAD)")
{
set req.http.X-Cookie = req.http.Cookie;
remove req.http.Cookie;
return(lookup);
}
}
sub vcl_deliver
{
if(resp.http.Cache-control ~ "(private|no-cache|no-store)"
&& !req.http.X-Force-Backend
&& req.request ~ "(GET|HEAD)"
)
{
set req.http.X-Force-Backend = "YES";
set req.http.Cookie = req.http.X-Cookie;
remove req.http.X-Cookie;
return(restart);
}
}
As you can see, by always deleting the Cookie
header and restarting the request when we have a non-cacheable response from the backend, we can achieve the desired effect. I don't know about possible performance drawbacks, but I'm using it in production and it works quite well.
I also wrote a blog post about this specific problem, if anyone is using Symfony and Varnish aswell, it might be interesting: http://albertofem.com/post/symfony-varnish-and-http-practical-considerations.html