【发布时间】:2015-06-09 18:55:35
【问题描述】:
我想用 haproxy 删除多个斜杠:
$ curl -I "http://www.host.com//some_path/sub_path/slug/"
并使其发送 301 响应以用于 SEO:
HTTP/1.1 301 Moved Permanently
Cache-Control: no-cache
Content-length: 0
Location: /some_path/subpath/slug/
第一种方法:创建 ACL -> 替换斜杠 -> 重定向
acl multiple-bars path_reg /{2,}
reqrep ^([^\ :]*)\ /{2,}(.*) \1\ /\2 if multiple-bars
...
redirect prefix / code 301 if multiple-bars
reqrep 更改了 URL,因此“multiple-bars”不再成立。因此我没有 301 重定向
$ curl -I "http://www.host.com//some_path/sub_path/slug/"
HTTP/1.1 200 OK
domain=www.host.com
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Content-Type: text/html; charset=UTF-8
Date: Tue, 09 Jun 2015 18:16:36 GMT
第二种方法:创建自定义Header,如果找到该Header则重定向
acl multiple-bars path_reg /{2,}
reqadd X-HadMultipleBars if multiple-bars
reqrep ^([^\ :]*)\ /{2,}(.*) \1\ /\2 if multiple-bars
...
redirect prefix / code 301 if { hdr_cnt(X-HadMultipleBars) 1 }
但是 HAProxy 先处理 reqrep 规则,然后再处理 reqadd。所以:
[ec2-user@haproxy-stage-m3m-a haproxy]$ sudo service haproxy restart
Stopping haproxy: [ OK ]
Starting haproxy: [WARNING] 159/181957 (11430) : parsing [/etc/haproxy/haproxy.cfg:87] : a 'reqrep' rule placed after a 'reqadd' rule will still be processed before.
[WARNING] 159/181957 (11430) : parsing [/etc/haproxy/haproxy.cfg:103] : a 'reqidel' rule placed after a 'reqadd' rule will still be processed before.
[WARNING] 159/181957 (11430) : parsing [/etc/haproxy/haproxy.cfg:104] : a 'reqrep' rule placed after a 'reqadd' rule will still be processed before.
[ OK ]
它不会重定向:
$ curl -I "http://www.host.com//some_path/sub_path/slug/"
HTTP/1.1 200 OK
domain=www.host.com
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Content-Type: text/html; charset=UTF-8
Date: Tue, 09 Jun 2015 18:16:36 GMT
第三种方法:
acl multiple-bars path_reg /{2,}
reqrep ^([^\ :]*)\ /{2,}(.*) \1\ /\2\nX-HadMultipleBars: if multiple-bars
...
redirect prefix / code 301 if { hdr_cnt(X-HadMultipleBars) 1 }
我不喜欢这个 hack,它看起来很脏,但它确实有效:hdr_cnt 的值是 1。
它适用于多个斜杠:
$ curl -I "http://www.host.com/////some_path/sub_path/slug/"
HTTP/1.1 301 Moved Permanently
Cache-Control: no-cache
Content-length: 0
Location: /some_path/sub_path/slug/
但它不适用于 sub_path 多个斜杠:
$ curl -I "http://www.host.com//////some_path///sub_path////slug/////"
HTTP/1.1 301 Moved Permanently
Cache-Control: no-cache
Content-length: 0
Location: /some_path///sub_path////slug/////
我在使这个正则表达式有点递归时遇到了麻烦,但是这段代码每次都会删除一些“随机”斜杠:
http://www.host.com//////some_path///sub_path////slug/////
301 -> Location: /some_path///sub_path////slug/////
301 -> Location: /some_path//sub_path//slug///
301 -> Location: /some_path/sub_path/slug//
301 -> Location: /some_path/sub_path/slug/
200!
我尝试使用这个在http://www.regexr.com/ 工作的正则表达式,而不是反向引用([^\ :]*)
#Parses Valid URL characters:
([!#$&-.0-;=?-[\]_a-z~]|%[0-9a-fA-F]{2})+
但它不适用于 HAProxy 1.4 :( 有人可以在这里给我一些帮助吗?
谢谢!
【问题讨论】: