Commit 2c2cf2a9 authored by Yann Ylavic's avatar Yann Ylavic
Browse files

Follow up to r1810605.

Update docs' BNF, provide a short description of the new %{::} syntax and
a few examples. To be continued..



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1811111 13f79535-47bb-0310-9956-ffa450edef68
parent e49e068b
Loading
Loading
Loading
Loading
+93 −29
Original line number Diff line number Diff line
@@ -79,29 +79,41 @@
      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.
      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
      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>
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
              | "<strong>(</strong>" cond "<strong>)</strong>"

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>in</strong>" "<strong>{</strong>" list "<strong>}</strong>"


stringcomp  ::= word "<strong>==</strong>" word
@@ -118,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

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>'
              | word "<strong>.</strong>" word
              | variable
              | rebackref
              | sub
              | join
              | 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
              | rebackref

cstring     ::= ...
digit       ::= [0-9]+

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>" wordlist "<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>

@@ -335,6 +376,21 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"
    <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 id="binop">
@@ -582,7 +638,7 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"

    <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
    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>

@@ -654,6 +710,14 @@ 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')

    </highlight>
</section>

@@ -666,7 +730,7 @@ Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path
    <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 wordlist</td></tr>
        <td>string contained in list</td></tr>
    <tr><td><code>/regexp/</code></td>
        <td><code>m#regexp#</code></td>
        <td>Regular expression (the second form allows different