fix(web): emit trailers when the response body ends - #2830
Open
emersonian wants to merge 1 commit into
Open
Conversation
The client decode path in GrpcWebCall::poll_frame buffers body bytes and, when a message frame and the gRPC-Web trailers frame land in the same buffer, parses the trailers into self.trailers and returns the data frame first. On the next poll the buffer is empty, find_trailers reports Done(0), and the stream ended with None without ever emitting the stored trailers, so tonic failed every such call with "protocol error: missing grpc-status trailer", even though the server sent a well-formed response. This is the common framing for unary responses (observed deterministically against Envoy's grpc-web filter), where the whole body arrives as one chunk. Take and emit the stored trailers in the Done(0) arm before ending the stream. Adds a regression test that polls a client_response body whose single chunk carries a message frame followed by the trailers frame, and asserts the data frame is followed by the trailers rather than end of stream.
|
|
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.
Motivation
GrpcWebClientLayer fails every call with "protocol error: missing grpc-status trailer, stream was terminated without a final status" when the server delivers a message frame and the gRPC-Web trailers frame in the same body chunk, the common framing for unary responses (observed against Envoy's grpc-web filter, which flushes the whole response in one chunk).
Solution
The client decode path in GrpcWebCall::poll_frame buffers body bytes and, when data and trailers share a buffer, parses the trailers into self.trailers and returns the data frame first.
On the next poll the buffer is empty, find_trailers reports Done(0), and the stream ended with None without ever emitting the stored trailers. This change takes and emits the stored trailers in the Done(0) arm before ending the stream.
Test coverage
This PR adds a regression test polling a client_response body whose single chunk carries a message frame followed by the trailers frame, asserting the data frame is followed by the trailers rather than end of stream (it fails on the unfixed code with the exact symptom above).