Hi, HAProxy 2.5-dev6 was released on 2021/09/03. It added 32 new commits after version 2.5-dev5.
There is not that many new features in that release but I wanted to issue it after haproxy.org experienced a freeze on 2.5-dev5, that was in fact caused by a locking bug in the queues that was introduced in 2.5-dev1 and that made me roll back. Aside this bug, I had a look at a large and complex config a few days ago and found a lot of room for improvement at very low cost, with certain things that were constantly being postponed and others that I hadn't thought about yet. One of them was the usual dance between variables and dummy headers, because headers support log-format lines allowing concatenation, but headers are relatively expensive to extract, and their tests rely on long and error-prone rules. Several times we said that we needed a set-var variant supporting format strings, to simplify this and to permit string manipulation from tcp rules (which cannot touch headers). This is what was done. There's now a new action "set-var-fmt" which accepts a string format instead of a sample expression. Thus it can be as simple as this to set and append strings to a variable: http-request set-var-fmt(txn.from) addr=%[src]:%[src_port] while in the past it used to require: http-request set-var(txn.from_addr) src http-request set-var(txn.from_port) src_port http-request set-var(txn.from) str("addr"),concat('=',txn.from_addr),concat(':',txn.from_port) This is quite an obvious example but it should also help manipulate multi-field variables (e.g. store multiple attributes inside a single variable). The other quite minor thing is that the var() sample fetch function now takes an optional default value. I've indeed seen quite a lot of this over time: http-request set-var(req.count) int(0) ... http-request set-var(req.count) var(req.count),add(1) if { condition } ... And indeed, req.count needed to be initialized in its own rule otherwise var(req.count) would return "not found" and add() would fail, so would the update. Now it's simpler, we can say just like with maps that if req.count does not exist, it equals 0, and we drop half of the rules: http-request set-var(req.count) var(req.count,0),add(1) if { condition } I'm sure this may help simplify some complex configs. RĂ©mi added new sample fetch functions to retrieve a backend connection error code and string (both raw and TLS): bc_conn_err, bc_conn_err_str, ssl_bc_hsk_err, ssl_bc_hsk_err_str. This can be helpful to log for those who do not have control over the server and want to ease troubleshooting when connections fail to establish. Tim fixed thread-safety issues in the functions used to return the local or GMT date, and which could have caused an occasional return of a wrong value to the http_date() converter in heavily threaded environments. It's unlikely that anyone ever noticed it but usually it's sufficient that we mention it for someone to raise their hand :-) Last, HTTP redirects now support a new "ignore-empty" option that skips the redirect rule if the target URL is empty. While it could look odd, it is particularly convenient when intercepting some URLs from a map file: http-request redirect code 301 location %[base,map(old-uris.map)] ignore-empty With this, URLs found in the map will match and redirect, those not found will continue to the next rule instead of redirecting to the empty URL. It could have made sense to make this the default but it could break setups that used to filter accesses by host so I'd rather not change the default: http-request redirect code 301 location %[base,map(public-uris.map)] if HOST_RESTRICTED And as usual, a few cleanups in the code, doc and regtests. One thing to be noted though. We're now building with -Wundef to catch "#if MACRO" where <MACRO> was not defined. There were very few in the code (which had been cleaned) and a few were wrong, making it a good reason to keep that option. I *think* we caught them all. If it fails to build for you, please report it. If it breaks on some systems, I'm even not opposed to removing it but I'd prefer to keep it as long as it doesn't break. Oh and yet another last thing, the latest version of BoringSSL breaks the build (we've disabled it in the CI for now), we'll have a look at it next week, Ilya already found a few things to fix. I started to work on a few backports in stable branches. There's this double-slash issue that I'd like to get rid of, so expect a bunch of stable releases early next week. Please find the usual URLs below : Site index : http://www.haproxy.org/ Discourse : http://discourse.haproxy.org/ Slack channel : https://slack.haproxy.org/ Issue tracker : https://github.com/haproxy/haproxy/issues Wiki : https://github.com/haproxy/wiki/wiki Sources : http://www.haproxy.org/download/2.5/src/ Git repository : http://git.haproxy.org/git/haproxy.git/ Git Web browsing : http://git.haproxy.org/?p=haproxy.git Changelog : http://www.haproxy.org/download/2.5/src/CHANGELOG Cyril's HTML doc : http://cbonte.github.io/haproxy-dconv/ Willy --- Complete changelog : Remi Tricot-Le Breton (5): MINOR: log: Remove log-error-via-logformat option MINOR: log: Add new "error-log-format" option MINOR: ssl: Add new ssl_bc_hsk_err sample fetch MINOR: connection: Add a connection error code sample fetch for backend side REGTESTS: ssl: Add tests for bc_conn_err and ssl_bc_hsk_err sample fetches Tim Duesterhus (3): BUG/MINOR threads: Use get_(local|gm)time instead of (local|gm)time BUG/MINOR: tools: Fix loop condition in dump_text() CLEANUP: Add missing include guard to signal.h Willy Tarreau (24): BUILD: ssl: next round of build warnings on LIBRESSL_VERSION_NUMBER BUILD: ssl: fix two remaining occurrences of #if USE_OPENSSL BUILD: tools: properly guard __GLIBC__ with defined() BUILD: globally enable -Wundef BUG/MAJOR: queue: better protect a pendconn being picked from the proxy MINOR: http-rules: add a new "ignore-empty" option to redirects. CI: Github Actions: temporarily disable BoringSSL builds BUG/MINOR: vars: fix set-var/unset-var exclusivity in the keyword parser BUG/MINOR: vars: improve accuracy of the rules used to check expression validity MINOR: sample: add missing ARGC_ entries BUG/MINOR: vars: properly set the argument parsing context in the expression DOC: configuration: remove wrong tcp-request examples in tcp-response MEDIUM: vars: add a new "set-var-fmt" action BUG/MEDIUM: vars: run over the correct list in release_store_rules() BUG/MINOR: vars: truncate the variable name in error reports about scope. BUG/MINOR: vars: do not talk about global section in CLI errors for set-var CLEANUP: vars: name the temporary proxy "CFG" instead of "CLI" for global vars MINOR: log: make log-format expressions completely usable outside of req/resp MINOR: vars: add a "set-var-fmt" directive to the global section MEDIUM: vars: also support format strings in CLI's "set var" command CLEANUP: vars: factor out common code from vars_get_by_{desc,name} MINOR: vars: make vars_get_by_* support an optional default value MINOR: vars: make the vars() sample fetch function support a default value BUILD: ot: add argument for default value to vars_get_by_name() ---