Apache .htaccess REQUEST_FILENAME 不限于 257 个字符

Apache .htaccess REQUEST_FILENAME not limited to 257 chars

我 运行 我的 API 通过 Apache (2.4.46) 使用 .htaccess-rewriting 提供干净的 URLs.
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/sub/?item= [L]

RewriteRule ^api/name/v([0-99]*)/sub/([0-9a-zA-Z+.,-_]*)/([0-9a-zA-Z+.,-_]*)/?$ api/name/v/sub/?field=&item= [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 标准来保证安全。

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

URL 路径段的字符限制实际上是底层文件系统的限制,与 .htaccess.

中的指令没有任何关系

它与您请求的 URL 完全相关。当 Apache 将请求的 URL 映射到文件系统时(发生在 之前 .htaccess 被处理)然后生成错误。

The 1st rule will limit to 257 chars for items: api/name/v1/sub/item1,item2,item3,item4,...
The 2nd rule will not limit to 257 chars for items: 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,... 成为附加路径名信息(路径信息) - 它没有映射到文件系统,所以没有错误。

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


旁白:

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

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

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

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

api/name/v/sub/?item=

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

using .htaccess-rewriting to provide clean URLs

这里的另一个小问题是何必呢? (它们真的“更干净”吗?)无论如何,这些都是非常长的 URLs,只被 API(一台机器)消耗。重写这些 URLs 并没有真正起到任何作用 IMO。 (?)