基于path的Haproxyredirect

与HAProxy reqrep类似, 删除后端请求上的URI 。

以下关注适用于我们。

我们有一些应用程序在不同的上下文根目录下运行。 然而,不是所有的url的客户都被改变了。

如果请求匹配传统path,我想redirecthaproxy中的301redirect。

http://example.com/abchttp://example.com/def为例

 ... frontend https bind *:{{ proxy_port }} ssl crt /etc/haproxy/bundle_dh.pem ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 no-sslv3 http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Port %[dst_port] acl has_legacy_abc path_beg /abc acl has_legacy_def path_beg /def redirect location 301 https://abcdomain.com/{PATH_WITHOUT_ABC} if { has_legacy_abc } redirect location 301 https://defdomain.com/{PATH_WITHOUT_ABC} if { has_legacy_def } use backend abc_backend if { hdr(Host) -i abcdomain.com } use backend def_backend if { hdr(Host) -i defdomain.com } ... 

问题是如何在redirect中保留path。 我可以做一个绝对的redirect。

看起来和reqrep但似乎是在传递到后端之前更改请求。 我想告诉所有访问者他们应该去新的域名。

这可以使用像这样的临时头文件来完成,在acl定义和use_backend关键字之间插入:

 http-request set-header X-Location-Path %[capture.req.uri] if has_legacy_abc OR has_legacy_def http-request replace-header X-Location-Path [^/]+/(.*) \1 if has_legacy_abc OR has_legacy_def http-request redirect location https://abcdomain.com/%[hdr(X-Location-Path)] if has_legacy_abc http-request redirect location https://defdomain.com/%[hdr(X-Location-Path)] if has_legacy_def 

根据域/path的实际configuration和所需的redirect,甚至可以将其全部折叠为一组指令,如下所示:

 ... frontend https bind *:{{ proxy_port }} ssl crt /etc/haproxy/bundle_dh.pem ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 no-sslv3 http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Port %[dst_port] acl has_legacy path_beg /abc /def http-request set-header X-Location-Path %[capture.req.uri] if has_legacy http-request set-header X-Location-Host %[capture.req.uri] if has_legacy http-request replace-header X-Location-Host /([^/]*)/ \1 if has_legacy http-request replace-header X-Location-Path [^/]+/(.*) \1 if has_legacy http-request redirect location https://%[hdr(X-Location-Host)]domain.com/%[hdr(X-Location-Path)] if has_legacy_abc use backend abc_backend if { hdr(Host) -i abcdomain.com } use backend def_backend if { hdr(Host) -i defdomain.com } ... 

如果path和域的数目是巨大的,你可以使用地图 (关键是path,值是目标主机)来简化事情。