apache 2.4,嵌套If指令

时间:2017-02-09 12:59:04

标签: apache

我尝试在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 个答案:

答案 0 :(得分: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>内部使用)。命名部分的正则表达式对应部分表现相同。