6.2 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 proxy to a backend, serve an existing Web Service, 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
$1or${1}in the replacement.
The query string is preserved. Rewrites change only the selected source path; reverse-proxy cache identity remains based on the public client URL.
Web Server
Web Server selects one reusable service previously created in the Web Server workspace. The location stores only the Web Service ID; document root, index list and directory-listing policy remain in that shared service. Existing location matching and path rewriting are reused, but backend pinning and reverse-proxy object-cache controls do not apply to local files. See WEB_SERVER.md.
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, per-location filesystem aliases/roots, embedded scripting, arbitrary if expressions or arbitrary module directives. Static roots are defined only by reusable Web Services. Use the explicit UI controls and the documented JSON schema instead; unknown fields are rejected on save.