0.29.7
This commit is contained in:
1 parent
ad95bfb050
commit
1431dd47f0
62 files changed
+1360
-198
No files matched your search
@@ -3,6 +3,24 @@
|
||||
This describes implemented source, not a verified Rust runtime. See
|
||||
[TEST_REPORT.md](TEST_REPORT.md).
|
||||
|
||||
## 0.29.7: show diagnostic headers only on cache HIT
|
||||
|
||||
Set `cache.expose_only_hits: true` globally (Settings > Cache) to emit
|
||||
`X-Cache`, `X-Cache-Hits`, `X-Cache-Reason`, `Cache-Status` and
|
||||
`X-Cache-Resident-Age` only when the response is actually served from
|
||||
RustProxy cache. MISS and BYPASS continue to be recorded in internal metrics
|
||||
and access logs but these diagnostic headers are absent from those responses.
|
||||
Cached stale/revalidated/range/conditional responses use the HIT outcome and
|
||||
continue to show cache diagnostics. Individual vhosts can override the global
|
||||
flag with `vhosts[].cache.expose_only_hits: true | false | null` (`null`
|
||||
inherits). Changing the flag alone does not purge cached objects.
|
||||
|
||||
The independent `Via` proxy-chain header can still appear on MISS/BYPASS when
|
||||
`cache.via_header` is configured. Set it to `null` to turn off that header.
|
||||
Existing `expose_status`, `expose_hits`, `expose_cache_status` and
|
||||
`expose_resident_age` switches still select which individual HIT headers are
|
||||
emitted.
|
||||
|
||||
## 0.19.1 cache identity safety
|
||||
|
||||
The frontend scheme is part of the primary cache identity. `http://host/path` and
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
|
||||
# Changelog
|
||||
|
||||
## 0.29.7 same-version `E0308` source correction
|
||||
|
||||
- Defer Reverse Proxy error interception from the upstream `Response<hyper::body::Incoming>` to the adapted `Response<axum::body::Body>` in `success_prepare.rs`. This preserves the H2 WebSocket tunnel's `Incoming` body type and ensures replacement still precedes response transformation and cache admission. Reapply response rules and enforce `no-store` for replaced application errors.
|
||||
- Change health supervisor member collection to own `Arc<Member>` and spawn probes with `Arc::clone(member)`, meeting Tokio's owned `'static` task requirement.
|
||||
- Extend the application-error UI/source regression check with the body-adaptation ordering, no-store and Arc ownership assertions. Offline checks passed; Rust compilation is not available in the packaging environment.
|
||||
|
||||
## 0.26.7
|
||||
|
||||
### Backend client lifecycle and cache diagnostics
|
||||
|
||||
@@ -116,6 +116,17 @@ RustProxy 0.29.1 can mark a Custom location as `internal`. An internal location
|
||||
|
||||
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 [0.29.1 implementation note](V0.29.1_IMPLEMENTATION.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.
|
||||
@@ -1,5 +1,10 @@
|
||||
# PHP-FPM / FastCGI for the Web Server
|
||||
|
||||
**Separate pools for distinct Web Services:** Reusing the same PHP-FPM socket
|
||||
with different `PHP_ADMIN_VALUE` maps can leak `open_basedir` restrictions into
|
||||
a different virtual host. See the 0.29.7 guide
|
||||
[PHP_FPM_ISOLATION.md](PHP_FPM_ISOLATION.md) for remediation and tests.
|
||||
|
||||
RustProxy 0.25 can execute configured PHP extensions through a long-running PHP-FPM pool while preserving the reusable Web Service architecture.
|
||||
|
||||
## Architecture
|
||||
@@ -44,6 +49,90 @@ Configuration example:
|
||||
Unspecified PHP fields inherit the safe serde defaults. A service without
|
||||
`php_profile_id` uses its own `php` object as in earlier versions.
|
||||
|
||||
## Where to configure each PHP setting (0.29.7)
|
||||
|
||||
Both editors expose the **same fields and validation**:
|
||||
|
||||
1. **Web Server → Web Service → PHP-FPM → Local configuration:** set values on one service (`web_services[].php`). Select **Local configuration** in the profile selector first.
|
||||
2. **Web Server → PHP-FPM profiles → Add/Edit profile:** set shared values on a profile (`php_fpm_profiles[].php`), then attach it in a Web Service's PHP-FPM tab (`php_profile_id`). Editing the profile changes every attached service. Per-service `php` values remain saved for later detach but do **not** override an attached profile.
|
||||
3. **Actual PHP-FPM pool config** (`php-fpm.d/*.conf` or distribution equivalent): the pool must exist and listen on the configured socket. Isolate restrictive `open_basedir`/`php_admin_value` settings in *separate pools and sockets*, not by alternating request-time `PHP_ADMIN_VALUE` on shared workers. RustProxy does not launch PHP-FPM.
|
||||
|
||||
| UI field (JSON property) | What to enter / sample | Notes |
|
||||
| --- | --- | --- |
|
||||
| Enable PHP-FPM / FastCGI (`enabled`) | Checked for PHP apps | Off means PHP is not executed. Never serve PHP source. |
|
||||
| PHP-FPM socket (`endpoint`) | `unix:/run/php/php_wordpress.sock`, `tcp:127.0.0.1:9000`, `tcp:[::1]:9000` | Only local Unix sockets or TCP loopback **IP**, not hostnames. Socket ownership and permissions must allow RustProxy access. |
|
||||
| PHP extensions (`extensions`) | `php, phtml` | Comma-separated, no leading dots; at most 16. Only listed extensions are executable. |
|
||||
| Enable PHP PATH_INFO splitting (`path_info`) | Checked for Roundcube `/static.php/skins/...` | Splits an existing PHP script path and its trailing URL; off for ordinary WordPress unless needed. |
|
||||
| Forward Authorization (`pass_authorization`) | Checked when API / Basic / Bearer auth is used | Sends request `Authorization` to `HTTP_AUTHORIZATION` in FastCGI. |
|
||||
| Connection timeout (`connect_timeout_ms`) | `1000` = 1 second | Integer 50–60000 milliseconds. |
|
||||
| Request timeout (`request_timeout_ms`) | `30000` = 30 seconds | Integer 100–3600000 milliseconds for the full FastCGI request. |
|
||||
| Max simultaneous PHP requests (`max_concurrent_requests`) | `64` | Integer 1–4096 per Web Service; excess is rejected with HTTP 503. |
|
||||
| Request-body limit (`max_request_body_bytes`) | `67108864` = 64 MiB; `0` = no additional limit | Integer 0–8589934592 **bytes**, independent of PHP `post_max_size`. |
|
||||
| Response-header limit (`max_response_header_bytes`) | `65536` = 64 KiB | Integer 4096–1048576 bytes. |
|
||||
| PHP-FPM STDERR log limit (`stderr_log_bytes`) | `4096`; `0` = disabled | Integer 0–65536 bytes collected per request. |
|
||||
| Custom FastCGI parameters (`custom_params`) | `APP_ENV = production` | One static `NAME = value` per line. Names A-Z/0-9/underscore, beginning with a letter. No core CGI, HTTP_* or PHP control params. |
|
||||
| PHP INI overrides (`php_values` / `PHP_VALUE`) | `memory_limit = 256M` | One php.ini `directive = value` per line. PHP decides which directives can change at this scope. |
|
||||
| Administrator PHP INI overrides (`php_admin_values` / `PHP_ADMIN_VALUE`) | `open_basedir = /var/www/webmail/:/tmp/` | Trusted operator only; for security isolation prefer dedicated PHP-FPM pool configuration. Do not define the same directive in both INI maps. |
|
||||
|
||||
**Syntax in the three multiline fields is not JSON:** use `key = value`, a separate line per entry; **do not** wrap it in `PHP_VALUE=...` or `php_admin_value[...]` inside the RustProxy editor. Those latter directives belong to the *native PHP-FPM pool configuration*, not the RustProxy FastCGI request fields. Empty values and control characters are rejected. Up to 64 entries per map, maximum 8192 bytes per value and 128 KiB combined.
|
||||
|
||||
### Ready-to-use WordPress and Roundcube examples
|
||||
|
||||
**WordPress — Web Service `/var/www/linuxiarz.pl/`, dedicated FPM socket:**
|
||||
|
||||
```text
|
||||
PHP enabled: checked
|
||||
PHP PATH_INFO: unchecked
|
||||
Endpoint: unix:/run/php/php_wordpress.sock
|
||||
PHP extensions: php
|
||||
PHP_VALUE:
|
||||
memory_limit = 256M
|
||||
upload_max_filesize = 64M
|
||||
post_max_size = 64M
|
||||
max_execution_time = 60
|
||||
PHP_ADMIN_VALUE: leave empty (or set security restrictions in WordPress's own FPM pool)
|
||||
```
|
||||
|
||||
Use `index.php` in **Index files**, plus `try_files` lines `$uri`, `$uri/`, `/index.php?$query_string` in **Routing**. The WordPress pool must be allowed to read its `wp-config.php`, `wp-includes` and `wp-content` directories.
|
||||
|
||||
**Roundcube — Web Service `/var/www/webmail/public_html`, separate FPM socket:**
|
||||
|
||||
```text
|
||||
PHP enabled: checked
|
||||
PHP PATH_INFO: checked
|
||||
Endpoint: unix:/run/php/php_roundcube.sock
|
||||
PHP extensions: php
|
||||
PHP_VALUE:
|
||||
memory_limit = 256M
|
||||
upload_max_filesize = 64M
|
||||
post_max_size = 64M
|
||||
PHP_ADMIN_VALUE: prefer the native Roundcube PHP-FPM pool instead; e.g.:
|
||||
open_basedir = /var/www/webmail/:/usr/lib/php/:/tmp/:/etc/enigma
|
||||
```
|
||||
|
||||
Add additional permitted external paths only if Roundcube's actual dependencies need them. Roundcube assets such as `/static.php/skins/elastic/...` require PATH_INFO splitting. Restart/recycle workers after separating pools; using a different RustProxy profile but the **same socket** does not isolate the worker state. See [pool isolation](PHP_FPM_ISOLATION.md).
|
||||
|
||||
### FastCGI vs php.ini examples
|
||||
|
||||
```text
|
||||
# Custom FastCGI parameters — application-specific static environment:
|
||||
APP_ENV = production
|
||||
APP_DEBUG = 0
|
||||
|
||||
# PHP_VALUE — regular PHP-level options:
|
||||
memory_limit = 256M
|
||||
max_execution_time = 60
|
||||
error_reporting = E_ALL
|
||||
log_errors = On
|
||||
display_errors = Off
|
||||
date.timezone = Europe/Warsaw
|
||||
|
||||
# PHP_ADMIN_VALUE — privileged operator-level options:
|
||||
open_basedir = /var/www/webmail/:/usr/lib/php/:/tmp/
|
||||
```
|
||||
|
||||
The `#` comments above are explanations separating fields; **do not paste them** into the corresponding form inputs. Boolean INI directives commonly accept `On`/`Off`, size directives can accept `K`/`M`/`G` and timeouts use seconds. The actual PHP/FPM version determines supported directives and permitted scopes.
|
||||
|
||||
## Runtime model
|
||||
|
||||
RustProxy implements the FastCGI protocol directly. It does not spawn `php`, `php-cgi` or shell processes for individual requests.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Dedicated PHP-FPM pools for distinct Web Services
|
||||
|
||||
PHP-FPM may retain request-supplied `PHP_VALUE` and `PHP_ADMIN_VALUE` directives in long-lived workers. When two applications use one PHP-FPM socket but different INI overrides, a setting such as `open_basedir` can be inherited by the next request, even when RustProxy routes the request to the correct Web Service. **RustProxy cannot provide process-level isolation inside a shared external PHP-FPM worker.**
|
||||
|
||||
## Affected operator configuration (0.29.6)
|
||||
|
||||
- WordPress Web Service `blog-linuxiarz-pl` uses document root `/var/www/linuxiarz.pl/` and endpoint `unix:/run/php/php_rustproxy.sock`, without an `open_basedir` override.
|
||||
- Roundcube Web Service `webmail-linuxiarz-pl` uses document root `/var/www/webmail/public_html` and the **same** endpoint. Its FastCGI `PHP_ADMIN_VALUE` includes `open_basedir=/var/www/webmail/:/usr/lib/php/:/tmp/:/etc/enigma:...`.
|
||||
- WordPress PHP-FPM stderr confirms the Roundcube `open_basedir` at the WordPress file check. As a result, `wp-config.php` is not visible and WordPress redirects to `/wp-admin/setup-config.php` before triggering fatal errors. This is **not** a cache MISS defect.
|
||||
|
||||
## Required operator remediation
|
||||
|
||||
1. Back up the current FPM configuration. Provision separate, access-restricted PHP-FPM pools under the PHP-FPM service manager used by your system (NixOS configuration when applicable). Use distinct Unix sockets, for example `/run/php/php_wordpress.sock` and `/run/php/php_roundcube.sock`. Ensure RustProxy's runtime user may connect to both. Do **not** expose raw FastCGI publicly.
|
||||
2. Configure pool-level `php_admin_value[open_basedir]` for **Roundcube only**, with exactly the filesystem paths it requires, or keep its validated override in RustProxy on a dedicated pool. Keep WordPress in its own pool with appropriate policy. Pool-level directives are preferable to request-supplied administrator directives for security-sensitive settings.
|
||||
3. In **Web Server > Web Services** set `blog-linuxiarz-pl > PHP-FPM endpoint` to `unix:/run/php/php_wordpress.sock` and `webmail-linuxiarz-pl` to `unix:/run/php/php_roundcube.sock`. Shared PHP-FPM profiles must also refer to the corresponding correct endpoint.
|
||||
4. Apply PHP-FPM configuration and **restart** the affected PHP-FPM service/pools to retire workers with leaked directives. Save the RustProxy Web Service changes. Check that both web apps respond and that private files remain blocked.
|
||||
5. Repeat requests in alternating order from both vhosts and inspect PHP-FPM warnings. Suggested tests: `curl -I https://blog.linuxiarz.pl/`, `curl -I https://blog.linuxiarz.pl/wp-login.php`, `curl -I https://webmail.linuxiarz.pl/`. The WordPress home page must no longer redirect to `/wp-admin/setup-config.php` due to `open_basedir`.
|
||||
|
||||
If WordPress still redirects to setup-config.php with a **dedicated** pool, check whether `wp-config.php` really exists and is readable by the pool user, the configured pool's own php_admin_value restrictions, and database credentials. Do not fix the issue by using unrestricted `open_basedir=/` globally or by disabling protections on Roundcube.
|
||||
|
||||
## New 0.29.7 protection
|
||||
|
||||
During configuration compilation, RustProxy emits a warning identifying pairs of Web Services sharing an endpoint with unequal `PHP_VALUE`/`PHP_ADMIN_VALUE` maps. For backward compatibility, the existing configuration remains loadable; the warning **does not** automatically rewrite operator FPM configuration or claim that sharing becomes safe.
|
||||
|
||||
## Per-backend health
|
||||
|
||||
For an internal 404 response origin, leave `pool_eligible: false`, set `health_check_enabled: false`, and continue routing a named `internal` location to its `backend_id`. If a backend does require separate probes, use an optional per-member `health_check` object (same shape as vhost `load_balancing.health_check`).
|
||||
|
||||
## HIT-only cache diagnostic headers
|
||||
|
||||
Enable global `cache.expose_only_hits: true`, optionally override each vhost at `vhosts[].cache.expose_only_hits`. HIT-only mode filters RustProxy diagnostic cache headers for MISS/BYPASS without altering internal hit/miss metrics or upstream cache eligibility. `Via` is a separate proxy-header option and can be disabled using `cache.via_header: null`.
|
||||
@@ -37,6 +37,7 @@ This is the canonical index for the current project documentation. The authentic
|
||||
|
||||
- [WEB_SERVER](WEB_SERVER.md) - reusable Web Services, static-file behavior, ranges/validators and document-root security.
|
||||
- [PHP_FPM](PHP_FPM.md) - implemented FastCGI/PHP-FPM integration, security model and runtime requirements.
|
||||
- [PHP_FPM_ISOLATION](PHP_FPM_ISOLATION.md) - separate PHP-FPM pools to prevent cross-vhost INI settings leakage.
|
||||
- [VHOSTS](VHOSTS.md) - vhosts and backend/source behavior.
|
||||
- [CUSTOM_LOCATIONS](CUSTOM_LOCATIONS.md) - location matching, rewrites and local responses.
|
||||
- [VHOST_ACCESS](VHOST_ACCESS.md) - access rules applied to vhosts and locations.
|
||||
|
||||
+38
-3
@@ -1,4 +1,39 @@
|
||||
# Verification report - RustProxy 0.29.6
|
||||
# Verification report - RustProxy 0.29.7
|
||||
|
||||
## Same-version 0.29.7 PHP profile UI, Rust warning and error interception review (2026-10-09)
|
||||
|
||||
- Move the shared PHP-FPM **Syntax and safety** help button to the bottom of the profile-management dialog, below **Add profile**, with a visible horizontal separator. Keep the service-local help button where it was. The simulated Web Service UI test asserts this placement and that the help modal still opens.
|
||||
- Remove the unused `mut` in the `web_server::serve` binding (`src/proxy/forward/web_source.rs`).
|
||||
- Correct application-error interception semantics in both Reverse Proxy and Web Server/PHP-FPM: responses supplied by a backend/service (including cache hits) are explicitly marked and are not overwritten by global/vhost error pages when `pages.intercept_statuses` is disabled. RustProxy-generated routing/upstream failures remain eligible for the configured local error page. Interception is performed before cache admission; selected statuses receive `no-store` even after response-header rules and always retain the application's HTTP status, ignoring a standalone error page's status override. An internal named-location fallback remains terminal and has precedence.
|
||||
- Rust regression tests cover the opt-in behavior, the marker's effect in the response observer, precedence and preservation of status with a differently configured page status. Source/UI contracts verify both forwarding paths and correct ordering around HTTP/2 WebSocket body adaptation; these are **not** substitutes for live protocol tests.
|
||||
- `./dev.sh test`: all Rust-independent source, JS, SQL/upgrade, security, documentation and translation checks passed; then exited **127** due to unavailable `cargo`/`rustc`. Rust compilation, unit tests and runtime HTTP/FastCGI/WebSocket acceptance have **not** been performed here. No configuration schema change or version bump.
|
||||
|
||||
## 0.29.7 same-version compile error corrections (2026-10-09)
|
||||
|
||||
- Correct the three operator-reported `E0308` mismatches. Reverse Proxy origin interception now receives an `axum::body::Body` response only **after** adapting the upstream `Response<hyper::body::Incoming>`, preserving the original `Incoming` body expected by the HTTP/2 WebSocket tunnel wrapper. The operation remains before transformation and cache admission.
|
||||
- Reapply configured response-header rules to an intercepted page, then restore `Cache-Control: no-store` so the admin page cannot accidentally enter shared cache through a custom header policy. Internal named error fallbacks retain precedence.
|
||||
- Build owned `Arc<Member>` candidates for the active health-check supervisor and clone the `Arc` into each `JoinSet::spawn` task, rather than attempting to spawn a future carrying `&Arc<Member>`.
|
||||
- Static/UI/source/SQL/upgrade/security/documentation checks passed via `./dev.sh test` up to the Rust guard (exit 127). `./dev.sh check` exited 127 before compilation due to missing Rust/Cargo. **These are source-level corrections, not a verified Rust build.** Operator should run `./dev.sh check` and `./dev.sh test` on a Cargo-equipped host before deployment.
|
||||
|
||||
## 0.29.7 in-version PHP UX and origin error interception (2026-10-09)
|
||||
|
||||
- Both Web Service local PHP fields and shared PHP-FPM profiles now expose per-field examples, units, bounded syntax, PATH_INFO/Authorization/PHP enablement info tooltips and a common detailed help dialog; all localized through language packs. Configuration semantics remain unchanged.
|
||||
- New optional `vhosts[].pages.intercept_statuses`: supported unique HTTP error codes are validated; selected application-origin responses are replaced by vhost/global/built-in RustProxy pages before admission to cache, preserve the HTTP status by default, and carry `Cache-Control: no-store`. The existing internal error fallback runs first. Empty/default list leaves existing origin error responses intact.
|
||||
- Added Rust source-level regression tests for default preservation, replacement, headers, precedence and malformed codes plus JS form behavior checks. `./dev.sh test` ran all pre-Cargo contracts (including Web Service PHP profile editing, origin-interception roundtrip, offline migration and security checks) successfully but exited **127** at the missing `cargo` guard. `./dev.sh check` also exited **127** for that reason. Rust compilation, Rust unit execution, and live Web Server/FastCGI/backend routing remain **unverified**.
|
||||
|
||||
## 0.29.7 backend/cache/FPM policy review (2026-10-09)
|
||||
|
||||
- Backend monitoring now has an explicit per-member switch and optional policy; tests cover backwards-compatible defaults, serialization, inherited Host and validation. Membership in the balanced pool remains a separate setting.
|
||||
- `cache.expose_only_hits` defaults to false globally and may be overridden at a vhost. Tests cover HIT/MISS/BYPASS suppression, origin diagnostic removal, independently configured Via and cache identity stability. Actual wire behavior requires Cargo/runtime tests.
|
||||
- **PHP limitation:** user-supplied WordPress and Roundcube services both target `unix:/run/php/php_rustproxy.sock`. Only Roundcube passes a restrictive FastCGI `PHP_ADMIN_VALUE: open_basedir`; PHP-FPM may retain this value across worker reuse, causing WordPress to fail. The 302 to setup-config.php is a consequence of missing access to wp-config.php. Added conflict warning, inline guidance and pool-isolation instructions; code changes cannot alter an already-shared PHP-FPM worker's isolation. The operator must provision and select a dedicated Roundcube FPM pool and restart/recycle affected old workers.
|
||||
- Source changes keep SQLite schema 9/Cold Cache format 3. Compiler-independent tests and verification are reported below; Rust compilation/live HTTP/2/H3/PHP integration is not asserted in this environment.
|
||||
|
||||
### 0.29.7 verification summary
|
||||
|
||||
- `./dev.sh test`: all Rust-independent contracts, SQLite migration/backup/source-upgrade checks, JS vhost/Web Server regressions, source security/dependency audits, docs and translation checks passed. It exits with code 127 at the Rust/Cargo availability guard, because `rustc` and `cargo` are not installed. This is **not** a successful Rust test-suite run.
|
||||
- `node tools/checks/backend_cache_0297_ui_test.mjs`: passed; simulates the actual backend form toggles and verifies independent monitoring/pool-eligibility state, per-member health override and cache controls.
|
||||
- Rust-only regression tests were added but could not execute: effective active/passive member policies and validation, HTTP Host defaults, HIT-only cache headers, per-vhost policy resolution, and cache compatibility identity.
|
||||
- Operator acceptance remains open: Rust compilation, real PHP-FPM worker isolation on separate sockets, alternating WordPress/Roundcube requests, live 404 fallback, and actual wire-level cache HIT/MISS/BYPASS checks on HTTP/1.1, H2 and H3.
|
||||
|
||||
## 0.29.6 FastCGI EOF and error-log routing (2026-10-09)
|
||||
|
||||
@@ -112,9 +147,9 @@ This source package is not certified for production deployment.
|
||||
|
||||
Installer/update now installs /etc/logrotate.d/rustproxy using the recorded service user/group. Updates repair /etc/profile.d/rustproxy-path.sh rather than warning. logrotate uses copytruncate because RustProxy holds open log descriptors; some log records may be lost during truncate. Rust build and live Debian/systemd acceptance remain unverified in this environment.
|
||||
|
||||
## Version identity (0.29.6 source release)
|
||||
## Version identity (0.29.7 source release)
|
||||
|
||||
`Cargo.toml` package version is the canonical release identity (now 0.29.6). Rust uses `CARGO_PKG_VERSION` at build time; `build.rs` substitutes the admin HTML placeholder. Packaging, upgrade and dev scripts read the manifest with `scripts/version.py`. Run `python3 tools/checks/version_contracts.py` to check that executable paths do not hardcode a version. Historical documentation and external dashboards may retain manually managed versions. Rust compilation/runtime verification is still pending.
|
||||
`Cargo.toml` package version is the canonical release identity (now 0.29.7). Rust uses `CARGO_PKG_VERSION` at build time; `build.rs` substitutes the admin HTML placeholder. Packaging, upgrade and dev scripts read the manifest with `scripts/version.py`. Run `python3 tools/checks/version_contracts.py` to check that executable paths do not hardcode a version. Historical documentation and external dashboards may retain manually managed versions. Rust compilation/runtime verification is still pending.
|
||||
|
||||
## Shared PHP-FPM profiles and Web Server cache/transform/Host patch (0.29.4)
|
||||
|
||||
|
||||
@@ -44,6 +44,23 @@ The main vhost `source` may define `error_fallback`, and each Custom location ma
|
||||
|
||||
Configured upstream/Web Server failures are intercepted before final response/cache publication. The original request method, URI/query and context are internally dispatched to the target, which then follows normal vhost/location processing. Validation rejects fallback cycles and runtime dispatch is depth-limited. See [V0.29.1_IMPLEMENTATION.md](V0.29.1_IMPLEMENTATION.md) for body replay bounds and an Nginx-style static -> app -> redirector example.
|
||||
|
||||
## Per-backend health monitoring (0.29.7)
|
||||
|
||||
Each backend has an independent `health_check_enabled` switch (default `true`).
|
||||
Setting it to `false` excludes that member from both active health probes and
|
||||
passive health ejection, **without** disabling the member for a named location.
|
||||
This is useful for an internal 404 handler configured with `pool_eligible: false`
|
||||
and a location pinned through `backend_id`: the 404 handler never receives
|
||||
ordinary balanced traffic and does not need health monitoring.
|
||||
|
||||
A backend may also define `health_check` with the same fields as
|
||||
`load_balancing.health_check` to use its own TCP/HTTP/off probe policy, timing,
|
||||
path, Host and status ranges. Omitting it inherits the vhost policy. A custom
|
||||
HTTP health check without `host` inherits the vhost Host default even when the
|
||||
vhost's main health check is TCP. When monitoring is disabled, the backend is
|
||||
assumed available; connection errors during real requests are still counted and
|
||||
logged, so monitoring off is not a guarantee of backend reachability.
|
||||
|
||||
## Frontend selection and private IP isolation
|
||||
|
||||
`frontend.hosts` is a normalized hostname-pattern list. Exact hostnames and a single
|
||||
|
||||
@@ -35,6 +35,44 @@ The Web Service editor is split into stable configuration tabs so later features
|
||||
|
||||
After the Web Service is saved, attach it under **Vhosts** by selecting `Web Server` and the service ID for the main source or a custom location.
|
||||
|
||||
### Intercept application HTTP errors (0.29.7)
|
||||
|
||||
Open **Vhosts → Edit vhost → Pages** (not the Web Service PHP tab), enable
|
||||
**Intercept application error responses**, and enter statuses such as `404, 500, 503`.
|
||||
This opt-in vhost policy applies to response bodies returned by both **Reverse
|
||||
Proxy origins** and **Web Server/PHP-FPM origins**. It is configured in
|
||||
`vhosts[].pages.intercept_statuses`; an omitted/empty list disables it and
|
||||
preserves the application error HTML. Supported codes: 400, 401, 403, 404,
|
||||
408, 413, 429, 500, 502, 503, 504.
|
||||
|
||||
For each opted-in origin status, RustProxy replaces the *body* using the
|
||||
vhost's configured error page, then the global error page, then its built-in
|
||||
error page. The HTTP response status always remains the application's status,
|
||||
even if the selected page has a custom `status` for standalone error handling.
|
||||
`Cache-Control: no-store` is set and origin response cookies, compression
|
||||
metadata and application error HTML are not forwarded. Relevant protocol
|
||||
headers such as `WWW-Authenticate`, `Allow` and `Retry-After` are retained.
|
||||
Local RustProxy security/routing failures are not treated as application
|
||||
responses. If `error_fallback` sends an error to a named internal location,
|
||||
that response takes precedence and is not overwritten by this option.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "my-vhost",
|
||||
"pages": {
|
||||
"intercept_statuses": [404, 500, 503],
|
||||
"errors": {
|
||||
"404": {"kind": "html", "status": null, "html": "<h1>Not found</h1>"}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is a **vhost fragment**, not a standalone valid vhost object. A page's
|
||||
`status` override still applies to locally generated RustProxy error pages,
|
||||
but is ignored when replacing an application's error body. See also
|
||||
[Custom locations](CUSTOM_LOCATIONS.md).
|
||||
|
||||
### Application presets
|
||||
|
||||
The editor provides one-shot presets for **Static site, SPA, PHP generic, WordPress, Drupal, Laravel, Symfony, Joomla, PrestaShop and Downloads/file repository**. Applying a preset writes normal Web Service fields; it does not store a hidden CMS mode and every generated field remains editable. Service ID/name, document root and the deployment-specific PHP-FPM endpoint/tuning are preserved. Laravel/Symfony operators should point `document_root` at the application's `public/` directory.
|
||||
|
||||
Reference in new issue
Block a user