How to add response headers with HAproxy 1.6 based on request URI?
I use HAproxy 1.6 as load balancer in front of tomcat servers.
I need to add response headers based on the request URI.
For e.g., I'd like to add the response header Cache-Control public,max-age="600"
when the request uri is /api
but not when the request uri is something else.
-
My first try was using acl based on path to add the headers to http-response:
acl api path_reg ^/api/(.*)$ http-response add-header Cache-Control public,max-age="600" if api
When I start haproxy with
-d
, I have warning saying thatpath_reg
(orpath
) is incompatible withhttp-response
:Dec 6 15:22:29 ip-10-30-0-196 haproxy-systemd-wrapper[315]: [WARNING] 340/152229 (2035) : parsing [/etc/haproxy/haproxy.cfg:78] : acl 'api' will never match because it only involves keywords that are incompatible with 'backend http-response header rule'
-
I tried to add the header in
http-request
instead ofhttp-response
:acl api path_reg ^/api/(.*)$ http-request add-header Cache-Control public,max-age="600" if api
That worked but I need it in the response
-
I also tried to use haproxy variables:
http-request set-var(txn.path) path acl path_acl %[var(txn.path)] -m ^/api/(.*)$ http-response add-header Cache-Control public,max-age="600" if path_acl
But when I try HAproxy doesn't event start and I have the following error:
[ALERT] 340/162647 (2241) : parsing [/etc/haproxy/haproxy.cfg:48] : error detected while parsing ACL 'path_acl' : unknown fetch method '%[var' in ACL expression '%[var(txn.path)]'.
How can I use the request path into an acl to set the response header?
Solution 1:
Try this:
http-response set-header Cache-Control no-cache,\ max-age=600 if { capture.req.uri -m beg /api/ }
capture.req.uri
persists until the response is processed, unlike path
, which does not.
A few notes:
This example uses an anonymous ACL. You could also do it with a named ACL, but that takes 2 lines.
There is no reason I am aware of why you should quote the max-age value.
You probably don't want to add-header
, you want to set-header
, which ensures that if one is already present, it will be removed.
acl path_acl %[var(txn.path)] -m ^/api/(.*)$
is probably correctly written as acl path_acl var(txn.path) -m ^/api/(.*)$
. HAProxy is a little finicky about when it expects %[ ]
and when it doesn't. I'm sure there's a pattern, but I'm not clear just what is is.