Apache 2.4:IF 规则的优先级?

Posted

技术标签:

【中文标题】Apache 2.4:IF 规则的优先级?【英文标题】:Apache 2.4: Precedence of IF Rules? 【发布时间】:2018-12-15 18:41:10 【问题描述】:

我在.htaccess 中有这组规则,按此顺序,由 Apache 2.4.33 处理:

RewriteEngine On

RewriteCond %HTTP_HOST    ^(subdomain\.olddomain)\.com$ [NC]
RewriteRule ^               https://www.example.com/directory/%1%REQUEST_URI [R=301,L]

## for some of the specific rules below
RewriteBase /

<If "%HTTP_HOST =~ /^(?:.*\.)?olddomain\.(?:com|net)$/i">

    ## some other specific rules which do not fire

    RewriteRule ^               https://%1example.com/directory%REQUEST_URI [R=301,L]

</If>

然而,具有一般规则集的 If 块似乎优先,尽管它遵循更具体的第一个重写到不同 URL 并以 L 终止的块。

(?:.*\.)? 更改为(?:www\.)? 会按预期工作。此外,如果将第一个规则集移动到 If 块中(无论如何代码效率更高,但事情已经发展)。

除其他外,我已阅读 this 发帖,我理解但不适用于此处的情况,因为第一条规则如果被触发,则应重写域/主机,因此不应匹配 If 条件没有了。

@covener 对this 发布的评论也提到了变量/模块的优先级,但是是否有更通用的文档? (我已经阅读了关于 TFM 中表达式的指令和引用的文章,注意到If 之前的身份验证的评论也是如此)。

TIA 提供任何建议或解释。

【问题讨论】:

抱歉,您的标签似乎不是真正的标签,我从未看过这篇文章。 【参考方案1】:

这看起来像是指令合并的另一种微妙行为,也是 mod_rewrite 稍微不标准的另一种行为。

基本上这里发生的是,当 &lt;If&gt; 匹配时,封闭的 RewriteRules 被视为一个新的“配置部分”,将与出现指令的模块的前一个合并。

但是,mod_rewrite 默认情况下会用新的配置部分替换以前的配置部分。它们没有合并在一起。在 RewriteOptions 下有控制它的指令。

指令配置是如何被评估、合并,然后在三个不同的阶段执行的,这真的很不直观。在 conf 文件中,它们看起来就像遇到时会单步执行的代码。

【讨论】:

根据您在另一个线程上引用的评论,我现在明白 .htaccess 是首先完全读入并匹配在(几乎)任何其他指令之前执行的 Ifblocks,对吧?与mod_rewrite 的非合并政策一起,这对于观察到的行为是有意义的。 如前所述,我们同时将所有子域/旧域重写规则移到了If 块中(也用于优化),但它仍然有助于理解未来情况下的偏好和指令流。谢谢。 (不小心在上一条评论中点击了Enter,并且在 5 分钟的限制内无法再对其进行编辑。)

以上是关于Apache 2.4:IF 规则的优先级?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot - ConfigDataEnvironmentPostProcessor(Boot 2.4)搞定配置文件加载优先级

5.10随笔

mod_alias 与 mod_rewrite 优先级

算法(第4版)-2.4 优先队列

Nginx核心模块——HTTP中的配置指令location和rewrite介绍

更改 HP Fortify C 规则优先级