Apache“if”指令中的正则表达式......这里有什么问题?

Mik*_*son 5 regex apache configuration if-statement

(现在怀疑 Apache 中可能存在错误......见下文。)

这是声明: (Apache 2.4)

<IfDefine !SERVER_TYPE>
    Define SERVER_TYPE prod
</IfDefine>
<If "${SERVER_TYPE} !~ /prod|demo|test/">   <===error here===
    Error "Define 'SERVER_TYPE' is hosed'"
</If>
Run Code Online (Sandbox Code Playgroud)

Apache 抱怨 IF:

Cannot parse condition clause: syntax error, unexpected T_OP_NRE, expecting '('
Run Code Online (Sandbox Code Playgroud)

我可以猜测 T_OP_NRE 指的是“否定正则表达式”,“!~”,但我终生无法弄清楚该语句中的语法错误是什么! (顺便说一句,“=~”产生[几乎]相同的消息。)

Apache 正在识别 ${SERVER_TYPE} 语法,因为我可以确认我是否拼错了标识符。<DEFINE> 的文档明确指出应该使用“${ident}”而不是“%{ident}”语法,就像我所做的那样。

我的语法有什么问题,为什么 Apache 需要左括号?


我开始谨慎地相信这实际上是Apache/2.4.12 中的一个BUG(!),因为解析错误仅在使用“${DEFINED_SYMBOL}”时发生。如果符号未定义,它会抱怨并做所有正确的事情(所以,它知道它在看什么......),但它给出了一个无意义的(对我来说......)消息,当且仅当,这个结构在左边。

一个明显的解决方法是将符号放在单引号中,例如:

<If "'${SERVER_TYPE}' != /prod/demo/test/">
Run Code Online (Sandbox Code Playgroud)

...但到目前为止,在我的测试中,我认为它没有正确匹配正则表达式。事实上,我还不确定发生了什么,因为以下被认为是匹配(“true”):

<If "'prod' !~ /prod|demo|test/">
Run Code Online (Sandbox Code Playgroud)

通过这个 Perl one-liner 可以显示正则表达式语法是正确的:

perl -e 'my $var = "prod"; if ($var =~ /prod|demo|test/) {print "yes\n";}'
Run Code Online (Sandbox Code Playgroud)

...打印“是的”。


PS在定义符号的情况下,“${IDENT}”语法正确的(而“%{}”则不是)。

anu*_*ava 2

试试这个语法:

<If "'${SERVER_TYPE}' !~ m#(prod|demo|test)#">
    #Error "Define 'SERVER_TYPE' is hosed"
    RedirectMatch /old /new/
</If>
Run Code Online (Sandbox Code Playgroud)