我运行一个提供静态文件的 nginx 服务器。一些文件名包含字符串,如 %3a
.
/var/www/testfile%3a
如果我尝试请求这些文件,则会收到 404 Not Found 错误。
这似乎是因为 nginx decodes the URL并替换
%3a
与 :
,然后没有找到名为 /var/www/testfile:
的文件.我从 nginx 的以下调试输出中推断出这一点:2018/06/21 10:03:21 [debug] 32523#0: *6 http process request line
2018/06/21 10:03:21 [debug] 32523#0: *6 http request line: "GET /testfile%3a HTTP/1.1"
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'2F:/'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:1 in:'74:t'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'65:e'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'73:s'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'74:t'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'66:f'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'69:i'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'6C:l'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'65:e'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'25:%'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:4 in:'33:3'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:5 in:'61:a'
2018/06/21 10:03:21 [debug] 32523#0: *6 s:0 in:'3A::'
2018/06/21 10:03:21 [debug] 32523#0: *6 http uri: "/testfile:"
到目前为止,我想出了两种可能的解决方案:
%3a
变成 :
在文件名中,并教育在这里上传文件的每个人。 %
签名为 %25
.但我相信重写阶段是在 URL 已经被解码之后。目前没有未转义的 :
文件名中的字符,所以我可以重写 :
至 %253a
这可能会奏效。尽管这些文件名中可能还有其他字符,但这是不可能的,因为它们可能以编码和未编码形式出现在 URL 中。 我认为可能有一个更简单的解决方案,我忽略了。有没有办法告诉 nginx 从字面上处理每个 URL,例如不解码转义字符?
最佳答案
如果您的 URL 中有百分号,只需将请求中的百分比与 %25 交换,如下所示:
https://domain/testfile%253a
这将成为文件
https://domain/testfile%3a
.问题不在于“Nginx 解码 URI”——您试图规避根据 RFC 标准工作的正常 URI 的工作方式,其中百分号始终用于对特殊字符进行编码。您可能会阅读 article about percent encoding并避免在 URI 中使用的所有特殊字符,因为使用这些都会导致问题(像 ?、&、# 等字符,还有 :)。对于文件名,完全避免使用它们是有意义的,例如将它们替换为另一个字符,如 _。
关于nginx - 阻止 nginx 解码 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50967622/