The Rust transport carries its own HTTP CONNECT tunnel rather than using
hyper_util::client::legacy::connect::proxy::Tunnel, for two defects in hyper-util 0.1.20, the latest
published version. Both are ours to fix upstream rather than to work around forever.
A status line split across reads fails a good tunnel. On the first read, tunnel.rs:216:
let recvd = &buf[..pos];
if recvd.starts_with(b"HTTP/1.1 200") || recvd.starts_with(b"HTTP/1.0 200") { ... }
else if recvd.starts_with(b"HTTP/1.1 407") { return Err(TunnelError::ProxyAuthRequired); }
else { return Err(TunnelError::TunnelUnsuccessful); }
"HTTP/1.1 2" matches neither prefix and lands in the last arm, so a successful CONNECT is rejected
because the bytes arrived in two segments. Legal, and likelier with a slow proxy or a small MSS.
hyperium/hyper-util#300 fixes this. It is open, unmerged and unreleased; follow it rather than duplicate
it.
Only 200 opens the tunnel. RFC 9110 says any 2xx switches a CONNECT connection to tunnel mode. A
proxy answering 201 gets TunnelError::TunnelUnsuccessful. Nothing upstream covers this; we should
open the pull request.
Ours reads to the blank line before parsing and accepts any 2xx, and both behaviours are covered by
integration tests against a real proxy.
Done when both are released upstream. Deleting ours is then tracked by #699.
Measured, not just read
Driving Tunnel against a fake proxy, with an unsplit 200 as the control:
plain 200: ACCEPTED, as it should be
201: REFUSED with `tunnel error: unsuccessful`
split: REFUSED with `tunnel error: unsuccessful`
The split case writes HTTP/1.1 2, waits 50ms, then the rest. Both defects are on hyper-util's main
branch today, not only in the published 0.1.20.
The Rust transport carries its own HTTP
CONNECTtunnel rather than usinghyper_util::client::legacy::connect::proxy::Tunnel, for two defects in hyper-util 0.1.20, the latestpublished version. Both are ours to fix upstream rather than to work around forever.
A status line split across reads fails a good tunnel. On the first read,
tunnel.rs:216:"HTTP/1.1 2"matches neither prefix and lands in the last arm, so a successfulCONNECTis rejectedbecause the bytes arrived in two segments. Legal, and likelier with a slow proxy or a small MSS.
hyperium/hyper-util#300 fixes this. It is open, unmerged and unreleased; follow it rather than duplicate
it.
Only
200opens the tunnel. RFC 9110 says any 2xx switches aCONNECTconnection to tunnel mode. Aproxy answering
201getsTunnelError::TunnelUnsuccessful. Nothing upstream covers this; we shouldopen the pull request.
Ours reads to the blank line before parsing and accepts any 2xx, and both behaviours are covered by
integration tests against a real proxy.
Done when both are released upstream. Deleting ours is then tracked by #699.
Measured, not just read
Driving
Tunnelagainst a fake proxy, with an unsplit200as the control:The split case writes
HTTP/1.1 2, waits 50ms, then the rest. Both defects are on hyper-util's mainbranch today, not only in the published 0.1.20.