Cleartext listener never speaks HTTP/2: gRPC peering impossible over plain HTTP (h2c missing) #143
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/Cairn#143
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Second live find of the #106 dogfood, immediately behind #140. With the dial port fixed, the next hop fails:
Root cause: the client dials plain-HTTP peers with prior-knowledge HTTP/2 (h2c), but
cairnd's listener is a stockhttp.Server.ListenAndServe()— HTTP/1.1 only on cleartext. The server answers the h2 preface with an HTTP/1.1 error response, which the client reports as the "frame header looked like an HTTP/1.1 header" mismatch.peering.Mux'sisGRPCcheck (ProtoMajor == 2) is correct but unreachable on cleartext: no request ever arrives as HTTP/2.Why tests missed it: the loopback test wires the gRPC server via an injected dialer/in-process listener; the single-port mux was never exercised through a real cleartext TCP connection.
Fix: wrap the root handler in
h2c.NewHandler(root, &http2.Server{})(golang.org/x/net/http2/h2c, already in the module graph as an indirect). Ordinary HTTP/1.1 traffic passes through untouched; TLS deployments keep HTTP/2 via ALPN exactly as before; the LAN plain-HTTP case — whichisPrivateHostdeliberately permits — becomes real. Add the missing test: an httptest server with h2c +peering.Mux, one prior-knowledge HTTP/2 request with a gRPC content type routed to the gRPC handler, one HTTP/1.1 request routed to the fallback.