Reputation: 47604
Ok, so I'm trying to make Varnish works properly and I've a weird behavior I can't explain (may be due by a lack of understanding).
Here is what I'm trying to do:
GET http://scm.dev:6081/articles
If-None-Match: "50a0794aaca51fce202e86da428b7dca9b4bbff93"
And I get:
HTTP/1.1 200 OK
Age: 3 // Correctly using a cached result
Content-Length: 3878
Content-Type: application/json
Date: Fri, 14 Dec 2012 10:59:34 GMT
Via: 1.1 varnish
X-Cacheable: YES // It is correct
Cache-Control: max-age=10, public, s-maxage=20
Etag: "50a0794aca51fce202e86da428b7dca9b4bbff93"
Vary: Accept,Accept-Encoding
Now, if I add a Cookie to my request:
GET http://scm.dev:6081/articles
If-None-Match: "50a0794aaca51fce202e86da428b7dca9b4bbff93"
Cookie: foo=bar
I get a non cached response and a non cacheable warning:
HTTP/1.1 200 OK
Age: 0 // Always set to 0
Content-Length: 3878
Content-Type: application/json
Date: Fri, 14 Dec 2012 10:59:34 GMT
Via: 1.1 varnish
X-Cacheable: NO:Not Cacheable // It is not correct
Cache-Control: max-age=10, public, s-maxage=20
Etag: "50a0794aca51fce202e86da428b7dca9b4bbff93"
Vary: Accept,Accept-Encoding
If you check the later vcl configuration, the X-Cacheable: NO:Not Cacheable
header is set if the beresp.ttl is less than or equal to 0.
Why?
I also assume that a Request with a Cookie
which returns a Cache-Control: public
should be cached as far as the backend assume the responsibility to correctly set the public
parameter when it should be.
I would have assumed that the X-Cacheable: NO:Got Session
would have been set when making a Request with a Cookie, but it even does not go further.
The command line to start varnish daemon:
/usr/sbin/varnishd -P /var/run/varnishd.pid -a :6081 -T 192.168.1.100:6082 -f /etc/varnish/custom.vcl -S /etc/varnish/secret -s malloc,256m
Here is my custom.vcl
backend scm {
.host = "scm.dev";
.port = "80";
}
sub vcl_recv {
set req.http.Surrogate-Capability = "abc=ESI/1.0";
}
sub vcl_fetch {
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
# Varnish determined the object was not cacheable
if (beresp.ttl <= 0s) {
set beresp.http.X-Cacheable = "NO:Not Cacheable";
# You don't wish to cache content for logged in users
} elsif (req.http.Cookie ~ "(foo)") {
set beresp.http.X-Cacheable = "NO:Got Session";
return(hit_for_pass);
# You are respecting the Cache-Control=private header from the backend
} elsif (beresp.http.Cache-Control ~ "private") {
set beresp.http.X-Cacheable = "NO:Cache-Control=private";
return(hit_for_pass);
# Varnish determined the object was cacheable
} else {
set beresp.http.X-Cacheable = "YES";
}
return(deliver);
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not purged";
}
}
Upvotes: 0
Views: 4529
Reputation: 2767
Varnish will not, by design, fetch any requests from cache if cookies are present. Usually cookies are an indication that the response will be unique to the specific user.
You can either unset req.http.Cookie;
in vcl_recv()
entirely, if you do not care about the cookies, or if you want to keep specific cookies do
if(req.http.Cookie) {
if (req.http.Cookie !~ "(important_cookie|php_session)" ) {
remove req.http.Cookie;
}
}
Upvotes: 1