Skip to content

Revisit the Rust transport's own CONNECT tunnel once hyper-util#300 lands #699

Description

@wkirschenmann

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions