nghttpx: Handle error from push_upload_data and end_upload_data
We have to gracefully handle the case where response ends before request body is fully received.
This commit is contained in:
parent
ec5e438a7c
commit
123752a032
|
@ -530,13 +530,14 @@ int Downstream::push_request_headers() {
|
|||
}
|
||||
|
||||
int Downstream::push_upload_data_chunk(const uint8_t *data, size_t datalen) {
|
||||
req_.recv_body_length += datalen;
|
||||
|
||||
// Assumes that request headers have already been pushed to output
|
||||
// buffer using push_request_headers().
|
||||
if (!dconn_) {
|
||||
DLOG(INFO, this) << "dconn_ is NULL";
|
||||
return -1;
|
||||
}
|
||||
req_.recv_body_length += datalen;
|
||||
if (dconn_->push_upload_data_chunk(data, datalen) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -447,7 +447,9 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
downstream->disable_upstream_rtimer();
|
||||
|
||||
if (downstream->end_upload_data() != 0) {
|
||||
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
|
||||
if (downstream->get_response_state() != Downstream::MSG_COMPLETE) {
|
||||
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
downstream->set_request_state(Downstream::MSG_COMPLETE);
|
||||
|
@ -472,7 +474,9 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
downstream->disable_upstream_rtimer();
|
||||
|
||||
if (downstream->end_upload_data() != 0) {
|
||||
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
|
||||
if (downstream->get_response_state() != Downstream::MSG_COMPLETE) {
|
||||
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
downstream->set_request_state(Downstream::MSG_COMPLETE);
|
||||
|
@ -522,7 +526,9 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
|
|||
downstream->reset_upstream_rtimer();
|
||||
|
||||
if (downstream->push_upload_data_chunk(data, len) != 0) {
|
||||
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
|
||||
if (downstream->get_response_state() != Downstream::MSG_COMPLETE) {
|
||||
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
if (upstream->consume(stream_id, len) != 0) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
|
|
@ -444,6 +444,12 @@ int htp_bodycb(http_parser *htp, const char *data, size_t len) {
|
|||
rv = downstream->push_upload_data_chunk(
|
||||
reinterpret_cast<const uint8_t *>(data), len);
|
||||
if (rv != 0) {
|
||||
// Ignore error if response has been completed. We will end up in
|
||||
// htp_msg_completecb, and request will end gracefully.
|
||||
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -363,7 +363,9 @@ void SpdyUpstream::initiate_downstream(Downstream *downstream) {
|
|||
auto &req = downstream->request();
|
||||
if (!req.http2_expect_body) {
|
||||
if (downstream->end_upload_data() != 0) {
|
||||
rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||
if (downstream->get_response_state() != Downstream::MSG_COMPLETE) {
|
||||
rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +387,9 @@ void on_data_chunk_recv_callback(spdylay_session *session, uint8_t flags,
|
|||
downstream->reset_upstream_rtimer();
|
||||
|
||||
if (downstream->push_upload_data_chunk(data, len) != 0) {
|
||||
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||
if (downstream->get_response_state() != Downstream::MSG_COMPLETE) {
|
||||
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
upstream->consume(stream_id, len);
|
||||
|
||||
|
@ -448,7 +452,9 @@ void on_data_recv_callback(spdylay_session *session, uint8_t flags,
|
|||
|
||||
downstream->disable_upstream_rtimer();
|
||||
if (downstream->end_upload_data() != 0) {
|
||||
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||
if (downstream->get_response_state() != Downstream::MSG_COMPLETE) {
|
||||
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
downstream->set_request_state(Downstream::MSG_COMPLETE);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue