Error detected replace-header expects exactly 3 arguments

I am upgrading our load balancers (haproxy 1.8.20 to haproxy 2.4.12) and some of the original configurations are deprecated. The one giving me the most trouble is reqirep. I understand that I need to use http-request replace-header instead of reqirep. I’ve learned that doing a simple find/replace reqirep with http-request replace-header won’t work given the current syntax we’re using. Hoping someone can help me understand this syntax better.

My current configuration with reqirep. Do I understand it correctly that reqirep uses two parameters (search and replace)? How can you tell where the search parameter ends and the replace parameter starts?

reqirep ^(.*)\ /oranges/.*-(\d+)-orange.html\ (.*) \1\ /orange.asp?id=\2\ \3 reqirep ^(.*)\ /oranges(/orange.asp.*)\ (.*) \1\ /oranges-old\2\ \3 reqirep ^(.*)\ /oranges(/orange-lookup-box/.*)\ (.*) \1\ /oranges-old\2\ \3 reqirep ^(.*)\ /py/do/lookupresults.asp(.*)\ (.*) \1\ /oranges/orange-lookup.asp\2\ \3

I found this article [PATCH 1/2] DOC: split the http-request actions in their own section while researching, is this the correct basic format for replace-header?

replace-header <name> <match-regex> <replace-fmt>

If it is, does this mean I’m only missing the parameter?

No, not in this case.

reqirep means:

Replace a regular expression with a string in an HTTP request line

in other words it can match&replace every HTTP request line, including the first line, which is not technically a HTTP header.

What you are really trying to do here is rewrite the URI. So, to rewrite the URI, you’d use http-request replace-path or http-request replace-pathq instead. Don’t use http-request replace-uri for the reason mentioned in the documentation.

So, lets take a look:

reqirep ^(.*)\ /oranges/.*-(\d+)-orange.html\ (.*) \1\ /orange.asp?id=\2\ \3 

We drop \1 and \3, since we are no longer working on a pure HTTP headers matching HTTP method and version, so things become way simpler:

http-request replace-pathq /oranges/.*-(\d+)-orange.html /orange.asp?id=\1

And so on.

Thank you for the response! When you say don’t use replace-uri for the reason mentioned in the documentation are you referring to where it might fail in HTTP/2? I ask because I ended up using replace-uri and that got me up and running.

Different circumstances trigger different behavior.

That is the point: it works now, in your specific situation. That’s why you shouldn’t use it, and use the reliable alternatives instead.