Apache 2.4,嵌套的If指令

Art*_*osz 3 apache

我尝试使用以下指令块Givet在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>
Run Code Online (Sandbox Code Playgroud)

结果,环境变量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>
Run Code Online (Sandbox Code Playgroud)

为什么在第一个示例中未验证内部块?指令文档中未提及任何有关可能嵌套或不可能嵌套的内容。

顺便说一句,我知道我可以在下面使用类似的逻辑,但是如果情况变得更复杂,嵌套就更简单,更方便。

<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>
Run Code Online (Sandbox Code Playgroud)

我明确要求嵌套版本在这里不起作用的原因。

Pet*_*erA 6

更新的答案:

从Apache 2.4.26开始<If>,允许使用嵌套指令。

Apache的2.4更新日志有以下变化指出:

评估嵌套的If / ElseIf / Else配置块。[卢卡·托斯卡诺(Luca Toscano),雅各布·冠军(Jacob Champion)]

问题中的嵌套<If>指令应在Apache 2.4.26及更高版本中有效。

虽然我无法确认问题中的特定规则,但这是htaccess规则与嵌套的工作示例 <If>指令:

RewriteEngine On

<If "%{REQUEST_URI} =~ /flintstones$/ ">
    <If "%{QUERY_STRING} == 'character=fred'">
        ErrorDocument 200 "Fred says, \"Yabba Dabba Doo\" <a href=\"flintstones\">back</a>"
    </If>
    <ElseIf "%{QUERY_STRING} == 'character=barney'">
        ErrorDocument 200 "Barney says, \"Uh hee hee hee... Okay Fred!\" <a href=\"flintstones\">back</a>"
    </ElseIf>
    <Else>
        ErrorDocument 200 "Pick a Flintstones character: <a href=\"flintstones?character=fred\">Fred</a> or <a href=\"flintstones?character=barney\">Barney</a>"
    </Else>
    RewriteRule ^ - [R=200,L]   
</If>
Run Code Online (Sandbox Code Playgroud)

原始答案

一个<If>指令不能嵌套在另一个<If>指令中。

If指令Apache 2.4文档具有以下注意事项:

不是脚本语言

该指令的名称是程序员和管理员非常熟悉的名称,但不要与脚本语言中的指令混淆。例如,当前的实现方式并未考虑<If>在另一部分(内部<If>将被忽略)。

没有给出为什么他们选择不允许嵌套的If指令的原因。

文档中提供的有关嵌套的唯一其他信息表明,每种节类型是否可以嵌套都不同:

节的嵌套

某些节类型可以嵌套在其他节类型中。一方面,<Files>可以在内部使用<Directory>。在另一方面,<If>可以使用内部<Directory><Location><Files>部分(但不是在另一个内部<If>)。命名部分的正则表达式对应的行为相同。