Add h2c upstream support for gRPC#242
Open
rodrigovidal wants to merge 1 commit intovercel-labs:mainfrom
Open
Conversation
Introduces an optional "protocol" field on RouteInfo ("http" | "h2c").
Routes marked h2c are proxied over cleartext HTTP/2 with a cached
client session per host:port, enabling gRPC and any backend that
only speaks HTTP/2 on its non-TLS listener.
|
@rodrigovidal is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Running a gRPC backend locally under portless currently fails: portless forwards over HTTP/1.1, the backend refuses the connection, and the user sees opaque 502s. This PR adds an opt-in
--h2cflag that switches the upstream leg to HTTP/2 cleartext so these backends workend to end.
Summary
--h2cflag to tell portless to speak HTTP/2 cleartext to the backend. Required for gRPC and any HTTP/2-only backend.h2croutes via a newproxyH2cpath that preserves bidirectional streaming, response trailers (grpc-status,grpc-message), and the trailers-only wire form (single HEADERS+END_STREAM frame) that some gRPC clients require.http2.ClientHttp2Sessionperhost:port; clear it ongoaway/close/errorso the next request reconnects cleanly.protocol: "h2c"), so the proxy dispatches the right path after a restart.README.md,skills/portless/SKILL.md, and the--helpoutput per AGENTS.md.Non-goals
h2). Scope is cleartext HTTP/2 only, which covers dev servers bound to a plain port.res.addTrailersbest-effort.Backwards compatibility
The HTTP/1.1 proxy path is unchanged.
proxyH2cis dispatched only when a route hasprotocol: "h2c", which is set solely by the new--h2cflag.Usage
portless grpc-svc --h2c tsx server.ts
Manual verification
Tested end to end against this branch. The child command itself runs the h2c server on portless's assigned
$PORT:Test plan
propagation, multi-chunk streaming, gRPC trailers (HTTP/2 client), and gRPC trailers-only wire form.
Running a gRPC backend locally under portless currently fails: portless forwards over HTTP/1.1, the backend refuses the connection, and the user sees opaque 502s. This PR adds an opt-in
--h2cflag that switches the upstream leg to HTTP/2 cleartext so these backends workend to end.
Summary
--h2cflag to tell portless to speak HTTP/2 cleartext to the backend. Required for gRPC and any HTTP/2-only backend.h2croutes via a newproxyH2cpath that preserves bidirectional streaming, response trailers (grpc-status,grpc-message), and the trailers-only wire form (single HEADERS+END_STREAM frame) that some gRPC clients require.http2.ClientHttp2Sessionperhost:port; clear it ongoaway/close/errorso the next request reconnects cleanly.protocol: "h2c"), so the proxy dispatches the right path after a restart.README.md,skills/portless/SKILL.md, and the--helpoutput per AGENTS.md.Non-goals
h2). Scope is cleartext HTTP/2 only, which covers dev servers bound to a plain port.res.addTrailersbest-effort.Backwards compatibility
The HTTP/1.1 proxy path is unchanged.
proxyH2cis dispatched only when a route hasprotocol: "h2c", which is set solely by the new--h2cflag.Usage
portless grpc-svc --h2c tsx server.ts
Manual verification
Tested end to end against this branch. The child command itself runs the h2c server on portless's assigned
$PORT:Test plan
propagation, multi-chunk streaming, gRPC trailers (HTTP/2 client), and gRPC trailers-only wire form.
Running a gRPC backend locally under portless currently fails: portless forwards over HTTP/1.1, the backend refuses the connection, and the user sees opaque 502s. This PR adds an opt-in
--h2cflag that switches the upstream leg to HTTP/2 cleartext so these backends workend to end.
Summary
--h2cflag to tell portless to speak HTTP/2 cleartext to the backend. Required for gRPC and any HTTP/2-only backend.h2croutes via a newproxyH2cpath that preserves bidirectional streaming, response trailers (grpc-status,grpc-message), and the trailers-only wire form (single HEADERS+END_STREAM frame) that some gRPC clients require.http2.ClientHttp2Sessionperhost:port; clear it ongoaway/close/errorso the next request reconnects cleanly.protocol: "h2c"), so the proxy dispatches the right path after a restart.README.md,skills/portless/SKILL.md, and the--helpoutput per AGENTS.md.Non-goals
h2). Scope is cleartext HTTP/2 only, which covers dev servers bound to a plain port.res.addTrailersbest-effort.Backwards compatibility
The HTTP/1.1 proxy path is unchanged.
proxyH2cis dispatched only when a route hasprotocol: "h2c", which is set solely by the new--h2cflag.Usage
portless grpc-svc --h2c tsx server.ts
Manual verification
Tested end to end against this branch. The child command itself runs the h2c server on portless's assigned
$PORT:Test plan
propagation, multi-chunk streaming, gRPC trailers (HTTP/2 client), and gRPC trailers-only wire form.