当两个条件成立时我想否定。
我在apache2.conf
中设置了一个变量:
SetEnv MY_SITE stage
然后在.htaccess
中检查header和env变量是否匹配。
# check the variable is set by outputting to header.
RewriteCond %{ENV:MY_SITE} (.+)
RewriteRule ^ - [E=MY_SITE:%1]
Header always set X-Site %{MY_SITE}e
然后拒绝访问,如果头是错误的,这是分段:
# check the azure header and that this is staging
RewriteCond %{HTTP:X-Azure-FDID} !^xxxxxx$ [NC]
RewriteCond %{ENV:MY_SITE} =stage
RewriteRule ^ - [F]
然而,第二条件不导致禁止消息。
如果我尝试这样做,它会工作并拒绝访问:
RewriteCond %{HTTP:X-Azure-FDID} !^xxxxxx$ [NC]
# RewriteCond %{ENV:MY_SITE} =stage
RewriteRule ^ - [F]
但这并不:
RewriteCond %{ENV:MY_SITE} =stage
RewriteRule ^ - [F]
为什么第二个条件不起作用?
1条答案
按热度按时间ldioqlga1#
SetEnv
(mod_env)处理得太晚,mod_rewrite无法提取它(mod_rewrite处理得早)。您需要使用SetEnvIf
(mod_setenvif)来设置env var,它处理得早得多。如
SetEnv
的文档所述:此指令设置的内部环境变量是在大多数早期请求处理指令运行后设置的,例如访问控制和URI到文件名的Map。如果您要设置的环境变量是作为此早期处理阶段的输入(例如RewriteRule指令),则应该使用SetEnvIf设置环境变量。
SetEnvIf
有一个不同的语法。要无条件地设置它,你需要做如下操作:第一个参数(
^
)是一个正则表达式,它匹配任何请求头。^
总是成功的。第二个参数(另一个
^
)是一个匹配前一个参数值的正则表达式。同样,这总是成功的。在
.htaccess
上下文中使用env vars和mod_rewrite时,需要小心重写引擎的任何循环。(例如,稍后在.htaccess
文件中的标准前端控制器模式可能会触发此操作)。如果重写引擎在第二次通过时使用REDIRECT_
前缀重命名第一次通过时设置的任何env变量(例如REDIRECT_MY_SITE
)。第三遍,REDIRECT_REDIRECT_MY_SITE
等。因此,您可能需要检查REDIRECT_<var>
,或者防止重写引擎进行额外的传递。(server 或 virtualhost 上下文中的mod_rewrite指令默认情况下没有这种额外的复杂性。)鉴于上述情况,这并没有测试你认为它做了什么。在这种情况下,mod_rewrite规则什么也没有做(因为在处理这个规则时没有设置
MY_SITE
)。当Header
被处理时(处理得很晚),SetEnv
已经设置了env var。使用
Define
替代我已经在我的
apache2.conf
中设置了变量然而,既然你可以访问服务器配置,那么考虑使用一个“defined”变量(使用
Define
指令)而不是一个环境变量。变量不能在.htaccess
中 defined(因为它们是在编译时设置的),但它们可以在.htaccess
中测试,并且不会像env vars那样被“重命名”(如上所述)。在
apache2.conf
中:在
.htaccess
中:这显然不会检查
MY_SITE
的值,因此假设它只会在staging服务器上设置(实际上是一个布尔值)。因此,最好将变量名改为类似STAGING_SITE
的名称。如果
MY_SITE
可以包含多个值,那么您可以使用${<varname>}
语法检查该值。例如: