From: Yann Ylavic expr.
- However, a few directives like LogMessage accept expressions
+ 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
@@ -92,35 +105,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 "(" wordlist ")"
+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">
@@ -296,6 +338,21 @@ listfunction ::= listfuncname "(" word ")"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.
-in operator. Functions names are not case
sensitive. Modules may register additional functions.
@@ -598,7 +655,15 @@ listfunction ::= listfuncname "(" word ")"
+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')
| Name | Alternative | Description |
|---|---|---|
-in |
in |
- string contained in wordlist | string contained in list |
/regexp/ |
m#regexp# |
Regular expression (the second form allows different
diff --git a/docs/manual/expr.html.fr b/docs/manual/expr.html.fr
index 3ec79b89959..da88c99007c 100644
--- a/docs/manual/expr.html.fr
+++ b/docs/manual/expr.html.fr
@@ -26,6 +26,8 @@
+ Cette traduction peut être périmée. Vérifiez la version
+ anglaise pour les changements récents.
Historiquement, il existe de nombreuses variantes dans la syntaxe
des expressions permettant d'exprimer une condition dans les
diff --git a/docs/manual/expr.xml.fr b/docs/manual/expr.xml.fr
index f1c563da9cf..9cdb9b3ba6f 100644
--- a/docs/manual/expr.xml.fr
+++ b/docs/manual/expr.xml.fr
@@ -1,7 +1,7 @@
-
+
diff --git a/docs/manual/expr.xml.meta b/docs/manual/expr.xml.meta
index d5a2e5e1a51..ea324a8bb25 100644
--- a/docs/manual/expr.xml.meta
+++ b/docs/manual/expr.xml.meta
@@ -8,6 +8,6 @@
|