v0.34.0_fina;
This commit is contained in:
1 parent
1ca019d849
commit
c207e8a03f
69 files changed
+1496
-13838
No files matched your search
+24
-115
@@ -1,132 +1,41 @@
|
||||
# Custom locations
|
||||
# Custom locations and path rules
|
||||
|
||||
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.
|
||||
Custom locations add exceptions to a Vhost's normal source. They are **not** required for the root path `/`: any request not matched by a custom rule continues to the Vhost's main backend pool or Web Service. Configure them under **Vhosts → Edit → Custom locations**.
|
||||
|
||||
## Routing model in 0.16.0
|
||||
## Path matching
|
||||
|
||||
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:
|
||||
| Match mode | Purpose | Priority |
|
||||
|---|---|---|
|
||||
| `exact` | One exact normalized path | Highest |
|
||||
| `prefix_priority` | Longest prefix that suppresses regex evaluation | Ahead of regex when matched |
|
||||
| `regex` / `regex_insensitive` | Case-sensitive or insensitive regular expression | Tested in configured order after priority-prefix rules |
|
||||
| `prefix` | Ordinary longest matching path prefix | Fallback among matching rules |
|
||||
|
||||
```text
|
||||
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.
|
||||
Ambiguous and unsafe encoded path forms are rejected rather than treated as alternative spellings. Avoid overlapping regex rules when order matters; test paths with and without trailing `/`. A Vhost's main source handles paths without a matching custom location.
|
||||
|
||||
## Actions
|
||||
|
||||
A location can proxy to a backend, serve an existing Web Service, return a local response, or redirect the client to another absolute HTTP(S) URL.
|
||||
- **Proxy:** use the Vhost backend pool or target a specific backend. A location can have an explicit cache override.
|
||||
- **Web Server:** reference an existing Web Service with its saved document root and PHP/static settings.
|
||||
- **Local response:** return a chosen `200–599` status, content type and body without connecting to an origin. `HEAD`, `204` and `304` do not return a body.
|
||||
- **Redirect:** issue `301`, `302`, `303`, `307` or `308` to a valid absolute HTTP(S) target. Query preservation is configurable. Redirect rewrite expressions may reference regex captures.
|
||||
|
||||
### Proxy
|
||||
### Path rewriting
|
||||
|
||||
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.
|
||||
`preserve` forwards the original path, `strip_prefix` removes the matched prefix, `replace_prefix` substitutes a new normalized prefix and `regex` rewrites using captures such as `$1` or `${name}`. Queries remain intact unless a redirect explicitly changes handling. Public cache keys are based on the client-facing URL, not an internal rewritten backend path.
|
||||
|
||||
Supported path transformations:
|
||||
**Example:** send `example.com/api/*` to a dedicated application while `/` remains on the main website. Create a `/api/` prefix location, select its backend and choose whether to preserve or strip `/api/`. Inspect the editor's effective-behavior preview before saving.
|
||||
|
||||
- **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.
|
||||
## Headers, access and method rules
|
||||
|
||||
The query string is preserved. Rewrites change only the selected source path; reverse-proxy cache identity remains based on the public client URL.
|
||||
Each location can add request/response header operations (`set`, `append`, `remove`), reusable ACL profiles, inline IP/CIDR rules, country access and HTTP-method allow/block lists. Every applicable host and Vhost policy must still pass; a location cannot remove a higher-level denial. Transport/forwarded-identity headers are protected from unsafe overrides. Authentication, rate limits, WebSocket policy and other Vhost settings continue to apply.
|
||||
|
||||
### Web Server
|
||||
## Internal error fallback
|
||||
|
||||
`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](WEB_SERVER.md).
|
||||
Mark a location **Internal** to make it unavailable to ordinary public URI matching. A Vhost or location may direct specific origin responses (`403`, `404`, `500`, `502`, `503`, `504`) to a named internal location ID in the same Vhost. The dispatch is internal, not a browser redirect; request context and access evaluation are preserved. Invalid targets or loops are rejected.
|
||||
|
||||
### Local response
|
||||
If all you need is a different error **page body**, use **Vhost → Pages → Intercept application error responses**, which keeps the original status without making a second origin request.
|
||||
|
||||
`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.
|
||||
## Not an Nginx configuration parser
|
||||
|
||||
### Redirect
|
||||
|
||||
`Redirect` is a backend-less action. Choose `301`, `302`, `303`, `307` or `308`, set an absolute `http://` or `https://` target, and optionally preserve the incoming query string. RustProxy validates the target and does not allow capture expansion inside the target scheme/authority.
|
||||
|
||||
For capture-based path rewriting, configure a separate **Redirect rewrite regex**. Captures can be referenced as `$1` or `${name}` in the redirect target path/query. This separation mirrors an Nginx `location` selector followed by a separate `rewrite` expression. For example, the Nginx pattern:
|
||||
|
||||
```nginx
|
||||
location ~* \.(?:tar\.gz|zip?)$ {
|
||||
rewrite ^/(.*)$ https://objectstorage.example.invalid/b/repo/o/$1 permanent;
|
||||
}
|
||||
```
|
||||
|
||||
corresponds to a case-insensitive regex Custom location `\.(?:tar\.gz|zip?)$`, action **Redirect**, status `301`, target `https://objectstorage.example.invalid/b/repo/o/$1`, and redirect rewrite regex `^/(.*)$`. Query preservation is controlled independently.
|
||||
|
||||
|
||||
## 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:
|
||||
|
||||
```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, select a reusable ACL profile, add a location-specific country block/allow-only rule, and configure an HTTP method policy (`off`, `allow` or `block`). Method names are normalized to uppercase and validated as HTTP method tokens.
|
||||
|
||||
All access layers are additive. The request must pass the vhost method policy, location method policy, host/profile/vhost IP ACLs, location profile ACL, inline location ACL and every applicable country policy. A location therefore cannot override a denial from its vhost. Method denial returns `405 Method Not Allowed` (with `Allow` for allow-list mode); IP/country denials retain the normal `403` pipeline. These checks occur before backend selection/connection.
|
||||
|
||||
Authentication, vhost rate limits, security headers, compression, custom error pages and WebSocket policy still apply through the normal vhost pipeline.
|
||||
|
||||
## Internal locations and error fallbacks
|
||||
|
||||
RustProxy 0.29.1 can mark a Custom location as `internal`. An internal location is addressed by its stable location `id` and is never selected by a public URI match. The vhost main source or another Custom location can use `error_fallback` to internally dispatch configured `403/404/500/502/503/504` responses to that target. The default intercepted status is `404`.
|
||||
|
||||
This is an internal request handoff, not an HTTP redirect. The original method, URI/query and request context are retained. The fallback target re-enters normal access/header/cache/compression/response processing. Fallback targets must be enabled internal locations in the same vhost; validation rejects cycles and runtime dispatch is depth-limited. See [current vhost documentation](VHOSTS.md).
|
||||
|
||||
### Replace origin error bodies without an internal location (0.29.7)
|
||||
|
||||
The independent, optional **Vhost → Pages → Intercept application error responses**
|
||||
setting (`pages.intercept_statuses`, for example `[404, 503]`) replaces a
|
||||
backend or Web Server/PHP origin's error *body* with the configured vhost
|
||||
error page, then global error page, or a built-in page. It retains the HTTP
|
||||
status and sets `Cache-Control: no-store`. Unlike `error_fallback`, it does
|
||||
**not** forward the request to a different backend. The existing internal
|
||||
`error_fallback` action has priority and its final response remains intact.
|
||||
See [Web Server – application HTTP error interception](WEB_SERVER.md#intercept-application-http-errors-0297).
|
||||
|
||||
## 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.
|
||||
The editor does not run arbitrary Nginx snippets, filesystem aliases, arbitrary `if` rules or per-location static roots. Configure static paths in a reusable Web Service, then assign that service to the location. Inspect [Vhosts](VHOSTS.md) and [Access](ACCESS.md) for the policies applied before connecting to the backend.
|
||||
Reference in new issue
Block a user