Skip to content

fix(web): report a size hint that matches the translated body - #2896

Open
polaz wants to merge 2 commits into
grpc:masterfrom
polaz:fix/tonic-web-size-hint
Open

polaz wants to merge 2 commits into
grpc:masterfrom
polaz:fix/tonic-web-size-hint

Conversation

@polaz

@polaz polaz commented Sep 28, 2026

Copy link
Copy Markdown

Fixes #2895

Motivation

GrpcWebCall returned the size hint of the body it wraps, but it changes the
length of what it yields: base64 decoding shrinks a grpc-web-text request,
encoding grows a response, a response gains a data frame for its trailers, and
a client response loses the trailers frame from its data. hyper sends an exact
hint as content-length, so a grpc-web-text request with a known length,
translated and forwarded over HTTP/2, announced its base64 length and the
server reset the stream (reproduction in the issue).

Solution

The inner hint is now kept only where the bytes pass through unchanged (a
binary request). The encoder keeps the inner lower bound, since it only adds a
trailers frame; an empty call reports exactly zero; the other directions report
no bound.

Tests wrap a body with an exact length in each direction, read it to the end
and check the hint taken beforehand against the bytes yielded. The four changed
directions fail without this change, and the binary request keeps its exact
hint. With the change, the reproduction from the issue gets the SERVING
response and grpc-status:0.

`GrpcWebCall` forwarded the size hint of the body it wraps, although it
changes the length of what it yields: base64 decoding shrinks a
grpc-web-text request, base64 encoding grows a response, a response
gains a data frame for its trailers, and a client response loses the
trailers frame from its data. HTTP implementations send an exact size
hint as the `content-length` of the message (hyper does on HTTP/1.1 and
HTTP/2), so a grpc-web-text request with a known length, translated and
forwarded over HTTP/2, announced its base64 length and was refused as a
protocol error.

The hint is now the inner one only where the bytes pass through
unchanged (a binary request); the encoder keeps the inner lower bound,
an empty call is exactly empty, and the other directions report no
bound.
@linux-foundation-easycla

linux-foundation-easycla Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: polaz / name: Dmitry Prudnikov (5649360)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tonic-web: GrpcWebCall size_hint doesn't match the translated body

1 participant