HA proxy, how to add dynamic header to incoming request based on request URI - haproxy

We need to add a header to incoming requests processed by HAproxy. However, each header needs to be composed of uri elements.
If the request is "http://myserver/system/apple/watch"
the header needs to be "Host:applewatch.com" where .com is static.
I am aware of "set-header" command, I just need to extract the second and the third URI elements via REGEX, string them together, and add static field .com.
Is there a way to save a URI element to a variable via regex and then reuse this variable as a header part?
Thanks you.

You can do something like this:
http-request set-header ASDF %[path,word(2,/)]%[path,word(3,/)].com
or
http-request set-header ASDF %[path,regsub(^/system/,''),regsub(/,''),regsub($,'.com')]

Related

How to remove the beginning slash from req.uri in haproxy

I need to extra the req.uri from a request in my frontend in haproxy. Here is what my haproxy looks like
frontend fe_ingress
...
http-request set-var(req.uri) path
http-request add-header endpoint %[var(req.uri)]
so I need to extract the req.uri and add it as a header to the subsequent request. Right now, it has / in its beginning but I need to remove the first /. How can I do this?
You can use the regsub filter to modify the value with a regular expression search-and-replace when setting the header. This can look like this:
http-request add-header endpoint %[path,regsub(^/,)]

Extracting params from the Referer Header field in HAProxy

I understand that I can use url_param / urlp to extract the query parameters from the URL that is requested, in HAProxy.
However, I need similar function for extracting parameters from the URL sent as HTTP Header field Referer. I guess url_param is only available for the requested URL, and not possible to use for HTTP Header values? If so, what other options do I have? I need to retrieve the value from query parameter and send it as specific HTTP Header to the backend server.
Sharing my solution (although Im not sure this is the most efficient and accurate way). I solved it with Regex.
# Example HTTP Referer: http://myexample.com/users?user-id=12345
# ACL
acl is_uid_in_hdr_referer hdr_sub(Referer) -i user-id
# Set value from query param "user-id" from Referer header to custom header "user-id"
http-request set-header user-id %[req.hdr(Referer),regsub(.+?user-id=,,g)] if is_uid_in_hdr_referer

How Can I modify a request header value from A to B by using Haproxy

Currently we are using Haproxy as a software loadbalancer.
I have an assignment, where I need to inspect each and request coming into my application and I need to look for a specific header (let's say Accept header) and I need to modify the value of header from A --> B.
Could you please guide me how can I do this by using HAPROXY.
Regards,
-Srini.
To replace one request header with another, example:
Accept: application/json # existing value
Accept: application/xml # desired value
Test the current value then set a header with the desired header.
http-request set-header Accept application/xml if { hdr(accept) -m str application/json }
Using http-request set-header removes any/all existing headers with the same name, which is what you would wanrtin this case. Using -m str specifies a case-sensitive string match on the value. Header name matching is always case-insensitive.
http://cbonte.github.io/haproxy-dconv/1.6/configuration.html#4-http-request

Concatenating strings in HAProxy

I'd like to have a throttling rule in HAProxy that limits rate at which a user can load any particular path, but I don't know of a way to concatenate strings in HAProxy (at least, in the context of generating a key for a stick table). So what I'd like is
tcp-request content track-sc1 concat(req.cook(user), path)
tcp-request content reject if {sc1_http_req_rate gt 10}
HAProxy manipulate string prior to map lookup suggests using regsub to do something somewhat similar, but I think I can only do constant manipulations with that.
The best I've come up with so far is to track path and req.cook(user) separately, and to reject if each of them is too high, but this isn't the actual behavior that I'm looking for.
The link in your question has the answer. You concat in set-header first and then use that.
http-request set-header X-Concat %[req.cook(user)]__%[path]
http-request track-sc0 hdr(X-Concat) table peruser

How to use set-header with a variable concatenated with req.hdr()

I am using set-header to rename an incoming header from an existing one. My problem is that in addition to renaming the header using req.hdr(my-old-header-name) I want to concatenate the interpreted value from the req.hdr() function with another static value (Bearer).
http-request set-header Authorization %[req.hdr(my-old-header-name)] if some-condition-applies
I want to be able to add a value "Bearer " in front of the interpreted %[req.hdr(my-old-header-name)] so that it ends up looking like this: Authorization: Bearer my-old-header-value-interpreted-from-req-hdr
Thanks for helping
Managed to make it work with replace-header as following:
http-request replace-header Authorization (.*) Bearer\ \1 if some_condition_applies
This basically takes the value of the Authorization header and prefixes it with Bearer.