X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=docs%2Fmanual%2Fexpr.xml;h=837865bfdd57e27d15114a1da48b2352494d221e;hb=402ea113bbd93eef00e66ba0caaef75df15cd0e8;hp=db339d40adf38207548fddafbb3f0bb1958b69a2;hpb=b5dae5e0bb0cc947b794b64222bf31a91468454a;p=apache diff --git a/docs/manual/expr.xml b/docs/manual/expr.xml index db339d40ad..837865bfdd 100644 --- a/docs/manual/expr.xml +++ b/docs/manual/expr.xml @@ -25,62 +25,95 @@ Expressions in Apache HTTP Server -

Historically, there are several syntax variants for expressions used to express - a condition in the different modules of the Apache HTTP Server. - There is some ongoing effort to only use a single variant, called ap_expr, - for all configuration directives. - This document describes the ap_expr expression parser. +

Historically, there are several syntax variants for expressions + used to express a condition in the different modules of the Apache + HTTP Server. There is some ongoing effort to only use a single + variant, called ap_expr, for all configuration directives. + This document describes the ap_expr expression parser.

The ap_expr expression is intended to replace most other - expression variants in HTTPD. For example, the deprecated - SSLRequire expressions can be - replaced by Require expr. -

+ expression variants in HTTPD. For example, the deprecated SSLRequire expressions can be replaced + by Require expr.

If ElseIf Else +ErrorDocument +Alias +ScriptAlias +Redirect AuthBasicFake AuthFormLoginRequiredLocation AuthFormLoginSuccessLocation AuthFormLogoutLocation +AuthName +AuthType RewriteCond SetEnvIfExpr Header RequestHeader FilterProvider +CryptoKey +CryptoIV Require expr +Require ldap-user +Require ldap-group +Require ldap-dn +Require ldap-attribute +Require ldap-filter +Require ldap-search +Require dbd-group +Require dbm-group +Require group +Require host SSLRequire LogMessage mod_include
Grammar in Backus-Naur Form notation -

Backus-Naur Form (BNF) is a notation - technique for context-free grammars, often used to describe the syntax of languages used in computing. +

Backus-Naur + Form (BNF) is a notation technique for context-free grammars, + often used to describe the syntax of languages used in computing. In most cases, expressions are used to express boolean values. - For these, the starting point in the BNF is expr. However, a few directives - like LogMessage accept expressions - that evaluate to a string value. For those, the starting point in the BNF is string. + For these, the starting point in the BNF is cond. + Directives like ErrorDocument, + Require, + AuthName, + Redirect, + Header, + CryptoKey or + LogMessage accept expressions + that evaluate to a string value. For those, the starting point in + the BNF is string.

-expr        ::= "true" | "false"
-              | "!" expr
-              | expr "&&" expr
-              | expr "||" expr
-              | "(" expr ")"
+expr        ::= cond
+              | string
+
+string      ::= substring
+              | string substring
+
+cond        ::= "true" 
+              | "false"
+              | "!" cond
+              | cond "&&" cond
+              | cond "||" cond
               | comp
+              | "(" cond ")"
 
 comp        ::= stringcomp
               | integercomp
               | unaryop word
               | word binaryop word
-              | word "in" "{" wordlist "}"
-              | word "in" listfunction
+              | word "in" listfunc
               | word "=~" regex
               | word "!~" regex
+              | word "in" "{" list "}"
 
 
 stringcomp  ::= word "==" word
@@ -97,35 +130,64 @@ integercomp ::= word "-eq" word | word "eq" wo
               | word "-gt" word | word "gt" word
               | word "-ge" word | word "ge" word
 
-wordlist    ::= word
-              | wordlist "," word
-
-word        ::= word "." word
-              | digit
+word        ::= digits
               | "'" string "'"
-              | """ string """
+              | '"' string '"'
+              | word "." word
               | variable
-              | rebackref
+              | sub
+              | join
               | function
+              | "(" word ")"
 
-string      ::= stringpart
-              | string stringpart
+list        ::= split
+              | listfunc
+              | "{" words "}"
+              | "(" list ")"
 
-stringpart  ::= cstring
+substring   ::= cstring
               | variable
-              | rebackref
-
-cstring     ::= ...
-digit       ::= [0-9]+
 
 variable    ::= "%{" varname "}"
               | "%{" funcname ":" funcargs "}"
+              | "%{:" word ":}"
+              | "%{:" cond ":}"
+              | rebackref
+
+sub         ::= "sub" ["("] regsub "," word [")"]
+
+join        ::= "join" ["("] list [")"]
+              | "join" ["("] list "," word [")"]
+
+split       ::= "split" ["("] regany "," list [")"]
+              | "split" ["("] regany "," word [")"]
+
+function    ::= funcname "(" words ")"
 
-rebackref   ::= "$" [0-9]
+listfunc    ::= listfuncname "(" words ")"
 
-function     ::= funcname "(" word ")"
+words       ::= word
+              | word "," list
 
-listfunction ::= listfuncname "(" word ")"
+regex       ::= "/" regpattern "/" [regflags]
+              | "m" regsep regpattern regsep [regflags]
+
+regsub      ::= "s" regsep regpattern regsep string regsep [regflags]
+
+regany      ::= regex | regsub
+
+regsep      ::= "/" | "#" | "$" | "%" | "^" | "|" | "?" | "!" | "'" | '"' | "," | ";" | ":" | "." | "_" | "-"
+
+regflags    ::= 1*("i" | "s" | "m" | "g")
+regpattern  ::= cstring ; except enclosing regsep
+
+rebackref   ::= "$" DIGIT
+
+digits      ::= 1*(DIGIT)
+cstring     ::= 0*(TEXT)
+
+TEXT        ::= <any OCTET except CTLs>
+DIGIT       ::= <any US-ASCII digit "0".."9">
 
@@ -155,6 +217,7 @@ listfunction ::= listfuncname "(" word ")" Name HTTP_ACCEPT + HTTP_COOKIE HTTP_FORWARDED HTTP_HOST HTTP_PROXY_CONNECTION @@ -177,7 +240,7 @@ listfunction ::= listfuncname "(" word ")" REQUEST_URI The path part of the request's URI DOCUMENT_URI - Same as REQUEST_URI + Same as REQUEST_URI REQUEST_FILENAME The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the @@ -208,10 +271,12 @@ listfunction ::= listfuncname "(" word ")" "GET /index.html HTTP/1.1") REMOTE_ADDR The IP address of the remote host + REMOTE_PORT + The port of the remote host (2.4.26 and later) REMOTE_HOST The host name of the remote host REMOTE_USER - The name of the authenticated user (if any) + The name of the authenticated user, if any (not available during <If>) REMOTE_IDENT The user name set by mod_ident SERVER_NAME @@ -242,13 +307,17 @@ listfunction ::= listfuncname "(" word ")" The DocumentRoot of the current vhost AUTH_TYPE - The configured AuthType - (e.g. "basic") + The configured AuthType (e.g. + "basic") CONTENT_TYPE - The content type of the response + The content type of the response (not available during <If>) HANDLER The name of the handler creating the response + HTTP2 + "on" if the request uses http/2, + "off" otherwise HTTPS "on" if the request uses https, "off" otherwise @@ -256,7 +325,7 @@ listfunction ::= listfuncname "(" word ")" "on" if the connection uses IPv6, "off" otherwise REQUEST_STATUS - The HTTP error status of the request + The HTTP error status of the request (not available during <If>) REQUEST_LOG_ID The error log id of the request (see ErrorLogFormat) @@ -266,6 +335,10 @@ listfunction ::= listfuncname "(" word ")" CONN_REMOTE_ADDR The peer IP address of the connection (see the mod_remoteip module) + CONTEXT_PREFIX + + CONTEXT_DOCUMENT_ROOT + @@ -278,12 +351,12 @@ listfunction ::= listfuncname "(" word ")" TIME_YEAR The current year (e.g. 2010) TIME_MON - The current month (1, ..., 12) + The current month (01, ..., 12) TIME_DAY - The current day of the month + The current day of the month (01, ...) TIME_HOUR The hour part of the current time - (0, ..., 23) + (00, ..., 23) TIME_MIN The minute part of the current time TIME_SEC @@ -292,14 +365,31 @@ listfunction ::= listfuncname "(" word ")" The day of the week (starting with 0 for Sunday) TIME - The date and time in the format 20101231235959 + The date and time in the format + 20101231235959 SERVER_SOFTWARE The server version string API_VERSION The date of the API version (module magic number) -

Some modules register additional variables, see e.g. mod_ssl.

+

Some modules register additional variables, see e.g. + mod_ssl.

+ +

Any variable can be embedded in a string, both in quoted + strings from boolean expressions but also in string expressions, + resulting in the concatenation of the constant and dynamic parts as + expected.

+ +

There exists another form of variables (temporaries) expressed like + %{:word:} and which allow embedding of the more + powerful word syntax (and constructs) in both type of expressions, + without colliding with the constant part of such strings. They are mainly + useful in string expressions though, since the word is directly + available in boolean expressions already. By using this form of variables, + one can evaluate regexes, substitutions, join and/or split strings and + lists in the scope of string expressions, hence construct complex strings + dynamically.

@@ -336,6 +426,12 @@ listfunction ::= listfuncname "(" word ")" >= String greater than or equal + =~ + + String matches the regular expression + !~ + + String does not match the regular expression -eq eq Integer equality @@ -431,7 +527,8 @@ listfunction ::= listfuncname "(" word ")" "false", or "no" (case insensitive). True otherwise. -R - Same as "%{REMOTE_ADDR} -ipmatch ...", but more efficient + Same as "%{REMOTE_ADDR} -ipmatch ...", but more + efficient @@ -447,9 +544,9 @@ listfunction ::= listfuncname "(" word ")" Modules may register additional functions.

- + - + @@ -457,16 +554,20 @@ listfunction ::= listfuncname "(" word ")" - + - + + - + + osenv @@ -488,15 +589,46 @@ listfunction ::= listfuncname "(" word ")" - + + + + regular file) + + + +
NameDescriptionRestricted
NameDescriptionSpecial notes
req, http Get HTTP request header; header names may be added to the Vary header, see below
Same as req, but header names will not be added to the Vary header
respGet HTTP response header
Get HTTP response header (most response headers will not yet be set + during <If>)
reqenvLookup request environment variable (as a shortcut, v can be used too to access variables).
Lookup request environment variable (as a shortcut, + v can also be used to access variables). + ordering
osenv Lookup operating system environment variable
noteLookup request note
Lookup request noteordering
env Return first match of note, reqenv, - osenv
ordering
tolower Convert string to lower case
toupperHash the string using SHA1, then encode the hash with hexadecimal encoding
fileRead contents from a fileyes
Read contents from a file (including line endings, when present) + restricted
filemodReturn last modification time of a file (or 0 if file does not exist + or is not regular file)restricted
filesize Return size of a file (or 0 if file does not exist or is not - regular file)yes
restricted
ldapEscape characters as required by LDAP distinguished name escaping + (RFC4514) and LDAP filter escaping (RFC4515).
replacereplace(string, "from", "to") replaces all occurrences of "from" + in the string with "to".
-

The functions marked as "restricted" are not available in some modules - like mod_include.

+

The functions marked as "restricted" in the final column are not + available in some modules like mod_include.

+ +

The functions marked as "ordering" in the final column require some + consideration for the ordering of different components of the server, + especially when the function is used within the + <If> directive which is + evaluated relatively early.

+ + Environment variable ordering + When environment variables are looked up within an + <If> condition, it's important + to consider how extremely early in request processing that this + resolution occurs. As a guideline, any directive defined outside of virtual host + context (directory, location, htaccess) is not likely to have yet had a + chance to execute. SetEnvIf + in virtual host scope is one directive that runs prior to this resolution +
+
+ When reqenv is used outside of <If>, the resolution will generally occur later, but the + exact timing depends on the directive the expression has been used within. +

When the functions req or http are used, the header name will automatically be added to the Vary header of the @@ -504,11 +636,11 @@ listfunction ::= listfuncname "(" word ")" the expression. The req_novary function can be used to prevent names from being added to the Vary header.

-

In addition to string-valued functions, there are also list-valued functions which - take one string as argument and return a wordlist, i.e. a list of strings. The wordlist - can be used with the special -in operator. - Functions names are not case sensitive. - Modules may register additional functions.

+

In addition to string-valued functions, there are also + list-valued functions which take one string as argument and return a + list, i.e. a list of strings. The list can be used with the + special -in operator. Functions names are not case + sensitive. Modules may register additional functions.

There are no built-in list-valued functions. mod_ssl provides PeerExtList. See the description of @@ -519,14 +651,16 @@ listfunction ::= listfuncname "(" word ")"

- - Example expressions -

The following examples show how expressions might be used to evaluate requests:

- - + + Example expressions +

The following examples show how expressions might be used to + evaluate requests:

+ + + # 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/ + Redirect permanent "/" "http://www.example.com/" </If> # Force text/plain if requesting a file with the query string contains 'forcetext' @@ -536,9 +670,59 @@ listfunction ::= listfuncname "(" word ")" # Only allow access to this content during business hours <Directory "/foo/bar/business"> - Require expr "%{TIME_HOUR} -gt 9 && %{TIME_HOUR} -lt 17" -</Directory> - + 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 examples in boolean context +<If "md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8'"> + Header set checksum-matched true +</If> +<If "md5('foo') == replace('md5:XXXd18db4cc2f85cedef654fccc4a4d8', 'md5:XXX', 'acb')"> + Header set checksum-matched-2 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$#" + +# Add a header to forward client's certificate SAN to some backend +RequestHeader set X-Client-SAN "expr=%{:join PeerExtList('subjectAltName'):}" + +# Require that the remote IP be in the client's certificate SAN +Require expr %{REMOTE_ADDR} -in split s/.*?IP Address:([^,]+)/$1/, PeerExtList('subjectAltName') +# or alternatively: +Require expr "IP Address:%{REMOTE_ADDR}" -in split/, /, join PeerExtList('subjectAltName') + +# 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'}" + +
@@ -550,10 +734,11 @@ listfunction ::= listfuncname "(" word ")" NameAlternative Description -in in - string contained in string list + string contained in list /regexp/ m#regexp# - Regular expression (the second form allows different delimiters than /) + Regular expression (the second form allows different + delimiters than /) /regexp/i m#regexp#i Case insensitive regular expression