I have the following VCL:
sub jamie_fetch
{
if(beresp.http.X-Var-Cache == "YES") {
unset beresp.http.Set-Cookie;
set beresp.http.X-Cacheable = "YES";
set beresp.grace = 365d;
set beresp.ttl = 365d;
return(deliver);
}
set beresp.http.X-Cacheable = "NO";
return(hit_for_pass);
}
I know it partly works because I get the following header when I first visit the page:
X-Cacheable:YES
However I also get:
Set-Cookie:foobar
I am assuming I have made a mistake in the following:
unset beresp.http.Set-Cookie;
But from my searching that seems to be correct? I'd be grateful if someone with more experience can point me in the right direction.
Thanks in advance for any help/tips/pointers :-)
You should lower-case header names when using unset:
unset beresp.http.set-cookie;
Related
I'm currently working on a migration project from varnish3 to varnish4 and
I am facing a behaviour that I don't understand.
To put it simply, with the same configuration file used both in Varnish3
and Varnish4, I don't have the same results concerning hits and misses.
This seems to be related to the grace attribute, but I don't figure out how
it works.
So below is an example which describes the problem into details:
My varnish3 configuration:
# ----------------------------------------------
backend default {
.host = "nginx";
.port = "80";
}
sub vcl_fetch {
set beresp.grace= 5s;
set beresp.ttl = 1s;
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
set resp.http.X-Cache-Hits = obj.hits;
}
# ----------------------------------------------
My varnish4 configuration: (only change is the method name
vcl_backend_response instead of vcl_fetch )
# ----------------------------------------------
vcl 4.0;
backend default {
.host = "nginx";
.port = "80";
}
sub vcl_backend_response {
set beresp.grace= 5s;
set beresp.ttl = 1s;
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
set resp.http.X-Cache-Hits = obj.hits;
}
# ----------------------------------------------
The result of a little scenario which retrieves headers of a given resource
after some time:
# ----------------------------------------------
Time 14-47-12
VARNISH4:
X-Cache: MISS
X-Cache-Hits: 0
VARNISH3:
X-Cache: MISS
X-Cache-Hits: 0
Time 14-47-13
VARNISH4:
X-Cache: HIT
X-Cache-Hits: 1
VARNISH3:
X-Cache: MISS
X-Cache-Hits: 0
Time 14-47-20
VARNISH4:
X-Cache: MISS
X-Cache-Hits: 0
VARNISH3:
X-Cache: MISS
X-Cache-Hits: 0
# ----------------------------------------------
So as you can see in the scenario, for the first request, both v3 and v4
return a MISS, which is normal.
But one second after, the second request returns a MISS for varnish3, which
is normal for me, and a HIT for varnish4, that I don't really understand.
As I suspected this was related to the grace parameter, I have added a
third request in my scenario 7 seconds later ( greeter than 1sec for cache
plus 5 seconds for grace), and as expected, both varnish 3 and varnish 4
are MISS.
So if someone can help me to understand / workaround this problem...
The objective for me is to get the same result with varnish4 than with
varnish3 (while I'm migrating from 3 to 4 ;) ).
My current workaround is to set beresp.grace=1ms on varnish4, but I don't
like that at all, and I can't do that on every of my configurations :(
Any help would be very appreciated !
Thanks in advance ! :)
Varnish 4 delivers a stale object (see How objects are stored) in the second request.
I suggest that you read Grace mode, and play with Understanding Grace using varnishtest.
On a multiple website set-up using varnish 5.1 on port 80, I don't want to cache all domains.
That is easily done in vcl_recv.
if ( req.http.Host == "cache.this.domain.com" ) {
return(hash);
}
return(pass);
Now in vcl_backend_response I want to do some processing for cached domains.
Of course I can do if( bereq.http.Host == "cache.this.domain.com" ), but is there a way to know if it was a return(hash) or a return(pass) call in vcl_recv from within vcl_backend_response?
I thought that this could make sense but couldn't find the information.
Thanks for your help.
In addition to the ad-hoc approach suggested by #Daniel V., an alternative that might fit your needs is:
sub vcl_backend_response {
if (!bereq.uncacheable) {
...
}
}
This let's you execute the extra processing only for cacheable objects.
It really makes me wonder why you need such processing in the first place.
I don't think there's a way to tell directly how you landed into vcl_backend_response. So I suppose you can set a flag and check on that later, i.e.:
sub vcl_recv {
if ( req.http.Host == "cache.this.domain.com" ) {
set req.http.return_type = "hash";
return(hash);
}
set req.http.return_type = "pass";
return(pass);
}
sub vcl_backend_response {
if( bereq.http.return_type == "pass" ) ...
}
I would like to setup Varnish 2.1.5 rules to show content from another page in some cases, yet keep the original URL intact.
eg When user requests /page/a s/he will be shown /page/b instead, but still see the /page/a URL in the browser.
This specific use case I need it for gracefully handling 404 errors on translated pages. Im not sure how to send the request back through to vcl_recv
The as I understand, the lifecycle flow, and current logic looks like this:
sub vcl_recv {
if(req.http.cookie ~ "lang_pref") {
# Redirect to Preferred Language
error 999 "i18n cookie";
}...
sub vcl_deliver {
if (resp.status == 999 ) {
set resp.status = 302;
set resp.response = "Found";
}... # more i18n logic
sub vcl_fetch {
# Set Varnish error if backend cant find requested i18n page
if (beresp.status == 404 && req.url ~ "^\/(en|fr|de)(\/.*)?$") {
error 494;
}...
sub vcl_error {
# Double check i18n pages for English before 404
if (obj.status == 494) {
set obj.http.Location = "https://site/page/a";
}
set obj.status = 302;
return(deliver);
}
What I'm assuming, instead of set obj.http.Location "https://site/page/a";, I need to somehow send the request back to vcl_recv then use regsub().
How would I go about that?
Should be as easy as:
sub vcl_error {
# Double check i18n pages for English before 404
if (obj.status == 494 && req.url == "/page/a") {
set req.url = "/page/b";
return(restart);
}
}
So I am trying to set my cache condition based on cookies found. I am using below code but the functionality is not working properly as the cookies page is getting cached for 24 hrs. Can any one take a look and let me know what the issue in below code of mine?
if (req.http.Cookie ~"(wp-postpass|wordpress_logged_in|comment_author_)") {
set cacheable = false;#versions less than 3
beresp.ttl>0 is cacheable so 0 will not be cached
set beresp.ttl = 0s;
} else {
set beresp.cacheable = true;
set beresp.ttl=300s;#cache for 24hrs
}
So your code is missing set beresp flag use below code and then test it will work perfectly.
if (req.http.Cookie ~"(wp-postpass|wordpress_logged_in|comment_author_)") {
set beresp.cacheable = false;#versions less than 3
beresp.ttl>0 is cacheable so 0 will not be cached
set beresp.ttl = 0s;
} else {
set beresp.cacheable = true;
set beresp.ttl=300s;#cache for 24hrs
}
I am trying to import my old Varnish configuration to version 4.0.
sub vcl_hit {
if (req.method == "PURGE") {
set beresp.ttl = 0s;
return (synth(200, "Purged."));
}
}
Error I am getting:
Message from VCC-compiler:
'beresp.ttl': cannot be set in method 'vcl_hit'.
At: ('input' Line 135 Pos 15)
set beresp.ttl = 0s;
--------------##########------
Running VCC-compiler failed, exited with 2
So how do I update that?
Thats not working ;) there is a complete migrate guide how to migrate from 3 to 4
https://varnish-cache.org/docs/4.0/whats-new/upgrading.html
Here is a complete list what has changed and how you can fix it.