<-
Apache > HTTP 服务器 > 文档 > 2.4 版

Apache HTTP 服务器中的表达式

可用语言:  en  |  fr 

从历史上看,Apache HTTP 服务器的不同模块中用于表达条件的表达式有几种语法变体。目前正在努力只使用一种名为ap_expr的变体来处理所有配置指令。本文档介绍了ap_expr表达式解析器。

ap_expr表达式旨在替换 HTTPD 中大多数其他表达式变体。例如,已弃用的 SSLRequire 表达式可以用 Require expr 替换。

Support Apache!

另请参见

top

巴科斯-诺尔范式语法

巴科斯-诺尔范式 (BNF) 是一种用于上下文无关语法的符号表示法,通常用于描述计算机中使用的语言的语法。在大多数情况下,表达式用于表达布尔值。对于这些,BNF 中的起点是 expr。但是,一些指令(如 LogMessage)接受计算结果为字符串值的表达式。对于这些,BNF 中的起点是 string

expr        ::= "true" | "false"
              | "!" expr
              | expr "&&" expr
              | expr "||" expr
              | "(" expr ")"
              | comp

comp        ::= stringcomp
              | integercomp
              | unaryop word
              | word binaryop word
              | word "in" "{" wordlist "}"
              | word "in" listfunction
              | word "=~" regex
              | word "!~" regex


stringcomp  ::= word "==" word
              | word "!=" word
              | word "<"  word
              | word "<=" word
              | word ">"  word
              | word ">=" word

integercomp ::= word "-eq" word | word "eq" word
              | word "-ne" word | word "ne" word
              | word "-lt" word | word "lt" word
              | word "-le" word | word "le" word
              | word "-gt" word | word "gt" word
              | word "-ge" word | word "ge" word

wordlist    ::= word
              | wordlist "," word

word        ::= word "." word
              | digit
              | "'" string "'"
              | """ string """
              | variable
              | rebackref
              | function

string      ::= stringpart
              | string stringpart

stringpart  ::= cstring
              | variable
              | rebackref

cstring     ::= ...
digit       ::= [0-9]+

variable    ::= "%{" varname "}"
              | "%{" funcname ":" funcargs "}"

rebackref   ::= "$" [0-9]

function     ::= funcname "(" word ")"

listfunction ::= listfuncname "(" word ")"
top

变量

表达式解析器提供许多形式为 %{HTTP_HOST} 的变量。请注意,变量的值可能取决于评估它的请求处理阶段。例如,在 <If > 指令中使用的表达式是在身份验证完成之前评估的。因此,在这种情况下,%{REMOTE_USER} 将不会被设置。

以下变量提供命名 HTTP 请求标头的值。可以使用 req 函数 获取其他标头的值。使用这些变量可能会导致标头名称被添加到 HTTP 响应的 Vary 标头中,除非接受表达式的指令另有说明。可以使用 req_novary 函数 来规避此行为。

名称
HTTP_ACCEPT
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_REFERER
HTTP_USER_AGENT

其他与请求相关的变量

名称描述
REQUEST_METHOD 传入请求的 HTTP 方法(例如 GET
REQUEST_SCHEME 请求 URI 的方案部分
REQUEST_URI 请求 URI 的路径部分
DOCUMENT_URI REQUEST_URI 相同
REQUEST_FILENAME 与请求匹配的文件或脚本的完整本地文件系统路径,如果服务器在引用 REQUEST_FILENAME 时已经确定了该路径。否则,例如在虚拟主机上下文中,与 REQUEST_URI 相同的值
SCRIPT_FILENAME REQUEST_FILENAME 相同
LAST_MODIFIED 文件的最后修改日期和时间,格式为 20101231235959,如果服务器在引用 LAST_MODIFIED 时已经确定了该时间。
SCRIPT_USER 脚本所有者的用户名。
SCRIPT_GROUP 脚本所属组的组名。
PATH_INFO 尾随路径名信息,请参见 AcceptPathInfo
QUERY_STRING 当前请求的查询字符串
IS_SUBREQ "true" 如果当前请求是子请求,否则为 "false"
THE_REQUEST 完整的请求行(例如,"GET /index.html HTTP/1.1")
REMOTE_ADDR 远程主机的 IP 地址
REMOTE_PORT 远程主机的端口(2.4.26 及更高版本)
REMOTE_HOST 远程主机的主机名
REMOTE_USER 已认证用户的名称(如果有)(在 <If> 中不可用)
REMOTE_IDENT mod_ident 设置的用户名
SERVER_NAME 当前虚拟主机的 ServerName
SERVER_PORT 当前虚拟主机的服务器端口,请参见 ServerName
SERVER_ADMIN 当前虚拟主机的 ServerAdmin
SERVER_PROTOCOL 请求使用的协议
DOCUMENT_ROOT 当前虚拟主机的 DocumentRoot
AUTH_TYPE 配置的 AuthType(例如 "basic")
CONTENT_TYPE 响应的内容类型(在 <If> 中不可用)
HANDLER 创建响应的 处理程序 的名称
HTTP2 "on" 如果请求使用 http/2,否则为 "off"
HTTPS "on" 如果请求使用 https,否则为 "off"
IPV6 "on" 如果连接使用 IPv6,否则为 "off"
REQUEST_STATUS 请求的 HTTP 错误状态(在 <If> 中不可用)
REQUEST_LOG_ID 请求的错误日志 ID(请参见 ErrorLogFormat
CONN_LOG_ID 连接的错误日志 ID(请参见 ErrorLogFormat
CONN_REMOTE_ADDR 连接的对等 IP 地址(请参见 mod_remoteip 模块)
CONTEXT_PREFIX
CONTEXT_DOCUMENT_ROOT

其他变量

名称描述
TIME_YEAR 当前年份(例如 2010
TIME_MON 当前月份(01,...,12
TIME_DAY 当前月份的日期(01,...)
TIME_HOUR 当前时间的时钟部分(00,...,23
TIME_MIN 当前时间的分钟部分
TIME_SEC 当前时间的秒钟部分
TIME_WDAY 星期几(从星期日开始,0 表示星期日)
TIME 日期和时间,格式为 20101231235959
SERVER_SOFTWARE 服务器版本字符串
API_VERSION API 版本的日期(模块魔数)

一些模块注册了额外的变量,例如 mod_ssl

top

二元运算符

除了某些内置比较运算符外,二元运算符的形式为 "-[a-zA-Z][a-zA-Z0-9_]+",即一个减号和至少两个字符。名称不区分大小写。模块可以注册额外的二元运算符。

比较运算符

名称备选 描述
== = 字符串相等
!= 字符串不相等
< 字符串小于
<= 字符串小于或等于
> 字符串大于
>= 字符串大于或等于
=~ 字符串与正则表达式匹配
!~ 字符串与正则表达式不匹配
-eq eq 整数相等
-ne ne 整数不相等
-lt lt 整数小于
-le le 整数小于或等于
-gt gt 整数大于
-ge ge 整数大于或等于

其他二元运算符

名称描述
-ipmatch IP 地址与地址/网络掩码匹配
-strmatch 左侧字符串与右侧字符串(包含通配符 *、?、[])给出的模式匹配
-strcmatch -strmatch 相同,但不区分大小写
-fnmatch -strmatch 相同,但斜杠不与通配符匹配
top

一元运算符

一元运算符接受一个参数,形式为 "-[a-zA-Z]",即一个减号和一个字符。名称区分大小写。模块可以注册额外的 一元运算符。

名称描述受限
-d 参数被视为文件名。如果文件存在且是目录,则为真yes
-e 参数被视为文件名。如果文件(或目录或特殊文件)存在,则为真yes
-f 参数被视为文件名。如果文件存在且是普通文件,则为真yes
-s 参数被视为文件名。如果文件存在且不为空,则为真yes
-L 参数被视为文件名。如果文件存在且是符号链接,则为真yes
-h 参数被视为文件名。如果文件存在且是符号链接,则为真(与 -L 相同)yes
-F 如果字符串是有效文件,并且可以通过服务器当前为该路径配置的所有访问控制进行访问,则为真。这使用内部子请求来执行检查,因此请谨慎使用 - 它会影响服务器的性能!
-U 如果字符串是有效 URL,并且可以通过服务器当前为该路径配置的所有访问控制进行访问,则为真。这使用内部子请求来执行检查,因此请谨慎使用 - 它会影响服务器的性能!
-A -U 的别名
-n 如果字符串不为空,则为真
-z 如果字符串为空,则为真
-T 如果字符串为空、"0"、"off"、"false" 或 "no"(不区分大小写),则为假。否则为真。
-R 与 "%{REMOTE_ADDR} -ipmatch ..." 相同,但效率更高

标记为“受限”的操作符在某些模块中不可用,例如 mod_include

top

函数

普通字符串值函数接受一个字符串作为参数并返回一个字符串。函数名不区分大小写。模块可以注册额外的函数。

名称描述特殊说明
req, http 获取 HTTP 请求头;头名称可能会添加到 Vary 头中,请参见下文
req_novary req 相同,但头名称不会添加到 Vary 头中
resp 获取 HTTP 响应头(大多数响应头在 <If> 期间尚未设置)
reqenv 查找请求环境变量(作为快捷方式,v 也可以用于访问变量)。 ordering
osenv 查找操作系统环境变量
note 查找请求备注ordering
env 返回 notereqenvosenv 的第一个匹配项ordering
tolower 将字符串转换为小写
toupper 将字符串转换为大写
escape 使用 %hex 编码转义特殊字符
unescape 取消转义 %hex 编码的字符串,保留编码的斜杠;如果找到 %00,则返回空字符串
base64 使用 base64 编码对字符串进行编码
unbase64 解码 base64 编码的字符串,如果找到 0x00,则返回截断的字符串
md5 使用 MD5 对字符串进行哈希运算,然后使用十六进制编码对哈希进行编码
sha1 使用 SHA1 对字符串进行哈希运算,然后使用十六进制编码对哈希进行编码
file 从文件读取内容(包括换行符,如果存在)restricted
filesize 返回文件的大小(如果文件不存在或不是普通文件,则返回 0)restricted
ldap 根据 LDAP 区分名称转义(RFC4514)和 LDAP 过滤器转义(RFC4515)的要求转义字符。
(在 httpd 2.4.53 及更高版本中可用)

在最后一列中标记为“受限”的函数在某些模块中不可用,例如 mod_include

在最后一列中标记为“ordering”的函数需要考虑服务器不同组件的排序,尤其是在函数在 <If> 指令中使用时,该指令在相对较早的时间进行评估。

环境变量排序

当在 <If> 条件中查找环境变量时,重要的是要考虑此解析发生在请求处理的极早期。作为指导原则,在虚拟主机上下文(目录、位置、htaccess)之外定义的任何指令都不太可能有机会执行。虚拟主机范围内的 SetEnvIf 是在解析之前运行的一个指令

reqenv 在 <If> 之外使用时,解析通常会在稍后发生,但确切时间取决于使用表达式的指令。

当使用 reqhttp 函数时,头名称将自动添加到 HTTP 响应的 Vary 头中,除非接受表达式的指令另有说明。req_novary 函数可用于防止名称添加到 Vary 头中。

除了字符串值函数之外,还有列表值函数,它们接受一个字符串作为参数并返回一个词列表,即字符串列表。词列表可以与特殊的 -in 运算符一起使用。函数名不区分大小写。模块可以注册额外的函数。

没有内置的列表值函数。 mod_ssl 提供 PeerExtList。有关详细信息,请参见 SSLRequire 的描述(但 PeerExtList 也可以在 SSLRequire 之外使用)。

top

示例表达式

以下示例展示了如何使用表达式来评估请求

# Compare the host name to example.com and redirect to www.example.com if it matches
<If "%{HTTP_HOST} == 'example.com'">
    Redirect permanent "/" "http://www.example.com/"
</If>

# Force text/plain if requesting a file with the query string contains 'forcetext'
<If "%{QUERY_STRING} =~ /forcetext/">
    ForceType text/plain
</If>

# Only allow access to this content during business hours
<Directory "/foo/bar/business">
    Require expr %{TIME_HOUR} -gt 9 && %{TIME_HOUR} -lt 17
</Directory>

# Check a HTTP header for a list of values
<If "%{HTTP:X-example-header} in { 'foo', 'bar', 'baz' }">
    Header set matched true
</If>

# Check an environment variable for a regular expression, negated.
<If "! reqenv('REDIRECT_FOO') =~ /bar/">
    Header set matched true
</If>

# Check result of URI mapping by running in Directory context with -f
<Directory "/var/www">
    AddEncoding x-gzip gz
<If "-f '%{REQUEST_FILENAME}.unzipme' && ! %{HTTP:Accept-Encoding} =~ /gzip/">
      SetOutputFilter INFLATE
</If>
</Directory>

# Check against the client IP
<If "-R '192.168.1.0/24'">
    Header set matched true
</If>

# Function example in boolean context
<If "md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8'">
  Header set checksum-matched true
</If>

# Function example in string context
Header set foo-checksum "expr=%{md5:foo}"

# This delays the evaluation of the condition clause compared to <If>
Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path\.php$#"

# Conditional logging
CustomLog logs/access-errors.log common "expr=%{REQUEST_STATUS} >= 400"
CustomLog logs/access-errors-specific.log common "expr=%{REQUEST_STATUS} -in {'405','410'}"
top

其他

名称备选 描述
-in in 包含在词列表中的字符串
/regexp/ m#regexp# 正则表达式(第二种形式允许使用与 / 不同的分隔符)
/regexp/i m#regexp#i 不区分大小写的正则表达式
$0 ... $9 正则表达式反向引用

正则表达式反向引用

字符串 $0 ... $9 允许引用先前执行的成功匹配的正则表达式的捕获组。它们通常只能在与匹配的正则表达式相同的表达式中使用,但某些模块允许特殊用途。

top

与 SSLRequire 的比较

ap_expr 语法主要是已弃用的 SSLRequire 指令语法的超集。差异在 SSLRequire 的文档中描述。

top

版本历史记录

req_novary 函数 在 2.4.4 及更高版本中可用。

可用语言:  en  |  fr 

top

注释

注意
这不是问答部分。此处放置的评论应指向有关改进文档或服务器的建议,如果它们被实施或被认为无效/不相关,可能会被我们的版主删除。有关如何管理 Apache HTTP Server 的问题应发送到我们的 IRC 频道 #httpd(在 Libera.chat 上)或发送到我们的 邮件列表