Transport - Fix a bug in decompression path

pull/11780/head
Muxi Yan 7 years ago
parent d07b884574
commit 0fd37e1951
  1. 45
      src/core/ext/transport/chttp2/transport/chttp2_transport.c

@ -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(

Loading…
Cancel
Save