Non www to www redirections should be handled by Varnish before requesting backend, to avoid weird errors such as loops, no backend connection...
In sub vcl_recv
(this is VCL 4 syntax) :
sub vcl_recv {
#THIS IS THE IMPORTANT POINT
#redirect non www to www domains ip no subdomain defined
if (req.http.host ~ "^([-0-9a-zA-Z]+)\.([a-zA-Z]+)$") {
return (synth (750, ""));
}
# Normalize the header, remove the port
set req.http.host = regsub(req.http.host, ":[0-9]+", "");
#OFTEN SHIPS WITH THIS OTHER ONE, COMMENT IT OTHERWISE IT WILL FAIL
#set req.http.Host = regsub(req.http.Host, "^www\.", "");
# For the sake of example, a couple of custom backends,
# note www is specified in the req.http.host
if (req.http.host ~ "foo.example.tld") {
set req.backend_hint = example;
}
elseif (req.http.host ~ "www.other.com") {
set req.backend_hint = other;
}
In sub vcl_synth
, add this :
if (resp.status == 750) {
#redirect non www to www
set resp.status = 301;
set resp.http.Location = "http://www." + req.http.host + req.url;
return(deliver);
}
Finally, in your vhosts, it is not necessary anymore to have two server blocks, you can comment or remove the non www one
#server {
# listen 1.2.3.4:8080;
# server_name example.tld;
# return 301 http://www.example.tld;
#}
server {
listen 1.2.3.4:8080;
server_name www.example.tld;