From 0e30c5bc261756dffaa874e4a9ef9858f16ba1d9 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Sun, 14 Jun 2020 11:10:32 -0400 Subject: http2: use and support non-empty DATA frame with END_STREAM flag Adds support for reading from a stream where the final frame is a non-empty DATA frame with the END_STREAM flag set, instead of hanging waiting for another frame. When writing to a stream, uses a END_STREAM flag on final DATA frame instead of adding an empty DATA frame. BREAKING: http2 client now expects servers to properly support END_STREAM flag Fixes: https://github.com/nodejs/node/issues/31309 Fixes: https://github.com/nodejs/node/issues/33891 Refs: https://nghttp2.org/documentation/types.html#c.nghttp2_on_data_chunk_recv_callback PR-URL: https://github.com/nodejs/node/pull/33875 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- src/node_http2.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/node_http2.cc b/src/node_http2.cc index 7b0e4e8af20..9c23281ece5 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -732,7 +732,7 @@ ssize_t Http2Session::OnMaxFrameSizePadding(size_t frameLen, // quite expensive. This is a potential performance optimization target later. ssize_t Http2Session::ConsumeHTTP2Data() { CHECK_NOT_NULL(stream_buf_.base); - CHECK_LT(stream_buf_offset_, stream_buf_.len); + CHECK_LE(stream_buf_offset_, stream_buf_.len); size_t read_len = stream_buf_.len - stream_buf_offset_; // multiple side effects. @@ -753,11 +753,11 @@ ssize_t Http2Session::ConsumeHTTP2Data() { CHECK_GT(ret, 0); CHECK_LE(static_cast(ret), read_len); - if (static_cast(ret) < read_len) { - // Mark the remainder of the data as available for later consumption. - stream_buf_offset_ += ret; - return ret; - } + // Mark the remainder of the data as available for later consumption. + // Even if all bytes were received, a paused stream may delay the + // nghttp2_on_frame_recv_callback which may have an END_STREAM flag. + stream_buf_offset_ += ret; + return ret; } // We are done processing the current input chunk. @@ -1093,6 +1093,7 @@ int Http2Session::OnDataChunkReceived(nghttp2_session* handle, if (session->is_write_in_progress()) { CHECK(session->is_reading_stopped()); session->set_receive_paused(); + Debug(session, "receive paused"); return NGHTTP2_ERR_PAUSE; } -- cgit v1.2.3