Files
RustProxy/docs/V0.28.0_IMPLEMENTATION.md
T
2026-10-08 09:42:10 +02:00

40 lines
4.3 KiB
Markdown

# RustProxy 0.28.0 implementation note
## Scope
0.28.0 extends the 0.27.3 maintenance release with operator-controlled GeoIP refresh, clearer listener status, cache `Via` metadata, narrower cache invalidation and a vhost Security header-rule layout repair. SQLite schema 8 and COLD cache format 3 are unchanged.
## GeoIP manual refresh and hot reload
`POST /api/geoip/update` is an authenticated/CSRF-protected control-plane action used by **Settings -> GeoIP updates -> Download now**. It invokes the same updater function as the background worker. The updater consumes direct source URLs, with optional publisher SHA-256 URLs per file, streams payloads into a private staging directory under the configured size limit, validates the selected database format, publishes only content whose local SHA-256 changed, and replaces the in-memory database only after validation succeeds. The UI action works when scheduled updates are disabled.
CSV mode uses separate IPv4 and IPv6 range files. MMDB mode uses one native MaxMind DB for both families and recognizes standard `country.iso_code` / `registered_country.iso_code` records plus a top-level `country_code` compatibility record or a root two-letter country string. The combined sapics `user-country.mmdb` is the default MMDB source. When the publisher checksum URL is empty, no remote checksum is required; structural validation and local content hashing remain mandatory. An updater-disabled MMDB configuration may leave the URL empty and manage `<data-dir>/geoip/country.mmdb` locally; the manual action then validates/reloads that local file.
The automatic worker, manual UI action and managed upgrade path serialize through `.geoip-update.lock`. Publishing uses the application's existing `ArcSwap<Database>`: a request that already owns the prior `Arc` remains memory-safe, while subsequent lookups load the new database. The request path uses this slot for country access rules, country rate limiting and optional country logging; administration and Prometheus status read the same slot. No process restart is needed.
## Listener status UX
Settings no longer compresses active endpoints into one `HTTP ... | HTTPS ...` sentence. Each active endpoint is rendered as a separate compact card with protocol and address plus badges for the protocols that are actually enabled on the running listener: `H1` is always present, TLS listeners add `H2` when ALPN HTTP/2 is enabled and `H3/UDP` when QUIC is enabled, while cleartext listeners add `H2C` when prior-knowledge HTTP/2 is enabled. Saved-listener restart semantics are unchanged.
## Cache Via and invalidation
`cache.via_header` is an optional string. Its default is `RustProxy`, producing `Via: RustProxy`; `null` disables RustProxy's Via value. Existing upstream Via fields are preserved and RustProxy appends its value. Validation bounds the configured field value to 256 valid HTTP-header bytes.
Cache compatibility hashing now normalizes request-only bypass fields and response-only cache diagnostics (`X-Cache`, hit counters, `Cache-Status`, resident age and `Via`). These changes apply on subsequent requests without discarding HOT/COLD objects. Representation/origin-affecting configuration remains in the compatibility identity and continues to invalidate incompatible objects.
## Vhost Security header rules
The request/response header-rule editor now uses the same structured header editor layout as location rules. Delete is contained in the rule heading and aligned to the right, while Operation, Name and Value remain in the field grid below it.
## Compatibility
- SQLite schema: **8**, unchanged.
- COLD cache format: **3**, unchanged.
- Existing saved configurations remain valid because `Settings` uses serde defaults; an absent `cache.via_header` becomes `RustProxy`.
- Legacy 0.27.3 release/checksum base URLs are accepted during configuration migration. The old default checksum base migrates to optional/no publisher checksum; custom legacy bases are translated into per-file URLs.
### Startup ACME runtime reporting
The human-readable startup banner no longer prints the initial `checking/preparing` ACME Python state, because that value can race the asynchronous runtime probe. When the probe finishes, RustProxy emits an `INFO` event named `ACME runtime check complete` containing the final status, mode, Python/pip/Certbot availability and managed-environment path.