4m1r
4m1r

Reputation: 12552

HAProxy Maps based on paths, if host match

I'm trying to load up and redirect several path maps on a per domain basis. Basically check domain, if domain match, use this domain path map (not the host header).

# redirect
http-request redirect location %[path,lower,map(/etc/haproxy/maps/foo.textmap)] code 301 if { hdr(host) -i foo.com }
#foo.textmap
path https://bar.com/path

And when I curl it like this. It looks like HAProxy is returning the 301, but location seems to be missing

[centos@ip-10-121-111-57 ~]$ curl -ILvs --resolve foo.com:80:127.0.0.1 http://foo.com/path
* Added foo.com:80:127.0.0.1 to DNS cache
* About to connect() to foo.com port 80 (#0)
*   Trying 127.0.0.1...
* Connected to foo.com (127.0.0.1) port 80 (#0)
> HEAD /path HTTP/1.1
> User-Agent: curl/7.29.0
> Host: foo.com
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
HTTP/1.1 301 Moved Permanently
< Content-length: 0
Content-length: 0
< Location: 
Location: 

< 
* Connection #0 to host foo.com left intact

Am I missing something here? Seems like the location from the path in the map should be returned in the location header. @Michael - sqlbot you seem to be the most knowledgeable in HAProxy world. Any suggestions? Thanks.

Upvotes: 0

Views: 1406

Answers (1)

mweiss
mweiss

Reputation: 1373

You're omitting / from the beginning of your path, so it's not matching. Namely, changing your text map to the following:

#foo.textmap
/path https://bar.com/path

Results in:

> curl -I foo.com/path
HTTP/1.1 301 Moved Permanently
Content-length: 0
Location: https://bar.com/path

For cases where the path does not match something in your map, you probably want to do something other than send an empty location in a 301. For example, here's a modification that would redirect to a default URL if the path was not found:

# redirect
http-request redirect location %[path,lower,map(/etc/haproxy/maps/foo.textmap,https://bar.com/default)] code 301 if { hdr(host) -i foo.com }

Otherwise if you want to only redirect if there's a match, then you would write a more complicated acl to match domain and if it exists in your map.

http-request redirect location %[path,lower,map(/etc/haproxy/maps/foo.textmap)] code 301 if { hdr(host) -i foo.com } { path,lower,map_str(/etc/haproxy/maps/foo.textmap) -m found }

Upvotes: 1

Related Questions