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 request resolution pipeline of the http-server module.

Info

For URL rewriting with regex, see URL rewriting. For HTTP response control with regex matching, see HTTP response control.

Named matchers⁠#

Declare a named matcher with match <name> { ... }. Inside a host block, reference it with if <name> { ... } or if_not <name> { ... }.

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:

OperatorMeaning
==String equality
!=String inequality
~Regex match
!~Negated regex match
inLeft value must equal one of the comma-separated items in the right value, or match a language in an Accept-Language header
Note
  • in splits the right-hand string on commas and trims each item.
  • When the right value looks like an Accept-Language header, in matches by base language code. For example, en matches en-US.
  • The header contains quality values or multiple language ranges.
Note

All expressions inside one match block must pass (AND semantics). If Ferron cannot resolve a variable, it keeps the placeholder as {{name}}.

Built-in variables⁠#

The HTTP resolver exposes these variables for use in match blocks and interpolation ({{...}}):

VariableValue
request.methodHTTP method (for example GET, POST)
request.uri.pathRequest path
request.uri.queryQuery string, or empty string
request.uri.query.<param>URL-decoded query parameter value, if present
request.uriFull request URI
request.versionHTTP version string (for example HTTP/1.1)
request.header.<name>Request header value
request.cookie.<name>URL-decoded HTTP cookie value, if present
request.hostResolved request hostname
request.schemehttp or https
request.path_infoExtra path info after a script match (for example /test in /index.php/test), or empty
server.ipLocal listener IP address
server.portLocal listener port
remote.ipClient IP address
remote.portClient port
auth.userAuthenticated user, if any
trace.idTrace ID, if available
trace.spanidSpan ID, if available
mtls.cnClient certificate common name, if available

Ferron normalizes header names 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 the NAME environment variable.
  • Other interpolation variables depend on the consumer of that directive.
  • If Ferron cannot resolve a variable, it keeps the placeholder as {{name}}.

For startup-only TLS settings such as cert and key, the bundled manual TLS provider relies on plain strings or env.* interpolation.

  • if: applies a block when a named matcher evaluates to true
  • if_not: applies a block when a named matcher evaluates to false
  • location: path-based matching