I have a server witten in Go that uses cmux
to allow multiple protocols to run on the same port, but there's a limitation specified in the README saying that
cmux
matches the connection when it's accepted. For example, one connection can be either gRPC or REST, but not both. That is, we assume that a client connection is either used for gRPC or REST.
I need the browser to be able to both stream from grpc-web and call a REST API on the same port, but the browser reuses the same connection and causes the muxing to not work.
This is a pretty tricky problem to identify. Since browsers prefer to use an existing TCP connection for pipelining, the mux tends to send packets to the wrong protocol handler, for example it could send
grpc-web
packets to REST, and vice versa. Luckily, there is a pretty simple solution for this:How does this work?
Essentially, instead of using
cmux
's default muxing (which only muxes per-connection) we registered a new mini http server handler on all HTTP requests coming in, which then lets us explicitly check headers and call handlers directly.