【问题标题】:Apache .htaccess REQUEST_FILENAME not limited to 257 charsApache .htaccess REQUEST_FILENAME 不限于 257 个字符
【发布时间】:2021-06-06 04:27:59
【问题描述】:

我使用 .htaccess-rewriting 通过 Apache (2.4.46) 运行我的 API,以提供干净的 URL。
Apache 在 URL 中的文件名限制为 257 个字符。

.htacces 看起来像这样:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^api/name/v([0-99]*)/sub/([0-9a-zA-Z+.,-_]*)/?$ api/name/v$1/sub/?item=$2 [L]

RewriteRule ^api/name/v([0-99]*)/sub/([0-9a-zA-Z+.,-_]*)/([0-9a-zA-Z+.,-_]*)/?$ api/name/v$1/sub/?field=$2&item=$3 [L]

第一条规则将限制为 257 个字符的项目:api/name/v1/sub/item1,item2,item3,item4,...
第二条规则不会限制为 257 个字符的项目:api/name/v1/sub/some_field/item1,item2,item3,item4,...

我可能使用 2nd-not-recognized-257-char-option 在 URL 中放置更多项目,但我想依靠 Apache 标准来保证安全。

谁能弄清楚为什么第一个重写规则符合限制而第二个不符合?

【问题讨论】:

  • 欢迎来到 SO,感谢您在问题中分享您的努力。您能否提及哪些规则有效以及哪些规则无效的示例或 URL?这将使我们更好地理解问题,谢谢。
  • @RavinderSingh13 如上面所写,URL 是 https://example.org/api/name/v1/sub/item1,item2,item3,item4,...,例如,限制为 257 个字符。和https://example.org/api/name/v1/sub/some_field/item1,item2,item3,item4,... 例如,项目字符串没有 257 个字符的限制
  • “正如这里所写的 Apache 有一个限制” - 链接的问题没有像您暗示的那样提及限制?

标签: apache .htaccess url-rewriting filenames rules


【解决方案1】:

URL 路径段的这个字符限制实际上是对底层文件系统的限制,与.htaccess 中的指令没有任何关系。

它与您请求的网址有关。当 Apache 将请求的 URL 映射到文件系统时(发生在 .htaccess 被处理之前),就会产生错误。

第一条规则将限制为 257 个字符的项目:api/name/v1/sub/item1,item2,item3,item4,...
第二条规则不会限制为 257 个字符的项目:api/name/v1/sub/some_field/item1,item2,item3,item4,...

如上所述,限制在 URL 上 - 因为它映射到文件系统,而不是 规则

第一个 URL 触发此错误的原因是因为 /api/name/v1/sub 是文件系统上的物理目录,而 item1,item2,item3,item4,... 映射到文件系统路径 - 失败。

但是,第二个 URL 不会触发此错误,因为 some_field 被映射到文件系统,并且假设这不是另一个子目录,则 item1,item2,item3,item4,... 成为附加路径名信息 (path-info) - 它没有映射到文件系统,所以没有错误。

要解决此文件系统限制,您可以将指令移动到服务器配置(或 VirtualHost)上下文 - 在请求映射到文件系统之前 处理这些指令。


旁白:

^api/name/v([0-99]*)/sub/([0-9a-zA-Z+.,-_]*)/?$

您的正则表达式中有几个“错误”:

  • [0-99]* - 第二个9 是多余的,与[0-9]* 相同。但是您真的要允许 empty 版本字符串吗?这应该是\d+

  • [0-9a-zA-Z+.,-_] - 字符类中倒数第二个字符中未转义的连字符创建了一个 范围,因此匹配的字符可能比您预期的要多,包括 /:; 等。要仅匹配文字连字符,您需要反斜杠转义它(\-)或将其包含在字符类的开头或结尾,即。 [0-9a-zA-Z+.,_-],与[\w+.,-]相同。

api/name/v$1/sub/?item=$2

您实际上并没有直接重写到有效的端点。目标 URL 仍需要额外的处理 - 仅此指令尚不清楚。看起来您可能依赖于DirectoryIndex(例如index.phpindex.html 等),所以实际目标更像api/name/v$1/sub/index.php?item=$2 - 这是应该在RewriteRule 中使用的em>替换字符串。

使用 .htaccess-rewriting 提供干净的 URL

这里的另一个琐碎想法是为什么要打扰? (它们真的“更干净”吗?)无论如何,这些都是非常长的 URL,仅由 API(机器)使用。重写这些 URL 并没有真正用于 IMO 的任何目的。 (?)

【讨论】:

  • 感谢@MrWhite 的详细解答!我已经看到了将规则放入 Vhost 配置的选项。但这不适合我的项目 - 因为我希望在为 PHP 本身提供动力的 docker 容器之外拥有 API 代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
  • 2019-04-16
相关资源
最近更新 更多