]> granicus.if.org Git - apache/blobdiff - docs/manual/expr.xml
Help doc writer to spot places where:
[apache] / docs / manual / expr.xml
index dc9e8fbe470eb8a52338d12ab336cdbc5b3cfefd..837865bfdd57e27d15114a1da48b2352494d221e 100644 (file)
   <title>Expressions in Apache HTTP Server</title>
 
   <summary>
   <title>Expressions in Apache HTTP Server</title>
 
   <summary>
-    <p>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 <em>ap_expr</em>,
-        for all configuration directives.
-        This document describes the <em>ap_expr</em> expression parser.
+    <p>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 <em>ap_expr</em>, for all configuration directives.
+    This document describes the <em>ap_expr</em> expression parser.
     </p>
     <p>The <em>ap_expr</em> expression is intended to replace most other
     </p>
     <p>The <em>ap_expr</em> expression is intended to replace most other
-        expression variants in HTTPD. For example, the deprecated
-        <directive module="mod_ssl">SSLRequire</directive> expressions can be
-        replaced by <a href="mod/mod_authz_core.html#reqexpr">Require expr</a>.
-    </p>
+    expression variants in HTTPD. For example, the deprecated <directive
+    module="mod_ssl">SSLRequire</directive> expressions can be replaced
+    by <a href="mod/mod_authz_core.html#reqexpr">Require expr</a>.  </p>
   </summary>
 
 <seealso><directive module="core" type="section">If</directive></seealso>
 <seealso><directive module="core" type="section">ElseIf</directive></seealso>
 <seealso><directive module="core" type="section">Else</directive></seealso>
   </summary>
 
 <seealso><directive module="core" type="section">If</directive></seealso>
 <seealso><directive module="core" type="section">ElseIf</directive></seealso>
 <seealso><directive module="core" type="section">Else</directive></seealso>
+<seealso><directive module="core">ErrorDocument</directive></seealso>
+<seealso><directive module="mod_alias">Alias</directive></seealso>
+<seealso><directive module="mod_alias">ScriptAlias</directive></seealso>
+<seealso><directive module="mod_alias">Redirect</directive></seealso>
 <seealso><directive module="mod_auth_basic">AuthBasicFake</directive></seealso>
 <seealso><directive module="mod_auth_form">AuthFormLoginRequiredLocation</directive></seealso>
 <seealso><directive module="mod_auth_form">AuthFormLoginSuccessLocation</directive></seealso>
 <seealso><directive module="mod_auth_form">AuthFormLogoutLocation</directive></seealso>
 <seealso><directive module="mod_auth_basic">AuthBasicFake</directive></seealso>
 <seealso><directive module="mod_auth_form">AuthFormLoginRequiredLocation</directive></seealso>
 <seealso><directive module="mod_auth_form">AuthFormLoginSuccessLocation</directive></seealso>
 <seealso><directive module="mod_auth_form">AuthFormLogoutLocation</directive></seealso>
+<seealso><directive module="mod_authn_core">AuthName</directive></seealso>
+<seealso><directive module="mod_authn_core">AuthType</directive></seealso>
 <seealso><directive module="mod_rewrite">RewriteCond</directive></seealso>
 <seealso><directive module="mod_setenvif">SetEnvIfExpr</directive></seealso>
 <seealso><directive module="mod_headers">Header</directive></seealso>
 <seealso><directive module="mod_headers">RequestHeader</directive></seealso>
 <seealso><directive module="mod_filter">FilterProvider</directive></seealso>
 <seealso><directive module="mod_rewrite">RewriteCond</directive></seealso>
 <seealso><directive module="mod_setenvif">SetEnvIfExpr</directive></seealso>
 <seealso><directive module="mod_headers">Header</directive></seealso>
 <seealso><directive module="mod_headers">RequestHeader</directive></seealso>
 <seealso><directive module="mod_filter">FilterProvider</directive></seealso>
+<seealso><directive module="mod_crypto">CryptoKey</directive></seealso>
+<seealso><directive module="mod_crypto">CryptoIV</directive></seealso>
 <seealso><a href="mod/mod_authz_core.html#reqexpr">Require expr</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#requser">Require ldap-user</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#reqgroup">Require ldap-group</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#reqdn">Require ldap-dn</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#reqattribute">Require ldap-attribute</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#reqfilter">Require ldap-filter</a></seealso>
 <seealso><a href="mod/mod_authz_core.html#reqexpr">Require expr</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#requser">Require ldap-user</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#reqgroup">Require ldap-group</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#reqdn">Require ldap-dn</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#reqattribute">Require ldap-attribute</a></seealso>
 <seealso><a href="mod/mod_authnz_ldap.html#reqfilter">Require ldap-filter</a></seealso>
+<seealso><a href="mod/mod_authnz_ldap.html#reqsearch">Require ldap-search</a></seealso>
+<seealso><a href="mod/mod_authz_dbd.html#reqgroup">Require dbd-group</a></seealso>
+<seealso><a href="mod/mod_authz_dbm.html#reqgroup">Require dbm-group</a></seealso>
+<seealso><a href="mod/mod_authz_groupfile.html#reqgroup">Require group</a></seealso>
+<seealso><a href="mod/mod_authz_host.html#reqhost">Require host</a></seealso>
 <seealso><directive module="mod_ssl">SSLRequire</directive></seealso>
 <seealso><directive module="mod_log_debug">LogMessage</directive></seealso>
 <seealso><module>mod_include</module></seealso>
 
   <section id="grammar">
     <title>Grammar in Backus-Naur Form notation</title>
 <seealso><directive module="mod_ssl">SSLRequire</directive></seealso>
 <seealso><directive module="mod_log_debug">LogMessage</directive></seealso>
 <seealso><module>mod_include</module></seealso>
 
   <section id="grammar">
     <title>Grammar in Backus-Naur Form notation</title>
-      <p><a href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form">Backus-Naur Form</a> (BNF) is a notation
-      technique for context-free grammars, often used to describe the syntax of languages used in computing.
+      <p><a
+      href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form">Backus-Naur
+      Form</a> (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.
       In most cases, expressions are used to express boolean values.
-      For these, the starting point in the BNF is <code>expr</code>. However, a few directives
-      like <directive module="mod_log_debug">LogMessage</directive> accept expressions
-      that evaluate to a string value. For those, the starting point in the BNF is <code>string</code>.
+      For these, the starting point in the BNF is <code>cond</code>.
+      Directives like <directive module="core">ErrorDocument</directive>,
+      <directive module="mod_authz_core">Require</directive>,
+      <directive module="mod_authn_core">AuthName</directive>,
+      <directive module="mod_alias">Redirect</directive>,
+      <directive module="mod_headers">Header</directive>,
+      <directive module="mod_crypto">CryptoKey</directive> or
+      <directive module="mod_log_debug">LogMessage</directive> accept expressions
+      that evaluate to a string value. For those, the starting point in
+      the BNF is <code>string</code>.
       </p>
 <blockquote>
 <pre>
       </p>
 <blockquote>
 <pre>
-expr        ::= "<strong>true</strong>" | "<strong>false</strong>"
-              | "<strong>!</strong>" expr
-              | expr "<strong>&amp;&amp;</strong>" expr
-              | expr "<strong>||</strong>" expr
-              | "<strong>(</strong>" expr "<strong>)</strong>"
+expr        ::= cond
+              | string
+
+string      ::= substring
+              | string substring
+
+cond        ::= "<strong>true</strong>" 
+              | "<strong>false</strong>"
+              | "<strong>!</strong>" cond
+              | cond "<strong>&amp;&amp;</strong>" cond
+              | cond "<strong>||</strong>" cond
               | comp
               | comp
+              | "<strong>(</strong>" cond "<strong>)</strong>"
 
 comp        ::= stringcomp
               | integercomp
               | unaryop word
               | word binaryop word
 
 comp        ::= stringcomp
               | integercomp
               | unaryop word
               | word binaryop word
-              | word "<strong>in</strong>" "<strong>{</strong>" wordlist "<strong>}</strong>"
-              | word "<strong>in</strong>" listfunction
+              | word "<strong>in</strong>" listfunc
               | word "<strong>=~</strong>" regex
               | word "<strong>!~</strong>" regex
               | word "<strong>=~</strong>" regex
               | word "<strong>!~</strong>" regex
+              | word "<strong>in</strong>" "<strong>{</strong>" list "<strong>}</strong>"
 
 
 stringcomp  ::= word "<strong>==</strong>" word
 
 
 stringcomp  ::= word "<strong>==</strong>" word
@@ -102,35 +130,64 @@ integercomp ::= word "<strong>-eq</strong>" word | word "<strong>eq</strong>" wo
               | word "<strong>-gt</strong>" word | word "<strong>gt</strong>" word
               | word "<strong>-ge</strong>" word | word "<strong>ge</strong>" word
 
               | word "<strong>-gt</strong>" word | word "<strong>gt</strong>" word
               | word "<strong>-ge</strong>" word | word "<strong>ge</strong>" word
 
-wordlist    ::= word
-              | wordlist "<strong>,</strong>" word
-
-word        ::= word "<strong>.</strong>" word
-              | digit
+word        ::= digits
               | "<strong>'</strong>" string "<strong>'</strong>"
               | "<strong>'</strong>" string "<strong>'</strong>"
-              | "<strong>"</strong>" string "<strong>"</strong>"
+              | '<strong>"</strong>' string '<strong>"</strong>'
+              | word "<strong>.</strong>" word
               | variable
               | variable
-              | rebackref
+              | sub
+              | join
               | function
               | function
+              | "<strong>(</strong>" word "<strong>)</strong>"
 
 
-string      ::= stringpart
-              | string stringpart
+list        ::= split
+              | listfunc
+              | "<strong>{</strong>" words "<strong>}</strong>"
+              | "<strong>(</strong>" list "<strong>)</strong>"
 
 
-stringpart  ::= cstring
+substring   ::= cstring
               | variable
               | variable
-              | rebackref
-
-cstring     ::= ...
-digit       ::= [0-9]+
 
 variable    ::= "<strong>%{</strong>" varname "<strong>}</strong>"
               | "<strong>%{</strong>" funcname "<strong>:</strong>" funcargs "<strong>}</strong>"
 
 variable    ::= "<strong>%{</strong>" varname "<strong>}</strong>"
               | "<strong>%{</strong>" funcname "<strong>:</strong>" funcargs "<strong>}</strong>"
+              | "<strong>%{:</strong>" word "<strong>:}</strong>"
+              | "<strong>%{:</strong>" cond "<strong>:}</strong>"
+              | rebackref
+
+sub         ::= "<strong>sub</strong>" ["<strong>(</strong>"] regsub "<strong>,</strong>" word ["<strong>)</strong>"]
+
+join        ::= "<strong>join</strong>" ["<strong>(</strong>"] list ["<strong>)</strong>"]
+              | "<strong>join</strong>" ["<strong>(</strong>"] list "<strong>,</strong>" word ["<strong>)</strong>"]
+
+split       ::= "<strong>split</strong>" ["<strong>(</strong>"] regany "<strong>,</strong>" list ["<strong>)</strong>"]
+              | "<strong>split</strong>" ["<strong>(</strong>"] regany "<strong>,</strong>" word ["<strong>)</strong>"]
+
+function    ::= funcname "<strong>(</strong>" words "<strong>)</strong>"
 
 
-rebackref   ::= "<strong>$</strong>" [0-9]
+listfunc    ::= listfuncname "<strong>(</strong>" words "<strong>)</strong>"
 
 
-function     ::= funcname "<strong>(</strong>" word "<strong>)</strong>"
+words       ::= word
+              | word "<strong>,</strong>" list
 
 
-listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
+regex       ::= "<strong>/</strong>" regpattern "<strong>/</strong>" [regflags]
+              | "<strong>m</strong>" regsep regpattern regsep [regflags]
+
+regsub      ::= "<strong>s</strong>" regsep regpattern regsep string regsep [regflags]
+
+regany      ::= regex | regsub
+
+regsep      ::= "/" | "#" | "$" | "%" | "^" | "|" | "?" | "!" | "'" | '"' | "," | ";" | ":" | "." | "_" | "-"
+
+regflags    ::= 1*("i" | "s" | "m" | "g")
+regpattern  ::= cstring ; except enclosing <em>regsep</em>
+
+rebackref   ::= "<strong>$</strong>" DIGIT
+
+digits      ::= 1*(DIGIT)
+cstring     ::= 0*(TEXT)
+
+TEXT        ::= &lt;any OCTET except CTLs&gt;
+DIGIT       ::= &lt;any US-ASCII digit "0".."9"&gt;
 </pre>
 </blockquote>
 
 </pre>
 </blockquote>
 
@@ -160,6 +217,7 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
 
     <tr><th>Name</th></tr>
     <tr><td><code>HTTP_ACCEPT</code></td></tr>
 
     <tr><th>Name</th></tr>
     <tr><td><code>HTTP_ACCEPT</code></td></tr>
+    <tr><td><code>HTTP_COOKIE</code></td></tr>
     <tr><td><code>HTTP_FORWARDED</code></td></tr>
     <tr><td><code>HTTP_HOST</code></td></tr>
     <tr><td><code>HTTP_PROXY_CONNECTION</code></td></tr>
     <tr><td><code>HTTP_FORWARDED</code></td></tr>
     <tr><td><code>HTTP_HOST</code></td></tr>
     <tr><td><code>HTTP_PROXY_CONNECTION</code></td></tr>
@@ -182,7 +240,7 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
     <tr><td><code>REQUEST_URI</code></td>
         <td>The path part of the request's URI</td></tr>
     <tr><td><code>DOCUMENT_URI</code></td>
     <tr><td><code>REQUEST_URI</code></td>
         <td>The path part of the request's URI</td></tr>
     <tr><td><code>DOCUMENT_URI</code></td>
-        <td>Same as REQUEST_URI</td></tr>
+        <td>Same as <code>REQUEST_URI</code></td></tr>
     <tr><td><code>REQUEST_FILENAME</code></td>
         <td>The full local filesystem path to the file or script matching the
             request, if this has already been determined by the server at the
     <tr><td><code>REQUEST_FILENAME</code></td>
         <td>The full local filesystem path to the file or script matching the
             request, if this has already been determined by the server at the
@@ -213,10 +271,12 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
             "<code>GET /index.html HTTP/1.1</code>")</td></tr>
     <tr><td><code>REMOTE_ADDR</code></td>
         <td>The IP address of the remote host</td></tr>
             "<code>GET /index.html HTTP/1.1</code>")</td></tr>
     <tr><td><code>REMOTE_ADDR</code></td>
         <td>The IP address of the remote host</td></tr>
+    <tr><td><code>REMOTE_PORT</code></td>
+        <td>The port of the remote host (2.4.26 and later)</td></tr>
     <tr><td><code>REMOTE_HOST</code></td>
         <td>The host name of the remote host</td></tr>
     <tr><td><code>REMOTE_USER</code></td>
     <tr><td><code>REMOTE_HOST</code></td>
         <td>The host name of the remote host</td></tr>
     <tr><td><code>REMOTE_USER</code></td>
-        <td>The name of the authenticated user (if any)</td></tr>
+        <td>The name of the authenticated user, if any (not available during <directive>&lt;If&gt;</directive>)</td></tr>
     <tr><td><code>REMOTE_IDENT</code></td>
         <td>The user name set by <module>mod_ident</module></td></tr>
     <tr><td><code>SERVER_NAME</code></td>
     <tr><td><code>REMOTE_IDENT</code></td>
         <td>The user name set by <module>mod_ident</module></td></tr>
     <tr><td><code>SERVER_NAME</code></td>
@@ -247,13 +307,17 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
         <td>The <directive module="core">DocumentRoot</directive> of
             the current vhost</td></tr>
     <tr><td><code>AUTH_TYPE</code></td>
         <td>The <directive module="core">DocumentRoot</directive> of
             the current vhost</td></tr>
     <tr><td><code>AUTH_TYPE</code></td>
-        <td>The configured <directive module="mod_authn_core">AuthType</directive>
-            (e.g. "<code>basic</code>")</td></tr>
+        <td>The configured <directive
+        module="mod_authn_core">AuthType</directive> (e.g.
+        "<code>basic</code>")</td></tr>
     <tr><td><code>CONTENT_TYPE</code></td>
     <tr><td><code>CONTENT_TYPE</code></td>
-        <td>The content type of the response</td></tr>
+        <td>The content type of the response (not available during <directive>&lt;If&gt;</directive>)</td></tr>
     <tr><td><code>HANDLER</code></td>
         <td>The name of the <a href="handler.html">handler</a> creating
             the response</td></tr>
     <tr><td><code>HANDLER</code></td>
         <td>The name of the <a href="handler.html">handler</a> creating
             the response</td></tr>
+    <tr><td><code>HTTP2</code></td>
+        <td>"<code>on</code>" if the request uses http/2,
+            "<code>off</code>" otherwise</td></tr>
     <tr><td><code>HTTPS</code></td>
         <td>"<code>on</code>" if the request uses https,
             "<code>off</code>" otherwise</td></tr>
     <tr><td><code>HTTPS</code></td>
         <td>"<code>on</code>" if the request uses https,
             "<code>off</code>" otherwise</td></tr>
@@ -261,7 +325,7 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
         <td>"<code>on</code>" if the connection uses IPv6,
             "<code>off</code>" otherwise</td></tr>
     <tr><td><code>REQUEST_STATUS</code></td>
         <td>"<code>on</code>" if the connection uses IPv6,
             "<code>off</code>" otherwise</td></tr>
     <tr><td><code>REQUEST_STATUS</code></td>
-        <td>The HTTP error status of the request</td></tr>
+        <td>The HTTP error status of the request (not available during <directive>&lt;If&gt;</directive>)</td></tr>
     <tr><td><code>REQUEST_LOG_ID</code></td>
         <td>The error log id of the request (see
             <directive module="core">ErrorLogFormat</directive>)</td></tr>
     <tr><td><code>REQUEST_LOG_ID</code></td>
         <td>The error log id of the request (see
             <directive module="core">ErrorLogFormat</directive>)</td></tr>
@@ -271,6 +335,10 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
     <tr><td><code>CONN_REMOTE_ADDR</code></td>
         <td>The peer IP address of the connection (see the
             <module>mod_remoteip</module> module)</td></tr>
     <tr><td><code>CONN_REMOTE_ADDR</code></td>
         <td>The peer IP address of the connection (see the
             <module>mod_remoteip</module> module)</td></tr>
+    <tr><td><code>CONTEXT_PREFIX</code></td>
+        <td></td></tr>
+    <tr><td><code>CONTEXT_DOCUMENT_ROOT</code></td>
+        <td></td></tr>
 
     </table>
 
 
     </table>
 
@@ -283,12 +351,12 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
     <tr><td><code>TIME_YEAR</code></td>
         <td>The current year (e.g. <code>2010</code>)</td></tr>
     <tr><td><code>TIME_MON</code></td>
     <tr><td><code>TIME_YEAR</code></td>
         <td>The current year (e.g. <code>2010</code>)</td></tr>
     <tr><td><code>TIME_MON</code></td>
-        <td>The current month (<code>1</code>, ..., <code>12</code>)</td></tr>
+        <td>The current month (<code>01</code>, ..., <code>12</code>)</td></tr>
     <tr><td><code>TIME_DAY</code></td>
     <tr><td><code>TIME_DAY</code></td>
-        <td>The current day of the month</td></tr>
+        <td>The current day of the month (<code>01</code>, ...)</td></tr>
     <tr><td><code>TIME_HOUR</code></td>
         <td>The hour part of the current time
     <tr><td><code>TIME_HOUR</code></td>
         <td>The hour part of the current time
-            (<code>0</code>, ..., <code>23</code>)</td></tr>
+            (<code>00</code>, ..., <code>23</code>)</td></tr>
     <tr><td><code>TIME_MIN</code></td>
         <td>The minute part of the current time </td></tr>
     <tr><td><code>TIME_SEC</code></td>
     <tr><td><code>TIME_MIN</code></td>
         <td>The minute part of the current time </td></tr>
     <tr><td><code>TIME_SEC</code></td>
@@ -297,14 +365,31 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
         <td>The day of the week (starting with <code>0</code>
             for Sunday)</td></tr>
     <tr><td><code>TIME</code></td>
         <td>The day of the week (starting with <code>0</code>
             for Sunday)</td></tr>
     <tr><td><code>TIME</code></td>
-        <td>The date and time in the format <code>20101231235959</code></td></tr>
+        <td>The date and time in the format
+        <code>20101231235959</code></td></tr>
     <tr><td><code>SERVER_SOFTWARE</code></td>
         <td>The server version string</td></tr>
     <tr><td><code>API_VERSION</code></td>
         <td>The date of the API version (module magic number)</td></tr>
     </table>
 
     <tr><td><code>SERVER_SOFTWARE</code></td>
         <td>The server version string</td></tr>
     <tr><td><code>API_VERSION</code></td>
         <td>The date of the API version (module magic number)</td></tr>
     </table>
 
-    <p>Some modules register additional variables, see e.g. <module>mod_ssl</module>.</p>
+    <p>Some modules register additional variables, see e.g.
+    <module>mod_ssl</module>.</p>
+
+    <p>Any variable can be embedded in a <em>string</em>, both in quoted
+    strings from boolean expressions but also in string expressions,
+    resulting in the concatenation of the constant and dynamic parts as
+    expected.</p>
+
+    <p>There exists another form of variables (temporaries) expressed like
+    <code>%{:<em>word</em>:}</code> and which allow embedding of the more
+    powerful <em>word</em> 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 <em>word</em> 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.</p>
 
 </section>
 
 
 </section>
 
@@ -341,6 +426,12 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
     <tr><td><code>&gt;=</code></td>
         <td></td>
         <td>String greater than or equal</td></tr>
     <tr><td><code>&gt;=</code></td>
         <td></td>
         <td>String greater than or equal</td></tr>
+    <tr><td><code>=~</code></td>
+        <td></td>
+        <td>String matches the regular expression</td></tr>
+    <tr><td><code>!~</code></td>
+        <td></td>
+        <td>String does not match the regular expression</td></tr>
     <tr><td><code>-eq</code></td>
         <td><code>eq</code></td>
         <td>Integer equality</td></tr>
     <tr><td><code>-eq</code></td>
         <td><code>eq</code></td>
         <td>Integer equality</td></tr>
@@ -436,7 +527,8 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
             "<code>false</code>", or "<code>no</code>" (case insensitive).
             True otherwise.</td><td></td></tr>
     <tr><td><code>-R</code></td>
             "<code>false</code>", or "<code>no</code>" (case insensitive).
             True otherwise.</td><td></td></tr>
     <tr><td><code>-R</code></td>
-        <td>Same as "<code>%{REMOTE_ADDR} -ipmatch ...</code>", but more efficient
+        <td>Same as "<code>%{REMOTE_ADDR} -ipmatch ...</code>", but more
+        efficient
         </td><td></td></tr>
     </table>
 
         </td><td></td></tr>
     </table>
 
@@ -452,9 +544,9 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
     Modules may register additional functions.</p>
 
     <table border="1" style="zebra">
     Modules may register additional functions.</p>
 
     <table border="1" style="zebra">
-    <columnspec><column width=".2"/><column width=".8"/></columnspec>
+    <columnspec><column width=".2"/><column width=".4"/><column width=".4"/></columnspec>
 
 
-    <tr><th>Name</th><th>Description</th><th>Restricted</th></tr>
+    <tr><th>Name</th><th>Description</th><th>Special notes</th></tr>
     <tr><td><code>req</code>, <code>http</code></td>
         <td>Get HTTP request header; header names may be added to the Vary
             header, see below</td><td></td></tr>
     <tr><td><code>req</code>, <code>http</code></td>
         <td>Get HTTP request header; header names may be added to the Vary
             header, see below</td><td></td></tr>
@@ -462,16 +554,20 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
         <td>Same as <code>req</code>, but header names will not be added to the
             Vary header</td><td></td></tr>
     <tr><td><code>resp</code></td>
         <td>Same as <code>req</code>, but header names will not be added to the
             Vary header</td><td></td></tr>
     <tr><td><code>resp</code></td>
-        <td>Get HTTP response header</td><td></td></tr>
+        <td>Get HTTP response header (most response headers will not yet be set
+            during <directive>&lt;If&gt;</directive>)</td><td></td></tr>
     <tr><td><code>reqenv</code></td>
     <tr><td><code>reqenv</code></td>
-        <td>Lookup request environment variable (as a shortcut, <code>v</code> can be used too to access variables).</td><td></td></tr>
+        <td>Lookup request environment variable (as a shortcut,
+        <code>v</code> can also be used to access variables). 
+        </td>
+        <td>ordering</td></tr>
     <tr><td><code>osenv</code></td>
         <td>Lookup operating system environment variable</td><td></td></tr>
     <tr><td><code>note</code></td>
     <tr><td><code>osenv</code></td>
         <td>Lookup operating system environment variable</td><td></td></tr>
     <tr><td><code>note</code></td>
-        <td>Lookup request note</td><td></td></tr>
+        <td>Lookup request note</td><td>ordering</td></tr>
     <tr><td><code>env</code></td>
         <td>Return first match of <code>note</code>, <code>reqenv</code>,
     <tr><td><code>env</code></td>
         <td>Return first match of <code>note</code>, <code>reqenv</code>,
-            <code>osenv</code></td><td></td></tr>
+            <code>osenv</code></td><td>ordering</td></tr>
     <tr><td><code>tolower</code></td>
         <td>Convert string to lower case</td><td></td></tr>
     <tr><td><code>toupper</code></td>
     <tr><td><code>tolower</code></td>
         <td>Convert string to lower case</td><td></td></tr>
     <tr><td><code>toupper</code></td>
@@ -493,15 +589,46 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
         <td>Hash the string using SHA1, then encode the hash with hexadecimal
             encoding</td><td></td></tr>
     <tr><td><code>file</code></td>
         <td>Hash the string using SHA1, then encode the hash with hexadecimal
             encoding</td><td></td></tr>
     <tr><td><code>file</code></td>
-        <td>Read contents from a file</td><td>yes</td></tr>
+        <td>Read contents from a file (including line endings, when present)
+        </td><td>restricted</td></tr>
+    <tr><td><code>filemod</code></td>
+        <td>Return last modification time of a file (or 0 if file does not exist
+            or is not regular file)</td><td>restricted</td></tr>
     <tr><td><code>filesize</code></td>
         <td>Return size of a file (or 0 if file does not exist or is not
     <tr><td><code>filesize</code></td>
         <td>Return size of a file (or 0 if file does not exist or is not
-            regular file)</td><td>yes</td></tr>
+            regular file)</td><td>restricted</td></tr>
+    <tr><td><code>ldap</code></td>
+        <td>Escape characters as required by LDAP distinguished name escaping
+            (RFC4514) and LDAP filter escaping (RFC4515).</td><td></td></tr>
+    <tr><td><code>replace</code></td>
+        <td>replace(string, "from", "to") replaces all occurrences of "from"
+            in the string with "to".</td><td></td></tr>
 
     </table>
 
 
     </table>
 
-    <p>The functions marked as "restricted" are not available in some modules
-    like <module>mod_include</module>.</p>
+    <p>The functions marked as "restricted" in the final column are not 
+    available in some modules like <module>mod_include</module>.</p>
+
+    <p>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 
+    &lt;<directive module="core">If</directive>&gt; directive which is
+    evaluated relatively early.</p>
+    <note>
+    <title>Environment variable ordering</title>
+    When environment variables are looked up within an 
+    &lt;<directive module="core">If</directive>&gt; 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. <directive module="mod_setenvif">SetEnvIf</directive>
+    in virtual host scope is one directive that runs prior to this resolution
+    <br/>
+    <br/>
+    When <code>reqenv</code> is used outside of &lt;<directive module="core"
+    >If</directive>&gt;, the resolution will generally occur later, but the 
+    exact timing depends on the directive the expression has been used within.
+    </note>
 
     <p>When the functions <code>req</code> or <code>http</code> are used,
     the header name will automatically be added to the Vary header of the
 
     <p>When the functions <code>req</code> or <code>http</code> are used,
     the header name will automatically be added to the Vary header of the
@@ -509,11 +636,11 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
     the expression. The <code>req_novary</code> function can be used to
     prevent names from being added to the Vary header.</p>
 
     the expression. The <code>req_novary</code> function can be used to
     prevent names from being added to the Vary header.</p>
 
-    <p>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 <code>-in</code> operator.
-    Functions names are not case sensitive.
-    Modules may register additional functions.</p>
+    <p>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 <code>-in</code> operator.  Functions names are not case
+    sensitive.  Modules may register additional functions.</p>
 
     <p>There are no built-in list-valued functions. <module>mod_ssl</module>
     provides <code>PeerExtList</code>.  See the description of
 
     <p>There are no built-in list-valued functions. <module>mod_ssl</module>
     provides <code>PeerExtList</code>.  See the description of
@@ -524,14 +651,16 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
 </section>
 
 <section id="examples">
 </section>
 
 <section id="examples">
-    
-       <title>Example expressions</title>
-       <p>The following examples show how expressions might be used to evaluate requests:</p>
-       <!-- This section should probably be extended with more, useful examples -->
-       <highlight language="config">
+
+    <title>Example expressions</title>
+    <p>The following examples show how expressions might be used to
+    evaluate requests:</p>
+
+    <!-- This section should probably be extended with more, useful examples -->
+    <highlight language="config">
 # Compare the host name to example.com and redirect to www.example.com if it matches
 &lt;If "%{HTTP_HOST} == 'example.com'"&gt;
 # Compare the host name to example.com and redirect to www.example.com if it matches
 &lt;If "%{HTTP_HOST} == 'example.com'"&gt;
-    Redirect permanent / http://www.example.com/
+    Redirect permanent "/" "http://www.example.com/"
 &lt;/If&gt;
 
 # Force text/plain if requesting a file with the query string contains 'forcetext'
 &lt;/If&gt;
 
 # Force text/plain if requesting a file with the query string contains 'forcetext'
@@ -541,9 +670,59 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
 
 # Only allow access to this content during business hours
 &lt;Directory "/foo/bar/business"&gt;
 
 # Only allow access to this content during business hours
 &lt;Directory "/foo/bar/business"&gt;
-    Require expr "%{TIME_HOUR} -gt 9 &amp;&amp; %{TIME_HOUR} -lt 17"
-&lt;/Directory&gt;     
-       </highlight>
+    Require expr %{TIME_HOUR} -gt 9 &amp;&amp; %{TIME_HOUR} -lt 17
+&lt;/Directory&gt;
+
+# Check a HTTP header for a list of values
+&lt;If "%{HTTP:X-example-header} in { 'foo', 'bar', 'baz' }"&gt;
+    Header set matched true
+&lt;/If&gt;
+
+# Check an environment variable for a regular expression, negated.
+&lt;If "! reqenv('REDIRECT_FOO') =~ /bar/"&gt;
+    Header set matched true
+&lt;/If&gt;
+
+# Check result of URI mapping by running in Directory context with -f
+&lt;Directory "/var/www"&gt;
+    AddEncoding x-gzip gz
+&lt;If "-f '%{REQUEST_FILENAME}.unzipme' &amp;&amp; ! %{HTTP:Accept-Encoding} =~ /gzip/"&gt;
+      SetOutputFilter INFLATE
+&lt;/If&gt;
+&lt;/Directory&gt;
+
+# Check against the client IP
+&lt;If "-R '192.168.1.0/24'"&gt;
+    Header set matched true
+&lt;/If&gt;
+
+# Function examples in boolean context
+&lt;If "md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8'"&gt;
+  Header set checksum-matched true
+&lt;/If&gt;
+&lt;If "md5('foo') == replace('md5:XXXd18db4cc2f85cedef654fccc4a4d8', 'md5:XXX', 'acb')"&gt;
+  Header set checksum-matched-2 true
+&lt;/If&gt;
+
+# Function example in string context
+Header set foo-checksum "expr=%{md5:foo}"
+
+# This delays the evaluation of the condition clause compared to &lt;If&gt;
+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'}"
+
+    </highlight>
 </section>
 
 <section id="other">
 </section>
 
 <section id="other">
@@ -555,10 +734,11 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
     <tr><th>Name</th><th>Alternative</th> <th>Description</th></tr>
     <tr><td><code>-in</code></td>
         <td><code>in</code></td>
     <tr><th>Name</th><th>Alternative</th> <th>Description</th></tr>
     <tr><td><code>-in</code></td>
         <td><code>in</code></td>
-        <td>string contained in string list</td></tr>
+        <td>string contained in list</td></tr>
     <tr><td><code>/regexp/</code></td>
         <td><code>m#regexp#</code></td>
     <tr><td><code>/regexp/</code></td>
         <td><code>m#regexp#</code></td>
-        <td>Regular expression (the second form allows different delimiters than /)</td></tr>
+        <td>Regular expression (the second form allows different
+        delimiters than /)</td></tr>
     <tr><td><code>/regexp/i</code></td>
         <td><code>m#regexp#i</code></td>
         <td>Case insensitive regular expression</td></tr>
     <tr><td><code>/regexp/i</code></td>
         <td><code>m#regexp#i</code></td>
         <td>Case insensitive regular expression</td></tr>