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.

Reply via email to