Files
MasterHttpRelayVPN-RUST/docs/changelog/v1.9.5.md
T
therealaleph 541b37ad7d fix: v1.9.5 — exit-node tolerates TLS close without close_notify (#585)
Issue #585 from @gregtheph: v1.9.4's exit-node feature failed for every
ChatGPT/Claude/Grok request with `io: peer closed connection without
sending TLS close_notify` and fell back to direct Apps Script (which
can't reach those sites either, producing the no-json error chain).

Root cause: rustls is strict about TLS shutdown — when the peer (val.town's
host) closes the underlying TCP without first sending a TLS close_notify
alert, rustls surfaces this as `io::ErrorKind::UnexpectedEof`. Our
read_http_response propagated this as a hard error, even when the body
was already complete per Content-Length.

Fix: treat UnexpectedEof the same as `n == 0` (graceful EOF). If
Content-Length is satisfied, return the response; if mid-body truncation,
still error as BadResponse. Same handling added to the chunked reader
and the no-framing reader.

4 new regression tests:
- read_http_response_tolerates_unexpected_eof_with_content_length
- read_http_response_tolerates_unexpected_eof_no_framing
- parse_exit_node_response_unwraps_valtown_envelope
- parse_exit_node_response_surfaces_explicit_error

173 lib tests + 33 tunnel-node tests + both release builds passing.
2026-05-01 15:38:47 +03:00

2.8 KiB

• fix exit-node v1.9.4: مدارا با TLS ungraceful close (peer closed without close_notify) که val.town از Apps Script عبور می‌دهد (#585 از @gregtheph): در v1.9.4، کاربری که val.town رو با درست‌ترین config setup کرد، در log می‌دید WARN exit node failed for https://chatgpt.com/: io: peer closed connection without sending TLS close_notify — falling back to direct Apps Script + سپس fallback به Apps Script که خود نمی‌تونه ChatGPT رو reach کنه، در نتیجه decoy/no-json error. علت: rustls سختگیر است درباره‌ی TLS shutdown — وقتی peer (val.town) underlying TCP رو می‌بنده بدون اول send کردن TLS close_notify alert، rustls io::ErrorKind::UnexpectedEof می‌فرسته. کد ما در read_http_response این error رو propagate می‌کرد به‌عنوان hard error. حالا UnexpectedEof به‌صورت graceful EOF (مشابه n == 0) درمان می‌شه — اگر body completed شده با Content-Length، response درست برمی‌گرده. اگر mid-body close بود، error real (truncation) همچنان propagate می‌شه. ۴ regression test جدید (شامل UnexpectedEof tolerance + envelope unwrap valtown). 173 lib tests + 33 tunnel-node tests pass.

• Fix v1.9.4 exit-node: tolerate ungraceful TLS close (peer closed without close_notify) on the val.town path (#585 by @gregtheph): in v1.9.4, users with a correctly-configured val.town deployment saw WARN exit node failed for https://chatgpt.com/: io: peer closed connection without sending TLS close_notify — falling back to direct Apps Script in the log, followed by a fallback to direct Apps Script which can't reach ChatGPT either, resulting in the decoy/no-json error. Root cause: rustls is strict about TLS shutdown — when the peer (val.town's host) closes the underlying TCP without first sending a TLS close_notify alert, rustls surfaces this as io::ErrorKind::UnexpectedEof. Our code in read_http_response was propagating this as a hard error rather than treating it as graceful EOF. Now UnexpectedEof is handled like n == 0: if the body has been fully received per Content-Length, the response returns successfully; if it's a real mid-body truncation, the error still propagates as BadResponse. Same handling added to the chunked reader and the no-framing reader. Four regression tests cover the new behavior (UnexpectedEof tolerance for Content-Length and no-framing branches + val.town envelope unwrap success and error paths). 173 lib tests + 33 tunnel-node tests passing.