<-
Apache HTTP 服务器 2.4 > 表达式解析器

Apache HTTP Server中的表达式

历史上,Apache HTTP Server的不同模块中用于表达条件的表达式有多种语法变体。目前正在进行一些努力,仅对所有配置指令使用单个变体ap_expr。本文档介绍ap_expr表达式解析器。

ap_expr表达旨在取代HTTPD大多数其他表达变种。例如,不赞成使用的SSLRequire表达式可以替换为Require expr

支持Apache!

也可以看看

最佳

Backus-Naur形式表示法的语法

Backus-Naur形式(BNF)是无上下文语法的一种注释技术,通常用于描述计算中使用的语言的语法。在大多数情况下,表达式用于表示布尔值。对于这些,BNF的起点是expr。但是,一些指令(例如LogMessageaccept表达式)的结果为字符串值。对于这些,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 ")"
最佳

变数

表达式解析器提供了多种形式的变量 %{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

最佳

二元运算符

除某些内置比较运算符外,二进制运算符的格式为“ -[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,但斜杠与通配符不匹配
最佳

一元运算符

一元运算符采用一个参数,格式为“ -[a-zA-Z]”,即减号和一个字符。该名称区分大小写。模块可以注册其他一元运算符。

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

标记为“受限”的运算符在诸如的某些模块中不可用mod_include

最佳

功能

普通的字符串值函数将一个字符串作为参数并返回一个字符串。函数名称不区分大小写。模块可以注册其他功能。

名称描述特别说明
reqhttp 获取HTTP请求头;标头名称可以添加到Vary标头中,请参见下文
req_novary 与相同req,但标头名称不会添加到Vary标头中
resp 获取HTTP响应标头(在期间尚未设置大多数响应标头<If>
reqenv 查找请求环境变量(作为快捷方式, v也可以用于访问变量)。 订购
osenv 查找操作系统环境变量
note 查找请求说明订购
env 返回首场比赛notereqenvosenv订购
tolower 将字符串转换为小写
toupper 将字符串转换为大写
escape 以%hex编码转义特殊字符
unescape 不转义%hex编码的字符串,仅保留编码的斜杠;如果找到%00,则返回空字符串
base64 使用base64编码对字符串进行编码
unbase64 解码base64编码的字符串,如果找到0x00,则返回截断的字符串
md5 使用MD5哈希字符串,然后使用十六进制编码对哈希进行编码
sha1 使用SHA1哈希字符串,然后使用十六进制编码对哈希进行编码
file 从文件中读取内容(包括行尾,如果存在) 受限制的
filemod 返回文件的上次修改时间(如果文件不存在或不是常规文件,则返回0)受限制的
filesize 返回文件的大小(如果文件不存在或不是常规文件,则返回0)受限制的

在最后一栏中标记为“受限”的功能在诸如的某些模块中不可用mod_include

在最后一栏中标记为“ ordering”的功能需要对服务器的不同组件的顺序进行一些考虑,尤其是在< If>指令中使用该功能时(相对较早评估)。

环境变量排序

在< If>条件中查找环境变量时,重要的是要考虑在请求处理过程中有多早出现这种解决方案。作为准则,在虚拟主机上下文(目录,位置,htaccess)之外定义的任何指令都不太可能有执行机会。SetEnvIf 在虚拟主机范围是在此之前的分辨率,运行一个指令

reqenv是<使用的外部If>将通常稍后发生的分辨率,但确切的定时依赖于表达已内使用的指令。

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

除了字符串值函数外,还有一些列表值函数,它们将一个字符串作为参数并返回一个单词列表,即字符串列表。单词表可以与特殊-in运算符一起使用。函数名称不区分大小写。模块可以注册其他功能。

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

最佳

范例表达式

以下示例说明如何使用表达式评估请求:

# 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'}"
最佳

其他

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

正则表达式反向引用

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

最佳

与SSLRequire的比较

ap_expr语法主要是已废弃的语法的超SSLRequire指令。的差异在SSLRequire的文档中进行了描述。

最佳

版本记录

req_novary 功能 可用于2.4.4和更高版本。

可用语言: zh  |  fr 

最佳

注释

注意:
这不是“问答”部分。此处放置的评论应指向有关改进文档或服务器的建议,如果实施或被认为无效/偏离主题,我们的主持人可以将其删除。有关如何管理Apache HTTP Server的问题,应直接指向我们的IRC频道#httpd(位于Freenode上),或发送至我们的邮件列表
目前,此页面已禁用评论。