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.php
或 index.html
等),因此实际目标更像是 api/name/v/sub/index.php?item=
- 应该是这个在 RewriteRule
substitution 字符串中使用。
using .htaccess-rewriting to provide clean URLs
这里的另一个小问题是何必呢? (它们真的“更干净”吗?)无论如何,这些都是非常长的 URLs,只被 API(一台机器)消耗。重写这些 URLs 并没有真正起到任何作用 IMO。 (?)
我 运行 我的 API 通过 Apache (2.4.46) 使用 .htaccess-rewriting 提供干净的 URLs.
Apache 在 URL.
.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.php
或 index.html
等),因此实际目标更像是 api/name/v/sub/index.php?item=
- 应该是这个在 RewriteRule
substitution 字符串中使用。
using .htaccess-rewriting to provide clean URLs
这里的另一个小问题是何必呢? (它们真的“更干净”吗?)无论如何,这些都是非常长的 URLs,只被 API(一台机器)消耗。重写这些 URLs 并没有真正起到任何作用 IMO。 (?)