Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gPRC and HTTP/2 health check with TLS #68

Open
jeffreydking opened this issue Jun 5, 2019 · 2 comments
Open

gPRC and HTTP/2 health check with TLS #68

jeffreydking opened this issue Jun 5, 2019 · 2 comments

Comments

@jeffreydking
Copy link

jeffreydking commented Jun 5, 2019

I can't get gPRC and HTTP/2 health checks (both with TLS) to work. I believe the prescribed approach is to follow the RecursiveCmux example; we need to handle the TLS handshake before we can match on HTTP2HeaderFieldPrefix for gRPC (all other TLS traffic would be routed to the HTTP/2 health check server).

The problem then arises that, for the HTTP/2 health check server, we can't use http.ListenAndServeTLS since the TLS is already resolved using tls.NewListener. So we must use http.Serve. http.Serve documentation says:

HTTP/2 support is only enabled if the Listener returns *tls.Conn connections and they
were configured with "h2" in the TLS Config.NextProtos.

Adding "h2" to the TLS Config.NextProtos is straight forward enough. However, even though tls.NewListener returns a listener that returns *tls.Conn connections, it appears that when this listener is wrapped in the CMux object, it modifies the listener to return MuxConn connections rather than *tls.Conn. This breaks things. When I execute:

curl https://localhost:443 --http2 -Ik

I get a response of

curl: (16) Error in the HTTP2 framing layer

Is it possible to serve gPRC and HTTP/2 health checks (both with TLS) using the cmux package?

@DanTulovsky
Copy link

I am also seeing this error. I am using RecursiveCmux approach. Additionally, it seems that:

m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldPrefixSendSettings("content-type", "grpc"))

does not actually work. It fails to match grpc traffic. So trying to serve bother http2 and grpc at the same time isn't working.

@raidancampbell
Copy link

I'm still seeing it with the same setup as OP. Walking through the code, it appears the issue occurs on this type assertion in the stdlib:

tlsConn, ok := c.rwc.(*tls.Conn)

rwc is of type MuxConn, which is:

type MuxConn struct {
	net.Conn
	buf bufferedReader
}

Unfortunately, type assertion on the embedded struct fails, even though the underlying net.Conn is of type *crypto/tls.Conn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants