Search code examples
http-redirecthaproxy

haproxy redirect both scheme and location together


I need to redirect a specific http URL first to its equivalent https and then on to a completely different https URL (don't ask why I can't just redirect the original http straight to the final https URL, this is what the client wants and the client is always right!). Additionally I need to be able to redirect the original https to the different https too.

So, what I need is the ability to redirect http://foo.bar.com => https://foo.bar.com and then https://foo.bar.com => https://another.foobar.com, as well as redirecting https://foo.bar.com => https://another.foobar.com.

Currently to redirect just https://foo.bar.com => https://another.foobar.com I'm using this:

acl is_new_portal hdr(host) -i foo.bar.com
redirect location https://another.foobar.com code 302 if is_new_portal 

with an initial bind on port 443, and I know to redirect http to https I would use:

redirect scheme https code 302 if !{ ssl_fc }

(using code 302 rather than 301 as eventually another.foobar.com will be removed, so I don't want the redirection permanently cached in clients' browsers)

but I need to be able to do both relocations, and I'm not sure how you combine the two?


Solution

  • I am not certain to understand if your issue is related to the binding or to the ACLs. You already have all the answers to your question. You can wrap them in a simple frontend:

    frontend main
      bind :80
      bind :443 ssl crt yourCertFile
    
      acl is_new_portal hdr(host) -i foo.bar.com
      redirect scheme https code 302 if !{ ssl_fc } is_new_portal
      redirect location https://another.foobar.com code 302 if { ssl_fc } is_new_portal
    
      http-response set-header Strict-Transport-Security max-age=31536000;\ includeSubDomains;\ preload; if { ssl_fc }
    

    The space between ACLs after the if is interpreted as a AND. So you will get something like:

    • redirect to https IF the host is foo.bar.com AND NOT using ssl
    • redirect to https://another.foobar.com IF the host is foo.bar.com AND using ssl