如何更改 mod_rewrite 来避免 {REQUEST_FILENAME},以绕过 255 个字符的 URL 限制?

如何更改 mod_rewrite 来避免 {REQUEST_FILENAME},以绕过 255 个字符的 URL 限制?

根据这个答案:mod_rewrite 的 url 最大长度为 257 个字符?根据文件系统,使用 mod_rewrite 的最大字符数有 255 个硬限制。

根据接受的答案,有两种解决方案:

  1. 将应用程序的 URL 格式更改为每个斜杠之间最多 255 个字符。
  2. 将重写规则移入 apache 虚拟主机配置并删除 REQUEST_FILENAME。

我无法使用第一种方法,因此我正在尝试找出第二种方法。

我已按要求将重写规则放入 Apache 虚拟主机配置中。但是我不知道如何删除 REQUEST_FILENAME 并让我的 Web 应用程序框架 (Dragonfly) 继续工作。

以下是我从 .htaccess 移到 Apache 虚拟主机配置文件中的重写规则部分:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f [OR]

# if don't want Dragonfly to process html files comment
# out the line below (you may need to remove the [OR] above too).
RewriteCond %{REQUEST_FILENAME} \.(html|nl)$

# Main URL rewriting.
RewriteRule (.*) index.cgi?$1 [L,QSA]

我尝试删除 {REQUEST_FILENAME},但它以各种方式破坏了框架。如何在不使用 {REQUEST_FILENAME} 的情况下重写它?

答案1

下面三行告诉 Apache 检查文件系统以查看该文件是否存在。

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f [OR]

第一个表示“如果 URI 不是目录”。第二个表示“如果 URI 不是链接”。第三个表示“如果 URI 不是文件”。

如果删除或注释掉这些行,Apache 将把下面的重写应用于每个不以“ .html”或“ .nl”结尾的文件,并且不会先检查文件系统以查看该文件是否存在。

上面三行代码是有目的的。它们之所以存在,是为了如果您将实际文件、目录或符号链接添加到文档根目录中,并且有人请求该文件、目录或符号链接,Apache 将照常处理它,而不会进行重写。如果您知道您永远不会将实际文件添加到文档根目录中,那么您可以安全地注释掉它们,而不会产生任何副作用。


一个可能更好的改变是在三行上面添加一条新规则,如下所示:

RewriteRule (.*[^/]{255}.*) index.cgi?$1 [L,QSA]

这将拦截任何在斜杠之间包含超过 255 个字符的单个字符串的 URI,并直接将它们发送到重写而不检查文件系统。[L] 选项确保如果匹配此规则,Apache 不会再检查任何规则。拦截映射到实际文件的 URI 不会有危险,因为与此正则表达式匹配的 URI 不是有效的文件路径。

更新:

与任何长度至少为 255 个字符的 URI 匹配的正则表达式。

RewriteRule (.{255}) index.cgi?$1 [L,QSA]

答案2

以下对我有用(在装有 apache 2.2.21 的 debian 上的默认虚拟主机中测试)。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} (.{255}) [OR]
RewriteCond %{REQUEST_FILENAME} \.(html|nl)$ [OR]
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-l [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) /index.cgi?$1 [L,QSA]

相关内容