CommandBox's server rules are based directly on the "Predicate Language" feature of JBoss Undertow. All of the official documentation for Undertow's predicate language applies to CommandBox. CommandBox doesn't limit the power of what Undertow provides at all. In fact, we give you some additional out-of-the box predicates and handlers you can use.
There are three concepts you need to understand and you'll be writing your own rules in no time.
Handler - A wrapper around the request that takes some sort of action such as returning a status code or rewriting the request.
Predicate - A conditional that evaluates to true or false. Used to Conditionally apply a handler
Exchange Attribute - An abstracted way to refer to any piece of information about the request or response. Can include URL, query string, cookies, headers, or CGI variables.
Since the parsing of your rules is handled by Undertow, it is case sensitive in many areas and CommandBox cannot control this. The following must always be lower case:
Predicate names
Handler names
Parameter names
Keywords like and
, or
, else
The full undertow docs can be found here: https://undertow.io/undertow-docs/undertow-docs-2.0.0/
A handler will take action on the request. This can redirect the request, rewrite it, abort it, or modify attributes of the request such as setting an HTTP header or status code. If the predicate is omitted, the handler will always fire for all requests. Ex:
set() - Sets an exchange attribute (see below)
rewrite() - Rewrite the request URL
redirect() - Redirect to another URL
header() - Sets an HTTP response header
set-error() - Set HTTP response code and returns the corresponding error page
ip-access-control() - Configure IP-based allow/deny rules (wildcards and IP ranges allowed)
done - Skips remaining rules
request-limit() - Limits concurrent requests
restart - Restarts process back at start of predicate rule chain (combine with rewrite, etc)
load-balanced-proxy() - Creates a round robin reverse proxy to a list of URLs
allowed-methods() / disallowed-methods() - Enforces whitelist/blacklist of HTTP methods on current request
A handler is called using the “name” from the docs and passing any required parameters. Params can be named or positional (if there is only one). Quoting values is only required if they have a space, comma or brace. The following are all equivalent:
Handler parameters that accept an array use the Java array literal syntax which is a comma-delimited list of values in curly braces.
More than one handler can be run by wrapping them in curly braces and using semicolons between them
A chain of handlers can be configured for the true AND false evaluation of a single predicate using the “else” keyword.
A predicate is a condition that must be matched for the handler to kick in. If using path-based predicates on Windows, make sure to use the -nocase
version for security rules since your file system is not case sensitive.
path()/path-nocase() - match the incoming request path
path-suffix()/path-suffix-nocase() - match full file/folder names at the end of the path like file.cfm
path-prefix()/path-prefix-nocase() - match full file/folder names at the start of the path like /lucee/admin
method() - Match the HTTP method
regex()/regex-nocase() - Match a regular expression against any exchange attribute
equals()/equals-nocase() and contains()/contains-nocase() - Do a text compare on any exchange attribute
path-template() - match a path with placeholders like /foo/{bar}
and the placeholders become variables for use in later predicates or handlers in the chain.
A predicate is called by placing parentheses after the name and passing in the required arguments as specified in the docs for that predicate. Quoting values is only required if they have a space, comma or brace. The following are all equivalent:
Complex conditions can be constructed with more than one predicate using the keywords “and” or “or”.
A predicate can be negated with the keyword “not”
Exchange attributes are an abstraction Undertow provides to reference any part of the HTTP request or response. There is a textual placeholder that can be used in predicates and handlers that will be expanded in-place.
%{REMOTE_IP} - Remote IP address
%{PROTOCOL} - Request protocol
%{METHOD} - Request method
%{REMOTE_USER} - Remote user that was authenticated
%{RESPONSE_TIME} - Time taken to process the request, in ms
%{c,cookie_name} - Any cookie value
%{q,query_param_name} - Any query parameter
%{i,request_header_name} - Any request header
%{o,response_header_name} - Any response header
${anything-here} - Any value from the predicate context (such as regex capture groups or path-template placeholders)
Use an exchange attribute like you would a variable as the parameter to a handler or predicate.
Attributes, Cookie, query params, request headers, and response header names are not case sensitive.
These are all equivalent: