Summary
Saving dynamic configuration silently drops backslashes from property values. Connection-pool domain regexes that use \Q…\E (or \., \d, …) lose their backslashes and stop matching.
Cause
ConfigurationStore.toStringConfiguration() serializes the configuration as raw key + "=" + value, with no escaping. On any change, HttpProxyServer.rewriteConfiguration() feeds that text back through ConfigResource.buildStore() → java.util.Properties.load(...), which treats \ as an escape and drops it before unrecognized characters (\Q→Q, \E→E).
This path runs for the connection-pool REST API (/api/connectionpools POST/PUT/DELETE) and for saving from the config editor, and it re-serializes the whole configuration — so every backslash-bearing value is corrupted except the one written in that same call.
Reproduction
A pool configured with domain=(\Qhost.example\E) becomes domain=(Qhost.exampleE) after any config save, so Pattern.matches no longer matches host.example.
Impact
A connection pool can silently stop matching its hostname and fall back to the default pool — no error, no log. Affects any backslash-bearing property (pool domains, request matchers, rewrite rules).
Affected versions
Present wherever the config editor / connection-pool CRUD API exist (2.0+); reproduced on 2.1.x and master.
Suggested fix
Serialize via Properties.store(...) (which escapes backslashes) instead of key + "=" + value, and/or avoid the text round-trip in rewriteConfiguration. Add a regression test asserting a \Q…\E domain survives a config save.
Summary
Saving dynamic configuration silently drops backslashes from property values. Connection-pool
domainregexes that use\Q…\E(or\.,\d, …) lose their backslashes and stop matching.Cause
ConfigurationStore.toStringConfiguration()serializes the configuration as rawkey + "=" + value, with no escaping. On any change,HttpProxyServer.rewriteConfiguration()feeds that text back throughConfigResource.buildStore()→java.util.Properties.load(...), which treats\as an escape and drops it before unrecognized characters (\Q→Q,\E→E).This path runs for the connection-pool REST API (
/api/connectionpoolsPOST/PUT/DELETE) and for saving from the config editor, and it re-serializes the whole configuration — so every backslash-bearing value is corrupted except the one written in that same call.Reproduction
A pool configured with
domain=(\Qhost.example\E)becomesdomain=(Qhost.exampleE)after any config save, soPattern.matchesno longer matcheshost.example.Impact
A connection pool can silently stop matching its hostname and fall back to the default pool — no error, no log. Affects any backslash-bearing property (pool domains, request matchers, rewrite rules).
Affected versions
Present wherever the config editor / connection-pool CRUD API exist (2.0+); reproduced on 2.1.x and
master.Suggested fix
Serialize via
Properties.store(...)(which escapes backslashes) instead ofkey + "=" + value, and/or avoid the text round-trip inrewriteConfiguration. Add a regression test asserting a\Q…\Edomain survives a config save.