4.0 KiB
RustProxy 0.31.6 implementation and acceptance gate
Scope
This patch is based on the delivered 0.31.5 source archive. It is a narrow HTTP/3 navigation follow-up. It does not change the logo link, normal panel SPA navigation, administrator security checks or the HTTP/3 listener controls. The report of iOS 21.0.1 is operator-provided device metadata and has not been independently verified.
Code changes
src/proxy/cache_helpers.rs: the cache/404 empty-body preflight is now bounded to 35 ms per initial frame for H3 GET/HEAD. A delayed FIN bypasses cache rather than blocking the entire route; all frames remain available for streaming. Separately, the H3-to-H1 unknown-length request-body normalization now includesGETandHEAD. The first meaningful frame is inspected up to eight times, and GET/HEAD wait for at most 35 ms per frame. If end-of-stream is observed, the body becomes an exact, empty H1 request. Nonempty DATA and trailers are replayed via the existingReplayBodywrapper. A slow stream is not discarded or buffered and stays on the existing streaming path. This makes the H3 receive half complete before H1 forwarding when FIN is already available, without relying on a claim that H1 GET/HEAD were chunked (Hyper already special-cases those methods).src/http3.rs: a failure of the H3 accept loop logs the event and stops accepting, but lets the existing bounded drain handle responses already in progress instead of aborting all response tasks immediately.src/http3.rs: pre-HEADERS peer stream cancellations are logged at HTTP status 0, never fabricated HTTP 400. Response failures record the transport stage, H3 stream identifier, method, path without query, advertised response status, bytes successfully sent and bounded/redacted error in per-vhost protocol-error logs. Peer-initiated cancellation remains distinct from a true truncated/error response.- A full HTTP/3
GET /emitshttp3_navigation_startedandhttp3_navigation_completeat INFO in the process/service logs (orhttp3_navigation_interruptedat WARN) with SNI, connection endpoints, stream ID, response status and sent bytes. No query, Cookie, Authorization or body content is included. Per-vhost HTTP/3 protocol errors are logged separately in JSONL when enabled. Correlate a missing completion for the new stream rather than assuming any cancellation caused a blank screen. - No change to the logo anchor
href="/", browser code paths, SSE on-page behavior, SQL schema, settings JSON, H1 WebSockets, QUIC RFC 9220 support, HOT/COLD cache or the/logsresponsive view.
Tests and risk
Rust unit tests cover empty and nonempty GET and HEAD forwarding, cache/404 preflight and stalled-client bounds; these are source-level additions, not proof of execution unless Cargo is available. The repository ships static checks, Node UI tests, SQLite upgrade smoke and Go tests. The pinned Cargo.lock dependency graph has not been re-resolved in this environment; a compiler-enabled build host must run scripts/resolve_dependencies_0312.sh, ./dev.sh check, ./dev.sh test, and a release build before deploying.
Reproduce on the actual iPhone with H3 enabled: open https://rp.h.linuxiarz.pl, sign in, click the original RustProxy logo repeatedly, compare successful GET / and JS/CSS access events with http3_* diagnostic events from the same peer and timestamp. In a failure capture Safari Web Inspector Network entries for document, JS and CSS, a QUIC packet/qlog trace if available, and the vhost JSONL. With systemd installations, view navigation breadcrumbs with journalctl -u rustproxy --since '10 minutes ago' | grep 'http3_navigation_'; the service log is separate from vhost JSONL. Old H3_REQUEST_CANCELLED events may be harmless; a failed new navigation or incomplete response is the acceptance condition. Test H1/H2, unrelated vhosts, cache retention and /logs mobile width as regressions.
Acceptance remains OPEN until compiled and tested on a real HTTP/3 listener with mobile devices; the original white-screen cause is not proven from one cancellation log alone.