|
|
|
@ -1671,9 +1671,8 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, |
|
|
|
|
} |
|
|
|
|
if (s->stream_compression_recv_enabled && |
|
|
|
|
!s->unprocessed_incoming_frames_decompressed) { |
|
|
|
|
grpc_slice_buffer decompressed_data; |
|
|
|
|
GPR_ASSERT(s->decompressed_data_buffer.length == 0); |
|
|
|
|
bool end_of_context; |
|
|
|
|
grpc_slice_buffer_init(&decompressed_data); |
|
|
|
|
if (!s->stream_decompression_ctx) { |
|
|
|
|
s->stream_decompression_ctx = |
|
|
|
|
grpc_stream_compression_context_create( |
|
|
|
@ -1681,17 +1680,18 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, |
|
|
|
|
} |
|
|
|
|
if (!grpc_stream_decompress(s->stream_decompression_ctx, |
|
|
|
|
&s->unprocessed_incoming_frames_buffer, |
|
|
|
|
&decompressed_data, NULL, 5, |
|
|
|
|
&s->decompressed_data_buffer, NULL, 5, |
|
|
|
|
&end_of_context)) { |
|
|
|
|
grpc_slice_buffer_reset_and_unref_internal(exec_ctx, |
|
|
|
|
&s->frame_storage); |
|
|
|
|
grpc_slice_buffer_reset_and_unref_internal( |
|
|
|
|
exec_ctx, &s->unprocessed_incoming_frames_buffer); |
|
|
|
|
s->seen_error = true; |
|
|
|
|
error = |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream decompression error."); |
|
|
|
|
} else { |
|
|
|
|
error = grpc_deframe_unprocessed_incoming_frames( |
|
|
|
|
exec_ctx, &s->data_parser, s, &decompressed_data, NULL, |
|
|
|
|
s->recv_message); |
|
|
|
|
exec_ctx, &s->data_parser, s, &s->decompressed_data_buffer, |
|
|
|
|
NULL, s->recv_message); |
|
|
|
|
if (end_of_context) { |
|
|
|
|
grpc_stream_compression_context_destroy( |
|
|
|
|
s->stream_decompression_ctx); |
|
|
|
@ -1740,7 +1740,38 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, |
|
|
|
|
} |
|
|
|
|
bool pending_data = s->pending_byte_stream || |
|
|
|
|
s->unprocessed_incoming_frames_buffer.length > 0; |
|
|
|
|
if (s->read_closed && s->frame_storage.length == 0 && |
|
|
|
|
if (s->stream_compression_recv_enabled && s->read_closed && |
|
|
|
|
s->frame_storage.length > 0 && |
|
|
|
|
s->unprocessed_incoming_frames_buffer.length == 0 && !pending_data && |
|
|
|
|
!s->seen_error && s->recv_trailing_metadata_finished != NULL) { |
|
|
|
|
/* Maybe some SYNC_FLUSH data is left in frame_storage. Consume them and
|
|
|
|
|
* maybe decompress the next 5 bytes in the stream. */ |
|
|
|
|
bool end_of_context; |
|
|
|
|
if (!s->stream_decompression_ctx) { |
|
|
|
|
s->stream_decompression_ctx = |
|
|
|
|
grpc_stream_compression_context_create( |
|
|
|
|
GRPC_STREAM_COMPRESSION_DECOMPRESS); |
|
|
|
|
} |
|
|
|
|
if (!grpc_stream_decompress(s->stream_decompression_ctx, |
|
|
|
|
&s->frame_storage, |
|
|
|
|
&s->unprocessed_incoming_frames_buffer, |
|
|
|
|
NULL, 5, &end_of_context)) { |
|
|
|
|
grpc_slice_buffer_reset_and_unref_internal(exec_ctx, |
|
|
|
|
&s->frame_storage); |
|
|
|
|
grpc_slice_buffer_reset_and_unref_internal( |
|
|
|
|
exec_ctx, &s->unprocessed_incoming_frames_buffer); |
|
|
|
|
s->seen_error = true; |
|
|
|
|
} else { |
|
|
|
|
if (s->unprocessed_incoming_frames_buffer.length > 0) { |
|
|
|
|
s->unprocessed_incoming_frames_decompressed = true; |
|
|
|
|
} |
|
|
|
|
if (end_of_context) { |
|
|
|
|
grpc_stream_compression_context_destroy(s->stream_decompression_ctx); |
|
|
|
|
s->stream_decompression_ctx = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (s->read_closed && s->frame_storage.length == 0 && s->unprocessed_incoming_frames_buffer.length == 0 && |
|
|
|
|
(!pending_data || s->seen_error) && |
|
|
|
|
s->recv_trailing_metadata_finished != NULL) { |
|
|
|
|
grpc_chttp2_incoming_metadata_buffer_publish( |
|
|
|
|