Conversation
Tunnel drops whatever the destination sends right after the proxy's 200, and fixing that in place would change its response type (hyperium#313). HttpConnect does a real CONNECT request over an h1 connection and returns the upgraded IO, so leftover bytes survive via hyper's upgrade buffer. HTTP/1 only for now. Closes hyperium/hyper#4095
| where | ||
| C: Service<Uri>, | ||
| C::Future: Send + 'static, | ||
| C::Response: Read + Write + Connection + Unpin + Send + 'static, |
There was a problem hiding this comment.
So, here's an idea. (It might have been in my head and I never expressed it.) This HttpConnect type could be generic over an HTTP service, instead of a "connector", and then it could work with HTTP/1 or 2 (or 3?).
That'd mean impl Service<http::Request<SomeEmptyBody>, Response = http::Response<B>>, and then we would build a CONNECT request kind of like in the handshake function, using hyper::upgrade. Of course, the user would have to provide an HTTP connection that supports upgrades (so if it's HTTP/2, they'd need to have enabled extended connect). But, that seems fine.
Is this too crazy?
There was a problem hiding this comment.
Not too crazy, h2 CONNECT multiplexing tunnels over one proxy connection is exactly what the gRPC folks want anyway. Two questions before I rework it:
1 Should the service-generic type be the whole API, or the core with the current connector version kept as a thin wrapper? With a bare service the caller has to drive the conn themselves, which is the one thing the connector version handles for you.
2 Behind a service I can't see the transport, so Tunneled loses the underlying Connected. Fine to just return Connected::new()?
Follow-up to hyperium/hyper#4095: #315 fixed the parsing, but
tunnel()still throws away anything after the header end, which breaks protocols where the server speaks first. Fixing it in place changesTunnel's response type, which is why #313 went nowhere.So this is the alternative @seanmonstar suggested on the issue: a new connector,
HttpConnect, that sends an actual CONNECT request over an h1 connection and returns the upgraded IO, early bytes survive through hyper's own upgrade buffer. The conn future is driven inside the connector future, so nothing needs to be spawned. The returned IO forwardsConnectedso it works with the legacy client.Tunnelitself is untouched except apub(super)on the sharedHeadersenum.HTTP/1 only for now, h2 CONNECT could go behind the same type later.
Closes hyperium/hyper#4095