5

We have a couple of haproxy configurations running fine for the most part. In our scenario, we simply route requests based on domain names. Here a sample for one domain, drawmessage.com:

frontend http
    bind *:80

    redirect prefix http://app.drawmessage.com code 301 if { hdr_dom(host) -i www.app.drawmessage.com }
    redirect prefix http://drawmessage.com code 301 if { hdr_dom(host) -i www.drawmessage.com }

    redirect prefix https://drawmessage.com code 301 if { hdr_dom(host) -i drawmessage.com }

    use_backend http:app.drawmessage.com if { hdr_dom(host) -i app.drawmessage.com }
    use_backend http:app.drawmessage.com if { hdr_dom(host) -i app-drawmessage-com.d250.hu }
    use_backend http:drawmessage.com if { hdr_dom(host) -i drawmessage.com }
    use_backend http:drawmessage.com if { hdr_dom(host) -i drawmessage-com.d250.hu }

There are other domains also, this is filtered for this domain only. As you can see, after redirects for www, we apply a special redirect for drawmessage.com, but theoretically not for app.drawmessage.com.

frontend https
     bind *:443 ssl crt /var/haproxy

     redirect prefix https://app.drawmessage.com code 301 if { hdr_dom(host) -i www.app.drawmessage.com }
     redirect prefix https://drawmessage.com code 301 if { hdr_dom(host) -i www.drawmessage.com }

     use_backend https:app.drawmessage.com if { hdr_dom(host) -i app.drawmessage.com }
     use_backend https:app.drawmessage.com if { hdr_dom(host) -i app-drawmessage-com.d250.hu }
     use_backend https:drawmessage.com if { hdr_dom(host) -i drawmessage.com }
     use_backend https:drawmessage.com if { hdr_dom(host) -i drawmessage-com.d250.hu }

The problem is that actually, we do not want a redirect to https for the subdomain app.drawmessage.com, but since we have a redirect for the domain the redirect rule applies for both. Reordering the rules in a way, so that the sorting matches the configuration we want to achieve does produce the same result, and we get haproxy warnings:

a 'redirect' rule placed after a 'use_backend' rule will still be processed before.

If the order of configuration lines affects the order of processing a request, thus the ordering is a configuration parameter itself, why are redirect rules processed before use_backend rules? ...

Anyone has a suggestion how to achieve domain-based routing, with the correct preference of redirects? I would prefer a clean and simple way, ..

1 Answer 1

8

Don't use hdr_dom(). Just use hdr().

redirect prefix https://drawmessage.com code 301 if { hdr(host) -i drawmessage.com }

The _dom suffix means you want to match the value given later against any number of complete, consecutive domain-name-like tokens found in the specified header, so the pattern you provide must begin either at the beginning of the string or immediately following a . and must end either at the end of the string or be immediately followed by a .. That isn't what you want to do, so hdr_dom() isn't the correct fetch to use.

The notation may imply that you are comparing left value against right value, but the comparison is actually right value against left value.

a 'redirect' rule placed after a 'use_backend' rule will still be processed before because these directives are handled by different parts of the HAProxy code, at different stages of request processing. Within each class of rule, the order is preserved, but redirects are handled near the beginning and backend selection is near the end of request processing.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. The problem with that was that port number have not been recognised, but I managed to extend my configuration with hdr(host) and adding port numbers to the domain.
@KirályIstván: please, could you share your result using ssl, multiple domains and port? Write your own answer, please, I am looking exactly to this kind of approach
@realtebo, my results are a set of scripts that generate HAproxy configs. All I had to do is to use hdr() instead of hdr_dom() ... as for port numbers, you can use the standard notation of domain:n where n is a port number.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.