使用HAProxy重定向URL路径并保留查询字符串

Lin*_*nay 1 haproxy

我们使用以下方法将URL映射文件加载到HAProxy中:

http-request redirect location %[capture.req.uri,map(/etc/haproxy/redirects.map)] code 301 if { capture.req.uri,map(/etc/haproxy/redirects.map) -m found }
Run Code Online (Sandbox Code Playgroud)

地图文件中一行的示例为:

/shop-by-category /products
Run Code Online (Sandbox Code Playgroud)

此重定向按预期工作。我遇到的唯一问题是使用/ shop-by-category路径传递查询字符串时。例如:

/shop-by-category?testingquerystring=test
Run Code Online (Sandbox Code Playgroud)

这不会重定向。

我尝试将我认为是HAProxy查询变量的内容添加到重定向映射中,例如:

/shop-by-category&%[query] /parts&%[query]
Run Code Online (Sandbox Code Playgroud)

但是,HAProxy在地图文件中似乎无法识别出这一点。有什么方法可以让HAProxy动态识别查询字符串并在重定向时将其传递通过?

Mic*_*bot 5

我可以肯定地说,您不能在地图文件中使用提取-它是静态的,并且在启动时加载,因此无法插值。

capture.req.uri 在RFC中指的是URI:

capture.req.uri : string

这将提取请求的URI,该URI从第一个斜杠开始,在请求的第一个空格之前终止(不包含主机部分)。与“ path”和“ url”不同,它是已分配的,因此可以在请求和响应中使用。

...因此,听起来好像您应该使用pathfetch进行匹配,并且query如果已设置,则在重写中使用fetch 。

path : string

这将提取请求的URL路径,该路径从第一个斜杠开始,在问号之前(不包含主机部分)结束。

query : string

这将提取请求的查询字符串,该字符串从第一个问号开始。如果不存在问号,则此访存不返回任何内容。如果存在问号,但没有任何后续内容,它将返回一个空字符串。这意味着可以使用“找到”匹配方法轻松知道是否存在查询字符串。此提取是“路径”的补充,该路径在问号之前停止。

然后需要两行用于匹配和重写。

首先,如果存在查询字符串,则进行重写:

http-request redirect location %[path,map(/etc/haproxy/redirects.map)]?%[query] code 301 if { path,map(/etc/haproxy/redirects.map) -m found } { query -m found }
Run Code Online (Sandbox Code Playgroud)

然后,如果查询字符串不存在,请重写:

http-request redirect location %[path,map(/etc/haproxy/redirects.map)] code 301 if { path,map(/etc/haproxy/redirects.map) -m found } ! { query -m found }
Run Code Online (Sandbox Code Playgroud)

您的地图文件只能是路径。