根据RFC3986类似这样的网址
http://example.com/catalog/category/goods/../brand/product.html
由某些 UserAgent 转换为(curl 就是很好的例子)http://example.com/catalog/category/brand/product.html
如果我的愚蠢的 UserAgent 无法以正确的方式解析原始 URL,我该如何使用 nginx 重写实现这种行为?
这有可能吗?
答案1
你可以用单个替换/./
序列和序列。例如:/goods/../
/
rewrite ^(.*)/\./(.*)$ $1/$2 redirect;
rewrite ^(.*)/(?!\.\.)[^/]+/\.\./(.*)$ $1/$2 redirect;
序列/(?!\.\.)[^/]+/
应与任何不是另一个 的路径元素匹配..
。上述重写是递归的,并发出 302 响应,直到所有/./
和/../
序列都被正确删除。
或者,也可以使用内部重定向来实现相同的目的,方法是将rewrite...last
语句放在合适的location
块内。例如:
location / {
rewrite ^(.*)/\./(.*)$ $1/$2 last;
rewrite ^(.*)/(?!\.\.)[^/]+/\.\./(.*)$ $1/$2 last;
}
这种情况下,浏览器地址栏上显示的URL不会改变。
答案2
我看到 nginx 默认使用normailses URL。引用文档:
规范化的 URI,在解码以“%XX”形式编码的文本后,解析对相对路径组件“.”和“..”的引用,并可能将两个或多个相邻的斜线压缩为一个斜线。
我已经测试过并且它可以在这里开箱即用(使用 proxy_pass),或者您对此有什么问题吗?