6

I am aiming to redirect clients to a SSL-version of a site using Varnish. In Varnish 3 this could be done by the following in the VCL:

sub vcl_recv {
    if ( (req.http.host ~ "^(?i)somesite.org" || req.http.host ~ "^(?i)www.somesite.org")
         && req.http.X-Forwarded-Proto !~ "(?i)https") {
        set req.http.x-Redir-Url = "https://www.somesite.org" + req.url;
        error 750 req.http.x-Redir-Url;
    }
}

sub vcl_error {
    if (obj.status == 750) {
        set obj.http.Location = obj.response;
        set obj.status = 302;
        return (deliver);
    }

Between Varnish versions 3 and 4 there were changes to the vcl requirements, these can be found in the varnish docs: https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.html#changes-to-vcl.

My attempt at a Varnish 4 version of the redirect leads to a redirect loop. I am not entirely sure if it is this section of the the vcl which is incorrect, or if even the correct implementation would work with my current setup.

Either way, it would be useful to have a confirmed working ?Varnish 4 version of this. My attempt is:

sub vcl_recv {
    if ( (req.http.host ~ "^(?i)somesite.org" || req.http.host ~ "^(?i)www.somesite.org")
         && req.http.X-Forwarded-Proto !~ "(?i)https") {
        set req.http.x-Redir-Url = "https://www.somesite.org" + req.url;
        return (synth(750, req.http.x-Redir-Url));
  }
}

sub vcl_synth {
    if (resp.status == 750) {
        set resp.http.Location = resp.reason;
        set resp.status = 302;
        return (deliver);
    }

Is anyone familiar with this and able to spot if it is correct or incorrect?

  • I think you need a set resp.http.Location = "https://www.somesite.org" + req.url; in vcl_synth just before return (deliver);. – KM. Dec 23 '14 at 16:33
7

Try the following for Varnish 4 while updating the TLD with your respective values:

sub vcl_recv {
        if ( (req.http.host ~ "^(?i)www.domain.com") && req.http.X-Forwarded-Proto !~ "(?i)https") {
                return (synth(750, ""));
        }
}

sub vcl_synth {
    if (resp.status == 750) {
        set resp.status = 301;
        set resp.http.Location = "https://www.domain.com" + req.url;
        return(deliver);
    }
}

You should be able keep the || statement and it should work (not tested):

sub vcl_recv {
        if ( (req.http.host ~ "^(?i)www.domain.com" || req.http.host ~ "^(?i)domain.com") && req.http.X-Forwarded-Proto !~ "(?i)https") {
                return (synth(750, ""));
        }
}
  • Using this gives me a redirect loop but it could be due to the server set-up(as mentioned in original question). Is it just the second vcl_rec suggestion that is untested or the first too? If you have tested it previously then let me know and I will accept, otherwise will have to wait a little while before I figure out if the rest of set-up is correct. Thanks. – Taylor Taff Dec 24 '14 at 10:55
  • Glad to hear it works! – Astron Dec 24 '14 at 14:45

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.