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.
This commit is contained in:
therealaleph
2026-05-01 15:38:45 +03:00
parent 7268baf098
commit 541b37ad7d
4 changed files with 157 additions and 8 deletions
Generated
+1 -1
View File
@@ -2222,7 +2222,7 @@ dependencies = [
[[package]]
name = "mhrv-rs"
version = "1.9.4"
version = "1.9.5"
dependencies = [
"base64 0.22.1",
"bytes",