v0.27.0
This commit is contained in:
1 parent
a9f9450f80
commit
762eb9e28b
81 files changed
+1242
-1095
No files matched your search
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Administration API access - 0.26.7
|
||||
# Administration API access - 0.27.0
|
||||
|
||||
## Sign-in boundary
|
||||
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ each Docker host, so the proxy container never needs Docker-socket access. See
|
||||
Build locally with a normal OCI builder:
|
||||
|
||||
```bash
|
||||
docker build -t rustproxy:0.26.7 .
|
||||
docker build -t rustproxy:0.27.0 .
|
||||
```
|
||||
|
||||
Persist `/var/lib/rustproxy`; it contains the SQLite database, certificates and the
|
||||
@@ -22,7 +22,7 @@ docker volume create rustproxy-data
|
||||
docker run --rm -d --name rustproxy \
|
||||
-p 8080:8080 \
|
||||
-v rustproxy-data:/var/lib/rustproxy \
|
||||
rustproxy:0.26.7
|
||||
rustproxy:0.27.0
|
||||
|
||||
docker exec rustproxy rust-proxy admin setup-token
|
||||
```
|
||||
|
||||
@@ -74,7 +74,7 @@ For each agent configure:
|
||||
- an optional configured frontend certificate to apply to every generated vhost for that agent;
|
||||
- an optional default ACL profile inherited by generated vhosts unless a service selects its own profile.
|
||||
|
||||
RustProxy polls each enabled agent according to its configured interval (30 seconds by default, checked by the scheduler in bounded steps). The 5-second Live-view refresh reads only cached RustProxy memory and does not force a Docker request. **Docker vhosts** shows the latest cached observation for every configured agent.
|
||||
RustProxy polls each enabled agent according to its configured interval (30 seconds by default, checked by the scheduler in bounded steps). The 5-second Live-view refresh reads only cached RustProxy memory and does not force a Docker request. **Docker vhosts** shows the latest cached observation for every configured agent. A failed agent request retains the last successful inventory when available, so a temporary control-plane outage does not withdraw working routes. A successful inventory that omits an already published service keeps its hostname and changes the generated route to 503 until discovery sees the service again.
|
||||
|
||||
## Publish a discovered service
|
||||
|
||||
@@ -90,6 +90,7 @@ For each discovered service you can change the mapping directly in **Docker vhos
|
||||
- **Redirect HTTP to HTTPS**: per-app Force SSL switch. New assignments default on when the agent has a usable plain-HTTP + TLS listener pair; assignments saved before 0.18.8 retain their previous redirect-off behavior until explicitly saved with the new switch;
|
||||
- **WebSockets**: enable or disable classic HTTP/1.1 Upgrade forwarding for this application;
|
||||
- **Cache**: enable or disable normal RustProxy caching for this generated vhost;
|
||||
- **Compression**: inherit/enable/disable dynamic compression for this published vhost and optionally filter zstd, Brotli, gzip and deflate; selecting Disabled hides/disables the codec selectors without clearing their saved values, and globally disabled codecs stay unavailable;
|
||||
- **Transform**: opt this generated vhost into the global static-response transform engine; it is off by default and still requires global transformation to be enabled;
|
||||
- **Backend health check**: HTTP/TCP/off active-probe mode, path/Host override, interval, timeout, slow threshold, rise/fall counters and accepted HTTP status range.
|
||||
- **Passive Backend Health**: independent opt-in policy, OFF by default, with separate connect/timeout/I/O/HTTP-5xx/slow-response switches and optional passive rise/fall overrides.
|
||||
@@ -123,9 +124,9 @@ Backend selection order is:
|
||||
4. the agent's preferred/primary detected address when compatible with the binding;
|
||||
5. another compatible detected host address.
|
||||
|
||||
An explicit target that is not compatible with the service's Docker bindings does not silently fall back to another IP; that dynamic vhost is not materialized until the selected address/binding is available.
|
||||
An explicit target that is not compatible with the service's Docker bindings does not silently fall back to another IP. In 0.27.0 the published hostname remains materialized and returns `503 Service Unavailable` until the selected service/address/binding is available again. Disabling the Docker agent stops discovery but keeps already published hostnames claimed as 503 routes; re-enabling the agent resumes reconciliation. Publication is removed when the administrator explicitly unpublishes the assignment or removes the agent configuration that owns it.
|
||||
|
||||
The generated backend is pinned to the selected IP through an address allowlist and uses the matching Docker-published host port. Cache, Transform, WebSockets and HTTP-to-HTTPS redirect are materialized from the per-app switches. If the Docker agent has a frontend certificate selected, that certificate ID is copied to every generated vhost and participates in the normal TLS/SNI certificate validation and ownership rules. The effective ACL profile is the per-app profile when selected, otherwise the agent default profile. Active backend health checks default to TCP. Passive Backend Health is materialized from the Docker assignment separately and defaults to OFF, so discovery refresh/restart does not silently re-enable production-traffic quarantine. The Docker vhosts page exposes the same passive policy as ordinary vhosts. Normal 5xx/timeouts/connect/I/O/slow-response observations remain visible in counters while passive health is OFF. Active checks can be switched between HTTP/TCP/off per service without changing the passive policy.
|
||||
The generated backend is pinned to the selected IP through an address allowlist and uses the matching Docker-published host port. Cache, Transform, Compression, WebSockets and HTTP-to-HTTPS redirect are materialized from the per-app settings. Compression has inherit/on/off plus per-codec overrides. Global Response codec switches remain the hard availability ceiling and the minimum size remains global. If the Docker agent has a frontend certificate selected, that certificate ID is copied to every generated vhost and participates in the normal TLS/SNI certificate validation and ownership rules. The effective ACL profile is the per-app profile when selected, otherwise the agent default profile. Active backend health checks default to TCP. Passive Backend Health is materialized from the Docker assignment separately and defaults to OFF, so discovery refresh/restart does not silently re-enable production-traffic quarantine. The Docker vhosts page exposes the same passive policy as ordinary vhosts. Normal 5xx/timeouts/connect/I/O/slow-response observations remain visible in counters while passive health is OFF. Active checks can be switched between HTTP/TCP/off per service without changing the passive policy.
|
||||
|
||||
## DNS
|
||||
|
||||
@@ -138,7 +139,7 @@ DNS for Docker vhost names must resolve to the RustProxy frontend/listener that
|
||||
|
||||
Custom FQDNs and aliases likewise need DNS records pointing at the relevant RustProxy frontend. The Docker-host addresses detected by the agent are backend routing candidates; they are not automatically published to DNS.
|
||||
|
||||
RustProxy does not change DNS records itself in 0.22.3.
|
||||
RustProxy does not change DNS records itself.
|
||||
## Prometheus metrics
|
||||
|
||||
Docker discovery has its own Prometheus collector switch, `prometheus.include_docker_vhosts`, enabled by default. It is intentionally separate from `include_vhosts` and `include_backends`. Dynamic Docker routes never appear under ordinary `rust_proxy_vhost_*` or `rust_proxy_backend_*` families.
|
||||
|
||||
@@ -36,7 +36,7 @@ Error messages from dependencies should still be treated as untrusted diagnostic
|
||||
|
||||
## Rotation
|
||||
|
||||
RustProxy does not implement file rollover, retention or compression. Use the system `logrotate`. The Debian package configuration in `debian/rustproxy.logrotate` already covers `/var/log/rustproxy/*.log` and uses `copytruncate`, so the default error-log path is included without a RustProxy restart.
|
||||
RustProxy does not implement file rollover, retention or compression. Use the system `logrotate`. Debian packaging is maintained outside this source tree and ready packages are published at `https://rustproxy.linuxiarz.pl`; package-specific logrotate policy belongs to that packaging repository.
|
||||
|
||||
## Stored-log explorer
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Stored log explorer
|
||||
|
||||
RustProxy 0.26.7 provides an authenticated, read-only **Logs** workspace at `/logs`. The top bar has one **Logs** menu with separate **Stored logs** and **Live Logs** actions; the two data paths remain independent.
|
||||
RustProxy 0.27.0 provides an authenticated, read-only **Logs** workspace at `/logs`. The top bar has one **Logs** menu with separate **Stored logs** and **Live Logs** actions; the two data paths remain independent.
|
||||
|
||||
## Separation from Live Logs
|
||||
|
||||
|
||||
+3
-1
@@ -1,10 +1,12 @@
|
||||
# Installing and updating RustProxy 0.26.7
|
||||
# Installing and updating RustProxy 0.27.0
|
||||
|
||||
The scripts prepare a Linux/systemd installation. This source archive is **not a
|
||||
verified production build**: Rust/Cargo, real CA operations, live systemd startup
|
||||
and rollback against a real Rust database have not been exercised in the packaging
|
||||
environment. Perform the acceptance steps below on an isolated server first.
|
||||
|
||||
Ready-to-use Debian packages are published separately at `https://rustproxy.linuxiarz.pl`. The Debian package-build repository and metadata are intentionally maintained outside this source tree.
|
||||
|
||||
## Debian 13+ one-line source install/update
|
||||
|
||||
```bash
|
||||
|
||||
+2
-1
@@ -15,6 +15,7 @@ This is the canonical index for the current project documentation. The authentic
|
||||
- [0.25.1 release audit](V0.25.1_AUDIT.md) - historical Traffic/module-split release scope and compiler-regression guards.
|
||||
- [0.25.0 specification audit](V0.25.0_AUDIT.md) - Web Server foundation point-by-point implementation status.
|
||||
- [0.25.0 pre-production security audit](V0.25.0_SECURITY_PREPROD_AUDIT.md) - threat-oriented source/configuration review, fixes made in-session and mandatory runtime security gates.
|
||||
- [0.27.0 implementation note](V0.27.0_IMPLEMENTATION.md) - compression defaults/scoped policy, persistent Docker publications and visible cache occupancy meter fill.
|
||||
- [0.26.7 implementation note](V0.26.7_IMPLEMENTATION.md) - HOT/COLD occupancy meters, backend rotation continuity and container Certbot packaging.
|
||||
- [0.26.6 implementation note](V0.26.6_IMPLEMENTATION.md) - composed ACL allow semantics, certificate-form reset, backend table preferences and NPM migration helper documentation.
|
||||
- [0.26.5 implementation note](V0.26.5_IMPLEMENTATION.md) - interface-scaled form/select alignment and corrected Streams listener navigation.
|
||||
@@ -67,7 +68,7 @@ This is the canonical index for the current project documentation. The authentic
|
||||
|
||||
## Historical or version-labelled context
|
||||
|
||||
Version-labelled `V*.md` files are retained as historical implementation/audit records. Their version number describes the audited milestone. The current release implementation note is [V0.26.7_IMPLEMENTATION.md](V0.26.7_IMPLEMENTATION.md); [V0.26.6_IMPLEMENTATION.md](V0.26.6_IMPLEMENTATION.md) is retained as the prior access-policy/administration milestone; [V0.26.5_IMPLEMENTATION.md](V0.26.5_IMPLEMENTATION.md) is retained as the prior interface-scaling/listener-navigation milestone, [V0.26.4_IMPLEMENTATION.md](V0.26.4_IMPLEMENTATION.md) as the prior administration/backend-lifecycle milestone, [V0.26.3_IMPLEMENTATION.md](V0.26.3_IMPLEMENTATION.md) as the prior appearance/UI milestone, [V0.26.2_IMPLEMENTATION.md](V0.26.2_IMPLEMENTATION.md) as the prior Logs/UI milestone and [V0.26.1_IMPLEMENTATION.md](V0.26.1_IMPLEMENTATION.md) as the prior protocol-attribution milestone. The latest retained audit is [V0.25.5_AUDIT.md](V0.25.5_AUDIT.md); older audit files remain historical evidence.
|
||||
Version-labelled `V*.md` files are retained as historical implementation/audit records. Their version number describes the audited milestone. The current release implementation note is [V0.27.0_IMPLEMENTATION.md](V0.27.0_IMPLEMENTATION.md); [V0.26.7_IMPLEMENTATION.md](V0.26.7_IMPLEMENTATION.md) is retained as the prior cache/backend/container milestone; [V0.26.6_IMPLEMENTATION.md](V0.26.6_IMPLEMENTATION.md) is retained as the prior access-policy/administration milestone; [V0.26.5_IMPLEMENTATION.md](V0.26.5_IMPLEMENTATION.md) is retained as the prior interface-scaling/listener-navigation milestone, [V0.26.4_IMPLEMENTATION.md](V0.26.4_IMPLEMENTATION.md) as the prior administration/backend-lifecycle milestone, [V0.26.3_IMPLEMENTATION.md](V0.26.3_IMPLEMENTATION.md) as the prior appearance/UI milestone, [V0.26.2_IMPLEMENTATION.md](V0.26.2_IMPLEMENTATION.md) as the prior Logs/UI milestone and [V0.26.1_IMPLEMENTATION.md](V0.26.1_IMPLEMENTATION.md) as the prior protocol-attribution milestone. The latest retained audit is [V0.25.5_AUDIT.md](V0.25.5_AUDIT.md); older audit files remain historical evidence.
|
||||
|
||||
Older context documents such as [INTEGRATIONS_040](INTEGRATIONS_040.md), [MANAGEMENT](MANAGEMENT.md), [SECURITY_AUDIT](SECURITY_AUDIT.md), [ACME_RFC2136](ACME_RFC2136.md) and older version audits remain available for traceability but should not override the current functional/technical documents above.
|
||||
|
||||
|
||||
+29
-21
@@ -31,7 +31,7 @@ this and preserves dirty settings forms across status/language refreshes.
|
||||
"http2_settings":{"idle_timeout_seconds":300, "max_connection_lifetime_seconds":0, "drain_timeout_seconds":10}}}
|
||||
]
|
||||
},
|
||||
"server_header": {"mode":"custom", "value":"RustProxy/v0.20.0"},
|
||||
"server_header": {"mode":"custom", "value":"RustProxy"},
|
||||
"compression": {"gzip":true, "br":true, "zstd":true, "deflate":false, "min_bytes":1024},
|
||||
"headers": {
|
||||
"request": [{"op":"set", "name":"x-proxy-name", "value":"RustProxy"}],
|
||||
@@ -206,7 +206,7 @@ endpoints are rejected rather than silently widened.
|
||||
|
||||
## Server and other client headers
|
||||
|
||||
`server_header.mode` is `preserve` (default), `hide`, or `custom`. Custom values are
|
||||
`server_header.mode` is `preserve`, `hide`, or `custom`. Fresh installations default to `custom` with the exact value `RustProxy`; existing saved installations retain their configured policy. Custom values are
|
||||
nonempty, bounded to 256 bytes and validated against header injection. Preserve
|
||||
means retain the result of origin/global/route rules; it does not add a missing
|
||||
header. Hide/custom take final precedence, including proxy-generated errors.
|
||||
@@ -225,26 +225,34 @@ snapshot; no mixed-version configuration is applied midway through a response.
|
||||
|
||||
## Compression
|
||||
|
||||
All four flags default false. `min_bytes` defaults to 1024 (valid 32..1048576).
|
||||
The library's default small-body/content-type predicate is also retained; actual
|
||||
minimum for a known-size body is at least that default. Unknown-length text bodies
|
||||
can be streamed without pre-buffering merely to discover their size.
|
||||
`zstd`, Brotli and gzip default ON; deflate defaults OFF. `min_bytes` defaults to 1024
|
||||
(valid 32..1048576). The streaming middleware keeps its default content-type safety
|
||||
predicate plus the RustProxy minimum-size predicate. Unknown-length eligible bodies can
|
||||
be streamed without aggregating the complete response merely to discover its size.
|
||||
|
||||
Accept-Encoding quality negotiation is delegated to tower-http. Text, JSON,
|
||||
JavaScript, XML, SVG and wasm are eligible; already encoded, SSE, range, upgrade,
|
||||
HEAD/204/304 and privacy-sensitive responses are excluded. Authorization and arbitrary
|
||||
cookie-bearing dynamic responses remain excluded. A cookie-bearing request may be
|
||||
compressed only when RustProxy is already serving a shared-cache HIT accepted by cache
|
||||
policy (including the configured static-cookie exception) or a local static Web Server
|
||||
response. Origin `private`, `no-store`, `no-transform` and `Set-Cookie` exclusions still
|
||||
win. Cached identity bodies can be streamed through compression on HIT; origin encodings
|
||||
are passed through without recompression.
|
||||
RustProxy parses `Accept-Encoding` quality weights before invoking the encoder. Client
|
||||
`q` values win. When two or more enabled codecs have equal quality, the deterministic
|
||||
server preference is `zstd -> br -> gzip -> deflate`. An existing `Content-Encoding` is
|
||||
always passed through and never recompressed. `no-transform`, request ranges/Content-Range,
|
||||
SSE, upgrades, HEAD/1xx/204/304 and explicitly skipped internal responses remain excluded.
|
||||
`Cookie`, `Authorization`, `Set-Cookie`, `Cache-Control: private` and `no-store` do not by
|
||||
themselves disable compression; cacheability and dynamic compression are separate policies.
|
||||
Applications that place secrets and attacker-controlled reflection in the same compressed
|
||||
response can disable compression at the vhost or Web Service scope when their threat model
|
||||
requires BREACH-style mitigation.
|
||||
|
||||
Vary: Accept-Encoding is added by compression; content length is removed for the
|
||||
transformed body. Strong ETags are weakened, and identity-body content digests and
|
||||
Accept-Ranges are removed. Encoders use their fastest preset; there is no panel
|
||||
compression-quality slider in this release. Real binary interoperability tests
|
||||
are still an acceptance requirement, not a result of this packaging session.
|
||||
The global Response panel selects available codecs and the minimum size. Each ordinary
|
||||
vhost may inherit, enable or disable dynamic compression and independently inherit/enable/disable
|
||||
zstd, Brotli, gzip and deflate. Generated Docker vhosts and Web Server services expose the same
|
||||
per-scope codec filters. When a scope is explicitly Disabled, the dashboard hides and disables
|
||||
those codec controls without clearing their saved values. Global codec switches remain the hard
|
||||
ceiling: a local `true` override cannot enable a codec disabled in the global Response panel.
|
||||
`min_bytes` remains global.
|
||||
|
||||
`Vary: Accept-Encoding` is added when compression is negotiated; content length is removed
|
||||
for the transformed body. Strong ETags are weakened, and identity-body content digests and
|
||||
`Accept-Ranges` are removed. Encoders use their fastest preset; there is no panel
|
||||
compression-quality slider in this release.
|
||||
|
||||
## Diagnostics and units
|
||||
|
||||
@@ -288,7 +296,7 @@ to downgrade.
|
||||
|
||||
Vhosts have their own backend pool, health/keepalive/affinity controls, ACL and
|
||||
security/custom response headers. See VHOSTS.md. Global Server policy still takes
|
||||
final precedence. There is no per-vhost compression algorithm override.
|
||||
final precedence. Per-vhost compression can filter individual globally enabled codecs.
|
||||
|
||||
The reported `SizeAbove(u16)` compilation error is removed by a custom u64 predicate,
|
||||
not a cast or panic-producing conversion. Compression thresholds retain the full
|
||||
|
||||
+20
-18
@@ -1,26 +1,29 @@
|
||||
# Verification report - RustProxy 0.26.7
|
||||
# Verification report - RustProxy 0.27.0
|
||||
|
||||
## Scope
|
||||
|
||||
RustProxy 0.26.7 is a compatibility-preserving cache observability, backend-client lifecycle and documentation patch on top of 0.26.6. SQLite remains schema 8 and the saved proxy configuration format is unchanged.
|
||||
RustProxy 0.27.0 changes downstream compression policy, Docker-vhost publication continuity, cache-meter rendering, fresh-install response identity and source-package layout while keeping SQLite schema 8.
|
||||
|
||||
The release adds explicit HOT/COLD cache occupancy meters on `/cache` for configured object and byte limits. It also preserves compatible upstream client instances across unrelated active-snapshot rebuilds, preventing generation age, generation request counts and cumulative `Rotations` from being reset by configuration publication. Backend changes that alter origin, address policy, keepalive settings or connect timeout still create fresh clients. The OCI/container documentation now matches the shipped certificate environment: Certbot plus the Cloudflare, OVH and RFC2136 DNS plugins are provided together. The same 0.26.7 source now also hardens cache `Age` ownership and aligns downstream compression with the static-cookie cache exception.
|
||||
Dynamic response compression defaults to zstd, Brotli and gzip enabled, with deflate opt-in. Client `Accept-Encoding` quality values are authoritative; equal quality uses deterministic `zstd -> br -> gzip -> deflate` server preference. Existing `Content-Encoding`, `no-transform`, range responses/requests, SSE and upgrades remain excluded. Cookie, authorization, `Set-Cookie`, `private` and `no-store` no longer disable compression as blanket rules.
|
||||
|
||||
Ordinary vhosts, generated Docker vhosts and Web Server services can inherit, enable or disable dynamic compression and can independently inherit/enable/disable zstd, Brotli, gzip and deflate. Global **Settings -> Response** codec switches remain the hard availability ceiling and `min_bytes` remains global. A scoped codec cannot activate a codec disabled globally. When scoped compression is explicitly Disabled, the dashboard hides and disables its codec selectors while preserving the stored override values.
|
||||
|
||||
An explicitly published Docker assignment keeps its generated hostname even when its service disappears. A successful inventory without the assigned service materializes an unavailable route that returns HTTP 503 instead of removing the hostname. Agent polling errors retain the previous successful inventory when one exists, and a returning service is reconciled automatically. The cache overview progress elements have explicit WebKit/Chromium and Firefox progress-value styling so their visual fill follows the numeric meter value.
|
||||
|
||||
Fresh installations now default the response `Server` policy to `custom` with the exact value `RustProxy`. Existing stored settings are not rewritten, and a configuration document predating the `server_header` field still deserializes with the historical preserve behavior. Debian package-build metadata is no longer shipped in the main source tree; ready packages are maintained separately at `https://rustproxy.linuxiarz.pl`.
|
||||
|
||||
## Regression coverage
|
||||
|
||||
Static source contracts require all four `/cache` occupancy meters (HOT objects, HOT bytes, COLD objects and COLD bytes) and their configured-limit inputs. Browser JavaScript syntax is checked with Node.
|
||||
|
||||
The existing upstream-client unit coverage retains age-triggered rotation without user traffic. A new pool regression, `compatible_pool_rebuild_reuses_upstream_clients`, verifies that a compatible rebuild reuses the previous compiled backend/client object so rotation state remains continuous. Source contracts also require the `reusable_with` compatibility check, maintenance calls for normal/WebSocket clients and backend reuse path. These Rust tests require a compiler-enabled release host.
|
||||
|
||||
Cache regressions now require a stored HIT/dashboard object to advance `Age`, while compression regressions require `Age` to survive encoding and require cookie-bearing compression to stay blocked unless the internal cache/static safety marker is present. Existing 0.26.6 `Age` rules stay loadable; response-side Age is tagged as a late wire-only override so the generic response-rule pass cannot influence cache freshness/storage. The bundled compression tester no longer forces `Cache-Control: no-cache` unless `--revalidate` is requested.
|
||||
|
||||
Documentation checks cover the 0.26.7 release note, Reader index, local Markdown links, cache diagnostics and container/ACME provider guidance. Packaging smoke tests verify the 0.26.7 release identity and deterministic source archive contract.
|
||||
Compression unit coverage checks defaults, q-value negotiation, equal-quality priority, each supported codec, existing-encoding passthrough, scoped per-codec resolution and the revised cookie/auth/cache-privacy policy. Docker unit coverage checks missing published service -> retained 503, failed agent observation -> retained last-known backend and persistence of Docker codec overrides. Settings coverage checks the fresh-install `Server: RustProxy` default and legacy missing-field compatibility. Static/UI contracts require ordinary-vhost, Docker-vhost and Web-Service codec controls to hide/disable when their scope is explicitly OFF without clearing saved values, plus the 503 path, visible cache progress styling, external Debian-packaging separation and reproducible archives without a `debian/` tree.
|
||||
|
||||
## Verification status in this workspace
|
||||
|
||||
Rust/Cargo is not installed in this workspace. Rust-independent checks pass here; compiler/type/runtime gates remain explicitly open until this source is checked on a Rust-enabled release host.
|
||||
|
||||
| Check | Status |
|
||||
|---|---|
|
||||
| `node --check` for changed administration JavaScript | PASS |
|
||||
| changed administration JavaScript syntax (`node --check`) | PASS |
|
||||
| language/OpenAPI JSON parse | PASS |
|
||||
| `python3 scripts/langs_check.py` | PASS |
|
||||
| `python3 scripts/memory_contracts.py` | PASS |
|
||||
| `python3 scripts/web_server_contracts.py` | PASS |
|
||||
@@ -31,14 +34,13 @@ Documentation checks cover the 0.26.7 release note, Reader index, local Markdown
|
||||
| `python3 scripts/docs_check.py` | PASS |
|
||||
| `python3 scripts/release_smoke.py` | PASS |
|
||||
| `node scripts/web_service_ui_test.mjs` | PASS |
|
||||
| language/OpenAPI JSON parse | PASS |
|
||||
| `go test ./...` in `docker-agent` | PASS |
|
||||
| `python3 scripts/check_source.py` | PASS; explicitly reports Rust parsing/types/runtime as not verified |
|
||||
| `./dev.sh test` | Rust-independent gates PASS; wrapper exits 127 at the Rust stage because Cargo is unavailable |
|
||||
| `./dev.sh check` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| `cargo fmt --check` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| `cargo clippy --all-targets --all-features -- -D warnings` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| `cargo test --all-targets --all-features` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| complete release build | BLOCKED at Rust compilation: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| `./dev.sh check` | BLOCKED: Rust/Cargo toolchain unavailable |
|
||||
| `cargo fmt --check` | BLOCKED: Rust/Cargo toolchain unavailable |
|
||||
| `cargo clippy --all-targets --all-features -- -D warnings` | BLOCKED: Rust/Cargo toolchain unavailable |
|
||||
| `cargo test --all-targets --all-features` | BLOCKED: Rust/Cargo toolchain unavailable |
|
||||
| complete release build | BLOCKED at Rust compilation: Rust/Cargo toolchain unavailable |
|
||||
|
||||
The 0.26.7 source archive must not be described as compiler-verified until the Rust-enabled release-host gates pass. Rust-independent checks do not substitute for Rust parsing, type checking, Clippy or runtime tests.
|
||||
The 0.27.0 source archive must not be described as compiler-verified or production-ready until the Rust-enabled release-host gates pass. Static/source contracts do not substitute for Rust parsing, type checking, Clippy, unit tests or real protocol runtime tests.
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
| Requirement | Source implementation | Status |
|
||||
|---|---|---|
|
||||
| Bound glibc arena proliferation for managed systemd installs | `deploy/rustproxy.service`, `debian/rustproxy.service` and `scripts/deploy.py::service_unit` set `MALLOC_ARENA_MAX=2`; `/etc/rustproxy/environment` remains the administrator override | implemented in source |
|
||||
| Bound glibc arena proliferation for managed systemd installs | `deploy/rustproxy.service` and `scripts/deploy.py::service_unit` set `MALLOC_ARENA_MAX=2`; Debian packaging moved to the external packaging repository in 0.27.0, and `/etc/rustproxy/environment` remains the administrator override | implemented in source |
|
||||
| Avoid a duplicate identity transform buffer | `src/transform/mod.rs::decode` returns `Cow<[u8]>`; identity input is borrowed and compressed input owns only the decoded buffer | implemented in source |
|
||||
| Reduce JS/CSS minifier peak allocations | `src/transform/js.rs` and `src/transform/css.rs` iterate with `Peekable<Chars>` rather than collecting `Vec<char>`, and return the completed `String` allocation with `into_bytes()` | implemented in source |
|
||||
| Release temporary transform buffers earlier | successful changed transforms drop the decoded/collected origin buffers before final response construction | implemented in source |
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# RustProxy 0.27.0 implementation note
|
||||
|
||||
## Scope
|
||||
|
||||
0.27.0 changes downstream compression defaults/negotiation, makes Docker publications persistent across transient service loss, adds scoped compression overrides, and fixes cache occupancy meter rendering. SQLite remains schema 8. Saved configuration changes are additive/defaulted: vhosts and Web Services gain scoped compression/codec overrides and Docker assignments gain nullable compression/codec fields. Fresh installations also default the `Server` header policy to `custom: RustProxy`, while a missing legacy field still deserializes with the previous preserve behavior.
|
||||
|
||||
## Compression
|
||||
|
||||
Global compression defaults to zstd, Brotli and gzip enabled, with deflate disabled and the existing 1024-byte minimum. RustProxy parses `Accept-Encoding` weights before entering tower-http. Client quality values are authoritative; equal qualities use server preference `zstd -> br -> gzip -> deflate`.
|
||||
|
||||
Responses carrying `Cookie`, `Authorization`, `Set-Cookie`, `Cache-Control: private` or `no-store` are no longer rejected merely because of those headers. Compression remains disabled for existing `Content-Encoding`, `no-transform`, request ranges/`Content-Range`, SSE, upgrades, HEAD and non-body statuses. Existing encoded bodies are never recompressed.
|
||||
|
||||
Ordinary vhosts, generated Docker vhosts and Web Server services expose inherit/enable/disable dynamic-compression policy plus individual zstd/Brotli/gzip/deflate overrides. Global Response codec switches remain the hard availability ceiling and the minimum size remains global. A child scope may re-enable a codec disabled by an enclosing scope only when that codec is still enabled globally. In the dashboard, explicitly selecting **Disabled** hides and disables the child codec selectors; their stored values are preserved so changing the scope back to Inherit/Enabled restores the previous choices.
|
||||
|
||||
## Persistent Docker publications
|
||||
|
||||
A Docker assignment is desired configuration, not merely a reflection of the latest inventory. Once published, its hostname remains owned until the administrator unpublishes it or disables/removes the agent. When a successful Docker inventory no longer contains the assigned service, RustProxy compiles an unavailable fallback route with no backend and returns `503 Service Unavailable` plus `Retry-After: 1` instead of withdrawing the hostname and falling through to 404.
|
||||
|
||||
Agent transport failures retain the previous successful inventory when one exists, allowing known working backends to continue routing during a temporary control-plane outage. If no inventory has ever succeeded, published assignments are still materialized as 503 routes. When the same service key becomes routable again, normal reconciliation rebuilds its backend pool automatically; no manual pool action is required.
|
||||
|
||||
## Cache occupancy meters
|
||||
|
||||
The `/cache` JavaScript already calculates occupancy percentages from configured object/byte limits and writes those values to native `<progress>` elements. 0.27.0 adds explicit WebKit/Chromium and Firefox progress-track/value styling so the filled portion is visible instead of relying only on `accent-color`.
|
||||
|
||||
## Compatibility and verification
|
||||
|
||||
No SQLite migration is required. Older vhost, Docker assignment and Web Service documents load with inherited compression behavior because all new fields are defaulted. Existing stored `server_header` settings are preserved; documents predating that field keep the historical preserve behavior. Rust compiler/runtime verification remains mandatory on the release host; Rust-independent checks in `docs/TEST_REPORT.md` do not substitute for `cargo fmt`, `cargo check`, Clippy, tests or live protocol acceptance.
|
||||
@@ -337,6 +337,8 @@ remain uneditable. `false`, `preserve` or null security settings otherwise leave
|
||||
origin values unchanged. CSP and Permissions-Policy must suit the application;
|
||||
RustProxy validates header encoding, not the semantic correctness of those policies.
|
||||
|
||||
The **Compression** tab inherits the enclosing/global policy by default. It can enable/disable dynamic compression and independently inherit/enable/disable zstd, Brotli, gzip and deflate. Selecting **Disabled** hides and disables the codec selectors while preserving their saved values for a later Inherit/Enabled selection. Global **Settings -> Response** codec switches are the hard availability ceiling, so a vhost cannot activate a codec disabled globally; `min_bytes` also remains global. Client `q` values are honored; equal-quality codecs use `zstd -> br -> gzip -> deflate`, and an existing `Content-Encoding` is never recompressed.
|
||||
|
||||
## Live state, cache and limits
|
||||
|
||||
The dashboard defaults a newly created vhost to `cache.enabled: false`. When the
|
||||
|
||||
+1
-1
@@ -295,7 +295,7 @@ Web Server dispatch occurs after the existing vhost/location selection and acces
|
||||
- vhost/location custom and security headers;
|
||||
- custom error pages;
|
||||
- access logging and per-vhost Traffic metrics;
|
||||
- response processing/compression where applicable;
|
||||
- response processing/compression where applicable; each Web Service can inherit, enable or disable dynamic compression independently of its precompressed `.br`/`.gz` sidecar policy and can filter individual codecs; selecting Disabled hides/disables those codec selectors without clearing their saved values, while globally disabled codecs stay unavailable and the minimum size remains global;
|
||||
- TLS and existing HTTP/1.1, HTTP/2 and HTTP/3 listeners.
|
||||
|
||||
A local Web Server request does not create a reverse-proxy backend connection. WebSocket upgrades remain unsupported for a Web Server source.
|
||||
|
||||
Reference in new issue
Block a user