diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index 82dd0695..019f3f9d 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -422,22 +422,27 @@ int Http2DownstreamConnection::push_request_headers() { auto transfer_encoding = req.fs.header(http2::HD_TRANSFER_ENCODING); + nghttp2_data_provider *data_prdptr = nullptr; + nghttp2_data_provider data_prd; + // Add body as long as transfer-encoding is given even if // req.fs.content_length == 0 to forward trailer fields. if (req.method == HTTP_CONNECT || transfer_encoding || req.fs.content_length > 0 || req.http2_expect_body) { // Request-body is expected. - nghttp2_data_provider data_prd{{}, http2_data_read_callback}; - rv = http2session_->submit_request(this, nva.data(), nva.size(), &data_prd); - } else { - rv = http2session_->submit_request(this, nva.data(), nva.size(), nullptr); + data_prd = {{}, http2_data_read_callback}; + data_prdptr = &data_prd; } + + rv = http2session_->submit_request(this, nva.data(), nva.size(), data_prdptr); if (rv != 0) { DCLOG(FATAL, this) << "nghttp2_submit_request() failed"; return -1; } - downstream_->reset_downstream_wtimer(); + if (data_prdptr) { + downstream_->reset_downstream_wtimer(); + } http2session_->signal_write(); return 0; diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index 802b4157..00d5afe7 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -1572,7 +1572,11 @@ int send_data_callback(nghttp2_session *session, nghttp2_frame *frame, wb->append(PADDING.data(), padlen); - downstream->reset_downstream_wtimer(); + if (input->rleft() == 0) { + downstream->disable_downstream_wtimer(); + } else { + downstream->reset_downstream_wtimer(); + } if (length > 0) { // This is important because it will handle flow control diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index 577a4e66..d6f1ec8f 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -803,7 +803,11 @@ int send_data_callback(nghttp2_session *session, nghttp2_frame *frame, wb->append(PADDING.data(), padlen); - downstream->reset_upstream_wtimer(); + if (body->rleft() == 0) { + downstream->disable_upstream_wtimer(); + } else { + downstream->reset_upstream_wtimer(); + } if (length > 0 && downstream->resume_read(SHRPX_NO_BUFFER, length) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; @@ -1413,6 +1417,7 @@ ssize_t downstream_data_read_callback(nghttp2_session *session, } if (nread == 0 && ((*data_flags) & NGHTTP2_DATA_FLAG_EOF) == 0) { + downstream->disable_upstream_wtimer(); return NGHTTP2_ERR_DEFERRED; } @@ -1485,6 +1490,10 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body, downstream->set_response_state(Downstream::MSG_COMPLETE); + if (data_prd_ptr) { + downstream->reset_upstream_wtimer(); + } + return 0; } @@ -1527,6 +1536,8 @@ int Http2Upstream::error_reply(Downstream *downstream, return -1; } + downstream->reset_upstream_wtimer(); + return 0; } @@ -1733,6 +1744,10 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) { return -1; } + if (data_prdptr) { + downstream->reset_upstream_wtimer(); + } + return 0; } @@ -1892,7 +1907,8 @@ int Http2Upstream::on_timeout(Downstream *downstream) { << downstream->get_stream_id(); } - rst_stream(downstream, NGHTTP2_NO_ERROR); + rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); + handler_->signal_write(); return 0; } diff --git a/src/shrpx_spdy_upstream.cc b/src/shrpx_spdy_upstream.cc index 4c560605..562df515 100644 --- a/src/shrpx_spdy_upstream.cc +++ b/src/shrpx_spdy_upstream.cc @@ -981,6 +981,10 @@ int SpdyUpstream::send_reply(Downstream *downstream, const uint8_t *body, downstream->set_response_state(Downstream::MSG_COMPLETE); + if (data_prd_ptr) { + downstream->reset_upstream_wtimer(); + } + return 0; } @@ -1022,6 +1026,8 @@ int SpdyUpstream::error_reply(Downstream *downstream, return -1; } + downstream->reset_upstream_wtimer(); + return 0; } @@ -1190,6 +1196,8 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) { return -1; } + downstream->reset_upstream_wtimer(); + return 0; } @@ -1298,6 +1306,8 @@ int SpdyUpstream::on_timeout(Downstream *downstream) { rst_stream(downstream, SPDYLAY_INTERNAL_ERROR); + handler_->signal_write(); + return 0; }