HAPROXY regsub match '?' questionmark

In HAproxy replacing the incoming url with some data. This is the incoming path:

/powerbi?redirectSuccessUrl=/reports

I want to match:

/powerbi? 

replace it with

clientId=${clientId}&

And final outcome must be:

/powerbi?clientId=${clientId}&redirectSuccessUrl=/reports

I tried this

http-request set-path %[path, regsub(^/powerbi\?,/powerbi?clientId="${clientId}"&]

But getting two questionmarks(near powerBi and before redirectSuccessUrl):

/powerbi?clientId=${clientId}&?redirectSuccessUrl=/reports

How to match '?' with regsub? I've tried '?' , '[?]', '[\?]'. None of these matches a questionmark.


Solution 1:

You don't match for ?, because it seperates path part of uri from query string part in haproxy and haproxy already does that for you. You want to change query string, but altered path. That's why your changes ended up on the wrong side of ?. Instead use http-request set-query, like this:

http-request set-query clientId=${clientId}&%[query]

In case you may want to properly set query depending on whether original uri had query or not, you may try this:

http-request set-query clientId=${clientId}&%[query] if { query -m found }
http-request set-query clientId=${clientId} unless { query -m found }

This avoids trailing & in case there was no query string in uri.

Alternatively you may try some magic regexp with set-uri and set whole uri instead, but be very careful and remember that uri may come as relative uri (e.g. /foobar?arg1=val1&arg2=val2) or absolute uri (e.g. https://example.com:6789/foobar?arg1=val1&arg2=val2) and then conjuring proper regexp to handle both will be far more difficult than simply using set-path and set-query as above. More about relative and absolute uri in haproxy docs

UPDATE in response to comment

You can match for path part and change query string, e.g.:

acl url_powerbi path_beg /powerbi
acl query_string_found query -m found
http-request set-query clientId=${clientId}&%[query] if url_powerbi query_string_found
http-request set-query clientId=${clientId} if url_powerbi !query_string_found