Files
RustProxy/docs/CUSTOM_LOCATIONS.md
T
2026-10-03 00:27:09 +01:00

5.7 KiB

Custom locations

RustProxy 0.22.3 supports the common location-level controls that are typically used for application reverse proxies. The UI intentionally exposes a safe subset instead of accepting arbitrary Nginx configuration text.

Routing model in 0.16.0

The vhost's main backend pool is an internal fallback and is not one of the Custom locations. Custom locations are optional overrides only. Request routing is therefore:

exact custom location
-> priority/regex/prefix custom location according to the documented precedence
-> main vhost backend pool

An empty Custom locations list is valid. Adding /test, a regex, a local response or a dedicated-backend location cannot disable /, /abc or other unmatched paths. Older saved documents that contain the former untouched synthetic root prefix / entry are normalized automatically. If / was deliberately customized with a backend, cache/ACL/header rule, rewrite or local response, it remains a real Custom location and intentionally overrides the main fallback.

Dashboard editor

The visual editor is the primary workflow. Every location card now shows a live Effective behavior preview at the bottom with the match mode/pattern, proxy or local-response action, selected backend, rewrite behavior, cache policy, ACL composition and request/response header-rule counts. The preview is calculated from the unsaved form state so an administrator can verify intent before saving.

Request and response header rules use numbered visual cards with localized Operation / Header name / Header value controls. Set, Append and Remove are supported. The Advanced JSON view remains available for automation/copy-paste, but is no longer required for normal editing. The documentation button in the location tab explains precedence, rewrites, local responses, policy composition and common examples.

Match modes

Each location has an ID, a pattern and one match mode:

RustProxy mode Nginx-style equivalent Behaviour
prefix location /path/ Longest matching path prefix. A matching regex may still win.
prefix_priority location ^~ /path/ Longest prefix and, when selected, skips regex locations.
exact location = /path Exact normalized path only. Exact matches have highest priority.
regex location ~ pattern Case-sensitive Rust regular expression. Regex locations are tested in configuration order.
regex_insensitive location ~* pattern Case-insensitive Rust regular expression. Regex locations are tested in configuration order.

Routing and ACL checks collapse repeated literal slashes, matching Nginx's usual merge_slashes on behaviour. For example /static/js//events.js is routed as /static/js/events.js. Unless a rewrite is configured, the original request target is still sent to the backend.

Encoded separators (%2f, %5c), encoded %, dot segments and other ambiguous path forms are still rejected instead of being silently normalized.

Actions

A location can either proxy to a backend or return a local response.

Proxy

The location can use the vhost pool or pin traffic to one backend. A dedicated backend can be created from the location editor. Cache policy can inherit from the vhost or be explicitly enabled/disabled for the location.

Supported path transformations:

  • Preserve — send the original client path unchanged.
  • Strip prefix — remove the matched prefix before proxying.
  • Replace prefix — replace the matched prefix with another normalized path prefix.
  • Regex rewrite — available for regex locations; Rust regex captures can be referenced as $1 or ${1} in the replacement.

The query string is preserved. Rewrites change only the upstream path; cache identity remains based on the public client URL.

Local response

Return custom response is the equivalent of a simple Nginx return: choose an HTTP status from 200 through 599, a Content-Type and a response body. RustProxy does not open a backend connection for this action. HEAD, 204 and 304 responses do not send a body.

For a redirect, use a 3xx status and add a Location response header in the visual header configurator.

Request and response headers

Every location has a visual header configurator and an Advanced JSON view. Both edit the same data.

Supported operations are:

  • set — replace the header with the configured value;
  • append — append another header value;
  • remove — remove the header.

Example JSON:

{
  "request": [
    {"op": "set", "name": "X-App-Route", "value": "api"}
  ],
  "response": [
    {"op": "set", "name": "Cache-Control", "value": "no-store"},
    {"op": "remove", "name": "X-Legacy-Header"}
  ]
}

Hop-by-hop/framing headers, forwarding identity headers, RustProxy request IDs and WebSocket handshake headers are protected and cannot be overwritten by custom rules. This prevents a location rule from changing transport framing or spoofing the verified client identity.

Access control

A location can define its own IPv4/IPv6 CIDR ACL. The location ACL is additive: it cannot override a deny enforced by the host policy, reusable ACL profile or vhost ACL.

Authentication, vhost rate limits, country policy, security headers, compression, custom error pages and WebSocket policy still apply through the normal vhost pipeline.

What is intentionally not an Nginx parser

Custom locations do not execute arbitrary Nginx directives or configuration snippets. RustProxy does not currently implement location-level try_files, filesystem aliases/roots, embedded scripting, arbitrary if expressions or arbitrary module directives. Use the explicit UI controls and the documented JSON schema instead; unknown fields are rejected on save.