Support downstream h2c upgrade in the H2 codec implementation
#7,161 opened on Jun 4, 2019
Repository metrics
- Stars
- (27,997 stars)
- PR merge metrics
- (Avg merge 8d) (378 merged PRs in 30d)
Description
Description There is currently a gap in support for H2 connections without ALPN. Envoy currently supports prior knowledge H2 connections, however, does not support the h2c upgrade header which is the default implementation of some clients when TLS is not provided and prior knowledge is not explicitly specified.
Relevant Links RFC-7540: h2c upgrade
Changes
To support the default codec_type value of auto the protocol detection will need to detect if the request is an H1 upgrade and send the request to the H2 path here: https://github.com/envoyproxy/envoy/blob/master/source/common/http/conn_manager_utility.cc#L44
I believe nghttp2 should handle the h2c upgrade, however, Envoy currently throws this exception: https://github.com/envoyproxy/envoy/blob/master/source/common/http/http2/codec_impl.cc#L665
[debug][http2] [source/common/http/http2/codec_impl.cc:735] [C65066] setting stream-level initial window size to 268435456
[debug][http2] [source/common/http/http2/codec_impl.cc:757] [C65066] updating connection-level initial window size to 268435456
[trace][http2] [source/common/http/http2/codec_impl.cc:353] [C65066] dispatching 182 bytes
[debug][http] [source/common/http/conn_manager_impl.cc:278] [C65066] dispatch error: Received bad client magic byte string
Prior to invoking dispatch the codec implementation should detect an H1 upgrade request and send the response of 101 Switching Protocols before buffering the frames to nghttp2. I assume there may be some low level API for nghttp2 to handle this scenario, or there may be some munging of the request to get nghttp2 to properly handle it, e.g. presenting the "magic byte".
@mattklein123 This is the implementation discussion that originated in #6972