Haproxy set backend server via query string

I am using sticky sessions for stateful requests to our backend servers. Haproxy sets the cookie and the setup works well. I now want the option to set the required backend server via a query string for testing and clients which can't use cookies.

Both of these curls should go to the same backend:

curl mysite.com -I --cookie "serverid=app-2"
curl mysite.com?serverid=app-2 -I

I have tried many combination of config to no avail.

backend myapp

  cookie      serverid insert indirect nocache

  stick-table type string len 32 size 1M

  stick on cookie(serverid)
  stick on url_param(serverid)

  server app-0 111.111.111.111:80 cookie app-0
  server app-1 222.222.222.222:80 cookie app-1
  server app-2 333.333.333.333:80 cookie app-2

Is it possible todo this in haproxy?


Yeah, it's possible.

Stick tables enable a client-server persistance, but they don't define which server a given client ends up on. That's what the cookie directive does (in combination with the cookie option to the server directives).

Unfortunately, if your client doesn't support cookies, it's not of much use.

The way to get around that is by having a set of use-server lines to catch those cases. These are processed before, and have precedence over, the cookie routing, so that if a use-server matches, it will be used.

Given your request that the two curl commands mentioned in the question end up on the same box, this config works for me in my testing (very minimal though it may have been).

backend myapp

  cookie serverid insert indirect nocache

  use-server app-0 if { urlp(serverid) -i app-0 }
  use-server app-1 if { urlp(serverid) -i app-1 }
  use-server app-2 if { urlp(serverid) -i app-2 }

  server app-0 142.135.221.205:10001 cookie app-0
  server app-1 142.135.221.205:10002 cookie app-1
  server app-2 142.135.221.205:10003 cookie app-2

If you have more than 3 servers, it's going to get a little unwieldy, but it's currently the only way I can see making it work the way you need.