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 | |
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" |
Named Option Blocks
Every action can also be written as a command block with named YAML options. The option names are the same arguments shown in the table above, in positional order. GoDoxy flattens the mapping into the normal positional argument list and then runs the same action validator, so behavior is identical to the inline form.
path /api {
rewrite {
from: /api
to: /backend
}
notify {
level: info
provider: ntfy
title: API request
body: "$req_method $req_url $status_code"
}
}Rules for option blocks:
- Do not mix inline arguments with named options. Use either
notify info ntfy "title" "body"ornotify { ... }, notnotify info ntfy { ... }. - All declared arguments for that command must be present.
- Unknown or duplicate option names are rejected.
- Option values must be scalar strings, numbers, booleans, or null.
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"