GoDoxy
Advanced TopicsRule-Based Routing

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:
    • PhasePre commands run in pre.
    • PhasePost commands run in post.
    • PhasePre|PhasePost can 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_header matcher rules are always evaluated in post phase.

Available Actions

ActionArgumentsTerminatingDescriptionExample
upstream/pass/bypasstrueCall upstream and terminate pre-phasebypass
require_authfalseRequire authentication (handler-dependent behavior)require_auth
rewrite<from> <to>falseRewrite request pathrewrite /api/ /backend/
serve<path>trueServe static files/directoryserve /static
handle<name>trueDispatch request to a registered in-process HTTP handlerhandle api
proxy<url | path>trueProxy request to absolute or relative pathproxy http://backend:8080
route<route_name>trueRoute request to another routeroute app-backend
redirect<url | path>trueRedirect to absolute or relative pathredirect /login
error<status> <template>trueReturn error responseerror 403 "Forbidden"
require_basic_auth<realm>trueSet WWW-Authenticate header and return 401require_basic_auth "Admin"
serve_file<path>trueServe one local fileserve_file /static/favicon.ico
set<field> <key> <template>falseSet field value (header, resp_header, query, cookie, body, resp_body, status)set header X-Custom value
add<field> <key> <template>falseAdd value to fieldadd header X-Custom value
remove<field> <key>falseRemove field keyremove header X-Custom
log<level> <path> <template>falseLog messagelog info /dev/stdout "$req_method $status_code"
notify<level> <service_name> <title> <body>falseSend notificationnotify 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" or notify { ... }, not notify 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.

VariableDescriptionExample Value
Request Information
$req_methodHTTP request methodGET, POST, PUT, etc.
$req_schemeRequest schemehttp or https
$req_hostRequest host without portexample.com
$req_portRequest port80, 443, 8080
$req_addrRequest host with portexample.com:443
$req_pathRequest path/api/users
$req_queryQuery string (raw)id=123&sort=desc
$req_urlFull request URLhttp://example.com/api/users?id=123
$req_uriRequest URI (path + query)/api/users?id=123
$req_content_typeRequest content typeapplication/json
$req_content_lengthRequest content length1024
Remote Client Information
$remote_hostClient IP address192.168.1.1
$remote_portClient port54321
$remote_addrClient address with port192.168.1.1:54321
Response Information
$status_codeHTTP response status code200, 404, 500
$resp_content_typeResponse content typeapplication/json, text/html
$resp_content_lengthResponse content length2048
Upstream Service Information
$upstream_nameUpstream route nameapi-backend
$upstream_schemeUpstream schemehttp or https
$upstream_hostUpstream hostbackend.internal
$upstream_portUpstream port8080
$upstream_addrUpstream host with portbackend.internal:8080
$upstream_urlUpstream URLhttp://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 name
    • index (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 name
    • index (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-urlencoded and multipart/form-data)

  • Query parameters

  • Arguments:

    • name (required): Field name
    • index (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 name
    • index (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"

On this page