<-
Apache > HTTP Server > 文件 > 第 2.4 版

Apache HTTP Server 中的運算式

可用的語言:  en  |  fr 

一般而言,在 Apache HTTP Server 的不同模組中用來表示條件的運算式有許多不同的語法變體。目前正有一些持續的計畫,想要統一為單一變體,稱為 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 的 scheme 區段
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 如果要求使用 http/2,則為「on」,否則為「off
HTTPS 如果要求使用 https,則為「on」,否則為「off
IPV6 如果連線使用 IPv6,則為「on」,否則為「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 如果字串為 valid 檔案,且可透過伺服器目前設定的所有存取控制存取該路徑,則為真。這會使用內部子請求來進行檢查,因此請小心使用 - 它會影響伺服器的效能!
-U 如果字串為 valid URL,且可透過伺服器目前設定的所有存取控制存取該路徑,則為真。這會使用內部子請求來進行檢查,因此請小心使用 - 它會影響伺服器的效能!
-A -U 的別名
-n 如果字串不為空,則為真
-z 如果字串為空,則為真
-T 如果字串為空、「0」、「off」、「false」或「no」 (大小寫不敏感),則為 false。否則為 true。
-R 與「%{REMOTE_ADDR} -ipmatch ...」相同,但更有效率。

標示為「受限」的運算式在一些模組中無法使用,例如 mod_include

top

函式

常規字串值函式接受字串作為參數,並傳回字串。函式名稱不區分大小寫。模組可能會註冊其他函式。

名稱說明特殊說明
reqhttp 取得 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 及更新版本中提供)

最後一欄中標記為「restricted」的功能在一些模組中不可用,例如 mod_include

最後一欄中標記為「ordering」的功能需要考慮伺服器不同元件的排序,特別是在 <If> 指令中使用該功能時,因為該指令的評估相對較早。

環境變數排序

在 <If> 條件中查詢環境變數時,務必考慮解析發生在要求處理非常早期的情況。作為準則,虛擬主機內容(目錄、位置、htaccess)以外定義的任何指令不太可能已有機會執行。虛擬主機範圍內的 SetEnvIf 是在該解析之前執行的其中一個指令。

當 <If> 外部使用 reqenv 時,解析通常會在稍後發生,但確切時機取決於已在其中使用表達式的指令。

當使用 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 文字清單中包含的字串
/正規表示式/ m#正規表示式# 正規表示式 (第二個形式允許與 / 不同的分隔符號)
/正規表示式/i m#正規表示式#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 上,或傳送至我們的 郵遞清單