diff --git a/examples/shrpx_downstream.cc b/examples/shrpx_downstream.cc index 5cf3bebe..78aa7f21 100644 --- a/examples/shrpx_downstream.cc +++ b/examples/shrpx_downstream.cc @@ -367,7 +367,11 @@ int Downstream::push_request_headers() } bufferevent *bev = dconn_->get_bev(); evbuffer *output = bufferevent_get_output(bev); - evbuffer_add(output, hdrs.c_str(), hdrs.size()); + int rv; + rv = evbuffer_add(output, hdrs.c_str(), hdrs.size()); + if(rv != 0) { + return -1; + } dconn_->start_waiting_response(); return 0; @@ -392,17 +396,20 @@ int Downstream::push_upload_data_chunk(const uint8_t *data, size_t datalen) res += rv; rv = evbuffer_add(output, chunk_size_hex, rv); if(rv == -1) { + LOG(FATAL) << "evbuffer_add() failed"; return -1; } } rv = evbuffer_add(output, data, datalen); if(rv == -1) { + LOG(FATAL) << "evbuffer_add() failed"; return -1; } res += rv; if(chunked_request_) { rv = evbuffer_add(output, "\r\n", 2); if(rv == -1) { + LOG(FATAL) << "evbuffer_add() failed"; return -1; } res += 2; @@ -415,7 +422,10 @@ int Downstream::end_upload_data() if(chunked_request_) { bufferevent *bev = dconn_->get_bev(); evbuffer *output = bufferevent_get_output(bev); - evbuffer_add(output, "0\r\n\r\n", 5); + if(evbuffer_add(output, "0\r\n\r\n", 5) != 0) { + LOG(FATAL) << "evbuffer_add() failed"; + return -1; + } } return 0; } diff --git a/examples/shrpx_https_upstream.cc b/examples/shrpx_https_upstream.cc index 6e9e45ed..9e8062cf 100644 --- a/examples/shrpx_https_upstream.cc +++ b/examples/shrpx_https_upstream.cc @@ -159,7 +159,10 @@ int htp_hdrs_completecb(http_parser *htp) delete dconn; return -1; } else { - downstream->push_request_headers(); + rv = downstream->push_request_headers(); + if(rv != 0) { + return -1; + } downstream->set_request_state(Downstream::HEADER_COMPLETE); return 0; } @@ -169,11 +172,15 @@ int htp_hdrs_completecb(http_parser *htp) namespace { int htp_bodycb(http_parser *htp, const char *data, size_t len) { + int rv; HttpsUpstream *upstream; upstream = reinterpret_cast(htp->data); Downstream *downstream = upstream->get_last_downstream(); - downstream->push_upload_data_chunk(reinterpret_cast(data), - len); + rv = downstream->push_upload_data_chunk + (reinterpret_cast(data), len); + if(rv != 0) { + return -1; + } return 0; } } // namespace @@ -181,13 +188,17 @@ int htp_bodycb(http_parser *htp, const char *data, size_t len) namespace { int htp_msg_completecb(http_parser *htp) { + int rv; if(ENABLE_LOG) { LOG(INFO) << "Upstream https request complete"; } HttpsUpstream *upstream; upstream = reinterpret_cast(htp->data); Downstream *downstream = upstream->get_last_downstream(); - downstream->end_upload_data(); + rv = downstream->end_upload_data(); + if(rv != 0) { + return -1; + } downstream->set_request_state(Downstream::MSG_COMPLETE); // Stop further processing to complete this request http_parser_pause(htp, 1); diff --git a/examples/shrpx_spdy_upstream.cc b/examples/shrpx_spdy_upstream.cc index f77d3c18..53fe838f 100644 --- a/examples/shrpx_spdy_upstream.cc +++ b/examples/shrpx_spdy_upstream.cc @@ -118,6 +118,9 @@ void on_stream_close_callback delete downstream; } else { // At this point, downstream read may be paused. + + // If shrpx_downstream::push_request_headers() failed, the + // error is handled here. upstream->remove_downstream(downstream); delete downstream; // How to test this case? Request sufficient large download @@ -201,7 +204,11 @@ void on_ctrl_recv_callback downstream->set_request_state(Downstream::CONNECT_FAIL); return; } - downstream->push_request_headers(); + rv = downstream->push_request_headers(); + if(rv != 0) { + upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR); + return; + } downstream->set_request_state(Downstream::HEADER_COMPLETE); if(frame->syn_stream.hd.flags & SPDYLAY_CTRL_FLAG_FIN) { if(ENABLE_LOG) { @@ -228,7 +235,10 @@ void on_data_chunk_recv_callback(spdylay_session *session, SpdyUpstream *upstream = reinterpret_cast(user_data); Downstream *downstream = upstream->find_downstream(stream_id); if(downstream) { - downstream->push_upload_data_chunk(data, len); + if(downstream->push_upload_data_chunk(data, len) != 0) { + upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR); + return; + } if(upstream->get_flow_control()) { downstream->inc_recv_window_size(len); if(downstream->get_recv_window_size() >