< IfVersion >容器用于判断httpd的版本。例如:
<IfVersion >= 2.4> # this happens only in versions greater or equal 2.4.0. </IfVersion> 1.3.4 < If >、< ElseIf >和< Else >容器意义不言自明。< If >...< /If >判断表达式是否为真,如果为真,则封装在其内的指令生效;< ElseIf >...< /ElseIf >作用于< If >...< /If >之后,而< Else >...< /Else >则作用于最后。
表达式的写法和shell脚本的表达式差不多,例如数值比较"-eq"、"-gt",字符串比较"=="、">=",以及其他一些表达式"-z"、"-n"、"-f"等,此外,它还支持正则匹配表达式"~="、"!~"。具体相关函数、变量、表达式、语法等见 。
例如:
# 请求首部没有Host字段时,该段指令将生效。 <If "-z req('Host')"> ... </If> # 如果请求主机地址属于0/16,则if段生效,否则如果属于0/8,则elseif段生效,否则else生效 <If "-R '10.1.0.0/16'"> #... </If> <ElseIf "-R '10.0.0.0/8'"> #... </ElseIf> <Else> #... </Else> 1.4 配置文件的合并规则配置文件的段落以一种非常特殊的顺序生效。理解配置文件的合并规则非常重要,否则配置了半天可能发现根本不会生效。
以下是5个组类合并的顺序:
1.< Directory > (正则匹配的容器除外)
2.< DirectoryMatch > (以及< Directory "~" >)
3.< Files >和< FilesMatch >同时处理
4.< Location >和< LocationMatch >同时处理
5.< If >
此外,还需要注意的一些规则是:
除了< Directory >容器,每个组以它们出现的顺序进行合并。例如一个/foo请求可以匹配< Location "/foo/bar" >和< Location "/foo" >,它们都属于上面列出的第4组,所以对于这两个Location容器,谁配置在前面就匹配谁。
< Directory >容器即上面的第一组处理的顺序是先处理路径"短"的,再处理路径长的。这里的短指的是离根文件系统的"/"越近就越短。由于这个组不包含正则匹配的表达式(即< Directory ~ >),所以这里的"短"就代表它的路径表达式短。例如< Directory "/var/web/dir" >将优先于< Directory "/var/web/dir/subdir" >被处理。
如果出现多个< Directory >的路径完全一样的极端情况,那么将按照出现顺序处理。
使用Include指令包含的文件将被插入到该指令的位置,然后按规则进行处理。
< VirtualHost >段落的配置将在外部对应的段处理完毕以后再处理,这样就允许虚拟主机覆盖主服务器的设置。
当请求是由mod_proxy处理的时候,< Proxy >容器将会在处理顺序中取代< Directory >容器的位置。
需要注意的是,配置文件中的指令都是由各个模块提供的,所以各指令是由各对于模块来解析、处理、合并的,配置文件的作用只不过是将各个模块的指令整合在一起方便定义。另外,上面定义的5个组别都是由httpd的核心模块提供的,因此它们才有处理顺序的要求。
当在运行时进行请求匹配,将先按照上面合并规则提供的顺序进行匹配,如果某个组中出现了能成功匹配请求的模块,将提升一次合并的层次,使得这次模块的匹配变为第三次匹配。例如下面的配置使用了由mod_headers提供的Header指令用于设置HTTP的首部,如果请求/example/index.html,那么最终设置的CustomHeaderName首部的值是什么呢?
<Directory "/"> Header set CustomHeaderName one <FilesMatch ".*"> Header set CustomHeaderName three </FilesMatch> </Directory> <Directory "/example"> Header set CustomHeaderName two </Directory>首先按照前面提供的合并顺序匹配到"/",这会初始化设置CustomHeaderName的值为one,再匹配到/example,CustomHeaderName被设置为two。最后分组中提供的指令FilesMatch匹配成功,提升一次合并的层次,这是第三次匹配,导致CustomHeaderName最终设置为three。