![Apache 如何处理其中包含百分比编码 URL 的路径?](https://linux22.com/image/546802/Apache%20%E5%A6%82%E4%BD%95%E5%A4%84%E7%90%86%E5%85%B6%E4%B8%AD%E5%8C%85%E5%90%AB%E7%99%BE%E5%88%86%E6%AF%94%E7%BC%96%E7%A0%81%20URL%20%E7%9A%84%E8%B7%AF%E5%BE%84%EF%BC%9F.png)
我遇到了一个意外的情况,当百分比编码的路径部分之一本身就是一个 HTTP URL 时,Apache 给出了 404 错误,而不是让 mod_rewrite 处理路径。
例如:
GET /myfolder/http%3A%2F%2Flocalhost%2Fnotify HTTP/1.0
我在/myfolder/.htaccess
文件中有一个非常简单的规则,它发送一切那不是脚本中的文件/myfolder/
。它与其他百分比编码值配合得很好,但在这种情况下,Apache 从不处理文件RewriteRule
中的.htaccess
。我可以对该值进行双重编码作为一种解决方法,但似乎 Apache 仍应处理 mod_rewrite 阶段。我打算将 URL 仅作为脚本的输入参数。
以下是 (不) 相关的 mod_rewrite 指令/myfolder/.htaccess
:
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule .* ./script-the-world.php
重写规则未被处理。在服务器配置中,我得到了RewriteLogLevel 5
等,并tail -f /var/log/http/rewrite.log
显示我所有要/myfolder/
重写的请求...除了上面提到的请求。我的意思是说,在上述特殊情况下发生了一些内部问题,但我不知道是什么问题。我希望有人可能知道另一个模块正在干扰我试图完成的任务。
这是 Apache 2.2.16。
答案1
您需要启用AllowEncodedSlashes
,这将导致 Apache 允许带有 和 的 URL %2F
,%5C
而不是抛出 404。当然,您仍然必须确保您的 PHP 脚本正确处理 URL 的解码,因为这不是 Apache 的职责。
答案2
由于这个问题已有 9 年历史,但仍然是一个当前问题,我想我应该给出一个更完整的答案来解决它。
为了在您的路径中启用%F2
而不%5C
出现 404 错误,您需要在 apache2 配置中添加以下行:
AllowEncodedSlashes NoDecode
来自Apache2.4文档:
该指令允许在路径信息中使用
AllowEncodedSlashes
包含编码路径分隔符(在相应的系统上为%2F
/ 以及\)的 URL。%5C
使用默认值,
Off
此类 URL 将被拒绝,并出现 404(未找到)错误。使用值
On
,这样的 URL 会被接受,并且编码的斜线会像所有其他编码字符一样进行解码。使用值
NoDecode
,这样的 URL 会被接受,但是编码的斜线不会被解码而是保持其编码状态。
正如NoDecode
2.4 中引入的,如果您仍在使用 Apache2.2,则可以将值设置为On
。请注意,它们的功能并不相同。正如文档所述,NoDecode
不会解码字符串并保持原样,而On
会。
没有人解释(至少对我而言)的是在哪里我应该应用这个值。有一些对该httpd.conf
文件的引用,但如果您在 Debian 上运行 Apache2,那么找到该文件就很困难了。在 Ubuntu 上,该文件名为apache2.conf
。如果您将这行添加到该apache2.conf
文件中,您可能看不到太大的变化。
原因是,正如你可能知道的,你的配置文件将包含每个部分虚拟主机。并且每个<VirtualHost>
部分内的配置都在虚拟主机定义之外的相应部分之后应用。
这允许虚拟主机覆盖主服务器配置。这通常是好的。但在这种情况下,它将在技术上覆盖指令AllowEncodedSlashes
(并将其设置回默认值Off
),除非您在每个<VirtualHost>
部分中明确说明该值应该是什么。
总之,如果您想解决这个问题,请执行以下操作(至少在 Ubuntu 上):
- 去
/etc/apache2/sites-enabled
- 打开您找到的每个文件。
- 添加
AllowEncodedSlashes NoDecode
里面每个<VirtualHost>
与您相关的部分。 - 保存文件。
- 重新启动 apache2
sudo systemctl restart apache2
:。