]> granicus.if.org Git - apache/blob - docs/manual/expr.xml
Help doc writer to spot places where:
[apache] / docs / manual / expr.xml
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
3 <?xml-stylesheet type="text/xsl" href="./style/manual.en.xsl"?>
4 <!-- $LastChangedRevision$ -->
5
6 <!--
7  Licensed to the Apache Software Foundation (ASF) under one or more
8  contributor license agreements.  See the NOTICE file distributed with
9  this work for additional information regarding copyright ownership.
10  The ASF licenses this file to You under the Apache License, Version 2.0
11  (the "License"); you may not use this file except in compliance with
12  the License.  You may obtain a copy of the License at
13
14      http://www.apache.org/licenses/LICENSE-2.0
15
16  Unless required by applicable law or agreed to in writing, software
17  distributed under the License is distributed on an "AS IS" BASIS,
18  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  See the License for the specific language governing permissions and
20  limitations under the License.
21 -->
22
23 <manualpage metafile="expr.xml.meta">
24
25   <title>Expressions in Apache HTTP Server</title>
26
27   <summary>
28     <p>Historically, there are several syntax variants for expressions
29     used to express a condition in the different modules of the Apache
30     HTTP Server.  There is some ongoing effort to only use a single
31     variant, called <em>ap_expr</em>, for all configuration directives.
32     This document describes the <em>ap_expr</em> expression parser.
33     </p>
34     <p>The <em>ap_expr</em> expression is intended to replace most other
35     expression variants in HTTPD. For example, the deprecated <directive
36     module="mod_ssl">SSLRequire</directive> expressions can be replaced
37     by <a href="mod/mod_authz_core.html#reqexpr">Require expr</a>.  </p>
38   </summary>
39
40 <seealso><directive module="core" type="section">If</directive></seealso>
41 <seealso><directive module="core" type="section">ElseIf</directive></seealso>
42 <seealso><directive module="core" type="section">Else</directive></seealso>
43 <seealso><directive module="core">ErrorDocument</directive></seealso>
44 <seealso><directive module="mod_alias">Alias</directive></seealso>
45 <seealso><directive module="mod_alias">ScriptAlias</directive></seealso>
46 <seealso><directive module="mod_alias">Redirect</directive></seealso>
47 <seealso><directive module="mod_auth_basic">AuthBasicFake</directive></seealso>
48 <seealso><directive module="mod_auth_form">AuthFormLoginRequiredLocation</directive></seealso>
49 <seealso><directive module="mod_auth_form">AuthFormLoginSuccessLocation</directive></seealso>
50 <seealso><directive module="mod_auth_form">AuthFormLogoutLocation</directive></seealso>
51 <seealso><directive module="mod_authn_core">AuthName</directive></seealso>
52 <seealso><directive module="mod_authn_core">AuthType</directive></seealso>
53 <seealso><directive module="mod_rewrite">RewriteCond</directive></seealso>
54 <seealso><directive module="mod_setenvif">SetEnvIfExpr</directive></seealso>
55 <seealso><directive module="mod_headers">Header</directive></seealso>
56 <seealso><directive module="mod_headers">RequestHeader</directive></seealso>
57 <seealso><directive module="mod_filter">FilterProvider</directive></seealso>
58 <seealso><directive module="mod_crypto">CryptoKey</directive></seealso>
59 <seealso><directive module="mod_crypto">CryptoIV</directive></seealso>
60 <seealso><a href="mod/mod_authz_core.html#reqexpr">Require expr</a></seealso>
61 <seealso><a href="mod/mod_authnz_ldap.html#requser">Require ldap-user</a></seealso>
62 <seealso><a href="mod/mod_authnz_ldap.html#reqgroup">Require ldap-group</a></seealso>
63 <seealso><a href="mod/mod_authnz_ldap.html#reqdn">Require ldap-dn</a></seealso>
64 <seealso><a href="mod/mod_authnz_ldap.html#reqattribute">Require ldap-attribute</a></seealso>
65 <seealso><a href="mod/mod_authnz_ldap.html#reqfilter">Require ldap-filter</a></seealso>
66 <seealso><a href="mod/mod_authnz_ldap.html#reqsearch">Require ldap-search</a></seealso>
67 <seealso><a href="mod/mod_authz_dbd.html#reqgroup">Require dbd-group</a></seealso>
68 <seealso><a href="mod/mod_authz_dbm.html#reqgroup">Require dbm-group</a></seealso>
69 <seealso><a href="mod/mod_authz_groupfile.html#reqgroup">Require group</a></seealso>
70 <seealso><a href="mod/mod_authz_host.html#reqhost">Require host</a></seealso>
71 <seealso><directive module="mod_ssl">SSLRequire</directive></seealso>
72 <seealso><directive module="mod_log_debug">LogMessage</directive></seealso>
73 <seealso><module>mod_include</module></seealso>
74
75   <section id="grammar">
76     <title>Grammar in Backus-Naur Form notation</title>
77       <p><a
78       href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form">Backus-Naur
79       Form</a> (BNF) is a notation technique for context-free grammars,
80       often used to describe the syntax of languages used in computing.
81       In most cases, expressions are used to express boolean values.
82       For these, the starting point in the BNF is <code>cond</code>.
83       Directives like <directive module="core">ErrorDocument</directive>,
84       <directive module="mod_authz_core">Require</directive>,
85       <directive module="mod_authn_core">AuthName</directive>,
86       <directive module="mod_alias">Redirect</directive>,
87       <directive module="mod_headers">Header</directive>,
88       <directive module="mod_crypto">CryptoKey</directive> or
89       <directive module="mod_log_debug">LogMessage</directive> accept expressions
90       that evaluate to a string value. For those, the starting point in
91       the BNF is <code>string</code>.
92       </p>
93 <blockquote>
94 <pre>
95 expr        ::= cond
96               | string
97
98 string      ::= substring
99               | string substring
100
101 cond        ::= "<strong>true</strong>" 
102               | "<strong>false</strong>"
103               | "<strong>!</strong>" cond
104               | cond "<strong>&amp;&amp;</strong>" cond
105               | cond "<strong>||</strong>" cond
106               | comp
107               | "<strong>(</strong>" cond "<strong>)</strong>"
108
109 comp        ::= stringcomp
110               | integercomp
111               | unaryop word
112               | word binaryop word
113               | word "<strong>in</strong>" listfunc
114               | word "<strong>=~</strong>" regex
115               | word "<strong>!~</strong>" regex
116               | word "<strong>in</strong>" "<strong>{</strong>" list "<strong>}</strong>"
117
118
119 stringcomp  ::= word "<strong>==</strong>" word
120               | word "<strong>!=</strong>" word
121               | word "<strong>&lt;</strong>"  word
122               | word "<strong>&lt;=</strong>" word
123               | word "<strong>&gt;</strong>"  word
124               | word "<strong>&gt;=</strong>" word
125
126 integercomp ::= word "<strong>-eq</strong>" word | word "<strong>eq</strong>" word
127               | word "<strong>-ne</strong>" word | word "<strong>ne</strong>" word
128               | word "<strong>-lt</strong>" word | word "<strong>lt</strong>" word
129               | word "<strong>-le</strong>" word | word "<strong>le</strong>" word
130               | word "<strong>-gt</strong>" word | word "<strong>gt</strong>" word
131               | word "<strong>-ge</strong>" word | word "<strong>ge</strong>" word
132
133 word        ::= digits
134               | "<strong>'</strong>" string "<strong>'</strong>"
135               | '<strong>"</strong>' string '<strong>"</strong>'
136               | word "<strong>.</strong>" word
137               | variable
138               | sub
139               | join
140               | function
141               | "<strong>(</strong>" word "<strong>)</strong>"
142
143 list        ::= split
144               | listfunc
145               | "<strong>{</strong>" words "<strong>}</strong>"
146               | "<strong>(</strong>" list "<strong>)</strong>"
147
148 substring   ::= cstring
149               | variable
150
151 variable    ::= "<strong>%{</strong>" varname "<strong>}</strong>"
152               | "<strong>%{</strong>" funcname "<strong>:</strong>" funcargs "<strong>}</strong>"
153               | "<strong>%{:</strong>" word "<strong>:}</strong>"
154               | "<strong>%{:</strong>" cond "<strong>:}</strong>"
155               | rebackref
156
157 sub         ::= "<strong>sub</strong>" ["<strong>(</strong>"] regsub "<strong>,</strong>" word ["<strong>)</strong>"]
158
159 join        ::= "<strong>join</strong>" ["<strong>(</strong>"] list ["<strong>)</strong>"]
160               | "<strong>join</strong>" ["<strong>(</strong>"] list "<strong>,</strong>" word ["<strong>)</strong>"]
161
162 split       ::= "<strong>split</strong>" ["<strong>(</strong>"] regany "<strong>,</strong>" list ["<strong>)</strong>"]
163               | "<strong>split</strong>" ["<strong>(</strong>"] regany "<strong>,</strong>" word ["<strong>)</strong>"]
164
165 function    ::= funcname "<strong>(</strong>" words "<strong>)</strong>"
166
167 listfunc    ::= listfuncname "<strong>(</strong>" words "<strong>)</strong>"
168
169 words       ::= word
170               | word "<strong>,</strong>" list
171
172 regex       ::= "<strong>/</strong>" regpattern "<strong>/</strong>" [regflags]
173               | "<strong>m</strong>" regsep regpattern regsep [regflags]
174
175 regsub      ::= "<strong>s</strong>" regsep regpattern regsep string regsep [regflags]
176
177 regany      ::= regex | regsub
178
179 regsep      ::= "/" | "#" | "$" | "%" | "^" | "|" | "?" | "!" | "'" | '"' | "," | ";" | ":" | "." | "_" | "-"
180
181 regflags    ::= 1*("i" | "s" | "m" | "g")
182 regpattern  ::= cstring ; except enclosing <em>regsep</em>
183
184 rebackref   ::= "<strong>$</strong>" DIGIT
185
186 digits      ::= 1*(DIGIT)
187 cstring     ::= 0*(TEXT)
188
189 TEXT        ::= &lt;any OCTET except CTLs&gt;
190 DIGIT       ::= &lt;any US-ASCII digit "0".."9"&gt;
191 </pre>
192 </blockquote>
193
194 </section>
195
196 <section id="vars">
197     <title>Variables</title>
198
199     <p>The expression parser provides a number of variables of the form
200     <code>%{HTTP_HOST}</code>. Note that the value of a variable may depend
201     on the phase of the request processing in which it is evaluated.  For
202     example, an expression used in an <directive>&lt;If &gt;</directive>
203     directive is evaluated before authentication is done. Therefore,
204     <code>%{REMOTE_USER}</code> will not be set in this case.</p>
205
206     <p>The following variables provide the values of the named HTTP request
207     headers. The values of other headers can be obtained with the
208     <code>req</code> <a href="#functions">function</a>. Using these
209     variables may cause the header name to be added to the Vary
210     header of the HTTP response, except where otherwise noted for the
211     directive accepting the expression. The <code>req_novary</code>
212     <a href="#functions">function</a> may be used to circumvent this
213     behavior.</p>
214
215     <table border="1" style="zebra">
216     <columnspec><column width="1"/></columnspec>
217
218     <tr><th>Name</th></tr>
219     <tr><td><code>HTTP_ACCEPT</code></td></tr>
220     <tr><td><code>HTTP_COOKIE</code></td></tr>
221     <tr><td><code>HTTP_FORWARDED</code></td></tr>
222     <tr><td><code>HTTP_HOST</code></td></tr>
223     <tr><td><code>HTTP_PROXY_CONNECTION</code></td></tr>
224     <tr><td><code>HTTP_REFERER</code></td></tr>
225     <tr><td><code>HTTP_USER_AGENT</code></td></tr>
226
227     </table>
228
229     <p>Other request related variables</p>
230
231     <table border="1" style="zebra">
232     <columnspec><column width=".4"/><column width=".6"/></columnspec>
233
234     <tr><th>Name</th><th>Description</th></tr>
235     <tr><td><code>REQUEST_METHOD</code></td>
236         <td>The HTTP method of the incoming request (e.g.
237             <code>GET</code>)</td></tr>
238     <tr><td><code>REQUEST_SCHEME</code></td>
239         <td>The scheme part of the request's URI</td></tr>
240     <tr><td><code>REQUEST_URI</code></td>
241         <td>The path part of the request's URI</td></tr>
242     <tr><td><code>DOCUMENT_URI</code></td>
243         <td>Same as <code>REQUEST_URI</code></td></tr>
244     <tr><td><code>REQUEST_FILENAME</code></td>
245         <td>The full local filesystem path to the file or script matching the
246             request, if this has already been determined by the server at the
247             time <code>REQUEST_FILENAME</code> is referenced. Otherwise, such
248             as when used in virtual host context, the same value as
249             <code>REQUEST_URI</code> </td></tr>
250     <tr><td><code>SCRIPT_FILENAME</code></td>
251         <td>Same as <code>REQUEST_FILENAME</code></td></tr>
252     <tr><td><code>LAST_MODIFIED</code></td>
253         <td>The date and time of last modification of the file in the format
254             <code>20101231235959</code>, if this has already been determined by
255             the server at the time <code>LAST_MODIFIED</code> is referenced.
256             </td></tr>
257     <tr><td><code>SCRIPT_USER</code></td>
258         <td>The user name of the owner of the script.</td></tr>
259     <tr><td><code>SCRIPT_GROUP</code></td>
260         <td>The group name of the group of the script.</td></tr>
261     <tr><td><code>PATH_INFO</code></td>
262         <td>The trailing path name information, see
263             <directive module="core">AcceptPathInfo</directive></td></tr>
264     <tr><td><code>QUERY_STRING</code></td>
265         <td>The query string of the current request</td></tr>
266     <tr><td><code>IS_SUBREQ</code></td>
267         <td>"<code>true</code>" if the current request is a subrequest,
268             "<code>false</code>" otherwise</td></tr>
269     <tr><td><code>THE_REQUEST</code></td>
270         <td>The complete request line (e.g.,
271             "<code>GET /index.html HTTP/1.1</code>")</td></tr>
272     <tr><td><code>REMOTE_ADDR</code></td>
273         <td>The IP address of the remote host</td></tr>
274     <tr><td><code>REMOTE_PORT</code></td>
275         <td>The port of the remote host (2.4.26 and later)</td></tr>
276     <tr><td><code>REMOTE_HOST</code></td>
277         <td>The host name of the remote host</td></tr>
278     <tr><td><code>REMOTE_USER</code></td>
279         <td>The name of the authenticated user, if any (not available during <directive>&lt;If&gt;</directive>)</td></tr>
280     <tr><td><code>REMOTE_IDENT</code></td>
281         <td>The user name set by <module>mod_ident</module></td></tr>
282     <tr><td><code>SERVER_NAME</code></td>
283         <td>The <directive module="core">ServerName</directive> of
284             the current vhost</td></tr>
285     <tr><td><code>SERVER_PORT</code></td>
286         <td>The server port of the current vhost, see
287             <directive module="core">ServerName</directive></td></tr>
288     <tr><td><code>SERVER_ADMIN</code></td>
289         <td>The <directive module="core">ServerAdmin</directive> of
290             the current vhost</td></tr>
291     <tr><td><code>SERVER_PROTOCOL</code></td>
292         <td>The protocol used by the request (e.g. HTTP/1.1). In some types of
293             internal subrequests, this variable has the value
294             <code>INCLUDED</code>.</td></tr>
295     <tr><td><code>SERVER_PROTOCOL_VERSION</code></td>
296         <td>A number that encodes the HTTP version of the request:
297             <code>1000 * major + minor</code>. For example, <code>1001</code>
298             corresponds to HTTP/1.1 and <code>9</code> corresponds
299             to HTTP/0.9</td></tr>
300     <tr><td><code>SERVER_PROTOCOL_VERSION_MAJOR</code></td>
301         <td>The major version part of the HTTP version of the request,
302             e.g. <code>1</code> for HTTP/1.0</td></tr>
303     <tr><td><code>SERVER_PROTOCOL_VERSION_MINOR</code></td>
304         <td>The minor version part of the HTTP version of the request,
305             e.g. <code>0</code> for HTTP/1.0</td></tr>
306     <tr><td><code>DOCUMENT_ROOT</code></td>
307         <td>The <directive module="core">DocumentRoot</directive> of
308             the current vhost</td></tr>
309     <tr><td><code>AUTH_TYPE</code></td>
310         <td>The configured <directive
311         module="mod_authn_core">AuthType</directive> (e.g.
312         "<code>basic</code>")</td></tr>
313     <tr><td><code>CONTENT_TYPE</code></td>
314         <td>The content type of the response (not available during <directive>&lt;If&gt;</directive>)</td></tr>
315     <tr><td><code>HANDLER</code></td>
316         <td>The name of the <a href="handler.html">handler</a> creating
317             the response</td></tr>
318     <tr><td><code>HTTP2</code></td>
319         <td>"<code>on</code>" if the request uses http/2,
320             "<code>off</code>" otherwise</td></tr>
321     <tr><td><code>HTTPS</code></td>
322         <td>"<code>on</code>" if the request uses https,
323             "<code>off</code>" otherwise</td></tr>
324     <tr><td><code>IPV6</code></td>
325         <td>"<code>on</code>" if the connection uses IPv6,
326             "<code>off</code>" otherwise</td></tr>
327     <tr><td><code>REQUEST_STATUS</code></td>
328         <td>The HTTP error status of the request (not available during <directive>&lt;If&gt;</directive>)</td></tr>
329     <tr><td><code>REQUEST_LOG_ID</code></td>
330         <td>The error log id of the request (see
331             <directive module="core">ErrorLogFormat</directive>)</td></tr>
332     <tr><td><code>CONN_LOG_ID</code></td>
333         <td>The error log id of the connection (see
334             <directive module="core">ErrorLogFormat</directive>)</td></tr>
335     <tr><td><code>CONN_REMOTE_ADDR</code></td>
336         <td>The peer IP address of the connection (see the
337             <module>mod_remoteip</module> module)</td></tr>
338     <tr><td><code>CONTEXT_PREFIX</code></td>
339         <td></td></tr>
340     <tr><td><code>CONTEXT_DOCUMENT_ROOT</code></td>
341         <td></td></tr>
342
343     </table>
344
345     <p>Misc variables</p>
346
347     <table border="1" style="zebra">
348     <columnspec><column width=".4"/><column width=".6"/></columnspec>
349
350     <tr><th>Name</th><th>Description</th></tr>
351     <tr><td><code>TIME_YEAR</code></td>
352         <td>The current year (e.g. <code>2010</code>)</td></tr>
353     <tr><td><code>TIME_MON</code></td>
354         <td>The current month (<code>01</code>, ..., <code>12</code>)</td></tr>
355     <tr><td><code>TIME_DAY</code></td>
356         <td>The current day of the month (<code>01</code>, ...)</td></tr>
357     <tr><td><code>TIME_HOUR</code></td>
358         <td>The hour part of the current time
359             (<code>00</code>, ..., <code>23</code>)</td></tr>
360     <tr><td><code>TIME_MIN</code></td>
361         <td>The minute part of the current time </td></tr>
362     <tr><td><code>TIME_SEC</code></td>
363         <td>The second part of the current time </td></tr>
364     <tr><td><code>TIME_WDAY</code></td>
365         <td>The day of the week (starting with <code>0</code>
366             for Sunday)</td></tr>
367     <tr><td><code>TIME</code></td>
368         <td>The date and time in the format
369         <code>20101231235959</code></td></tr>
370     <tr><td><code>SERVER_SOFTWARE</code></td>
371         <td>The server version string</td></tr>
372     <tr><td><code>API_VERSION</code></td>
373         <td>The date of the API version (module magic number)</td></tr>
374     </table>
375
376     <p>Some modules register additional variables, see e.g.
377     <module>mod_ssl</module>.</p>
378
379     <p>Any variable can be embedded in a <em>string</em>, both in quoted
380     strings from boolean expressions but also in string expressions,
381     resulting in the concatenation of the constant and dynamic parts as
382     expected.</p>
383
384     <p>There exists another form of variables (temporaries) expressed like
385     <code>%{:<em>word</em>:}</code> and which allow embedding of the more
386     powerful <em>word</em> syntax (and constructs) in both type of expressions,
387     without colliding with the constant part of such strings. They are mainly
388     useful in string expressions though, since the <em>word</em> is directly
389     available in boolean expressions already. By using this form of variables,
390     one can evaluate regexes, substitutions, join and/or split strings and
391     lists in the scope of string expressions, hence construct complex strings
392     dynamically.</p>
393
394 </section>
395
396 <section id="binop">
397     <title>Binary operators</title>
398
399     <p>With the exception of some built-in comparison operators, binary
400     operators have the form "<code>-[a-zA-Z][a-zA-Z0-9_]+</code>", i.e. a
401     minus and at least two characters. The name is not case sensitive.
402     Modules may register additional binary operators.</p>
403
404     <section id="comp">
405     <title>Comparison operators</title>
406
407     <table border="1" style="zebra">
408     <columnspec><column width=".2"/><column width=".2"/><column width=".6"/></columnspec>
409
410     <tr><th>Name</th><th>Alternative</th> <th>Description</th></tr>
411     <tr><td><code>==</code></td>
412         <td><code>=</code></td>
413         <td>String equality</td></tr>
414     <tr><td><code>!=</code></td>
415         <td></td>
416         <td>String inequality</td></tr>
417     <tr><td><code>&lt;</code></td>
418         <td></td>
419         <td>String less than</td></tr>
420     <tr><td><code>&lt;=</code></td>
421         <td></td>
422         <td>String less than or equal</td></tr>
423     <tr><td><code>&gt;</code></td>
424         <td></td>
425         <td>String greater than</td></tr>
426     <tr><td><code>&gt;=</code></td>
427         <td></td>
428         <td>String greater than or equal</td></tr>
429     <tr><td><code>=~</code></td>
430         <td></td>
431         <td>String matches the regular expression</td></tr>
432     <tr><td><code>!~</code></td>
433         <td></td>
434         <td>String does not match the regular expression</td></tr>
435     <tr><td><code>-eq</code></td>
436         <td><code>eq</code></td>
437         <td>Integer equality</td></tr>
438     <tr><td><code>-ne</code></td>
439         <td><code>ne</code></td>
440         <td>Integer inequality</td></tr>
441     <tr><td><code>-lt</code></td>
442         <td><code>lt</code></td>
443         <td>Integer less than</td></tr>
444     <tr><td><code>-le</code></td>
445         <td><code>le</code></td>
446         <td>Integer less than or equal</td></tr>
447     <tr><td><code>-gt</code></td>
448         <td><code>gt</code></td>
449         <td>Integer greater than</td></tr>
450     <tr><td><code>-ge</code></td>
451         <td><code>ge</code></td>
452         <td>Integer greater than or equal</td></tr>
453     </table>
454     </section>
455
456     <section id="binaryother">
457     <title>Other binary operators</title>
458
459     <table border="1" style="zebra">
460     <columnspec><column width=".2"/><column width=".8"/></columnspec>
461
462     <tr><th>Name</th><th>Description</th></tr>
463     <tr><td><code>-ipmatch</code></td>
464         <td>IP address matches address/netmask</td></tr>
465     <tr><td><code>-strmatch</code></td>
466         <td>left string matches pattern given by right string (containing
467             wildcards *, ?, [])</td></tr>
468     <tr><td><code>-strcmatch</code></td>
469         <td>same as <code>-strmatch</code>, but case insensitive</td></tr>
470     <tr><td><code>-fnmatch</code></td>
471         <td>same as <code>-strmatch</code>, but slashes are not matched by
472             wildcards</td></tr>
473     </table>
474     </section>
475
476 </section>
477
478 <section id="unnop">
479     <title>Unary operators</title>
480
481     <p>Unary operators take one argument and have the form
482     "<code>-[a-zA-Z]</code>", i.e. a minus and one character.
483     The name <em>is</em> case sensitive.
484     Modules may register additional unary operators.</p>
485
486     <table border="1" style="zebra">
487     <columnspec><column width=".2"/><column width=".2"/><column width=".6"/></columnspec>
488
489     <tr><th>Name</th><th>Description</th><th>Restricted</th></tr>
490     <tr><td><code>-d</code></td>
491         <td>The argument is treated as a filename.
492             True if the file exists and is a directory</td><td>yes</td></tr>
493     <tr><td><code>-e</code></td>
494         <td>The argument is treated as a filename.
495             True if the file (or dir or special) exists</td><td>yes</td></tr>
496     <tr><td><code>-f</code></td>
497         <td>The argument is treated as a filename.
498             True if the file exists and is regular file</td><td>yes</td></tr>
499     <tr><td><code>-s</code></td>
500         <td>The argument is treated as a filename.
501             True if the file exists and is not empty</td><td>yes</td></tr>
502     <tr><td><code>-L</code></td>
503         <td>The argument is treated as a filename.
504             True if the file exists and is symlink</td><td>yes</td></tr>
505     <tr><td><code>-h</code></td>
506         <td>The argument is treated as a filename.
507             True if the file exists and is symlink
508             (same as <code>-L</code>)</td><td>yes</td></tr>
509     <tr><td><code>-F</code></td>
510         <td>True if string is a valid file, accessible via all the server's
511             currently-configured access controls for that path. This uses an
512             internal subrequest to do the check, so use it with care - it can
513             impact your server's performance!</td><td></td></tr>
514     <tr><td><code>-U</code></td>
515         <td>True if string is a valid URL, accessible via all the server's
516             currently-configured access controls for that path. This uses an
517             internal subrequest to do the check, so use it with care - it can
518             impact your server's performance!</td><td></td></tr>
519     <tr><td><code>-A</code></td>
520         <td>Alias for <code>-U</code></td><td></td></tr>
521     <tr><td><code>-n</code></td>
522         <td>True if string is not empty</td><td></td></tr>
523     <tr><td><code>-z</code></td>
524         <td>True if string is empty</td><td></td></tr>
525     <tr><td><code>-T</code></td>
526         <td>False if string is empty, "<code>0</code>", "<code>off</code>",
527             "<code>false</code>", or "<code>no</code>" (case insensitive).
528             True otherwise.</td><td></td></tr>
529     <tr><td><code>-R</code></td>
530         <td>Same as "<code>%{REMOTE_ADDR} -ipmatch ...</code>", but more
531         efficient
532         </td><td></td></tr>
533     </table>
534
535     <p>The operators marked as "restricted" are not available in some modules
536     like <module>mod_include</module>.</p>
537 </section>
538
539 <section id="functions">
540     <title>Functions</title>
541
542     <p>Normal string-valued functions take one string as argument and return
543     a string. Functions names are not case sensitive.
544     Modules may register additional functions.</p>
545
546     <table border="1" style="zebra">
547     <columnspec><column width=".2"/><column width=".4"/><column width=".4"/></columnspec>
548
549     <tr><th>Name</th><th>Description</th><th>Special notes</th></tr>
550     <tr><td><code>req</code>, <code>http</code></td>
551         <td>Get HTTP request header; header names may be added to the Vary
552             header, see below</td><td></td></tr>
553     <tr><td><code>req_novary</code></td>
554         <td>Same as <code>req</code>, but header names will not be added to the
555             Vary header</td><td></td></tr>
556     <tr><td><code>resp</code></td>
557         <td>Get HTTP response header (most response headers will not yet be set
558             during <directive>&lt;If&gt;</directive>)</td><td></td></tr>
559     <tr><td><code>reqenv</code></td>
560         <td>Lookup request environment variable (as a shortcut,
561         <code>v</code> can also be used to access variables). 
562         </td>
563         <td>ordering</td></tr>
564     <tr><td><code>osenv</code></td>
565         <td>Lookup operating system environment variable</td><td></td></tr>
566     <tr><td><code>note</code></td>
567         <td>Lookup request note</td><td>ordering</td></tr>
568     <tr><td><code>env</code></td>
569         <td>Return first match of <code>note</code>, <code>reqenv</code>,
570             <code>osenv</code></td><td>ordering</td></tr>
571     <tr><td><code>tolower</code></td>
572         <td>Convert string to lower case</td><td></td></tr>
573     <tr><td><code>toupper</code></td>
574         <td>Convert string to upper case</td><td></td></tr>
575     <tr><td><code>escape</code></td>
576         <td>Escape special characters in %hex encoding</td><td></td></tr>
577     <tr><td><code>unescape</code></td>
578         <td>Unescape %hex encoded string, leaving encoded slashes alone;
579             return empty string if %00 is found</td><td></td></tr>
580     <tr><td><code>base64</code></td>
581         <td>Encode the string using base64 encoding</td><td></td></tr>
582     <tr><td><code>unbase64</code></td>
583         <td>Decode base64 encoded string, return truncated string if 0x00 is
584             found</td><td></td></tr>
585     <tr><td><code>md5</code></td>
586         <td>Hash the string using MD5, then encode the hash with hexadecimal
587             encoding</td><td></td></tr>
588     <tr><td><code>sha1</code></td>
589         <td>Hash the string using SHA1, then encode the hash with hexadecimal
590             encoding</td><td></td></tr>
591     <tr><td><code>file</code></td>
592         <td>Read contents from a file (including line endings, when present)
593         </td><td>restricted</td></tr>
594     <tr><td><code>filemod</code></td>
595         <td>Return last modification time of a file (or 0 if file does not exist
596             or is not regular file)</td><td>restricted</td></tr>
597     <tr><td><code>filesize</code></td>
598         <td>Return size of a file (or 0 if file does not exist or is not
599             regular file)</td><td>restricted</td></tr>
600     <tr><td><code>ldap</code></td>
601         <td>Escape characters as required by LDAP distinguished name escaping
602             (RFC4514) and LDAP filter escaping (RFC4515).</td><td></td></tr>
603     <tr><td><code>replace</code></td>
604         <td>replace(string, "from", "to") replaces all occurrences of "from"
605             in the string with "to".</td><td></td></tr>
606
607     </table>
608
609     <p>The functions marked as "restricted" in the final column are not 
610     available in some modules like <module>mod_include</module>.</p>
611
612     <p>The functions marked as "ordering" in the final column require some
613     consideration for the ordering of different components of the server,
614     especially when the function is used within the 
615     &lt;<directive module="core">If</directive>&gt; directive which is
616     evaluated relatively early.</p>
617     <note>
618     <title>Environment variable ordering</title>
619     When environment variables are looked up within an 
620     &lt;<directive module="core">If</directive>&gt; condition, it's important 
621     to consider how extremely early in request processing that this 
622     resolution occurs. As a guideline, any directive defined outside of virtual host 
623     context (directory, location, htaccess) is not likely to have yet had a 
624     chance to execute. <directive module="mod_setenvif">SetEnvIf</directive>
625     in virtual host scope is one directive that runs prior to this resolution
626     <br/>
627     <br/>
628     When <code>reqenv</code> is used outside of &lt;<directive module="core"
629     >If</directive>&gt;, the resolution will generally occur later, but the 
630     exact timing depends on the directive the expression has been used within.
631     </note>
632
633     <p>When the functions <code>req</code> or <code>http</code> are used,
634     the header name will automatically be added to the Vary header of the
635     HTTP response, except where otherwise noted for the directive accepting
636     the expression. The <code>req_novary</code> function can be used to
637     prevent names from being added to the Vary header.</p>
638
639     <p>In addition to string-valued functions, there are also
640     list-valued functions which take one string as argument and return a
641     list, i.e. a list of strings. The list can be used with the
642     special <code>-in</code> operator.  Functions names are not case
643     sensitive.  Modules may register additional functions.</p>
644
645     <p>There are no built-in list-valued functions. <module>mod_ssl</module>
646     provides <code>PeerExtList</code>.  See the description of
647     <directive module="mod_ssl">SSLRequire</directive> for details
648     (but <code>PeerExtList</code> is also usable outside
649     of <directive module="mod_ssl">SSLRequire</directive>).</p>
650
651 </section>
652
653 <section id="examples">
654
655     <title>Example expressions</title>
656     <p>The following examples show how expressions might be used to
657     evaluate requests:</p>
658
659     <!-- This section should probably be extended with more, useful examples -->
660     <highlight language="config">
661 # Compare the host name to example.com and redirect to www.example.com if it matches
662 &lt;If "%{HTTP_HOST} == 'example.com'"&gt;
663     Redirect permanent "/" "http://www.example.com/"
664 &lt;/If&gt;
665
666 # Force text/plain if requesting a file with the query string contains 'forcetext'
667 &lt;If "%{QUERY_STRING} =~ /forcetext/"&gt;
668     ForceType text/plain
669 &lt;/If&gt;
670
671 # Only allow access to this content during business hours
672 &lt;Directory "/foo/bar/business"&gt;
673     Require expr %{TIME_HOUR} -gt 9 &amp;&amp; %{TIME_HOUR} -lt 17
674 &lt;/Directory&gt;
675
676 # Check a HTTP header for a list of values
677 &lt;If "%{HTTP:X-example-header} in { 'foo', 'bar', 'baz' }"&gt;
678     Header set matched true
679 &lt;/If&gt;
680
681 # Check an environment variable for a regular expression, negated.
682 &lt;If "! reqenv('REDIRECT_FOO') =~ /bar/"&gt;
683     Header set matched true
684 &lt;/If&gt;
685
686 # Check result of URI mapping by running in Directory context with -f
687 &lt;Directory "/var/www"&gt;
688     AddEncoding x-gzip gz
689 &lt;If "-f '%{REQUEST_FILENAME}.unzipme' &amp;&amp; ! %{HTTP:Accept-Encoding} =~ /gzip/"&gt;
690       SetOutputFilter INFLATE
691 &lt;/If&gt;
692 &lt;/Directory&gt;
693
694 # Check against the client IP
695 &lt;If "-R '192.168.1.0/24'"&gt;
696     Header set matched true
697 &lt;/If&gt;
698
699 # Function examples in boolean context
700 &lt;If "md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8'"&gt;
701   Header set checksum-matched true
702 &lt;/If&gt;
703 &lt;If "md5('foo') == replace('md5:XXXd18db4cc2f85cedef654fccc4a4d8', 'md5:XXX', 'acb')"&gt;
704   Header set checksum-matched-2 true
705 &lt;/If&gt;
706
707 # Function example in string context
708 Header set foo-checksum "expr=%{md5:foo}"
709
710 # This delays the evaluation of the condition clause compared to &lt;If&gt;
711 Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path\.php$#"
712
713 # Add a header to forward client's certificate SAN to some backend
714 RequestHeader set X-Client-SAN "expr=%{:join PeerExtList('subjectAltName'):}"
715
716 # Require that the remote IP be in the client's certificate SAN
717 Require expr %{REMOTE_ADDR} -in split s/.*?IP Address:([^,]+)/$1/, PeerExtList('subjectAltName')
718 # or alternatively:
719 Require expr "IP Address:%{REMOTE_ADDR}" -in split/, /, join PeerExtList('subjectAltName')
720
721 # Conditional logging
722 CustomLog logs/access-errors.log common "expr=%{REQUEST_STATUS} >= 400"
723 CustomLog logs/access-errors-specific.log common "expr=%{REQUEST_STATUS} -in {'405','410'}"
724
725     </highlight>
726 </section>
727
728 <section id="other">
729     <title>Other</title>
730
731     <table border="1" style="zebra">
732     <columnspec><column width=".2"/><column width=".2"/><column width=".6"/></columnspec>
733
734     <tr><th>Name</th><th>Alternative</th> <th>Description</th></tr>
735     <tr><td><code>-in</code></td>
736         <td><code>in</code></td>
737         <td>string contained in list</td></tr>
738     <tr><td><code>/regexp/</code></td>
739         <td><code>m#regexp#</code></td>
740         <td>Regular expression (the second form allows different
741         delimiters than /)</td></tr>
742     <tr><td><code>/regexp/i</code></td>
743         <td><code>m#regexp#i</code></td>
744         <td>Case insensitive regular expression</td></tr>
745     <tr><td><code>$0 ... $9</code></td>
746         <td></td>
747         <td>Regular expression backreferences</td></tr>
748     </table>
749
750     <section id="rebackref">
751         <title>Regular expression backreferences</title>
752         <p>The strings <code>$0</code> ... <code>$9</code> allow to reference
753         the capture groups from a previously executed, successfully
754         matching regular expressions. They can normally only be used in the
755         same expression as the matching regex, but some modules allow special
756         uses.</p>
757     </section>
758
759 </section>
760
761 <section id="sslrequire">
762     <title>Comparison with SSLRequire</title>
763     <p>The <em>ap_expr</em> syntax is mostly a superset of the syntax of the
764     deprecated <directive module="mod_ssl">SSLRequire</directive> directive.
765     The differences are described in <directive
766     module="mod_ssl">SSLRequire</directive>'s documentation.</p>
767 </section>
768
769 <section id="compatibility">
770     <title>Version History</title>
771     <p>The <code>req_novary</code> <a href="#functions">function</a>
772     is available for versions 2.4.4 and later.</p>
773     <p>The <code>SERVER_PROTOCOL_VERSION</code>,
774     <code>SERVER_PROTOCOL_VERSION_MAJOR</code> and
775     <code>SERVER_PROTOCOL_VERSION_MINOR</code>
776     <a href="#vars">variables</a>
777     are available for versions 2.5.0 and later.</p>
778 </section>
779
780 </manualpage>