envoy: TcpProxy improperly sets `:protocol=bytestream` for HTTP2
TcpProxy improperly sets :protocol=bytestream for HTTP2: When using TunnelingConfig for an HTTP/2 tunnel, it send an out-of-spec psuedo header.
Description:
https://github.com/envoyproxy/envoy/blob/main/source/common/tcp_proxy/upstream.cc#L282-L285
Envoy will always set :protocol, but it’s not part of the HTTP/2 spec:
An extended CONNECT spec does mention it however:
This becomes a problem for picky implementations, like Go/Golang’s net/http:
- https://github.com/golang/go/issues/32763
- https://github.com/golang/go/blob/81d3c25c6cf39a76b17ab4eda97e8ad7b92a21e9/src/net/http/h2_bundle.go#L2808-L2833
Repro steps:
- Run. a Go HTTP/2 server with
GODEBUG="http2debug=2" - Create a listener with
TunnelingConfig(UsePost=false) - Send traffic from the listener to a cluster with
Http2ProtocolOptionsAllowConnectand astaticendpoint which is a Golang HTTP2 server. - You will see
http2: invalid pseudo headers: invalid pseudo-header ":protocol"
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 41 (35 by maintainers)
Commits related to this issue
- http: fixing up CONNECT to be RFC compliant (#21440) Risk Level: Medium (data plane changes) Testing: updated tests Docs Changes: n/a Release Notes: inline Runtime guard: envoy.reloadable_feature... — committed to envoyproxy/envoy by alyssawilk 2 years ago
- http: fixing up CONNECT to be RFC compliant (#21440) Risk Level: Medium (data plane changes) Testing: updated tests Docs Changes: n/a Release Notes: inline Runtime guard: envoy.reloadable_features.us... — committed to tyxia/envoy by alyssawilk 2 years ago
- http: fixing up CONNECT to be RFC compliant (#21440) Risk Level: Medium (data plane changes) Testing: updated tests Docs Changes: n/a Release Notes: inline Runtime guard: envoy.reloadable_features.us... — committed to Amila-Rukshan/envoy by alyssawilk 2 years ago
This is specifically about non-websocket CONNECT usage. For websockets, Envoy is correct -
:protocolmust be used for HTTP2 WS. Go doesn’t support this, so you should use HTTP1.@moderation RFC9113 still refers to “TCP streams”, so it doesn’t clarify things. The draft RFC that David mentioned is an updated HTTP semantics which is decoupled from the underlying transport. I think the concern is that this new HTTP semantics may not be universally supported, but same can be said about Extended CONNECT.
Or from a different perspective: “extended CONNECT” extends the normal CONNECT, which is intended for proxying HTTPS/TCP with extra functionality, like WS or UDP. It is not deprecating or replacing the original CONNECT, just extends it.
On Tue, May 31, 2022 at 8:21 AM David Schinazi @.***> wrote:
Also was the first link supposed to be https://datatracker.ietf.org/doc/html/rfc8441 ?