GoDoxy
Advanced TopicsRule-Based Routing

Conditions

Conditions are used to match the request and determine if the rule should be applied.

In block syntax, conditions are written in the rule header (before { ... }). In YAML, the same expression is written in on:. Conditions can be combined using logical operators.

Logical Operators

OperatorDescriptionExample
|OR - Any condition can matchheader X-API-Key | header Authorization
& or \nAND - All conditions must matchmethod GET & path /api/*

Syntax

<condition> <args> [[ | <condition> <args> ] [ & <condition> <args> ]]...

Available Conditions

ConditionArgumentsDescriptionExample
header<name> <pattern>Match when request header matches patternheader Content-Type application/json, header X-API-Key regex("^sk-.*")
header<name>Match when header exists (any value)header X-API-Key
query<name> <pattern>Match when query parameter matches patternquery debug true, query id regex("^[a-f0-9-]{36}$")
query<name>Match when query parameter existsquery debug
cookie<name> <pattern>Match when cookie matches patterncookie session_id abc123, cookie token glob("sess_*")
cookie<name>Match when cookie existscookie session_id
form<name> <pattern>Match when form field matches patternform action submit, form email regex("^[^@]+@[^@]+$")
form<name>Match when form field existsform action
postform<name> <pattern>Match when POST form field matches patternpostform action submit, postform file glob("*.pdf")
postform<name>Match when POST form field existspostform action
proto<http | https | h1 | h2 | h2c | h3>Match when protocol equals valueproto h2
method<method>Match when HTTP method equals valuemethod POST
host<pattern>Match when host matches patternhost example.com, host glob(*.example.com), host regex("^[a-z]+-prod\.com$")
path<pattern>Match when path matches patternpath /version, path glob(/api/*), path regex("^/api/v[0-9]+/.*)
remote<ip | cidr>Match when client IP matches CIDR rangeremote 192.168.1.0/24
route<pattern>Match when route name matches patternroute api, route glob(api-*)
basic_auth<username> <hashed_password>Match when basic auth credentials matchbasic_auth admin $2y$10$...
status<status>Match when status code matches valuestatus 200, status 200-300, status 2xx
resp_header<name> <pattern>Match when response header matches patternresp_header Content-Type application/json, resp_header X-API-Key regex("^sk-.*")
resp_header<name>Match when response header existsresp_header Content-Type

Form Field Conditions

Both form and postform conditions match form field values, but they resolve values differently:

postform Precedence Order

  • Matches request body form fields only (no query-string fallback)

form Precedence Order

  1. Form body fields (POST/PUT/PATCH, urlencoded or multipart)
  2. Query parameters (fallback)

Example

# For POST /example?action=query with body action=form
postform action form     # Matches body value only
form action form         # Matches form value first; query can be fallback

Basic Authentication

For basic_auth conditions, the password must be bcrypt hashed. Generate the hash using:

htpasswd -nbB '' your-password | cut -c 2-

Basic Auth Concept

To protect a resource, you need to:

  • Require basic authentication by default
  • Allow specific users to pass through (or proxy to another service) with valid credentials

Example Basic Auth Rule

default {
  require_basic_auth "Restricted Area"
}

basic_auth user1 "$2y$10$..." | basic_auth user2 "$2y$10$..." {
  pass
}

Path Pattern Syntax

The path condition supports three types of patterns for matching request paths:

String Matching

path /api/users # Exact match for /api/users

Glob Patterns

Glob patterns use the following syntax based on the github.com/gobwas/glob library:

PatternDescriptionExampleMatchesNon-matches
*Any sequence of non-separator characters/api/*/api/users, /api/posts/api/users/123, /api/v1/users
**Any sequence of characters (including separators)/static/**/static/css/style.css, /static/js/app.js-
?Any single non-separator character/file?.txt/file1.txt, /fileA.txt/file12.txt, /file/abc.txt
[abc]Character class (match any listed character)/file[123].txt/file1.txt, /file2.txt, /file3.txt/file4.txt, /fileA.txt
[!abc]Negated character class (match any except listed)/file[!123].txt/fileA.txt, /fileB.txt/file1.txt, /file2.txt, /file3.txt
[a-z]Character range (match any in range)/file[a-z].txt/filea.txt, /filem.txt, /filez.txt/fileA.txt, /file1.txt
[0-9]Numeric range/v[0-9]/api/v1/api, /v5/api, /v9/api/v10/api, /va/api
{a,b,c}Pattern alternatives (comma-separated)/api/{users,posts,comments}/api/users, /api/posts, /api/comments/api/products, /api/users/123
\*Literal asterisk (escaped)/file\*.txt/file*.txt/fileabc.txt, /file123.txt
\?Literal question mark (escaped)/file\?.txt/file?.txt/filea.txt, /file1.txt

Advanced Glob Examples

# Match common web asset files
path glob("/static/**/*.{css,js,png,jpg,jpeg,gif,svg}")

# Match versioned API paths
path glob("/api/v[0-9]/*")

# Match UUID patterns (simplified)
path glob("/users/[a-f0-9-]*/profile")

# Match date-based paths
path glob("/logs/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/*")

# Match file extensions with character classes
path glob("/uploads/*.{[Pp][Dd][Ff],[Dd][Oo][Cc][Xx]}")

# Exclude specific patterns with negated character classes
path glob("/images/[!_]*")  # Exclude files starting with underscore

Regular Expressions

path regex("^/api/v[0-9]+/users/[a-f0-9-]{36}$")  # Match specific UUID pattern
path regex("^/files/[0-9]{4}-[0-9]{2}-[0-9]{2}$")  # Match date pattern

On this page