Hi community!
I want to preface this with saying that I’m kinda new to HAproxy. I’ve been banging my head against a wall trying to figure out how to rewrite a path and I’ve tried a bunch of directives, like set-path, replace-path, set-uri, setting headers, regsub, map-files and whatnot.
What I’m trying to do is simply to rewrite all requests for https://test-req.domain.com/resource/* to be rewritten to https://test-req.domain.com/req/resource/, but no matter what I’ve tried, what is being sent to the backend is always /resource/ and not /req/resource/. I’ve read a lot of forum posts, reddit posts, SO posts, documentation HAproxy config tutorial documentation. I’ve tried the examples from the documentation also, but nothing will rewrite the path. It feels like I’m missing something very obvious…
Some context:
The paths I’ve configured in the map files are meant for exact path matches. For the rewrite I’m trying to do, exact path is not required.
Here is an excerpt of my working haproxy.cfg (replaced names etc) without the rewrite related stuff:
...
frontend req_front
bind *:443 ssl crt /path/to/cert.pem
acl host_prod hdr(host) -i req.domain.com
acl host_test hdr(host) -i test-req.domain.com
acl match_prod path,map(/etc/haproxy/maps/backend_prod.map) -m found
acl match_dev path,map(/etc/haproxy/maps/backend_dev.map) -m found
use_backend %[path,map(/etc/haproxy/maps/backend_prod.map)] if host_prod match_prod
use_backend %[path,map(/etc/haproxy/maps/backend_dev.map)] if host_dev match_dev
default_backend fallback
backend req_back_prod
balance roundrobin
server host01 IP:PORT check ssl verify required ca-file /path/to/CAcert.pem
server host02 IP:PORT check ssl verify required ca-file /path/to/CAcert.pem
backend req_back_dev
balance roundrobin
server host03 IP:PORT check ssl verify required ca-file /path/to/CAcert.pem
server host04 IP:PORT check ssl verify required ca-file /path/to/CAcert.pem
backend fallback
http-request return status 404 content-type text/plain string "The requested resource was not found"
...
Below are some things that I’ve tried to incorporate in my working configuration:
# Having this in the frontend configuration grouped with the other ACLs, http-requests, and use_backend directives.
# Backend config is the same as above. This results in request being sent to default_backend.
acl req_resource path_beg -i /resource/
http-request set-path /req/%[path] if host_dev req_resource
use_backend req_back_dev if host_dev req_resource
# I've also tried this with map files.
# Request is being sent to right backend but is not being written at all:
http-request replace-path ^/resource/(.*) %[path,lower,map_sub(/etc/haproxy/maps/path-rewrite-mapping.map)]\1 if host_dev { path_beg -i /resource/ }
use_backend %[path,lower,map_beg(/etc/haproxy/maps/path-to-backends-sub.map)] if host_dev { path_beg -i /resource/ }
# Tried doing the rewrite in the backend, with a use_backend directive if path was /resource/ in frontend.
# Results in request sent to right backend but not being rewritten:
http-request replace-path ^/resource/(.*) /req/resource\1 if { path_beg /resource/ } # <-- Did not work
http-request set-path /req/%[path] if { path_beg /resource/ } # This also did not work
Please help me figure out what I’m missing. I’d be really grateful! Or if you’d be so kind - suggest a different approach to achieve my requirements of using exact paths, like in the working map files, mixed with rewriting paths beginning with /resource/ to /req/resource.
Best Regards,
S
1 post - 1 participant