Hello. I'm having trouble working out a way to rewrite a request URI and do a
redirect with haproxy.
I have rules like this:
http-request add-header X-Forwarded-Proto http if !{ ssl_fc }
http-request add-header X-Forwarded-Proto https if { ssl_fc }
http-request redirect prefix
%[hdr(X-Forwarded-Proto)]://%[capture.req.uri,map_reg(/usr/local/etc/haproxy/cdn-hosts.lst)]
drop-query
reqrep ^([^\ ]*)\ /cdn/([^/]*)/(.*) \1\ /\3
In cdn-hosts.lst, I have this:
/[^/]+/A/.+ cdnA
/[^/]+/B/.+ cdnB
Specifically, I'm trying to do 2 things:
* Strip /cdn/whatever/ out of the request URI and forward to what remains. The
reqrep does this successfully, but only when I use "redirect" and not
"http-request redirect".
* Redirect to a location using a map. I can looks this up successfully with the
map_reg above and get back the correct host.
I can't combine these two: http-request is processed before reqrep and stops
the processing before it's ever seen. Doing things at the http-request stage, I
can't seem to find a way to rewrite the path portion of the Location header.
So I thought I could rewrite the entire request URI at that stage and I
wouldn't need anything like reqrep. I've tried doing this instead:
http-request redirect location
%[hdr(X-Forwarded-Proto)]://%[capture.req.uri,map_reg(/usr/local/etc/haproxy/cdn-redirects.lst)]
drop-query
where cdn-redirects.lst has this:
/[^/]+/A/(.+) cdnA/\1
/[^/]+/B/(.+) cdnB/\1
The problem is that when using map_reg(), \N substitutions aren't recognized. I
end up with a header like this:
Location: http://cdnA/\1
So is there another way to perform this kind of magic with haproxy? Right now I
have dozens of static rules where I use reqrep and ACLs, listing each CDN
endpoint. I'd like to get away from that and limit my maintenance to a map file.
I appreciate any insight. Thanks.