我尝试在Apache配置文件中设置一些环境变量,并使用下面的指令块来设置头文件“X-Forwarded-Proto”。
<If "-n req('X-Forwarded-Proto')">
SetEnv NON_EMPTY_PROTO on
<If "req('X-Forwarded-Proto') =~ /https/">
SetEnv HTTPS on
</If>
<Else>
SetEnv HTTPS off
</Else>
</If>
结果,环境变量NON_EMPTY_PROTO按预期设置,但变量HTTPS没有。但如果我避免嵌套只是为了测试,两个变量都按预期设置。
<If "-n req('X-Forwarded-Proto')">
SetEnv NON_EMPTY_PROTO on
</If>
<If "req('X-Forwarded-Proto') =~ /https/">
SetEnv HTTPS on
</If>
<Else>
SetEnv HTTPS off
</Else>
为什么在第一个例子中没有验证内部块?指令文档没有提到任何关于可能或不可能嵌套的内容。
顺便说一下,我知道我可以使用下面这样的逻辑等价物,但是如果场景变得更复杂,嵌套会更简单、更方便。
<If "-n req('X-Forwarded-Proto') && req('X-Forwarded-Proto') =~ /https/">
SetEnv HTTPS on
</If>
<ElseIf "-n req('X-Forwarded-Proto')">
SetEnv HTTPS off
</ElseIf>
我明确地询问嵌套版本在这里不起作用的原因。
1条答案
按热度按时间siotufzp1#
更新的答案:
自Apache 2.4.26起,允许嵌套
<If>
指令。Apache 2.4 ChangeLog具有以下变更:
计算嵌套的If/ElseIf/Else配置块。[Luca Toscano,Jacob Champion]
问题中嵌套的
<If>
指令应该可以在Apache 2.4.26及更高版本中使用。虽然我无法确认问题中的具体规则,但下面是一个带有嵌套
<If>
指令的htaccess规则的工作示例:原始答案
<If>
指令不能嵌套在另一个<If>
指令内。If指令的Apache 2.4文档中有以下注意事项:
不是脚本语言
程序员和管理员都很熟悉这个指令的名字,但不要把它和脚本语言中的对应指令混淆。例如,当前的实现没有考虑到
<If>
部分在另一个部分中的可能性(内部的<If>
将被忽略)。没有给出为什么他们选择不允许嵌套If指令的原因。
文档中唯一的other information about nesting provided指示每种节类型在是否可以嵌套方面有所不同:
节的嵌套
某些节类型可以嵌套在其他节类型中。一方面,
<Files>
可以在<Directory>
中使用。另一方面,<If>
可以在<Directory>
、<Location>
和<Files>
节中使用(但不能在另一个<If>
中使用)。命名节的正则表达式副本的行为相同。