I'm trying to set up an in-the-middle varnish server to allow a Rails app on xyz.com to work on several other domain names.
What happens is that from time to time the Rails app outputs some 301/302 redirects and apparently varnish does not change these headers, so visitors get redirected to the original site (which is behind the public-facing varnish server), so... error.
Is there a way to configure this rewrite on the varnish side of things?
under vcl_fetch I tried the following:
if ( (beresp.status == 301) || (beresp.status == 302) ) {
set req.url = regsub(req.url,".*",regsuball(regsub(beresp.http.Location,"^http://[^/]+(.*)","\1"),"[+]","%2520"));
return(restart);
But maybe I don't understand how this works exactly? Any help will be much appreciated
After fighting with your regex an thinking of the use case... I think you would probably can do a much straightforward thing, such as rewrite the location and cache the object corrected (and leave redirection to client browser).
On vcl_fetch
:
# ...
if ( beresp.status == 301
|| beresp.status == 302
) {
# Check if we're redirecting to a different site
if ( ! beresp.http.Location ~ req.http.host ) {
# Rewrite HTTP Location header to cache it and pass redirection to client
set beresp.http.Location = regsub(
beresp.http.Location,
"^http://[^/]+/",
"http://" + req.http.host + "/"
);
}
}
# ...
If you still prefer to restart the request on a different url inside Varnish, I'll try (again on vcl_fetch
):
# ...
if ( beresp.status == 301
|| beresp.status == 302
) {
# Add a header so you can debug cleanly on varnishlog
set req.http.X-Redirected-Orig = beresp.http.Location;
# Rewrite request host
set req.http.host = regsub(
regsub(
beresp.http.Location,
"^http://",
"",
),
"^([^/]+)/.*$",
"\1"
);
# Rewrite request url
set req.url = regsub(
beresp.http.Location,
"^http://[^/]+/(.*)$",
"/\1",
);
# Add a header so you can debug cleanly on varnishlog
set req.http.X-Redirected-To = "http://" + req.http.host + req.url;
return (restart);
}
# ...
PS: Excuse me for the regsub indentations, but I think it's much more readable with it.