我想设置一个类似这样的重定向映射https://stackoverflow.com/questions/23001799/how-do-i-used-the-map-feature-in-haproxy-to-build-massive-redirect-tables-1-5
不同之处在于我想使用http-response
而不是http-request
。原因是因为我想重定向仅有的当后端服务器返回404时。
这是我的配置
http-response redirect location %[capture.req.uri,regsub(\?(.*),),map(/etc/haproxy/redirects.map)] code 301 if { status 404 } { capture.req.uri,regsub(\?(.*),),map(/etc/haproxy/redirects.map) -m found }
我尝试使用regsub
从 中删除查询参数capture.req.uri
。但是,重新启动 HAProxy 时出现此错误。
[ALERT] 280/171612 (6176) : parsing [/etc/haproxy/haproxy.cfg:87] : error detected in proxy 'http' while parsing 'http-response redirect' rule : error in condition: invalid arg 2 in conv method 'regsub' : missing arguments (got 1/2), type 'string' expected in ACL expression 'capture.req.uri,regsub(\?(.*),),map(/etc/haproxy/redirects.map)'. [ALERT] 280/171612 (6176) : Error(s) found in configuration file : /etc/haproxy/haproxy.cfg Errors found in configuration file, check it with 'haproxy check'.
有没有办法获取没有查询参数的 URL?我尝试使用path
而不是capture.req.uri
但 HAProxy 无法启动。
这是我的配置使用path
http-response redirect location %[path,map(/etc/haproxy/redirects.map)] code 303 if { status 404 } { path,map(/etc/haproxy/redirects.map) -m found }
这是警告
[WARNING] 283/090721 (2875) : parsing [/etc/haproxy/haproxy.cfg:88] : 'redirect' : sample fetch <path,map(/etc/haproxy/redirects.map)> may not be reliably used here because it needs 'HTTP request headers' which is not available here. [WARNING] 283/090721 (2875) : parsing [/etc/haproxy/haproxy.cfg:88] : anonymous acl will never match because it uses keyword 'path' which is incompatible with 'backend http-response header rule'
答案1
最初的问题是 的问题regsub(\?(.*),)
,这导致了一个问题,因为 转换器regsub
仅限于配置解析器可以处理的表达式——并且括号不可用,因为解析器认为以太少的参数)
结尾。(对于文字,您可以使用十六进制转义来解决解析器的限制,但这在这里不起作用。)regsub()
\\xnn
regsub
之所以被使用,是因为这个重定向是在响应处理期间触发的if { status 404 }
,并且path
在该处理阶段无法进行提取——一旦将请求发送到服务器,HAProxy 就会释放该请求所使用的缓冲区。
但是,HAProxy 1.6 还引入了用户变量,如果在事务()范围内使用,可以用来从请求端传输数据txn
。
在请求处理期间,将获取的内容存储path
在名为(巧合的是)的事务范围变量中path
。
http-request set-var(txn.path) path
然后,可以在响应处理期间访问它。
为清楚起见,以下内容显示在多行上,但必须在单行配置上。
http-response redirect
location %[var(txn.path),map(/etc/haproxy/redirects.map)]
code 303
if { status 404 } { var(txn.path),map(/etc/haproxy/redirects.map) -m found }
如果响应状态代码为 404,则从变量中取回值并检查映射文件中是否有值。如果有,则使用该值进行重定向。