Configuration: conditionals and variables
This page describes how to define and use conditional matchers in Ferron configuration. Named matchers let you apply configuration selectively based on request properties. The matcher system is part of the http-server module’s request resolution pipeline.
Named matchers
Named matchers are declared with match <name> { ... } and referenced by if <name> { ... } or if_not <name> { ... } inside host blocks.
match curl_client {
request.header.user_agent ~ "curl"
}
example.com {
if curl_client {
# Configuration for curl clients
}
}Language matching example:
match english_language {
"en" in request.header.accept_language
}
example.com {
if english_language {
root "/var/www/english"
}
}Operators
The following operators are available inside match blocks:
| Operator | Meaning |
|---|---|
== | String equality |
!= | String inequality |
~ | Regex match |
!~ | Negated regex match |
in | Left value must equal one of the comma-separated items in the right value, or match a language in an Accept-Language header |
Notes:
insplits the right-hand string on commas and trims each item.- When the right value looks like an
Accept-Languageheader (contains quality values or multiple language ranges),inperforms language matching with support for base language codes (e.g.enmatchesen-US). - All expressions inside a single
matchblock must pass (AND semantics).
Built-in variables
The HTTP resolver exposes these variables for use in match blocks and interpolation ({{...}}):
| Variable | Value |
|---|---|
request.method | HTTP method (e.g. GET, POST) |
request.uri.path | Request path |
request.uri.query | Query string, or empty string |
request.uri | Full request URI |
request.version | HTTP version string (e.g. HTTP/1.1) |
request.header.<name> | Request header value |
request.host | Resolved request hostname |
request.scheme | http or https |
request.path_info | Extra path info after a script match (e.g. /test in /index.php/test), or empty |
server.ip | Local listener IP address |
server.port | Local listener port |
remote.ip | Client IP address |
remote.port | Client port |
Header names are normalized by lowercasing them and converting _ to -. For example, request.header.x_forwarded_for reads the x-forwarded-for header.
IP canonicalization
The server.ip and remote.ip variables automatically canonicalize IPv4-mapped IPv6 addresses (::ffff:x.x.x.x) to their IPv4 form. For example, if the client connects via ::ffff:192.0.2.1, remote.ip returns 192.0.2.1.
Interpolated strings
Interpolated strings use {{name}} syntax:
{{env.NAME}}reads theNAMEenvironment variable.- Other interpolation variables depend on the consumer of that directive.
- If a variable cannot be resolved, the placeholder is kept as
{{name}}.
For startup-only TLS settings such as cert and key, the bundled manual TLS provider relies on plain strings or env.* interpolation.
Related directives
if— applies a block when a named matcher evaluates to trueif_not— applies a block when a named matcher evaluates to falselocation— path-based matching
Notes and troubleshooting
- All expressions inside a single
matchblock must pass (AND semantics). - If a variable cannot be resolved, the placeholder is kept as
{{name}}. - For URL rewriting with regex, see URL rewriting.
- For HTTP response control with regex matching, see HTTP response control.