forwarder icon indicating copy to clipboard operation
forwarder copied to clipboard

martian: allow to use http2 connection to upstream

Open mmatczuk opened this issue 2 years ago • 3 comments

Upstream requests don't interact well with Transport: connections could always be reused, but Transport thinks they go to different Hosts, so it spawns tons of useless connections. Just use dialContext, which will multiplex via single connection, if http/2.

mmatczuk avatar Feb 22 '23 10:02 mmatczuk

Currently the http/2 proxy is not supported in http.Transport https://github.com/golang/go/issues/26479. However, it can be worked around by a custom transport that manages http2 connections.

In a simplified case of a single upstream proxy it would be sufficient to have a http2.ClientConn to the proxy passed to Martian as a http.RoundTripper. The more complete solution is to have http2.Transport with a custom connection pool and manage connection lifecycle i.e. dial connections when needed.

Another example of similar, but different, approach can be github.com/caddyserver/forwardproxy/httpclient. There for each request we establish new CONNECT tunnel over http2 stream. This solution does not work well with proxy chaining and only works for http1 backends. The last proxy enters the CONNECT path and it's difficult to coordinate.

mmatczuk avatar Feb 22 '23 11:02 mmatczuk

One thing to note is not to use the http2 conn if the handling with connection upgrade.

https://github.com/kubernetes/kubernetes/pull/88781/files#diff-09ebe223122bee0cad4dde23b1c6b36ea2e30fe45e25ca4cd2e04b32a13948d6

mmatczuk avatar Feb 22 '23 15:02 mmatczuk

Another thing to note is that this approach can be used to elegantly implement #99.

mmatczuk avatar Feb 23 '23 09:02 mmatczuk