how to redirect from www to non-www varnish
How do I go about automatically redirect any link of the type www.example.com to example.com.
I would like to do this for all link that hits the varnish instance (so i don't have to individually define the value for all domain that hits the server).
I tried using the following:
if(req.http.host ~ "^www\.(.+)$"){
set req.http.host = regsub(req.http.host, "^www\.", "");
}
It works, but the problem with that is it's hitting the right backend, but it's not redirecting. I understand from here: https://www.varnish-cache.org/vmod/redirect you can redirect to a url, but I am not sure how to get the "full" url from varnish to strip out the www and redirect.
Any help would be appreciated!
Thanks a lot!
Jason
Solution 1:
Varnish does not have a native mechanism for redirection from vcl_recv()
. Instead you have to throw an error from vcl_recv()
to be caught in vcl_error()
. This is because vcl_recv()
doesn't have access to the response object. You can read about how this is done. Below is my attempt at an answer in terms of your situation.
In vcl_recv()
:
if (req.http.host ~ "^www\.") {
error 750 regsub(req.http.host, "^www\.(.*)", "http://\1"); //Capture everything after the www. and place it after a http://
}
In vcl_error()
:
if (obj.status == 750) {
set obj.http.Location = obj.response;
set obj.status = 302;
return(deliver);
}
Solution 2:
vcl 4.0;
sub vcl_recv {
if (req.http.host ~ "^([-0-9a-zA-Z]+)\.([a-zA-Z]+)$") {
return (synth (750, ""));
}
}
sub vcl_synth {
if (resp.status == 750) {
set resp.status = 301;
set resp.http.Location = "http://www." + req.http.host + req.url;
return(deliver);
}
}