apache 2.4,嵌套if指令

问题描述 投票:0回答:1

我尝试在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>

我明确地问为嵌套版本在这里不起作用的原因。

apache
1个回答
3
投票

更新答案:

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

Apache 2.4 ChangeLog有以下变化:

评估嵌套的If / ElseIf / Else配置块。 [卢卡托斯卡诺,雅各布冠军]

问题中嵌套的<If>指令应该适用于Apache 2.4.26和转发。

虽然我无法确认问题中的具体规则,但这是一个使用嵌套<If>指令的htaccess规则的工作示例:

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>

原始答案

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

Apache 2.4 Documentation for the If Directive有以下通知:

不是脚本语言

程序员和管理员非常熟悉该指令的名称,但不应将其与脚本语言中的对应程序混淆。例如,当前的实现没有考虑在另一个内部具有<If>部分的可能性(内部<If>将被忽略)。

没有理由为什么他们选择不允许嵌套的If指令。

文档中唯一的other information about nesting provided表示每个节类型是否可以嵌套:

部分嵌套

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

© www.soinside.com 2019 - 2024. All rights reserved.