haproxy 和复杂重定向:我遗漏了什么吗?

haproxy 和复杂重定向:我遗漏了什么吗?

我有一个复杂的 Apache 配置,它主要只执行 ProxyPassReverse,这似乎很愚蠢,所以我一直在将其转换为 haproxy。这主要使事情变得更加简单和清晰;耶。例外是复杂的 RewriteRule 和 RedirectMatch 之类的东西。特别是,我有这些:

RewriteRule ^(?:/l?mw)+/(.*\.php.*)$ https://mw-live.lojban.org/$1 [R=301,L]
RewriteRule ^(?:/l?mw)+/(.*)$ https://mw-live.lojban.org/papri/$1 [R=301,L]

这里的目的是将请求重定向到例如 /lmw/mw/lmw/foo.php 到 /foo.php,将 /mw/lmw/mw/MyPage 重定向到 /papri/MyPage(是的,这些 URL 很奇怪;该网站的旧版本存在一些重定向问题)。

据我所知,正确的做法是不是在 haproxy 中执行此操作,并使用后端 Web 服务本身。我询问这个​​问题是为了防止我遗漏了什么,但看起来在后端 Web 服务上执行此类操作确实比在 haproxy 中执行效果好得多。

我在 haproxy 中尝试执行此操作时遇到两个问题:

  1. 我找不到让 haproxy 记录其自身执行的重定向的方法。我已告诉 haproxy 显示 Location 响应标头,但它仅显示来自后端服务器的重定向:

     capture response header Location len 128
    
  2. 在 haproxy 中执行此操作的方法很笨拙。我发现两种似乎可行的方法:

    # Old URL formats; trim leading "/mw" and "/lmw" when the target is a php file
    http-request redirect code 301 location http://%[hdr(host)]%[url,regsub(^/lmw,,g)] if { path_beg /lmw } { path_sub .php }
    http-request redirect code 301 location http://%[hdr(host)]%[url,regsub(^/mw,,g)] if { path_beg /mw } { path_sub .php }
    # Old URL formats; trim leading "/mw" and "/lmw"
    http-request redirect code 301 location http://%[hdr(host)]/papri%[url,regsub(^/lmw,,g)] if { path_beg /lmw }
    http-request redirect code 301 location http://%[hdr(host)]/papri%[url,regsub(^/mw,,g)] if { path_beg /mw }
    http-request redirect code 301 location http://%[hdr(host)]/papri%[url,regsub(^/papri/lmw,,g)] if { path_beg /papri/lmw }
    http-request redirect code 301 location http://%[hdr(host)]/papri%[url,regsub(^/papri/mw,,g)] if { path_beg /papri/mw }
    

此方法的问题在于,除了代码很长之外,它还会产生一系列重定向,重复将每个 URL 重定向到少一个 /mw 或其他内容的 URL。

另一个是在前端有这个:

use_backend mw-live-back-old-with-php if { hdr_beg(host) -i mw-live. } { path_reg ^/l?mw.*\.php }
use_backend mw-live-back-old-without-php if { hdr_beg(host) -i mw-live. } { path_reg ^/l?mw }

然后是与它配合使用的这些特殊后端:

backend mw-live-back-old-with-php
    http-request replace-path ^(?:/l?mw)+/(.*\.php.*)$ /\1
    http-request redirect prefix / code 301

backend mw-live-back-old-without-php
    http-request replace-path ^(?:/l?mw)+/(.*) /papri/\1
    http-request redirect prefix / code 301

这种方法的问题在于超级长,但仅为此创建后端似乎也很愚蠢。

你认为有用的东西,是我偷来的https://fromanegg.com/post/2014/12/05/how-to-rewrite-and-redirect-with-haproxy/,将这些行作为通用后端的一部分。

http-request replace-path ^(?:/l?mw)+/(.*\.php.*)$ /\1 if { path_reg ^/l?mw.*\.php }
http-request redirect prefix / code 301 if { path_reg ^/l?mw.*\.php }
http-request replace-path ^(?:/l?mw)+/(.*)$ /papri/\1 if { path_reg ^/l?mw }
http-request redirect prefix / code 301 if { path_reg ^/l?mw }

这会失败,因为重定向从未触发,因为当我们到达重定向行时,path_reg 不再匹配。

所以。

我是否遗漏了什么,或者我真的应该将这种复杂性转移到后端网络服务?

答案1

据我所知,正确的方法是不要在 haproxy 中执行此操作,而是使用后端 Web 服务本身。

太棒了。这里没必要再重新发明轮子了。

相关内容