The Rust transport carries its own HTTP CONNECT tunnel while hyper-util ships one. Ours exists for a
single reason, and that reason has an open pull request upstream.
hyper_util::client::legacy::connect::proxy::Tunnel reads the CONNECT response like this, in
hyper-util 0.1.20:
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); }
On the first read, a status line that has not fully arrived matches neither prefix and falls into the last
arm, so a perfectly good tunnel is rejected because the response was split across TCP segments. That is
legal, and more likely with a slow proxy or a small MSS. HTTP/1.0 407 lands in the same arm, losing the
"authentication required" distinction. Their pull request hyperium/hyper-util#300 fixes the first part.
Ours reads a byte at a time until the blank line and then parses, so it has neither problem. The rest of
the proxy story is already upstream and is used: client::proxy::matcher::Matcher handles the *_PROXY
convention, NO_PROXY on curl's rules, and taking credentials out of a proxy URL.
When #300 is released, compare the two and delete ours if theirs is then equivalent. That would remove
tunnel, status_code, target_authority, basic_auth and the base64 dependency, and would bring
SOCKS4/SOCKS5 with it.
Worth checking at the same time whether Matcher::from_system has become usable on Windows: it reads the
registry, which several open pull requests are still fixing (#280, #285, #290, #293). The system option
deliberately uses from_env today.
How each half is watched
The tunnel half needs no watching: armonik-transport/tests/upstream_tunnel.rs drives Tunnel against
a fake proxy and asserts both defects are still there, so the release that fixes either turns CI red and
names what to delete.
The Matcher::from_system half cannot be watched the same way, and it is worth writing down so nobody
spends an afternoon trying. hyperium/hyper-util#293 puts its parsing inside mod win, between the
registry read and the builder, so a test going through the public Matcher::builder().http(...) would
exercise a path the fix does not touch and would never fire. The only real path, win::with_system,
reads HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings, and a test has no business
writing there. client-proxy-system is not even enabled here, since system uses from_env.
So that half stays a human check, at the next hyper-util bump.
The Rust transport carries its own HTTP
CONNECTtunnel whilehyper-utilships one. Ours exists for asingle reason, and that reason has an open pull request upstream.
hyper_util::client::legacy::connect::proxy::Tunnelreads theCONNECTresponse like this, inhyper-util 0.1.20:
On the first read, a status line that has not fully arrived matches neither prefix and falls into the last
arm, so a perfectly good tunnel is rejected because the response was split across TCP segments. That is
legal, and more likely with a slow proxy or a small MSS.
HTTP/1.0 407lands in the same arm, losing the"authentication required" distinction. Their pull request hyperium/hyper-util#300 fixes the first part.
Ours reads a byte at a time until the blank line and then parses, so it has neither problem. The rest of
the proxy story is already upstream and is used:
client::proxy::matcher::Matcherhandles the*_PROXYconvention,
NO_PROXYon curl's rules, and taking credentials out of a proxy URL.When #300 is released, compare the two and delete ours if theirs is then equivalent. That would remove
tunnel,status_code,target_authority,basic_authand thebase64dependency, and would bringSOCKS4/SOCKS5 with it.
Worth checking at the same time whether
Matcher::from_systemhas become usable on Windows: it reads theregistry, which several open pull requests are still fixing (#280, #285, #290, #293). The
systemoptiondeliberately uses
from_envtoday.How each half is watched
The tunnel half needs no watching:
armonik-transport/tests/upstream_tunnel.rsdrivesTunnelagainsta fake proxy and asserts both defects are still there, so the release that fixes either turns CI red and
names what to delete.
The
Matcher::from_systemhalf cannot be watched the same way, and it is worth writing down so nobodyspends an afternoon trying. hyperium/hyper-util#293 puts its parsing inside
mod win, between theregistry read and the builder, so a test going through the public
Matcher::builder().http(...)wouldexercise a path the fix does not touch and would never fire. The only real path,
win::with_system,reads
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings, and a test has no businesswriting there.
client-proxy-systemis not even enabled here, sincesystemusesfrom_env.So that half stays a human check, at the next hyper-util bump.