Actions
Actions are the command lines inside `{ ... }`. In YAML, the same commands go in `do:`.
Action Execution Rules
- Actions execute in declaration order.
- Termination is explicit by command semantics (not inferred from status changes).
- Commands are internally split by phase:
PhasePrecommands run in pre.PhasePostcommands run in post.PhasePre|PhasePostcan happen in nested/compound bodies.
- If a pre command terminates, later pre commands are skipped.
- Post-only commands can still run in post phase.
status/resp_headermatcher rules are always evaluated in post phase.
Available Actions
| Action | Arguments | Terminating | Description | Example |
|---|---|---|---|---|
upstream/pass/bypass | true | Call upstream and terminate pre-phase | bypass | |
require_auth | false | Require authentication (handler-dependent behavior) | require_auth | |
middleware | <name> option block | conditional | Run the request phase of a built-in or composed middleware | See middleware |
rewrite | <from> <to> | false | Rewrite request path | rewrite /api/ /backend/ |
serve | <path> | true | Serve static files/directory | serve /static |
handle | <name> | true | Dispatch request to a registered in-process HTTP handler | handle api |
proxy | <url | path> | true | Proxy request to absolute or relative path | proxy http://backend:8080 |
route | <route_name> | true | Route request to another route | route app-backend |
redirect | <url | path> | true | Redirect to absolute or relative path | redirect /login |
error | <status> <template> | true | Return error response | error 403 "Forbidden" |
require_basic_auth | <realm> | true | Set WWW-Authenticate header and return 401 | require_basic_auth "Admin" |
serve_file | <path> | true | Serve one local file | serve_file /static/favicon.ico |
set | <field> <key> <template> | false | Set field value (header, resp_header, query, cookie, body, resp_body, status) | set header X-Custom value |
add | <field> <key> <template> | false | Add value to field | add header X-Custom value |
remove | <field> <key> | false | Remove field key | remove header X-Custom |
log | <level> <path> <template> | false | Log message | log info /dev/stdout "$req_method $status_code" |
notify | <level> <service_name> <title> <body> | false | Send notification | notify info ntfy "Request" "$req_method $status_code" |
middleware
A middleware <name> { ... } action runs the request phase of a built-in or
composed middleware at that point in rule execution. It continues to the next action
when the middleware permits the request. If the middleware handles the request
and stops the chain, later actions and the rule fallback do not run.
Only middleware with a request phase is supported. Response-only middleware,
such as ModifyResponse, is rejected when the rules are loaded. The name in the
block header selects the middleware. The block contains that middleware's
configuration properties and may include nested lists and mappings.
Use this action only in request-phase rules and action blocks. A status or
resp_header matcher is evaluated after the response is available. A nested
action block containing response-phase actions is also scheduled after the
response. Both cases are too late for request middleware and are rejected.
default {
middleware CloudflareRealIP {
}
}
To configure middleware properties directly in a rule:
default {
middleware RealIP {
header: CF-Connecting-IP
from:
- 173.245.48.0/20
}
}Named Option Blocks
Every action can also be written as a command block. Its header contains the command name followed by any header arguments owned by that command. The YAML-like property body is also defined and validated by the command. For scalar commands, the property names correspond to the arguments shown in the table above.
path /api {
rewrite {
from: /api
to: /backend
}
notify {
level: info
provider: ntfy
title: API request
body: "$req_method $req_url $status_code"
}
}Rules for command blocks:
- Each command owns its header arguments and accepted property shapes.
- Scalar command blocks do not take header arguments. All declared properties must be present.
- Unknown or duplicate property names are rejected.
- Scalar property values must be strings, numbers, booleans, or null unless the command accepts structured data. Middleware configuration, for example, may contain nested lists and mappings.
log example
log info /dev/stdout "$req_method $req_url $status_code"notify example
notify info ntfy "Request received" "$req_method $status_code"Equivalent named-option form:
notify {
level: info
provider: ntfy
title: Request received
body: "$req_method $status_code"
}handle example
path glob("/api/v1/*") {
handle api
}Use handle when the target is an HTTP handler already registered inside GoDoxy itself. For external services, keep using proxy.
*log/notify run in pre or post depending on variables used in template (for example $status_code requires post phase).
Template Variables
Template variables can be used in error, log, notify, set, add, body, and resp_body commands. Variables are expanded at runtime using the syntax $variable_name or $function_name(args).
Static Variables
Static variables provide information about the request, response, and upstream service.
| Variable | Description | Example Value |
|---|---|---|
| Request Information | ||
$req_method | HTTP request method | GET, POST, PUT, etc. |
$req_scheme | Request scheme | http or https |
$req_host | Request host without port | example.com |
$req_port | Request port | 80, 443, 8080 |
$req_addr | Request host with port | example.com:443 |
$req_path | Request path | /api/users |
$req_query | Query string (raw) | id=123&sort=desc |
$req_url | Full request URL | http://example.com/api/users?id=123 |
$req_uri | Request URI (path + query) | /api/users?id=123 |
$req_content_type | Request content type | application/json |
$req_content_length | Request content length | 1024 |
| Remote Client Information | ||
$remote_host | Client IP address | 192.168.1.1 |
$remote_port | Client port | 54321 |
$remote_addr | Client address with port | 192.168.1.1:54321 |
| Response Information | ||
$status_code | HTTP response status code | 200, 404, 500 |
$resp_content_type | Response content type | application/json, text/html |
$resp_content_length | Response content length | 2048 |
| Upstream Service Information | ||
$upstream_name | Upstream route name | api-backend |
$upstream_scheme | Upstream scheme | http or https |
$upstream_host | Upstream host | backend.internal |
$upstream_port | Upstream port | 8080 |
$upstream_addr | Upstream host with port | backend.internal:8080 |
$upstream_url | Upstream URL | http://backend.internal:8080 |
Dynamic Variables (Functions)
Dynamic variables accept arguments and can extract specific values from headers, cookies, query parameters, and form data.
Functions support composition: the result of one function can be passed as the argument to another. For example:
# Redact the Authorization header value in logs
log info /dev/stdout "Auth: $redacted($header(Authorization))"Request Headers: $header(name) or $header(name, index)
Extract header values from the request.
-
Arguments:
name(required): Header name (case-sensitive)index(optional): Index in the header value list (default: 0)
-
Example:
$header(User-Agent)→Mozilla/5.0...$header(Accept, 0)→text/html
Response Headers: $resp_header(name) or $resp_header(name, index)
Extract header values from the response.
-
Arguments:
name(required): Header name (case-sensitive)index(optional): Index in the header value list (default: 0)
-
Example:
$resp_header(Content-Type)→application/json$resp_header(Set-Cookie, 0)→session_id=abc123
Cookies: $cookie(name) or $cookie(name, index)
Extract cookie values from the request.
-
Arguments:
name(required): Cookie nameindex(optional): Index in the cookie value list (default: 0)
-
Example:
$cookie(session_id)→abc123$cookie(preferences, 0)→dark_mode
Query Parameters: $arg(name) or $arg(name, index)
Extract query parameter values.
-
Arguments:
name(required): Parameter nameindex(optional): Index in the parameter value list (default: 0)
-
Example:
$arg(page)→1$arg(filter, 0)→active
Form Fields: $form(name) or $form(name, index)
Extract form field values with query parameter fallback. Searches in these sources (from req.Form):
-
POST/PUT/PATCH form body (
application/x-www-form-urlencodedandmultipart/form-data) -
Query parameters
-
Arguments:
name(required): Field nameindex(optional): Index in the field value list (default: 0)
-
Example:
$form(username)→john_doe$form(tags, 1)→backend(second tag)
POST Form Fields: $postform(name) or $postform(name, index)
Extract form field values from POST/PUT/PATCH request bodies only (no query parameter fallback). Only matches application/x-www-form-urlencoded format.
-
Arguments:
name(required): Field nameindex(optional): Index in the field value list (default: 0)
-
Example:
$postform(action)→ matches only form field, not query parameter
Redact: $redacted(value)
Mask a sensitive value, showing only the first 2 and last 2 characters with asterisks in between.
-
Arguments:
value(required): A literal string or the result of another dynamic variable function
-
Example:
$redacted(mysecrettoken)→my*********en$redacted($header(Authorization))→Be************ne(redacts the Authorization header value)$redacted($cookie(session_id))→ab****23
Variable Examples
Complete examples showing how to use variables in different commands:
# Logging with request and response information
log info /dev/stdout "Method=$req_method Path=$req_path Status=$status_code"
# Logging with headers (redacting sensitive values)
log info /dev/stdout "User-Agent=$header(User-Agent) Auth=$redacted($header(Authorization))"
# Logging with response headers
log info /dev/stdout "Content-Type=$resp_header(Content-Type) Content-Length=$resp_content_length"
# Notifications with request context
notify info ntfy "New request" "From $remote_host to $req_host at $req_path"
# Setting headers with upstream information
set header X-Upstream-URL $upstream_url
set header X-Request-Path $req_path
# Body modifications with request info
set body "Status: $status_code for $req_method $req_path"
# Response body with request and response info
set resp_body "Request: $req_method $req_url\nResponse: $status_code"