From 9b72053f633ce90cf32916b8c577315cd57e2dc5 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Thu, 22 Feb 2018 02:52:59 +0100 Subject: [PATCH] http2: fix endless loop when writing empty string Refs: https://github.com/nodejs/node/pull/18673 Fixes: https://github.com/nodejs/node/issues/18169 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 --- src/node_http2.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/node_http2.cc b/src/node_http2.cc index 0ef77da13aca4f..f1454aa11e58e9 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -2184,6 +2184,17 @@ ssize_t Http2Stream::Provider::Stream::OnRead(nghttp2_session* handle, size_t amount = 0; // amount of data being sent in this data frame. + // Remove all empty chunks from the head of the queue. + // This is done here so that .write('', cb) is still a meaningful way to + // find out when the HTTP2 stream wants to consume data, and because the + // StreamBase API allows empty input chunks. + while (!stream->queue_.empty() && stream->queue_.front().buf.len == 0) { + WriteWrap* finished = stream->queue_.front().req_wrap; + stream->queue_.pop(); + if (finished != nullptr) + finished->Done(0); + } + if (!stream->queue_.empty()) { DEBUG_HTTP2SESSION2(session, "stream %d has pending outbound data", id); amount = std::min(stream->available_outbound_length_, length); @@ -2197,7 +2208,8 @@ ssize_t Http2Stream::Provider::Stream::OnRead(nghttp2_session* handle, } } - if (amount == 0 && stream->IsWritable() && stream->queue_.empty()) { + if (amount == 0 && stream->IsWritable()) { + CHECK(stream->queue_.empty()); DEBUG_HTTP2SESSION2(session, "deferring stream %d", id); return NGHTTP2_ERR_DEFERRED; }