Can I change a header value with a regex?
Short answer
Yes, with the Replace HTTP Header Content action. The header name is written in the Header to Replace field, the pattern in the Regex to Match field and the new value in the Replacement Content field; if the pattern matches in the value, the entire value is rewritten with Replacement content, and the parts to be kept are added back with capture groups in the form \1, \2. Matching is case-sensitive. With Match Type, either the whole value or each of the comma-separated values is processed separately. The action is applied to the request or the response according to the Execution Level selection.
Background
A regex defines a pattern searched for in a text. ^ denotes the start of the value, $ its end, .* "anything", and [0-9]+ one or more digits; \. searches for the dot itself. The part in parentheses is a capture group and is reused in the replacement text with \1 (first group) and \2 (second group).
Problem: Only Part of the Header Value Must Change
Only a specific part of a value, such as the internal address in the Location header returned by the Backend Service, the domain name of a cookie or the addresses in the X-Forwarded-For list, must be changed, and the rest must be kept. This cannot be done with Set HTTP Header, which overwrites the entire header with a fixed value.
Solution: Two Methods
In both methods, the patterns are written in Perl-compatible (PCRE) syntax.
| Your situation | Suitable method |
|---|---|
| Changing part of the existing value with a pattern and keeping the rest | Method 1: Replace HTTP Header Content |
| Deriving the value from another header or variable and writing it (creating the header if it does not exist) | Method 2: Set HTTP Header + Replace function |
Method 1: Replace HTTP Header Content Recommended
- How it works The pattern is searched for anywhere in the value; if it matches, the entire value is replaced with Replacement content with its group references filled in, and if it does not match, the value stays as it is.
- Where it is openedLoad Balancer → Actions → Replace HTTP Header Content
- Requirement The header must be present in the request or the response (otherwise nothing is done)
- vService type HTTP
Step-by-Step Configuration
Load Balancer → Actions → Add is clicked (how to add).
Action Name is entered, and Action Type = Replace HTTP header content is selected. Execution Level: On response for a header in the response of the Backend Service, On request (default; cannot be changed after saving) for a header in the request going to the Backend Service. Header to Replace = Location.
Regex to Match = ^http://192\.0\.2\.10:8080(.*)$; Replacement Content = https://www.example.com\1. With the flask icon next to the field (Test this pattern against a sample input), the pattern is tested on a sample value. In Replacement content, a reference greater than the number of groups in the pattern (e.g. \2 with a single group) gives an error; if $1 is written, the interface shows the Group references are written as \1, not $1 warning.
Match Type = Replace whole header (default): the whole value of the header is processed as a single piece; for headers such as Location and Set-Cookie. Replace values separated by comma: each comma-separated value is processed separately; for multi-value headers such as X-Forwarded-For and Accept (matching modes).
Add is clicked.
On the Load Balancer → Load Balancer vService List screen, the HTTP vService is selected and Edit is clicked.
Save is clicked. The change is applied without dropping open connections; in a cluster, it is also sent to the peer device with the default auto-sync (if Manual Sync Mode is on, with Synchronize).
Results of the example patterns:
| Header · Match type | Regex to Match | Replacement content | Value | Result |
|---|---|---|---|---|
| Location · whole | ^http://192\.0\.2\.10:8080(.*)$ | https://www.example.com\1 | http://192.0.2.10:8080/login | https://www.example.com/login |
http://192.0.2.10:8080 | https://www.example.com | |||
http://192.0.2.100:8080/x | Unchanged | |||
| Location · whole | ^http://(.*)$ | https://\1 | http://www.example.com/giris?x=1 | https://www.example.com/giris?x=1 |
HTTP://www.example.com/b | Unchanged (case-sensitive); changes with (?i)^http://(.*)$ | |||
| Set-Cookie · whole | ^(.*)Domain=app\.internal(.*)$ | \1Domain=example.com\2 | SID=1; Domain=app.internal; Path=/ | SID=1; Domain=example.com; Path=/ |
| X-Forwarded-For · comma | ^(198\.51\.100)\.[0-9]+$ | \1.0 | 198.51.100.23, unknown, 198.51.100.77 | 198.51.100.0, unknown, 198.51.100.0 |
Verification
Debug is turned on on the vService; the header list on the Response tab of the Debug Mode Logs record is checked.
Location row in dark orange with a right-arrow icon: old value in pale red, new value in greenThe address for which the Backend Service returns a redirect is requested: curl -skI https://www.example.com/giris
Location: https://www.example.com/loginMethod 2: Set HTTP Header + Replace Function
- How it works In the Header content field, the existing value of the header is taken as a Smart Variable, changed with the Replace (first) or Replace (all) function and written to the header; if the header does not exist, it is created.
- Where it is openedLoad Balancer → Actions → Set HTTP Header → Header Content → fx
- Requirement The function pattern does not contain parentheses (groups); if a group is needed, Method 1 is used
- vService type HTTP
Step-by-Step Configuration
Load Balancer → Actions → Add is clicked.
Action Name is entered, and Action Type = Set HTTP header is selected. Execution Level = On request; Header to Edit = Host.
With fx in the Header Content field, Request HTTP header content is selected and host is entered as the header name (for a response header, Response HTTP header content with On response).
In the variable window, Add Functions → Replace (first): To Replace = :[0-9]+$, and New Value is left empty (the matched part is deleted). The example value removes the port from a Host that arrives with a non-standard port.
Add is clicked.
On the Load Balancer → Load Balancer vService List screen, the HTTP vService is selected and Edit is clicked.
The action is selected in the Details → Actions field.
Save is clicked.
| Host | Result |
|---|---|
www.example.com:8443 | www.example.com |
www.example.com | www.example.com (unchanged) |
[2001:db8::1]:8443 | [2001:db8::1] |
Verification
curl -sk https://www.example.com:8443/ is sent; the Request tab of the Debug Mode Logs record is checked.
Host row in dark orange: www.example.com:8443 → www.example.comCommon Mistakes
The entire value is rewritten
When there is a match, not only the matched part but the entire value is replaced with Replacement content. The pattern http://(.*), which does not start with ^, matches in the middle of the value https://www.example.com/?next=http://x, and the value becomes https://x. The pattern is written with ^ and $ so that it covers the whole value, and every part to be kept is captured with a group.
- Writing
$1. Group references are in the form\1; the interface shows a warning. - Forgetting case sensitivity. Matching is case-sensitive; for case-insensitive matching,
(?i)is added to the start of the pattern. - Writing the dot without escaping.
.matches any character; in IP addresses and domain names,\.is written. - Using Replace whole header on a multi-value header. In headers such as X-Forwarded-For, the pattern is applied to the whole list; for each value, Replace values separated by comma is selected. In Set-Cookie, however, Replace whole header stays because the date contains a comma.
- Selecting the wrong Execution level. A header in the response of the Backend Service changes with On response; Execution level cannot be changed after saving.
How it is done in the documentation
