Files
RustProxy/README.md
T
2026-10-17 11:57:16 +02:00

92 KiB
Raw Blame History

RustProxy 0.33.8

0.33.8: request-path performance and compatibility verification

This release reduces unnecessary cache-policy work and header copies when caching is disabled, creates body-idle timers only when a read actually waits, and formats request IDs without a generic per-byte formatter. Request IDs retain fresh operating-system entropy and the same SHA-256 construction.

Live-log history moves entry cloning and eviction cleanup outside its mutex critical section. Its bounded retention, best-effort insertion, drop counters, live stream and external sinks retain their existing contracts. Saturation tests record history losses explicitly alongside throughput and resource use.

The Web Server uses a narrow filesystem context and borrows its pinned root descriptor for nonempty paths. Adaptive reads are bounded at 64 KiB. A local file-body wrapper reports completion with the last expected byte, fixing HTTP/1 cache publication and complete-response accounting for ordinary and empty files. Range, conditional, HEAD, sidecar, cancellation and short-file cases are covered by additional tests; arbitrary upstream bodies retain their trailer semantics.

Compatibility testing also fixes existing explicit-Host-port validation, long-form .htaccess Expires parsing, expired cache inventory visibility, reserved backend-diagnostic header protection, escaped-JSON secret redaction, and certificate deployment authorization ordering. Obsolete tests are updated to exercise the existing documented behavior, including scheme-isolated cache keys, purge generations, private administration responses and bundled error pages.

The LB panel, database schema, default TLS/caching policies and bounded pool recycling retain their existing behavior. Live process regression, verified TLS, H2/H3/QUIC and WebSocket runners, repeated nginx comparisons, resource sampling, syscall profiling and a mixed-traffic soak are included in scripts/performance/. See the verification contract and the separately generated performance results for measured outcomes and limits.

0.33.7: named dashboard presets, panel components and chart typography

Titles across metric tiles and charts now use the same understated text tone (--muted) as the small Overview counters. The shade follows the active UI color theme; numerical readings keep their original contrast and fonts. The shared Vhosts Backend/H2 quick-view popover follows Corner rounding settings (including square, subtle, rounded and extra-rounded) for its panel, rows and close button, immediately and without losing the open popover.

Every Overview card title is now set at 12px in sentence case: counters, Process, RAM cache, backend tiles, charts and diagnostics use one proportional heading font. Secondary labels and small numeric readings use consistent monospace, while established HTTP/RAM/H1/H2 abbreviations retain their case. This Overview-only refinement does not change the uppercase styling of chart headings elsewhere in the interface.

The Cache page separates Domains and effectiveness from Stored objects with a consistent 10px gap. Vhosts upstream H1/H2 protocol badges now open the same anchored click-to-open popover used by the backend quick-view. It shows protocol observations and H1/H2 totals without a native hover tooltip; live status updates change its contents in place, without closing it.

Chart legends use the same 9px monospaced size as Requests per second throughout the interface, including numeric values and Overview density modes. In the Vhosts list, click the Backends count or Status metric to show a compact per-origin overview (ID, configured address and port, HTTP/HTTPS and HTTP version policy, health and last HTTP status from a real proxied response). Missing HTTP responses remain explicitly unknown; the configured hostname is shown rather than inventing a DNS-resolved IP. No additional probe or request is made to open the panel. Click outside or press Escape to dismiss. The H1/H2 policy badges use that same click-to-open popover instead of a transient hover tooltip. Its text and response counters update in place on live status ticks. Clickable Backend and Health tiles retain the square shape of adjacent Vhost metrics at every corner-rounding setting. Cache's two adjacent domain/object tables have a 10px gap.

  • Dashboard Presets replaces the former Arrange Overview modal. Save up to 16 named layouts per administrator, including widget order, visibility, card widths, density and Overview history sample count. Load, overwrite, rename, delete or restore factory defaults from one dialog. Unlock layout remains the interactive editor; existing saved preferences are retained.
  • Presets are persisted in a separate SQLite dashboard_presets table (schema 10), outside the 4096-byte administrator appearance document. They do not change the active proxy configuration revision. A factory reset changes the current dashboard, not existing named presets.
  • Chart headings throughout Overview, Web Server, diagnostics, Cache, Transform, Traffic, Vhosts and Streams use the established proportional font at 12px (Overview sentence case, other sections uppercase). Chart labels, values and entire legends (including Compression activity series names) use the existing monospaced font. Chart behavior is unchanged; two Overview titles now use sentence-case English/Polish translations. Proxy forwarding, trusted-client IP headers and WAF behavior were not modified. See API and verification. Rust compilation and live server acceptance remain outstanding.

0.33.5: fixed CPU chart scale on Overview

  • System and process CPU uses a fixed 0–100% vertical scale, without autoscaling when measured CPU usage is low. Both lines and the legend retain real CPU percentages; values above 100% are clipped at the top of the plot.
  • Keep the CPU plot 125px high across viewport sizes and dashboard densities so it does not stretch neighboring widgets. Other chart scales and heights, grid layout, sampling, APIs, databases and saved preferences are unchanged.
  • Overview heading follow-up: Requests per second shows the existing dynamic max XX.X req/s value in the upper-right instead of the LIVE badge; remove the redundant LIVE TRAFFIC eyebrow and its former peak footer label. Remove the LIVE badge from Connection Activity, without changing its counter, history, legend or chart rendering.

0.33.4: unified Web Server live metrics

  • Web Services now display six always-visible live metric tiles using the same responsive layout, borders, labels and typography as Vhost live metrics.
  • Each service's request-rate history uses the same full-width Vhost chart container, responsive SVG rendering and chart palette. The live metrics no longer need to be expanded, and values appear as soon as status is available.
  • Preserve the existing per-service counters, rate sampling, history limits, authenticated status stream and PHP availability semantics. No configuration, database or API changes are required.

0.33.3 sidebar appearance follow-up

  • Main navigation takes active/hover backgrounds and selection colors from the selected interface theme, not the chart color palette. Dark and ultra-dark use theme brand tones; light and cream blend theme brand/text for contrast. Switching the chart palette no longer changes sidebar or mobile-menu highlighting.
  • Sidebar navigation and the mobile menu follow the existing Appearance → Corner rounding setting. Changes take effect live with the current preferences; no additional JavaScript, API changes or preference migrations are required.

0.33.3: resizable Overview dashboard and free card placement

  • Visual layout editor fix: Arrange Overview cards uses uniformly sized, readable preview tiles (three columns on desktop, two on tablets, one on phones), not the 12-column canvas used by the actual Overview. Its 2/12 through 12/12 width controls still resize the real dashboard cards. Toolbars and hidden-card actions wrap cleanly without horizontal modal scroll; dragging, hiding, Save/Cancel and factory reset work as before.
  • Fixed time-series SVG viewport scaling after widening cards. All Overview line plots (numeric sparklines, full-width charts and diagnostic/network interface charts) now span their available width while keeping their vertical sizing and stroke thickness; donut charts remain circular. No new status polling is required.
  • In Unlock layout or Arrange cards visually, use − / + to change a card's width in the 12-column dashboard grid. Available widths are 2, 3, 4, 6 and 12 columns, restricted by card type for readability. 3 columns fits four graphs in one row on a desktop canvas wider than 1080px. Even the smallest number/sparkline cards can be expanded to 4 columns (twice their original width) and moved to the very top, beside regular charts.
  • The first manual move or resize enables a freely ordered layout, with no enforced separation between numbers, small charts, wide charts or panels. Responsive widths clamp to six/two columns on smaller canvases; dense grid packing reduces empty gaps without changing chart sampling or polling.
  • Card sizes are saved with the account's existing Overview preferences in nullable dashboard_widget_sizes; null retains 0.33.2 group ordering for older saved layouts, while {} enables free order with normal widths. Save, cancel, factory reset and modal preview include dimensions. Existing per-account layouts, factory visibility and 600-sample default are preserved. No SQLite migration or extra status fetches are needed. Runtime Rust acceptance remains required.

0.33.2: unified progressbar appearance

  • Cache HOT/COLD object, RAM and disk occupancy bars now use the same selected chart palette (--chart-accent) as Overview meters, instead of fixed green. Changing Appearance → Chart style updates every bar immediately, including native <progress> controls. The neutral track retains theme contrast.
  • Progressbar rounding follows Appearance → Corner rounding (default, square, subtle, rounded and extra) across Cache, Overview, WWW and traffic ranking bars. Both the track and its fill follow the same radius. No metrics, APIs, polling behavior, dashboards or saved preferences are changed.
  • The System Load → RAM used / total meter uses the same custom track/fill as other Overview cards (including the chart palette and corner radius), instead of browser-specific native <progress> rendering. Its original 5px height and status-based used/total percentage are unchanged. Missing total RAM does not produce an invented percentage.

0.33.1: factory Overview preset and live layout preview

  • src/admin/web/dashboard-defaults.json defines the factory Overview card order, visibility, density and initial 600-sample history. Both the Rust preference defaults and authenticated JavaScript use this same file. New accounts without stored preferences use the full preset; Reset to default restores card order/visibility, not density or browser-local sample history. Existing saved layouts and browser-persisted sample choices are preserved. Future registry additions remain opt-in.
  • An unlocked inline layout is now authoritative during live backend/Stream updates and unrelated preference refreshes. Showing/hiding those cards takes effect immediately and stays stable until Save and lock or Cancel. Cancel restores the saved layout. No extra polling, storage migrations or production request-path changes are introduced.

0.31.0 panel/cache additions: browser-negotiated Zstd/Brotli/gzip for HTML, JS and CSS (Settings → Administration); optional HTTP BAN/PURGE restricted to explicit IP/CIDR allowlist (Settings → Cache, disabled by default); System information Refresh button beside the API badge. See Settings and Cache.

Independent Rust reverse proxy and static Web Server with a dashboard, SQLite configuration, streaming HTTP/TLS/WebSocket forwarding, raw TCP/UDP stream hosts, IP-bound vhosts and backend pools.

0.31.9 Certificate API management: inspect and edit credential settings without exposing/rotating the current token, or regenerate one existing token with one-time display. Rust/Cargo and live testing required.

0.33.0: Web Server / PHP-FPM observability

  • Fixed dashboard startup: initialize the shared Overview history selector before any bundled top-level change listener. This prevents onChange startup errors and allows the authenticated panel to load. The History selector supports 60/120/300/600 samples, temporary edits and browser-persistent choices, in the header row beside the connection indicator (Overview only), independently of Cache/Transform, without additional status polling.
  • Compilation cleanup: restrict record_web visibility to the Web Server module, matching its ResponseKind argument and removing the private_interfaces diagnostic without changing request accounting.
  • Compact donut layout: move HIT/MISS totals beside the rings/legends rather than above them, preserving standard card-row heights and responsive behavior.
  • Twelve opt-in WWW widgets in the existing Overview layout registry: HTTP status split, static/PHP/other, PHP permit capacity, HTTP methods, recent 5xx percentage, PHP requests/s, requests/s, response-header latency, FastCGI failures, emitted-body byte rates, status-class rates, and top services. Every new widget starts hidden for both new accounts and upgrades from older saved layouts. Existing cards remain as configured.
  • Web Server per-service live details: expandable metrics in existing service cards, including RPS, 5xx, header latency, PHP concurrency permits, static versus PHP classification, and body bytes. The main live SSE/status snapshot is reused; no new API polling, SQL schema or per-request untrusted labels.
  • Prometheus exporter: bounded per-Web-Service response-kind/method/status, body byte and downstream compression counters, plus active headers, PHP concurrency limit/use/available gauges and classified FastCGI failures. Response byte counts are sampled from produced body frames before final downstream compression (not wire throughput). Response latency is time to headers (not complete delivery). PHP capacity is RustProxy's semaphore, not the actual PHP-FPM worker pool.
  • Grafana: retain the existing operations dashboard and extend it with Web Server, PHP-FPM, per-service breakdown and WWW/PHP correlation rows, all filterable by configured web_service IDs.

0.32.8: Overview metric visualizations

  • HOT cache RAM occupancy, COLD write-queue RAM occupancy and COLD disk occupancy appear as compact progress bars with used/limit details on the Overview. COLD cache objects live on disk; queue RAM and disk storage have separate budgets. Without a configured budget, the card shows bytes and an indeterminate meter rather than an invented percentage.
  • The main cache HIT ratio has a small HIT/MISS donut with counts and legend. The optional recent-window cache ratio uses the same format; bounded file-descriptor, HTTP protocol-share and backend-capacity widgets use progress bars.
  • Transformation and compression activity use two full-width, four-series live charts like the existing HTTP protocol mix. They show sampled per-second counts with named series; compression charts count gzip, Brotli, Zstd and deflate responses (not uncompressed ones).
  • These changes use existing status/SSE data without extra polling, API routes, database migrations or altered appearance presets. Existing account-specific Overview ordering/visibility preferences remain in effect; newly added cards are visible by default in factory layouts. Runtime integration testing remains required.

0.32.8: Overview action layout

  • The Overview heading stays left-aligned while the refresh, arrangement and layout-lock actions flow to the right; small screens wrap buttons without squeezing them into three equal columns.
  • The inline layout actions and visual editor keep their existing IDs and behavior while sharing the standard button styles (including Compact mode).

0.32.7 development follow-up: Appearance and H2 diagnostics

  • Overview Refresh now, Arrange Overview, Unlock layout, and Appearance Visual Overview editor / Show all cards use the common button sizing, including the global Compact preset on mobile.
  • Dashboard density is more distinguishable in metric tile spacing/numbers, chart heights and non-table panel padding/headers. The grid gutters, visibility/order preferences, refresh cadence and proxy routes remain unchanged.
  • A terminal request failure tied to a recently confirmed GOAWAY(NO_ERROR) is only traced at TRACE (not DEBUG) as a duplicate upstream diagnostic. It still returns 502 and appears in the access diagnostics; unrelated Canceled -> connection closed failures remain genuine errors. No blanket suppression by error string.

What changed in 0.32.7

  • H2 upstream recovery: gracefully drained upstream H2 connections sending GOAWAY(NO_ERROR) no longer poison Passive Health. Retire the affected Hyper pool generation and retry once, only for empty, replay-safe GET/HEAD/OPTIONS without WebSocket/administration tunneling. Non-replay-safe requests are not resent and can still receive 502 if the peer closes their connection.

  • Passive Health: collapse bursts of I/O failures within 250 ms into one failure observation; when active checks are enabled, consecutive successful probes can reopen a passively quarantined backend. Passive-only monitoring uses a bounded cooldown before a half-open traffic attempt. Keep the I/O error checkbox enabled to count unrelated, genuine I/O failures.

  • Error log: WARN when a backend is first removed from traffic, including backend ID, health source, failure reason, timestamp/description of the first error in that failure streak and the triggering error. Requires enabling the existing Error log sink (Settings -> Logging); when disabled, WARN goes to stderr/journald. Access logs still show individual 502s and subsequent 503s.

  • Acceptance: Rust compile/test and live negotiated H2/GOAWAY testing on staging are required before production installation.

  • **Appearance Dashboard layout ** Overview cards now use a full-width horizontal strip instead of a long list in the right half of Settings. Navigate sideways with the arrow buttons, toggle card visibility or reorder in place, or select Show all cards to expand to a full grid. The existing visual editor and saved per-account preferences are unchanged.

  • Rate-chart pause recovery: share one counter continuity policy across Cache HIT/MISS/BYPASS, Transform, HTTP Overview/protocols, optional wide/small charts, backend and Stream/Vhost traffic charts. After tab hide/pagehide (including BFCache) or a delayed refresh, keep plotted history, use the first reading as a new baseline, and resume rate points on the next normal interval. Full-width Overview, WWW and Web Server charts keep their drawn lines continuous by not appending the unavailable first rate sample; the current rate displays "-" until a valid interval is measured. A genuine measured zero still appears as 0/s. Cache and Transform intervals and the separate System information interval remain configurable; no additional polling.

  • Development fixes : keep Network diagnostics chart DOM stable across live refreshes, preventing repeated row/SVG replacement during scrolling. Network-interface chart history advances at the Overview live-status cadence using the latest sampled rates; fetching system data still follows the independent System information interval in Settings. Current CPU/RSS and per-interface RX/TX chart points now come from the existing background OS sampler through compact SSE/fallback data, every 3 s by default (saved 2 s settings remain valid), while Process details still follow the configured System information refresh. On mobile the Network interface chart list no longer traps touch scrolling in a nested scroll area. Origin protocol badges use exactly the same rounding as adjacent pills for all corner presets, without changing their color. Repair CSS descendant selector transformation and protect admin responses with Cache-Control: no-transform. Real iOS 27 scrolling remains unverified.

  • Mobile Overview: display two metric tiles per row on phone-width canvases, including 320-430px layouts and the initial pre-script paint. Keep horizontal overflow disabled, allow vertical touch scrolling and avoid unnecessary DOM reparenting/scroll anchoring during Dashboard preference refreshes.

  • Global corner presets: apply the selected Appearance shape consistently to vhost cards, status badges, entity cards and secondary panels as well as the existing metric and content cards. Keep the square-style draft dock unchanged.

  • Vhosts backend HTTP badges: show the configured upstream mode alongside the last HTTP/1.1 or HTTP/2 version actually returned by a real upstream proxy request for each origin, in the same lower badge row as the Vhost policy indicators (retaining the original observed/unknown badge colors). AUTO → ? means there is no response from the past five minutes; never guess a negotiation result or run an extra probe. The authenticated status payload includes last observation timestamp and counters per upstream client; the active connection may vary across requests.

  • Tests: Chromium simulated-mobile layout/scroll and shape presets, JavaScript live-status protocol badges and Rust response-version recorder test. The actual Rust build, iOS Safari interaction and end-to-end negotiated ALPN verification remain pending on a deployment host.

Previously in 0.32.5

  • ACL editor startup hotfix: fix the JavaScript i18n initialization order that could prevent the entire administration UI from loading. This does not change stored configuration or DNS ACL behavior.
  • Dynamic DNS/DDNS ACL allow rules: reusable ACL profiles, host policies, inline vhost/location ACLs, and Docker ACL assignments now accept allow office.example.ddns.net in place of a static client IP/CIDR. Existing IP, CIDR and country-based controls retain their previous precedence.
  • DNS answers (A and AAAA) are refreshed every 60 seconds, with up to 128 distinct hostnames, 32 unique addresses per hostname, 8 parallel lookups and a 4-second timeout. A failed/empty/invalid resolution is removed from the allowlist (fail closed); successful entries expire within 180 seconds if refresh tasks stall. Initial access is denied until the first successful lookup. No DNS lookup or locks on the proxy request path.
  • The ACL profile editor now offers an IP/CIDR vs DNS/DDNS selector and explains the allow-only semantics. Existing JSON documents keep the network string format; no database migration, extra public route or backend resolver behavior change. Name resolution follows the machine's DNS configuration.
  • DNS names are allow-only: dynamic deny rules are rejected because a DNS outage could otherwise silently remove a security deny. Hostnames must be ASCII FQDNs (punycode for IDNs, no wildcards, URL or ports).
  • Security note: allowing a DDNS hostname delegates address authorization to whoever controls its DNS records. Use trusted domains and keep a default-deny ACL profile; old IPs may remain allowed until the next DNS refresh.
  • Rust/Cargo compilation and real DNS/address-rotation testing are pending before production deployment.

Previously in 0.32.4

  • Follow-up build correction: a retry request now passes a cloned URI to the HTTP request builder, retaining the original for backend-specific HTTP/2 :authority selection. This resolves Rust E0382 (borrow after move) in src/proxy/types.rs. Neither retry policy nor backend dialing changes. Rust compilation is still required on a host with Cargo.

  • Tighter, consistent Overview gutters: the aligned Dashboard uses 4px gaps at normal UI density, 3px at dense and 12px at comfortable, in both axes. This applies between small tiles and between tiles and large panels. The more-specific dashboard-density CSS rules no longer override the grid gutter. Widget sizes, responsive rows and saved layouts are unchanged.

  • Preserve Host for every upstream protocol. http1, auto, compatible http2 and strict h2 accept preserve_host: true without forced UI downgrades. For HTTP/2, the outgoing HTTP authority follows the chosen Host; network address validation/DNS/TCP continue to use the configured backend URL. HTTP/2 ALPN and H2C retain their previous protocol/retry semantics, and legacy WebSocket Upgrade stays isolated.

  • Separated HTTP authority from transport identity. The existing TLS server-name setting still controls SNI and certificate identity independently of the visitor Host. No extra DNS queries, forced HTTP/1.1 fallback, protocol probing or request replay are introduced. For a verified certificate issued to a DNS name, specify tls_server_name and private CA as appropriate.

  • Less restrictive HTTPS-by-IP warning. The H1 diagnostic preset remains an explicit optional troubleshooting action, not a validation requirement for Auto/H2, pools or Preserve Host. Warn only when verifying HTTPS-by-IP without an explicit certificate DNS name (IP-SAN certificates are also possible).

  • Overview spacing: remove the leftover outer margin of the shared grid so the transition from metric tiles to large charts uses the same density-aware gutter as every other row, without altering saved layouts or card sizes.

  • No database/configuration migration or new privileges. Rust compilation, runtime protocol acceptance against real Angie and benchmarks are still required before production rollout.

Previously in 0.32.3

  • Consistently sized Overview rows: the dashboard now uses ordinary CSS Grid for both default and customized layouts. Six numeric tiles, three standard live charts, two optional wide charts and three diagnostic panels form separate, equal-height rows with the original density-controlled gaps. Blocks cannot float into unfinished rows of another size or acquire arbitrary heights. Ordering and Hide/Show remain editable inside each size group; existing saved widget IDs, visibility, preference API, chart data and reset/default behavior stay compatible. CSS Grid automatically resizes whole rows when live content grows, without pixel offsets, layout timers or extra polling.

  • Layout and shape polish: all 62 blocks remain movable, hideable, recoverable and resettable using existing account preferences. The X Hide control now matches the rounding of the arrow buttons for all five global corner presets; the RustProxy logo keeps its established outline and is excluded from global corner changes. No new metric polling, backend settings, API routes or version changes.

  • 62 optional/standard blocks: six more miniature history cards and seven new full-width multi-series charts. The new views cover requests/s, H1/H3 shares, cache misses, backend activity, protocol traffic rates, CPU, RAM, cache behavior, open connections, backend availability and latency. All 13 additions are hidden by default, consume the existing snapshot and have bounded histories; no extra backend polling. Buttons remain right-aligned, with the badge before them.

  • Backend upstream protocols: four explicit, backward-compatible choices: HTTP/1.1 (http1, default), Auto (auto: HTTPS ALPN H2/H1, cleartext H1), HTTP/2 compatible (http2: HTTPS ALPN H2/H1, cleartext h2c) and H2 only (h2: HTTPS requires H2, cleartext h2c). No post-failure request replay, extra retry loop or changes to WebSocket semantics.

  • Whole-Overview arrangement: the same visual editor now manages all 62 independent blocks: the previous 30 metric cards, 12 optional time-series cards and seven full-width panels (live traffic, system, connections, cache, process, network and backend table). A responsive, row-aligned grid allows free ordering/hiding of every block without sacrificing the symmetrical factory layout. Default view previews the factory layout without writing it; Reset layout requests confirmation and restores only Dashboard order/visibility in one preference PUT. Existing saved layout and unrelated account settings remain unchanged.

  • More opt-in charts: CPU, RSS, file descriptors, open connections, WebSocket tunnels, TLS failures/s, request errors/s, recent cache HIT percentage, cache HOT RAM, incoming HTTP/2 share, mean response latency and unhealthy backend count. All are optional and hidden initially; 30-sample history uses the existing status updates and never creates network calls. Ratios and rates require genuine counter deltas; missing observations remain unavailable, not fabricated zeros.

  • Overview Cards registry: source of truth for widget IDs, translations, selectors, defaults and data-source metadata is src/admin/web/dashboard-widgets.json. Both server-side preference validation and the authenticated dashboard JavaScript use this registry. Existing order and opt-ins are preserved; stale unknown widget IDs no longer invalidate an entire saved preference document.

  • Optional HTTP backend cards: fourteen opt-in Overview tiles: origin health, in-flight requests, errors/s, health-probe RTT, byte rates, configured upstream modes, request-rate trend, concurrency-capacity utilization, HTTP 5xx, timeouts, DNS/TCP/TLS/I/O errors, retry attempts, queue pressure and Hyper client-pool rotations. All reuse the existing status stream; all fourteen are hidden by default, including upgraded accounts. Configured protocol modes are not negotiated ALPN results.

  • No protocol migration or behavior regression for saved origins: unchanged protocol: "http2" HTTPS origins retain their 0.32.2 H1 TLS fallback. The new strict mode must be selected explicitly as protocol: "h2". The Origin editor labels ALPN/H2C transport behaviors, and HTTP/1.1 WebSocket Upgrade continues using its separate client. The OpenAPI Dashboard preferences schema now matches all 49 registered blocks.

  • Two optional appearance themes: Ultra dark uses an AMOLED-style near-black canvas and restrained mint highlights; Warm cream uses a muted ivory, low-glare palette. Both are selectable in Settings -> Appearance, persisted per administrator via the existing preferences API, available on the login screen after a cached choice, and preserve the original Dark/Light options and dark default.

  • Direct block hiding and restoring: when Overview is unlocked, each numeric tile, chart, diagnostic panel and table has an accessible × Hide from Dashboard button. This changes only the current layout draft; the collapsible Hidden blocks shelf restores any block immediately. Save and lock persists order/visibility once; Cancel reverts both. Hidden blocks also remain available in the visual editor. No measurement, registry or server data is deleted.

  • Direct, lockable Dashboard arrangement: choose Unlock layout on Overview, drag the handles on actual number tiles, charts, diagnostics panels or the backend table, or use the arrow buttons. Save and lock saves once; Cancel changes restores the previous order. Moving to another panel discards unsaved edits. No status re-polling or cloning of live charts is necessary. The modal editor remains available for enabling hidden blocks.

  • Labeled block types: all 49 entries have explicit registry metadata for Number, Number + chart, Chart, Diagnostics panel or Table. Appearance settings and the arrangement modal show the type, and the modal filters hidden blocks by type. Existing selections and defaults are unchanged.

  • Visual Overview layout editor: use Arrange cards visually on Overview or Visual layout editor in Settings -> Appearance -> Dashboard layout. Drag previews of metrics or large panels to reorder; Show/Hide controls and keyboard arrows are available. Save commits both lists in one account-preference update; Cancel leaves the layout unchanged. Existing Appearance controls still work.

  • Connection-level ALPN reuse: H1/H2 is negotiated only when opening a TLS connection, not on every HTTP request. The existing per-backend Hyper keep-alive/pool and bounded generation recycling (default 25,000 requests or 3,600 seconds) reuse negotiated connections and permit renegotiation when new connections open. No shared protocol-decision cache or extra probes were added: DNS and multi-origin backends may have peers with different H2 support. Explicit H1, H2C and H2-only, and WebSocket isolation keep their existing behavior.

  • Regression coverage: add local TLS peers for H2/H1 ALPN, H2-required failures, cleartext Auto, protocol serialization, and WebSocket isolation; add registry/preference regressions. Existing pooling, health probes, HTTP/3/QUIC and WebSocket transport behavior are unchanged.

  • Verification limit: pre-Cargo checks are runnable here, but Rust 1.99+, real-peer Rust tests, process benchmarks and production acceptance must be executed on a Rust-enabled host; see test report.

Previously in 0.32.2

  • Web Server cache revalidation: browser refresh (Cache-Control: no-cache or max-age=0), stale objects and freshness-constrained requests now use stored origin ETag / Last-Modified validators. An unchanged local static resource returns 304 to RustProxy; it reuses the cached body and increases X-Cache-Hits rather than resetting it to a new MISS.
  • Correct conditional delivery: retain the client's original validators for downstream 304 decisions (or serve a body on an unconditional refresh). HEAD, single byte ranges, transformed-response headers and Vary isolation are retained. If the local resource changes, a successful response replaces the previous representation; an uncacheable 304 discards the shared copy.
  • Reverse Proxy caching, frontend routing, PHP-FPM, configuration/storage schemas and the administration API remain unchanged. Rust/Cargo and browser-based runtime acceptance are required; see verification report.

Previously in 0.32.1

  • Overview readability at 90% UI scale: compare the supplied 0.31.9 source with 0.32.0, remove the latter's forced desktop card heights and restore content-sized rows. The six-column desktop layout and visible chart legends remain intact. Increase compact Dashboard headings (10 → 11px), values (22 → 25px), secondary text (8.5 → 10px) and the Payload breakdown (9 → 10px).
  • Consistent tile spacing: Overview now uses --ui-gap, the same density-aware spacing variable as other Dashboard sections, instead of its own fixed 10/8/6px spacing in normal/compact/ultra Dashboard modes. UI scale (including 90%) affects all gaps equally.
  • Appearance hints without overflow-causing tooltips: Dashboard layout Stream card descriptions now use native, localized browser tooltips and accessible button descriptions instead of absolute-positioned custom bubbles. The settings grid fits narrower containers and obsolete tooltip CSS has been removed.
  • Preserve Dashboard visibility/order preferences, density choices, responsive column breakpoints and opt-in Stream cards. No runtime, API, SQLite, proxy routing or language-pack changes. The Rust-independent ./dev.sh test checks passed, then stopped with code 127 because Cargo is unavailable; Cargo/build and authenticated-browser validation remain open until executed on a supported runtime.

Previously in 0.32.0

Dashboard follow-up: saved opt-in cards show on Overview even without active Streams (neutral no-data state). Appearance card-setting explanations remain on hover/focus; Overview metrics and legends are permanently visible inside the original six-column desktop grid, with taller tiles and no hover popovers. Stream editor explains the detailed-metrics inheritance and omits the redundant enable hint. scripts/start_stream_backends.sh, scripts/test_stream_tcp.py and scripts/test_stream_udp.py provide runnable mock peers and separate black-box tests. See STREAMS.md.

  • TCP and UDP Stream hosts support optional pools of up to 32 IP:port backends with weighted Round Robin and weighted Least Connections/Sessions, stable backend IDs, session caps, enabled/drain flags and per-session backend affinity (including UDP).
  • Optional bounded TCP Connect checks with rise/fall thresholds, and explicit UDP probes with exact response matching. UDP connect without a verified response is Unverified, not Healthy. Health checks are canceled on listener shutdown and globally bounded to 16 concurrent probes.
  • Existing per-Stream counters, status snapshot, Prometheus include_streams and RX/TX charts are retained. Opt-in backend detail counters and health observations use bounded config IDs only.
  • Settings → Appearance → Dashboard layout adds Stream overview, traffic, sessions and backend-health cards. These use the existing preference persistence, layout, status updates and SSE/polling; all new cards are hidden by default for existing and fresh accounts. No UI action restarts the proxy.
  • Old single-upstream configs remain valid, with an implicit backend primary. Backend pool edits still follow the existing Stream restart-required lifecycle. See Streams.
  • Release acceptance remains open until Cargo check/tests and live TCP/UDP/health checks are exercised on a Rust toolchain host.

Layer-4 streams

Raw TCP/UDP forwarding has its own Streams page in the primary navigation, alongside Vhosts, Redirects and 404 hosts. Streams use the same card/modal workflow as vhosts, but each stream owns a dedicated Layer-4 listener and an optional backend pool and intentionally bypasses HTTP ACL/cache/header/compression logic. The page exposes live per-stream connections/sessions, rejects, errors, transferred bytes and RX/TX rate charts. Listener changes require a restart. See TCP/UDP streams.

Named HTTP/HTTPS listener bind addresses use the same chip-style editor as vhost hostnames, including multi-address listeners.

Previously in 0.31.9

  • Settings → Certificate API: view the saved non-secret configuration of any Key ID, including comment, allowed certificate IDs, reload/deploy permission and creation/last-use timestamps. Current bearer tokens cannot be retrieved.
  • Edit settings: change a credential's comment, certificate allowlist and deploy permission without replacing its bearer token, Key ID, creation timestamp or last-use timestamp. Existing automation can continue with the current secret.
  • Regenerate token: replace only the selected credential's token, keep its settings, immediately invalidate the old secret and display the new token once. New per-Key-ID endpoints: GET and PATCH /api/certificate-api/{key_id}, POST /api/certificate-api/{key_id}/regenerate. Administrator session and CSRF are required for writes; external automation bearer tokens cannot call the management endpoints.
  • No SQLite migration or public proxy change. Existing PUT /api/certificate-api creation/manual rotation, revocation and token grants remain compatible. Verify with Rust 1.99+ before production use.

Previously in 0.31.8

  • Test organization: merge 28 mechanically numbered Rust test fragments into seven coherent tests.rs suites. Test-only files are exempt from the 500-line production-module limit; no test cases or runtime behavior are intentionally changed. See test report.
  • Stored Logs: click a desktop column heading to sort ascending/descending (including discovered nested JSON columns). Sorting applies to the entire bounded server-side matching scan before pagination, with missing values last. Direction and selected sort column persist per administrator. Existing filters, mobile cards, and repeated-value analysis are unchanged.
  • Built-in HTML responses: add missing styled pages for 200, 400, 408, 410, 413, 500 and 502. Any other built-in HTTP status uses the same compact dark appearance as the established 401/403/404/429/503/504 templates. Administrators' custom HTML remains authoritative, and 204/205/304 remain bodyless.
  • GeoIP: freeze loaded CSV arrays to exactly sized boxed slices; pack IPv6 range addresses in network byte order (34 bytes versus 48 bytes per record) without changing lookup semantics. Expected decrease in retained GeoIP allocations is workload-dependent, approximately 17 MiB for the reported 293,569 IPv4 and 284,256 IPv6 records; verify actual RSS separately.
  • Cache fills: avoid a duplicate body allocation when a transformed response supplies a single uniquely owned frame with known, tightly sized capacity. Preserve the existing bounded Vec-based streaming/fallback path and charge the shared backing capacity to HOT. This targets temporary peak allocations, not a guaranteed reduction of steady-state RSS.
  • Docker VHosts: display a neutral waiting state while the first agent observation is pending after restart, then the result from background discovery. Opening Docker VHosts reads the latest cached status even with per-page Live view off; first-result synchronization stops afterward. A configured TLS fingerprint no longer falsely signals a verified connection. Agent polling and security remain unchanged.
  • No settings/SQLite schema migration or change to the HOT limit. Runtime acceptance gate remains open until Cargo build/tests, browser, H1/H2/H3 and real-process resource tests pass.

Previously in 0.31.7

  • Source-package cleanup: old per-version audits and implementation reports may be omitted; preflight still requires active sources and docs embedded in the panel Reader. This fixes the removed docs/V0.25.5_AUDIT.md preflight error without restoring obsolete files.
  • Settings → Rules & headers: the global User-Agent blocklist, global custom header editor and client response settings now share a Cache-style tabbed page (three persistent sub-tabs). Settings → Security keeps sessions/password and host access policies.
  • Vhosts → Traffic policy: optional User-Agent-specific per-client-IP request limits. First matching case-insensitive substring or * wildcard rule overrides the default/country rate for that request, even when ordinary throttling is disabled. Each vhost, UA rule and IP has independent bounded fixed-window accounting. Up to 64 rules per vhost; patterns are validated and the feature is opt-in.
  • Revision history: show changed leaf fields rather than object-sized JSON previews, including stable IDs for array members. Full before/after JSON is available through a separate comparison dialog. Restore behavior unchanged.
  • Listeners: space apart HTTP/2 and HTTP/3 tuning shortcuts. ACL profiles: “Attached to” is initially collapsed but expandable.
  • update.sh: retain exactly two installed binary release directories (including current) and three private pre-update backups. Correct the previous mtime-sort path deletion bug; old releases were only printed, not actually deleted. After a successful update, optionally purge only incremental Cargo state unused for 30+ days, never fingerprint, dependency, build-script or compiled executable artifacts. A source-tree upgrade retains its own backups and target directory.
  • Graceful managed update: trace marker → systemd stop → forced best-effort HOT→COLD handoff when COLD is enabled; record completion, even when zero items were demoted. Existing update flush works regardless of cold_on_shutdown; no persisted schema or cold format change.
  • Compatibility: retains all 0.31.6 H3/iPhone diagnostic fixes, 0.31.5 mobile Logs and protocol-independent cache behavior. SQLite schema 9 unchanged. Rust/Cargo and live reload/update verification remain mandatory. See test report and configuration.

Previously in 0.31.6

  • HTTP/3 full-navigation GET/HEAD receive-stream handling, client cancellation classification and diagnostic events. Keep logo behavior unchanged. See HTTP/3 and test report.

Previously in 0.31.5

  • Add bounded User-Agent blocking globally under Settings → Security and per vhost under Vhosts → Security. Matching is case-insensitive; plain text matches a substring and * is a wildcard. Global and per-vhost rules are cumulative and run before opening an upstream.
  • Make Traffic table/chart values directly copyable, including User-Agent, IP, host/path and other displayed dimensions, to speed up blocklist creation and investigation.
  • Add Advanced parser · repeated values in Stored Logs. It counts repeated values for user_agent, client_ip, host, path or any supported parsed field across the bounded matching scan before pagination.
  • Add a default-enabled Consolidate rotated logs per vhost switch. Active vhost.jsonl and matching vhost.jsonl.*.gz rotations are queried as one logical vhost source while retaining individual source IDs internally.
  • Preserve SQLite schema 9 and existing saved configurations through serde defaults. See Stored Logs and test report.
  • Make /logs usable on phones with expandable log cards, full parsed-field details and no global horizontal scrolling; dynamic columns remain available.
  • Treat H3 peer-cancelled pre-header requests (e.g. F5 navigation) as stream cancellations, not fabricated HTTP 400 results. This corrects error reporting and avoids redundant internal response resets; it does not yet prove the reported mobile white-screen symptom resolved.
  • Keep both memory and cold cache across per-vhost H2/H3 switches; changing frontend protocols alone does not invalidate cached representations.
  • Keep optional Administration public panel HTTPS origin for the trusted-proxy Origin/CSRF security context; additional DNS hostnames are a separate Host allowlist, not its replacement.
  • Release gate remains open: Rust/Cargo compilation and real proxy/browser acceptance are still required before production deployment.

Previously in 0.31.4

  • Fix intermittent auth.invalid_origin on the administration panel only behind a trusted reverse proxy. The optional administration.public_origin pins the browser-facing HTTPS origin and allows a bounded X-Forwarded-Proto: https, http chain when the immediate proxy peer is trusted. Without a pin, ambiguous forwarded-proto values still return HTTP 403.
  • Set only administration.public_origin, for example https://panel.example.test, in Settings → Administration. Its DNS hostname is automatically included in the panel Host allowlist; it does not need to be repeated in allowed_hosts.
  • The advanced Additional allowed DNS hostnames section remains optional. Older configurations with a duplicate pinned hostname still load, and editing/saving omits that duplicate while preserving independent entries. Removing or changing the pinned URL never silently keeps the previous hostname implicitly allowed.
  • Keep strict checks for foreign Origin, mismatched or duplicate X-Forwarded-Host, cross-site requests, CSRF and untrusted proxies. The narrow opt-in self-admin session-cookie path may use the derived hostname only under its existing local-listener-risk conditions. Public proxy traffic and SQLite schema 9 are unchanged.
  • Restart RustProxy after modifying the setting. See Administration HTTPS and test report.
  • Release gate remains open: Rust/Cargo compilation, resolved dependency lockfile and real mobile/reverse-proxy acceptance are still required before production deployment.

Previously in 0.31.3

  • Correct mobile tab/BFCache recovery: share in-flight session validation across resume events and defer SSE/polling until verification succeeds. A failed check keeps a visible retry UI instead of reloading the page, and 401 still requires a fresh login.
  • Preserve the one-time initial Origin reload guard until full panel initialization succeeds. Authenticated dashboard navigation rejected for invalid Origin now returns a visible 403 HTML explanation rather than raw JSON; API requests retain JSON errors and the same Origin/Sec-Fetch-Site authorization policy.
  • Log bounded, credential-redacted Origin mismatch diagnostics (HTTP method, path, public host/scheme, fetch site and trusted forwarding metadata). No cookies, authorization headers, query strings or session tokens are logged.
  • New deterministic UI tests cover simultaneous visibility/BFCache events, session errors, manual recovery, stale session epochs and repeated transitions. No configuration or database migration; SQLite schema 9 and proxy traffic remain unchanged.
  • Release gate remains open: Rust/Cargo were unavailable in the validation environment, and the inherited 0.31.2 Cargo.lock still requires a real cargo update/build on Rust 1.99+. Reproduce mobile behavior in Safari/Chrome through the actual reverse proxy before deploying to production.

Previously in 0.31.2

  • Refresh Rust dependencies to current stable API families, including SQLx 0.9, Rand 0.10, Argon2 0.6, rcgen 0.14, Tower HTTP 0.7, Brotli 9 and Sysinfo 0.39. Retain SQLite schema 9, serialized settings, TLS/QUIC behavior and administration contracts.
  • Raise the minimum compiler version to Rust 1.99 for current dependency requirements, including Docker and RouterOS build images.
  • Release gate open: the updated dependency graph must be resolved with Cargo; the bundled lockfile is a prior-resolution snapshot and must be refreshed and tested before release. The source package is not production-verified.
  • Complete the dependency upgrade on a Rust 1.99+ build host with bash scripts/resolve_dependencies_0312.sh (registry and the pinned Swagger UI asset must be reachable, or supply an audited local archive). This calls cargo update, verifies the refreshed lockfile and runs formatting, clippy, build and tests. Review the lockfile diff and fix any Rust compiler errors before publishing.

Previously in 0.31.1

  • Improve mobile panel startup via an ordered JavaScript resource, versioned URLs and retry of temporary config failures.

Earlier panel improvements

  • Improved mobile panel loading behind reverse proxies: one ordered JavaScript resource, versioned assets and retry of temporary configuration errors.

  • Panel startup/mobile follow-up: replace the former white loading state with a RustProxy spinner, an automatic delayed reload suggestion and an error screen with reload link. Paint the shell before waiting for preferences/configuration/initial status; the header's Refresh now action sits beside the Overview title without adding a row. Negotiate Zstd/Brotli/gzip for fixed panel HTML and assets, with one-time encoding per resource; preserve public login and identity clients.

  • Refresh Overview through a shared, authenticated SSE channel with per-administrator live pacing (1, 2, 3, 5 or 10 seconds; default 3); fallback status/log polling is active only after SSE failure. Detailed system diagnostics remain in the separately scheduled API; live status carries a small cached CPU/RSS/network chart snapshot.

  • Settings → Appearance → Data refresh now stores per-account Live enable/disable and independent Traffic, Cache and System information intervals. Manual mode (0) and the global Live switch disable automatic requests while preserving manual refresh, charts, filters and pagination.

  • Poll only the current Traffic/Cache view, and fetch system diagnostics independently from /api/system-info when Overview or the relevant Settings section needs them. The previous full /api/status response remains supported, while ?view=live provides compact fallback.

  • Centralize dashboard polling with cancellation/in-flight guards, hidden-tab pause and logout cleanup; retain SQLite schema 9, previous preferences, proxy traffic and the existing authentication model.

  • Rust compilation and live wire/performance acceptance remain required on an equipped target; see verification report.

Previously in 0.30.1

  • Match H1/H2/H3 legend markers to the corresponding protocol-chart line colors across chart palettes.
  • Keep About focused on the product, author, license and source/package links. Move Python/ACME diagnostics out of the About dialog.
  • Add Settings -> System information (/settings?tab=system-info), showing OS release/kernel/architecture where available, CPU, RAM, uptime, process metrics, ACME interpreter/pip/Certbot versions where discoverable from local metadata, ACME mode/state, and data paths. OS/kernel details come from the existing sysinfo Rust library. Version display reads bounded pyvenv.cfg and Python .dist-info/METADATA files at ACME initialization; it does not execute diagnostic commands. Some system-installed tools lack these metadata files, so their versions will be shown as unavailable rather than guessed. Operational ACME checks and certificate issuance still run Python/Certbot as required.
  • The authenticated status API exposes the extra read-only runtime fields; SQLite schema 9, Cold Cache format 3 and existing configurations are unchanged. Real Rust compilation and live integration verification are still required.

Previously in 0.30.0

  • Edit individual active health-check policies in Vhosts → Health. The backend selector lists only members with monitoring enabled in Backends. Choose a member and optionally customize its TCP/HTTP mode, path, Host, interval, timeout, thresholds and expected status range. Other backends retain their unsaved edits; disabling monitoring hides its editor but preserves the saved override for future re-enablement. No API or SQLite schema changes.
  • Improve sustained-memory handling: reclaim selective PURGE-generation bookkeeping, avoid unnecessary analytics-label allocations, reuse serialized access JSON across JSONL/Logstash/Loki, and avoid duplicate directory listing vectors/HTML buffers. Stored Logs discovery retains at most 256 per-vhost and 64 rotated-gzip candidates. See memory stress verification for the audit and real-world RSS/load test procedure; source-only checks cannot rule out runtime leaks.
  • The previous 0.29.7 improvements remain included. SQLite schema 9 and Cold Cache format 3 are unchanged.

Previously in 0.29.7

  • Configure active/passive monitoring per backend independently from backend enablement and balanced-pool eligibility. Optional per-member active TCP/HTTP health-check overrides inherit the vhost's HTTP Host when omitted. An unmonitored internal 404 backend remains routable but is no longer probed or passively ejected.

  • Add global and per-vhost HIT-only cache diagnostics. Suppress X-Cache, X-Cache-Hits, X-Cache-Reason and Cache-Status on MISS/BYPASS, while retaining diagnostic headers on actual HIT. The separately configured Via header still applies; internal metrics are unaffected.

  • Detect and warn about Web Services sharing the same PHP-FPM endpoint with different PHP_VALUE or PHP_ADMIN_VALUE settings. Shared PHP-FPM worker processes can retain dynamic ini settings between requests (including open_basedir), so WordPress/Roundcube must use distinct PHP-FPM pools/sockets when their policy differs. See PHP-FPM isolation.

  • Add configuration/Rust source regressions for per-backend monitor overrides, HIT-only cache policy and cache revision stability. Existing persisted settings load with their prior defaults; SQLite schema 9 and Cold Cache format 3 remain unchanged.

  • Cargo and live PHP-FPM tests remain required before production deployment.

  • Expand per-service and shared-profile PHP-FPM editor help: field-by-field examples, FastCGI NAME = value, PHP_VALUE and PHP_ADMIN_VALUE syntax, and dedicated WordPress/Roundcube pool guidance. Fix checkboxes/labels and add explanatory info tooltips for PHP execution, PATH_INFO and Authorization forwarding. See PHP-FPM settings.

  • Add opt-in vhost origin-error interception (Vhosts → Pages) with selected 400/404/5xx statuses. RustProxy replaces application HTML with a configured vhost/global page or a built-in page; the application's HTTP error status is always preserved, final internal fallbacks have precedence, and intercepted responses are no-store. Origin responses remain unchanged when interception is disabled, even if a global RustProxy error page exists.

Previously in 0.29.6

  • Fix native Web Server/PHP-FPM response compression across HTTP/1.1, HTTP/2 and HTTP/3 by fusing the FastCGI response stream; prevent a futures-util::stream::unfold panic after EOF.
  • When Error file is enabled, write warnings, errors, PHP-FPM stderr and worker panic diagnostics to the error file instead of duplicating them in systemd. When disabled, use the console. If the file cannot be written, fall back to console diagnostics.
  • Add EOF, gzip and error-log routing regressions; actual Rust/Cargo build and Roundcube runtime verification are still required.

Previously in 0.29.5

  • Fix PHP-FPM PATH_INFO dispatch for existing scripts such as Roundcube 1.7 /static.php/skins/...: when PATH_INFO is enabled, invoke the script before try_files can fall back to /index.php.
  • Keep FastCGI SCRIPT_FILENAME, SCRIPT_NAME, PATH_INFO, REQUEST_URI and the query string accurate, and check access rules on the resolved PHP script path.
  • Add mock FastCGI regression tests proving that Roundcube static assets reach static.php; opt-out (path_info: false) retains the previous fallback behavior.
  • No database migration or saved Web Service configuration changes. Rust compiler/runtime verification is still required before production deployment.

Previously in 0.29.4

  • Reuse named PHP-FPM profiles across Web Services, or keep per-service PHP-FPM settings; edit profiles in the expandable Web Server modal.
  • Open the same PHP-FPM profile manager from the PHP-FPM profiles button beside New Web Service on the Web Server page.
  • Run vhost RustProxy cache and enabled response transformations for Web Server filesystem/PHP sources with normal response privacy protections.
  • Preserve the original request Host in FastCGI HTTP_HOST for WordPress, including HTTP/2/HTTP/3 authority-only requests.
  • Added regression tests; the Rust compiler/runtime gate is still required before production deployment.

Previously in 0.29.3

  • Fix internal error fallback for empty GET/HEAD requests over HTTP/2 or HTTP/3 with unknown body-length hints by safely checking if the body stream is empty; nonempty and unbounded bodies remain protected from unsafe replay.
  • Preserve the final status, headers and HTML returned by the internal fallback location, including its own 404 page, instead of replacing it with RustProxy's global error page. Warn when a named internal target cannot be found.
  • Add Rust regression tests for empty H2/H3 GET/HEAD, unknown-length request bodies and response precedence. These Rust tests require a Cargo-enabled environment before production deployment.

Previously in 0.29.2

  • Add Nginx-style internal error fallbacks for the vhost source and Custom locations. Configured upstream/Web Server statuses can internally hand the original method, URI, query string and request context to an internal Custom location without an HTTP redirect. Supported bounded statuses are 403/404/500/502/503/504; configuration cycles are rejected and runtime dispatch has a depth limit.
  • Execute error fallback before an intercepted response is finalized or cached. The target location re-enters the normal vhost/location pipeline, including ACL, headers, compression, cache policy and response processing. Request bodies are replayed only when safely bounded and replayable; otherwise the original error is retained.
  • The main Web Server source ignores backend health/unavailability; Custom Locations configured for Reverse Proxy continue to use their backend pool. Error-fallback-specific Prometheus counters have been removed.
  • Add streaming multipart byte-range responses for requests such as Range: bytes=0-99,200-299, with a maximum of 16 ranges and identity representation for multipart responses.
  • Add opt-in PHP-FPM PATH_INFO splitting. With path_info: true, /index.php/foo/bar securely resolves the existing index.php script, keeps SCRIPT_FILENAME on that file and sends /foo/bar as PATH_INFO.

0.30.0 keeps SQLite schema 9 and Cold Cache format 3. Existing configurations remain loadable; new optional health and diagnostic fields receive backward-compatible defaults. Historical details are in CHANGELOG.md.

Historical 0.26.7 release notes

  • Show explicit HOT and COLD cache occupancy progress on /cache, including object-count and byte/disk limits from Cache settings plus percentage usage.
  • Preserve compatible upstream client pools across unrelated active-snapshot rebuilds so generation age, request count and Rotations diagnostics do not restart at zero unless the backend connection policy actually changes.
  • Keep age-based backend rotation in the maintenance loop and retain request-count rotation; compatible snapshot reuse now makes the existing counters observable over long-running processes.
  • Refresh container documentation and ship the OCI image with one pinned Certbot environment containing all RustProxy-supported DNS plugins: Cloudflare, OVH and RFC2136.
  • Review current installation/container/cache/backend lifecycle documentation for stale version or behavior statements.
  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.6 requires no data migration.

0.26.7 retains the 0.26.6 access-policy and administration fixes below.

Retained 0.26.6 release notes

  • Keep backend diagnostics visible-column selection, sort key and sort direction synchronized with the account-scoped administrator preferences whenever preferences are loaded or updated.
  • Clear the ACME certificate-creation form after the issuance job finishes successfully, so successful certificates do not leave stale values while failed jobs keep the non-secret form values available for correction.
  • Compose explicit IP allows and Allow only countries as alternatives inside one ACL policy scope. Explicit IP denies and blocked countries still win, and profile/vhost/location scopes remain cumulative. This makes default=deny support private CIDRs or selected countries as intended.
  • Document the sibling migrate_npm_core.py and migrate_npm_api.py modules required by scripts/migration/migrate_npm.py, and fix the container example to mount the dedicated scripts/migration directory.
  • Detect the Linux runtime environment in Process diagnostics. LXC reports Linux / LXC and overrides system uptime with PID 1 age plus load average from the container-visible /proc/loadavg; VM/host/Docker and other Linux environments keep the existing host statistics path.
  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.5 requires no data migration.

0.26.6 retains the 0.26.5 interface-scaling and listener-navigation fixes below.

Retained 0.26.5 release notes

  • Keep compact toolbar select controls on the same scaled box model as neighboring inputs, including Stored Logs, Backends, Docker, vhost-style lists and Settings filters. Form-control dimensions consume the interface-scale field variables consistently.
  • Make Streams -> Add TCP/UDP listener navigate to Settings -> Listeners instead of opening a new Stream configuration dialog.
  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.4 requires no data migration.

Retained 0.26.4 release notes

  • Extend session-only editor drafts to 404 hosts, preserving the complete unfinished form state when another editor is opened or the dialog is minimized.
  • In Settings -> Appearance, the Overview list shows clean card names and visibility/reorder actions without type badges; the draggable visual editor still identifies numeric cards, charts, tables and diagnostic panels. Appearance is the first Settings tab on a new browser, then the last active tab is remembered; explicit links such as /settings?tab=cache always win.
  • Independently of Dark, Light, Ultra Dark and Cream, administrators can choose Corner rounding (Original, Square, Subtle, Rounded or Extra rounded). Original matches the established geometry in every theme and is the default for existing accounts. Ultra Dark preserves the original coral/soft-green logo mark while keeping its near-black background.
  • Complete the Polish translation for Settings -> Appearance -> Button style and keep the button-size preference independent from global interface scale.
  • Keep search/filter inputs in compact toolbars no taller than the active button style, including Backends, vhost-style lists, Docker, Logs and Settings search controls.
  • Reuse the vhost Enabled control presentation in 404 hosts, Redirects and Streams so modal enable/disable state is visually consistent.
  • Replace the tall Overview-card checkbox list in Appearance with a compact responsive tile grid; each tile toggles visibility and retains reorder controls.
  • Run time-based upstream-client pool recycling from backend maintenance as well as request dispatch, so an idle backend rotates after its configured age instead of remaining on generation 0 until the next request.
  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.3 requires no data migration.

Retained 0.26.3 release notes

  • Make interface scaling truly global: the 70-125% setting now scales the authenticated dashboard, navigation, dialogs, overlays, draft dock and other top-level administration UI consistently. Form fields receive an additional proportional size adjustment so inputs/selects/textarea do not remain visually oversized at low scale or undersized at high scale.
  • Tighten the Overview metric cards so wide dashboards fit more telemetry with less empty vertical space.
  • Expand chart presentation presets to Default, Soft, Technical, High contrast, Neon, Monochrome, Warm and Cool. Presets now alter palette, surface treatment, grid character, line weight and chart contrast instead of changing only stroke shape.
  • Restyle the bottom-right draft dock as a square-corner panel that follows the existing RustProxy card/navigation language instead of using a rounded glass/floating treatment.
  • Let the draft dock collapse to one bar and show the age of every suspended draft.
  • Add Settings search across translated section labels and settings content, per-section Appearance resets, and a full Appearance reset.
  • Add visual palette buttons for all chart presets, independent table/log density, independent dashboard density, and an Ultra compact option for both data tables/logs and Overview cards.
  • Add a per-user Button style selector: Normal keeps the refreshed buttons and Compact restores the smaller source-style button sizing independently from interface scale. The selection now applies consistently to generated vhost actions and tab buttons inside dialogs.
  • Let administrators hide/show and reorder the Overview telemetry cards from Appearance without changing metric collection.
  • Keep all new appearance choices account-scoped in the existing SQLite administrator-preferences document; schema 8 and the saved proxy configuration format remain unchanged.

0.26.3 includes the 0.26.2 administration workflow improvements below:

  • Add session-only editor drafts for Web Server, Vhosts, Redirects and Streams. Closing an edited form minimizes it into a bottom-right draft dock, while opening another item starts a clean independent editor.

  • Add Settings -> Appearance. Theme, language, interface scale, 12/24-hour time display and chart style are account-scoped preferences stored in SQLite; the scale slider now spans 70-125%.

  • Apply time-format preferences to dashboard timestamps and compact expanded Stored Logs details to reduce scrolling on large records.

  • Merge the Stored Logs and Live Logs top-bar actions into one Logs menu.

  • Replace the Stored Logs filter row with an optional log-source selector, one query field and page-size control. Search accepts Kibana-style field clauses such as req: GET AND !country: Poland, quoted values, wildcards and numeric comparisons.

  • Parse JSON/JSONL records into dynamic selectable columns discovered from returned fields instead of maintaining fixed protocol-specific columns. matched_by and sni are no longer hard-coded table columns, but remain available when present in a record.

  • Parse the built-in RAW error-log format into timestamp, level, target, message and detected key=value fields while retaining the original raw line.

  • Expand selected records as parsed field/value rows with optional raw JSON, and move the column picker to the upper-right edge of the result table.

  • Remove the Configured files inventory while keeping an optional source selector; the explorer searches all bounded configured log sources by default and narrows to one selected source when requested.

  • Replace backend sort text (A-Z / Z-A) with direction arrows (↑ / ↓).

  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.1 requires no data migration.

Historical release information remains in CHANGELOG.md and docs/CHANGELOG_TECHNICAL_ARCHIVE.md. Current verification status is maintained in docs/TEST_REPORT.md.

Documentation

  • /docs - authenticated project documentation Reader plus the API/OpenAPI tab.
  • docs/README.md - canonical documentation index.
  • docs/WEB_SERVER.md - Web Server configuration, HTTP behavior and filesystem security.
  • docs/FILE_LOGS.md - stored-log explorer, protocol-error records, bounds and filesystem security.
  • docs/PHP_FPM.md - implemented FastCGI/PHP-FPM integration, safety model and runtime requirements.
  • docs/TEST_REPORT.md - verification results and environment limitations.
  • docs/TODO.md - unresolved follow-up only.

Release history

Historical user/operator-visible changes are maintained in CHANGELOG.md. Detailed historical implementation notes are retained in docs/CHANGELOG_TECHNICAL_ARCHIVE.md, and completed roadmap milestones are retained in docs/ROADMAP_HISTORY.md.

Core capabilities and references

Managed certificates imported into the library renew automatically unless disabled. Initial issuance/import remains explicit and staging-first; imported PEM alone is not auto-managed. See renewal and recovery.

Read installation and update, host access and locations, migration, NPM migration, ACME providers, Prometheus, cache diagnosis, HTTP/3 scope, TCP/UDP streams and container deployment. Cloudflare Tunnel remains deferred. Docker discovery is available through the standalone agent; see Docker discovery. Examples are disposable full configurations: applying one replaces, not merges, an existing document.

Installation and source build

Official package repositories

The preferred installation/update path is the project-maintained package repositories:

  • DEB/RPM packages: https://rustproxy.linuxiarz.pl/
  • OPNsense plugin: https://rustproxy-opn.linuxiarz.pl/

Use the repository instructions appropriate for the target operating system. Package/service installs do not need a packaging-time GeoIP download: the proxy starts an enabled-by-default background updater after its listeners bind, performs the first verified refresh immediately, and then checks again every 24 hours unless changed in Settings -> GeoIP updates. Building on Debian is kept as an optional source/development path rather than the primary installation method.

The production CLI default data directory is /var/lib/rustproxy. dev.sh explicitly overrides it to the repository-local ./data directory for development commands.

Optional: Debian 13+ one-line source install/update

The bootstrap installs the compiler/build dependencies and Rust, clones this repository and builds the locked release. With no argument it runs in auto mode: a host without a managed RustProxy installation is installed, while an existing /opt/rustproxy/install.json triggers the safe update.sh path with backup, health check and rollback. First install starts HTTP on 0.0.0.0:80, HTTPS on 0.0.0.0:443 and keeps the administration panel on loopback HTTP 127.0.0.1:9090. Updates preserve the saved listener and service settings. Use an SSH tunnel for initial remote access, then enable Administration HTTPS before exposing a non-loopback admin bind.

# automatic: install on a new host, update an existing managed installation
wget -qO- https://git.linuxiarz.pl/gru/RustProxy/raw/branch/master/install-debian13.sh | bash

# explicit update
wget -qO- https://git.linuxiarz.pl/gru/RustProxy/raw/branch/master/install-debian13.sh | bash -s -- update

Manual build prerequisites used by that bootstrap:

apt install -y build-essential gcc git ca-certificates python3 pkg-config wget sudo python3-certbot-dns-rfc2136 python3-certbot-dns-cloudflare
wget -qO- --https-only --secure-protocol=TLSv1_2 https://sh.rustup.rs | sh

Rust stable (declared minimum 1.88), Cargo, C compiler/linker, Bash and Python 3.10+. Linux is the primary deployment target; macOS/WSL2 need normal native build tools. Detailed OS diagnostics currently use Linux procfs and cgroup v2. Unsupported measurements remain null/N/A.

The first build needs access to the Rust toolchain and crate registry. dev.sh never installs system software or runs sudo. Rustls handles runtime TLS; zstd's native dependency still needs a C build toolchain.

The Debian bootstrap intentionally builds with one Cargo job, LTO disabled and codegen-units=8. This avoids rustc being killed by the OOM killer on small VPSes while leaving the repository's normal release profile unchanged. For a manual low-memory build use:

CARGO_BUILD_JOBS=1 CARGO_PROFILE_RELEASE_LTO=false \
  CARGO_PROFILE_RELEASE_CODEGEN_UNITS=8 cargo build --release --locked

Package-build metadata remains outside this source tree and is maintained with the official package repositories above.

The 0.28.1 source archive preserves the resolved Cargo.lock supplied with the source tree and updates only this package's own version entry. This packaging environment has no Cargo, so the dependency graph was not re-resolved here. On the compiler-enabled deployment host, run the locked check/test/release gates below and retain the verified lockfile. dev.sh can generate a lockfile only when one is genuinely absent; it does not replace normal locked verification.

cd RustProxy
bash dev.sh doctor
bash dev.sh check
bash dev.sh test
bash dev.sh
Service Development default
Default HTTP http://127.0.0.1:8080
Default HTTPS https://localhost:8443
Administration (default) http://127.0.0.1:9090; HTTPS/remote bind is opt-in in Settings
Optional protocol fixture 127.0.0.1:9000, only with RUST_PROXY_DEMO=1

In a second terminal, print the one-time setup capability and use the browser, or initialize an administrator locally:

bash dev.sh admin setup-token
# Alternative: interactive account creation, no default credentials.
bash dev.sh admin init

There is no default username/password. Normal startup serves a neutral informational page for an unconfigured address and does not seed sample vhosts. The self-signed bootstrap certificate is retained under data/certs and is not publicly trusted. Assign intended certificates explicitly. Public frontend TLS does not implicitly expose the separate administration listener. Administration remains loopback HTTP by default; enable its own HTTPS setting before choosing a remote bind. Existing databases are never reset by this default.

Use the protocol fixture only explicitly when running the documented test suites; RUST_PROXY_DEMO=1 bash dev.sh seeds a new disposable database. The separate bash dev.sh mock helper remains available for cache/backend testing.

For a system service, build as an ordinary user and follow the complete procedure in INSTALL.md:

bash dev.sh release
bash install.sh --plan --binary target/release/rust-proxy
sudo bash install.sh --binary target/release/rust-proxy
# A subsequent release:
sudo bash update.sh --binary target/release/rust-proxy

Copy .env.example to .env for startup defaults; it is trusted shell code. RUST_PROXY_DEMO=0 disables the demo. RUST_PROXY_TLS=0 removes the startup TLS default used when bootstrapping listeners.

The release checker reads its compile-time defaults from repository-root UPDATE_CHECK.toml, which is embedded in the final binary. It checks the configured Cargo.toml URL immediately on startup and then every 3600 seconds by default. A failed request is ignored until the next interval; it never blocks startup or proxy traffic and it never installs updates. On Unix-like systems the checker keeps its bundled public roots and also imports certificates from SSL_CERT_FILE, CURL_CA_BUNDLE and common Linux/BSD CA bundles, including the FreeBSD/OPNsense ca_root_nss path. It follows at most five credential-free HTTP(S) redirects and never downgrades an HTTPS check to HTTP. Failed checks stay invisible in the dashboard, preserving the existing footer behavior, but are emitted as application ERROR events so the optional error-file sink can capture them. Operators may override the embedded values with global CLI options or equivalent environment variables:

--update-repository-url         RUST_PROXY_UPDATE_REPOSITORY_URL
--update-version-url            RUST_PROXY_UPDATE_VERSION_URL
--update-check-interval-secs    RUST_PROXY_UPDATE_CHECK_INTERVAL_SECS

Set the interval to 0 to disable automatic checks. Debian/systemd installs may place the environment overrides in /etc/rustproxy/environment; source/development runs may use the normal process environment.

Persisted frontend sockets live only in listeners.endpoints and are edited under Settings -> Listeners. Listener address/TLS/H2/H3 capability changes need a process restart; vhost H2/H3 switches only narrow those capabilities and routing/pool policies otherwise use validated hot publication.

Private vhosts and backend pools

Use Settings -> Listeners to configure frontend sockets, then use Vhosts to select those named listeners and configure backend members. examples/vhosts-private.json binds its named listener only to 127.0.0.2 and uses two explicit loopback origins. Replace these with addresses assigned to your machine and your real services. examples/vhosts-balanced.json shows an opt-in public 80/443 deployment; do not apply it unintentionally.

A private vhost is selected by hostname and the accepted socket's actual local IP, port and TLS state. Sending its Host/X-Forwarded-* values to a different IP does not select it. A shared wildcard socket may accept TCP at multiple addresses, but each vhost keeps its original routing constraints. IP binding is not a firewall or authentication: NAT/another proxy can still forward traffic to that private IP. Keep network restrictions and application authentication.

New health-checked members remain in checking until the configured successes make them eligible. No healthy member means 503; a healthy backup may be selected. HTTP checks measure time to response headers, not whole-body throughput. Affinity cookies bypass shared cache; they contain only an opaque routing token and are not login sessions. Existing cookie sessions may finish on a draining healthy member. The keepalive controls are connection reuse, not Keepalived/VRRP.

Save pool/routing/security changes live. New/removed sockets and TLS ALPN changes need a process restart; active vs desired endpoints are visible in Settings/API. Old top-level routes are converted once into vhosts during validated startup/import. There is no separate legacy routing UI or dispatcher; path-to-origin ownership is retained. Read the migration guide before updating an existing database. See VHOSTS.md for algorithms, defaults, bounds, caveats and the complete configuration contract.

Standard ports without running as root

Settings -> Listeners accepts multiple named endpoints and socket addresses such as 0.0.0.0:80, 0.0.0.0:443, [::]:443 and custom ports. Presets change only the port: they do not silently replace a loopback interface with a public one. The admin listener is independent of these controls and stays loopback by default. In Settings -> Administration, enabling HTTPS permits a persisted non-loopback bind using either the application-managed certificate or a selected certificate. Plain remote HTTP remains available only with the explicit --allow-remote-admin startup flag.

Linux low-port binding can require CAP_NET_BIND_SERVICE. Use a dedicated service account and the example in deploy/README.md, not a root-run application. Port conflicts and OS permissions cannot be proved by merely saving configuration; bind failures are reported on restart. See settings, defaults and rollback.

Cache and response controls

The shared cache is enabled by default. Normal fresh 200 GET and cacheable HEAD requests use s-maxage, max-age or Expires; a configurable default TTL applies only to explicit public responses without an origin freshness lifetime and defaults to zero. GET/HEAD share the same frontend scheme + Host + exact URL object, response Vary selects representation variants, and unrelated request headers or the selected backend-pool member do not fragment that object. Since 0.19.1 HTTP and HTTPS use distinct primary cache identities so scheme-dependent origin responses cannot cross protocols. Non-GET/HEAD methods pass without globally purging unrelated cached objects.

Cookies (except the configured static-asset exception), authorization, ranges, If-Match/If-Unmodified-Since, private/no-store responses, Set-Cookie, Vary: *, streaming events and failed/incomplete bodies are not reused. If-None-Match and If-Modified-Since can be answered from a fresh cache entry as local conditional HITs. Request no-cache/freshness constraints revalidate a stored validator instead of blanket-bypassing the cache. Response no-cache with a usable validator may be retained, but must validate before every reuse. Request/response no-store remains a hard exclusion.

Default cache memory limits are 256 MiB HOT allocated/charged data, 16 MiB per object, 64 MiB transient RAM, a 32 MiB COLD writer queue, 4096 HOT entries and eight fill permits. The panel also offers memory-aware conservative/recommended/performance presets derived from the lower of detected host RAM and a finite cgroup memory limit; automatic presets are disabled below 256 MiB effective RAM. max_object_bytes remains an independent per-object ceiling and cannot exceed the global HOT budget. If it is configured above the transient budget, the panel warns that objects near that size will pass through uncached because a fill cannot reserve enough bounded transient RAM. Optional cold cache defaults to disabled; when enabled it uses a bounded disk path under the private data directory and asynchronously demotes LRU/idle hot objects. Cold objects survive process restart for the same configuration revision and are promoted to RAM on a fresh hit. Large fill buffers grow incrementally and consume multiple permits. Actual process RSS also includes in-flight responses, compression buffers and runtime allocations. HIT/MISS/BYPASS, hit count and standardized RFC 9211 Cache-Status diagnostics are independently optional; required Age advances on ordinary cache hits even when the origin does not send Age. A successful origin 304 Not Modified starts a new freshness-age calculation, so the next Age may legitimately be 0; optional X-Cache-Resident-Age tracks RustProxy residency across revalidation and tier movement. Purge is authenticated, CSRF-protected, audited and invalidates both tiers plus older fills. See cache behavior and limits and cache diagnostics.

Response compression is streamed and negotiated with Accept-Encoding; zstd, Brotli and gzip default ON while deflate defaults OFF, and equal client quality uses zstd -> br -> gzip -> deflate server preference. The selected algorithm is reported in Content-Encoding with Vary: Accept-Encoding. Existing Content-Encoding, ranges, SSE, upgrades and no-transform are passed through without recompression. Cookie, Authorization, Set-Cookie, private and no-store headers do not by themselves disable dynamic compression. Ordinary vhosts and Web Server services may inherit/enable/disable compression and individual codecs. Docker publications expose a single Compression on/off switch and always use the globally enabled codec set; explicitly disabling a configurable scope hides/disables its codec selectors in the dashboard while preserving their saved values. Strong ETags are weakened after transformation, and obsolete content digests are removed. Server policy is applied after generic response rules. Protected framing/identity headers and cache-owned Age cannot be edited through generic rules.

With the separate demo enabled, /cache-demo returns an explicitly public 30-second object. Enable cache and X-Cache in Settings, then issue this twice without cookies:

curl -i -H 'Host: localhost' http://127.0.0.1:8080/cache-demo

The first eligible request is MISS, then HIT while fresh. The origin timestamp stays unchanged on HIT. Unlike proxy/system measurements, this endpoint is explicitly demo content. The reserved admin cookie is removed before eligibility; application cookies still trigger privacy bypass. Use anonymous curl requests to check cache behavior.

Adding a language

Create langs/de_DE.json with metadata and string translations, then rebuild and restart. No JavaScript language switch or registry edits are needed:

{
  "meta": {
    "locale": "de-DE", "name": "German", "native_name": "Deutsch", "direction": "ltr"
  },
  "translations": { "settings": "Einstellungen", "overview": "Ubersicht" }
}

Missing keys fall back to en_US.json. Translation strings are rendered as text, not HTML; locale and direction metadata also control formatting/RTL. The two bundled languages are English and Polish. New packs are compile-time assets, not untrusted runtime plugins. See langs/README.md.

Updating an installed source tree

Read MIGRATION.md. Back up actual data/certificates, stop the old server and extract this archive into a separate, non-nested directory. From the new source directory:

rust-proxy --data-dir /actual/RustProxy/data backup create \
  --output /private/rustproxy-before-upgrade.rpb
bash upgrade.sh /actual/RustProxy --stopped
# Also pass --data-dir /actual/private/data when it is external.
cd /actual/RustProxy
bash dev.sh test
bash dev.sh

The supported operator backup is the password-encrypted rust-proxy backup create command. tools/legacy/backup.py is retained only as an offline release-test helper and must not be used as a Secret Store backup. See Secret Store and encrypted backup/restore.

.env, data, unmanaged files and previous managed sources are preserved. Extra language JSON files survive the update; shipped files replace their old names, whose previous bytes remain in the backup. Unknown custom source edits are not merged. Do not overlay individual source files onto an old tree.

RustProxy 0.25.3 upgrades SQLite to schema version 8 by adding retained manual-configuration history. Existing schema-7 data is migrated automatically; the current configuration is seeded as the first retained history row and future successful saves keep the newest 512 revisions. Vhost/location method and access-policy fields are additive and default to disabled/inherited behavior when omitted. Once a 0.25.3 configuration containing the new fields is saved, an older binary may reject unknown configuration fields. Roll back using the pre-upgrade data backup as well as the old source, not just the binary.

Source helper layout

script responsibilities are intentionally separated:

  • scripts/runtime, scripts/build, scripts/deploy, scripts/migration are coupled to application/build/deployment behavior;
  • tools/dev, tools/audit, tools/legacy are optional operator/development helpers; the removed tools/checks suite is not shipped;
  • integrations/ contains external platform helpers such as OPNsense ACME and RouterOS OCI tooling.

See scripts/README.md, tools/README.md and integrations/README.md.

Documentation and checks

documentation index, API, architecture, security, transport, vhosts and pools, Web Server, settings, cache, roadmap, changelog, verification.

# Source preflight without Rust:
./dev.sh doctor
# Cargo validation and the Rust test suite (Rust required):
./dev.sh check
./dev.sh test
# Source-only package, with no Git checkout required:
python3 make_zip.py /tmp/RustProxy-0.33.0.zip

New management and test-origin guide

See MANAGEMENT.md for the certificate staging workflow, page/status behavior and logs; MOCK_SERVER.md provides a ready-to-use cache/health test setup. The example examples/mock-vhost.json is a complete minimal document for a fresh test installation, not a merge patch.

Authentication and mock development

In Vhosts -> Authentication, enable Tinyauth and supply its base URL (or the complete /api/auth/nginx endpoint) and public login URL. Private verifiers need the explicit private-network permission; optionally constrain allowed networks. Default identity headers are Remote-User and Remote-Email. No embedded provider password or disabled TLS verification is required. Do not protect the login host with itself. See INTEGRATIONS_040.md for exact status/redirect behavior and limits.

# Separate terminals, after building the real proxy on a toolchain-enabled host:
bash dev.sh mock --port 9001 --name origin-a --ttl 30
bash dev.sh mock-auth --port 9300

The fake-auth server accepts the intentionally insecure cookie mock_auth=allow; it is a loopback-only development peer, never an authentication product.

Docker vhosts operational controls

Docker vhosts now publish/unpublish immediately per service. Each Docker agent has a configurable inventory polling interval, while the optional Live view refreshes cached runtime state only. Docker-backed applications can use ACL profiles/inline ACLs and per-vhost proxy connect/header/read/send timeouts, matching the ordinary vhost proxy controls.

Dashboard layout export (0.33.1)

To share a preferred Overview arrangement for a future factory preset, open the authenticated Overview and run this in the browser developer console (no privileged database access):

(async () => {
  const response = await fetch('/api/preferences', { credentials: 'same-origin' });
  if (!response.ok) throw new Error(`Preferences HTTP ${response.status}`);
  const prefs = await response.json();
  const exportData = {
    dashboard_widgets: prefs.dashboard_widgets,
    dashboard_hidden_widgets: prefs.dashboard_hidden_widgets,
    dashboard_density: prefs.dashboard_density,
    overview_samples: localStorage.getItem('rustproxy.overview.liveChartSamples')
  };
  console.log(JSON.stringify(exportData, null, 2));
})();

Copy the JSON shown in Console using the browser's selection or context menu. Do not export the full preferences response or session cookies. This is an export for review, not an automatic factory-default change; existing account layouts remain unchanged.

The original Cache HIT donut shows accumulated cache counters; the optional recent Cache HIT chart displays interval-delta counters. They intentionally measure different windows and can produce different percentages.