HAProxy: Using path variables to match one acl to a backend, depending on variable

haproxyreverse-proxyroutingurl

I would like to setup HAProxy to redirect to a particular backend based on the variable in the acl rule. As an example, right now, I have a standard 1-to-1 setup for the ACLs and the corresponding backends:

#Due to privacy concerns, this is not the actual file, but it is the same basic syntax and layout
frontend http
  maxconn 2000
  bind 0.0.0.0:5000
  
  acl test1-server path_reg -i /test/test1/home/.*
  use_backend servers-test1-server if test1-server

  acl test2-server path_reg -i /test/test2/home/.*
  use_backend servers-test1-server if test2-server

backend servers-test1-server
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  server www.testserver.com 127.0.0.1:9000

backend servers-test2-server
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  server www.testserver.com 127.0.0.1:9001

This setup works, but in our real file, we now have an absolutely enormous file due to all the rules and backend in it, making maintenance painful. What I would like to do is have one ACL that will match to backend based on the variable in the path. For example, if I have an ACL with a {profile} variable, and the user enters test1 in its place in the URL, then they should be connected to the test1 backend. Same for test2:

#Due to privacy concerns, this is not the actual file, but it is the same basic syntax and layout
frontend http
  maxconn 2000
  bind 0.0.0.0:5000
  
  acl test-server path_reg -i /test/{profile}/home/.*
  #match to backend based on value of {profile}

backend servers-test1-server
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  server www.testserver.com 127.0.0.1:9000

backend servers-test2-server
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  server www.testserver.com 127.0.0.1:9001

Is this possible in HAProxy? I'm using version 1.5.19.

EDIT:
I think I might have found the beginning of a solution. HAProxy 1.5 seems to support a map function, and I've begun rewriting frontend to take this into account:

frontend http
  maxconn 2000
  bind 0.0.0.0:5000

  use_backend bk_%[hdr(host),map(/path/to/map/file/config/haproxy.map)]

backend servers-test1-server
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  server www.testserver.com 127.0.0.1:9000

backend servers-test2-server
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  server www.testserver.com 127.0.0.1:9001

The map file, haproxy.map, looks like this:

/test/test1/home/*. servers-test1-webserver
/test/test2/home/*. servers-test2-webserver

I'm able to start haproxy using this, but am receiving a 503 error when trying to connect to the service. Can anyone tell me what the correct way of setting this up would be? Also, does the map files support wild cards in the path?

Best Answer

Having gone through this, I think the mapping function I mention in my edit is the best way to resolve this:

frontend http
  maxconn 2000
  bind 0.0.0.0:5000

  use_backend bk_%[base,map_beg(/path/to/map/file/config/haproxy.map)]

backend servers-test1-server
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  server www.testserver.com 127.0.0.1:9000

backend servers-test2-server
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  server www.testserver.com 127.0.0.1:9001

haproxy.map:

/test/test1/home/*. servers-test1-webserver
/test/test2/home/*. servers-test2-webserver