You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Support grpcweb trailers encoded in the message (#481)
* Support grpcweb's in-message-encoded trailers
As the Fetch API does not expose HTTP trailers to the Javascript runtime,
grpcweb mandates that tailers are included in the message payload with
the most-significant bit of the leading byte (flags) set to 1.
What follows is a run-length-encoded block of text that follows the same
formatting as normal headers.
Most extant grpcweb libraries written in JS/TS are lenient about this
and will happily forego receiving trailers. However, some are more
picky about this and REQUIRE trailers (the buf.read connect libraries
are an example of this).
GRPC.Server follows the spec when sending protos over grpcweb, allowing
errors and other custom trailers to be sent in a way that is visible to
the client.
GRPC.Message also now recognizes trailers and parses them appropriately:
it extracts partial-buffer messages using the run-length encoding bytes
(which it was previously quietly ignoring, which would also allow
malformed buffers due to e.g. network problems sneak through anwyays),
it respects the trailers flag, and returns appropriate data in each of
these cases.
The GRPC client now also works with embedded trailers.
Overhead for non-grpcweb should be nominal as new code paths are hidden
behind grpcweb checks, while the additional binary checks are placed in
front the error paths (so errors may be nominally slower to be reached,
but the happy paths should be untouched).
* mix format a few files
* more formatting juggling to make the formatter running CI happy
* specify only two parts, even if the more colons appear in the header line
* Refactor: grpcweb trailer sending in its own function
Reads cleaner, perhaps a bit more idiomatic as well.
* call `stream_grpcweb_trailers` from `send_error_trailers`
This *may* require that the status was already sent, as well as the
state passed to `send_error_trailers` to decided whether or not to
send grpcweb trailers.
And so:
* `send_error_trailers` now uses `check_sent_resp` instead of doing that
check itself
* `check_sent_resp` now takes an optional `status`, with 200 as the
default
* state is passed to `send_error_trailers`
* `send_error_trailers` calls `stream_grpcweb_trailers` before
`cowboy_req.stream_trailers` (which closes the connection as trailers
implies fin)
* return the req from send_error_trailers
* the next action taken can depend on the request being grpcweb
when the request isn't a grpcweb request, then it's business as usual.
otherwise, the grpcweb trailers must be sent first, as they may cause a
body to be sent.
only after checking for grpcweb can the regular trailers be sent once
the state of the req is confirmed, namely whether or not a reply has
been started already or if a full reply must be initiated.
* ignore .expert dirs
* fixup formating
* remove tooling ignores. put them in your global gitignore instead, if desired.
---------
Co-authored-by: Aaron Seigo <aseigo@yaybr.com>
Co-authored-by: Adriano Santos <solid.sistemas@gmail.com>
0 commit comments