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
Calling addEncodedData from the encodeTrailers callback fails when encodeHeaders had previously returned StopIteration.
A filter (e.g. the grpc-json transcoder) wants to turn a headers-only response into a response with a body. And StreamEncoderFilterCallbacks::addEncodedData allows that:
1) If a headers only response needs to be turned into a response with a body, this method can
be called to add body in the encodeHeaders() callback. Subsequent filters will receive
encodeHeaders(..., false) followed by encodeData(..., true). This works both in the direct
iteration as well as the continuation case.
However it doesn't work when upstream sends a header frame and a trailer frame:
The filter returns StopIteration from encodeHeaders.
In encodeTrailers, it calls addEncodedData. ConnectionManagerImpl::ActiveStream::addEncodedData has a special branch for EncodeTrailers, which calls encodeData with the comment:
// In this case we need to inline dispatch the data to further filters. If those filters
// choose to buffer/stop iteration that's fine.
Now there are two cases:
if there is another filter, encodeData will call its encodeData callback, and then fail the ASSERT(headers_continued_) in ActiveStreamFilterBase::commonHandleAfterDataCallback - this filter never had its encodeHeaders called.
if there is no filter to iterate, ActiveStream::encodeData will call response_encoder_->encodeData and write response body before writing any headers.
For HTTP/1.1 downstream it will assume chunked transfer-encoding and write something like:
4
body
HTTP/1.1 200 OK
other: headers
How to fix that:
For EncodeTrailers, the ActiveStream::addEncodedData should buffer data when filter stopped iteration.
The text was updated successfully, but these errors were encountered:
ascheglov
pushed a commit
to ascheglov/envoy
that referenced
this issue
Sep 26, 2019
Now filters can return StopIteration from encodeHeaders,
and then call addEncodedData from encodeTrailers.
This allows the JsonTranscoderFilter to properly transcode gRPC status
in trailer headers into a JSON reply body.
Risk Level: Low
Testing: unit-tests, integration tests in gRPC JSON transcoder filter.
Documentation: n/a
Release notes: n/a
Fixesenvoyproxy#8402
Signed-off-by: Anatoly Scheglov <ascheglov@yandex-team.ru>
Now filters can return StopIteration from encodeHeaders,
and then call addEncodedData from encodeTrailers.
This allows the JsonTranscoderFilter to properly transcode gRPC status
in trailer headers into a JSON reply body.
Risk Level: Low
Testing: unit-tests, integration tests in gRPC JSON transcoder filter.
Documentation: n/a
Release notes: n/a
Fixes#8402
Signed-off-by: Anatoly Scheglov <ascheglov@yandex-team.ru>
danzh2010
pushed a commit
to danzh2010/envoy
that referenced
this issue
Oct 4, 2019
…yproxy#8404)
Now filters can return StopIteration from encodeHeaders,
and then call addEncodedData from encodeTrailers.
This allows the JsonTranscoderFilter to properly transcode gRPC status
in trailer headers into a JSON reply body.
Risk Level: Low
Testing: unit-tests, integration tests in gRPC JSON transcoder filter.
Documentation: n/a
Release notes: n/a
Fixesenvoyproxy#8402
Signed-off-by: Anatoly Scheglov <ascheglov@yandex-team.ru>
Calling addEncodedData from the encodeTrailers callback fails when encodeHeaders had previously returned StopIteration.
A filter (e.g. the grpc-json transcoder) wants to turn a headers-only response into a response with a body. And StreamEncoderFilterCallbacks::addEncodedData allows that:
However it doesn't work when upstream sends a header frame and a trailer frame:
The filter returns StopIteration from
encodeHeaders
.In
encodeTrailers
, it callsaddEncodedData
.ConnectionManagerImpl::ActiveStream::addEncodedData
has a special branch for EncodeTrailers, which calls encodeData with the comment:Now there are two cases:
ASSERT(headers_continued_)
inActiveStreamFilterBase::commonHandleAfterDataCallback
- this filter never had its encodeHeaders called.response_encoder_->encodeData
and write response body before writing any headers.For HTTP/1.1 downstream it will assume chunked transfer-encoding and write something like:
How to fix that:
For EncodeTrailers, the ActiveStream::addEncodedData should buffer data when filter stopped iteration.
The text was updated successfully, but these errors were encountered: