nghttpx: Fix possible multiple replies on HTTP2 and SPDY upstreams

This commit is contained in:
Tatsuhiro Tsujikawa 2013-08-21 00:56:08 +09:00
parent 407027452c
commit aa9688b459
2 changed files with 16 additions and 6 deletions

View File

@ -583,7 +583,8 @@ void spdy_downstream_readcb(bufferevent *bev, void *ptr)
} }
if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) { if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
} else { } else if(downstream->get_response_state() != Downstream::MSG_COMPLETE) {
// If response was completed, then don't issue RST_STREAM
if(upstream->error_reply(downstream, 502) != 0) { if(upstream->error_reply(downstream, 502) != 0) {
delete upstream->get_client_handler(); delete upstream->get_client_handler();
return; return;
@ -704,8 +705,12 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
delete dconn; delete dconn;
dconn = 0; dconn = 0;
if(downstream->get_response_state() == Downstream::MSG_COMPLETE) { if(downstream->get_response_state() == Downstream::MSG_COMPLETE) {
// For SSL tunneling // For SSL tunneling, we issue RST_STREAM. For other types of
// stream, we don't have to do anything since response was
// complete.
if(downstream->get_upgraded()) {
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
}
} else { } else {
if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) { if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);

View File

@ -488,7 +488,8 @@ void spdy_downstream_readcb(bufferevent *bev, void *ptr)
} }
if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) { if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR); upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
} else { } else if(downstream->get_response_state() != Downstream::MSG_COMPLETE) {
// If response was completed, then don't issue RST_STREAM
if(upstream->error_reply(downstream, 502) != 0) { if(upstream->error_reply(downstream, 502) != 0) {
delete upstream->get_client_handler(); delete upstream->get_client_handler();
return; return;
@ -609,8 +610,12 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
delete dconn; delete dconn;
dconn = 0; dconn = 0;
if(downstream->get_response_state() == Downstream::MSG_COMPLETE) { if(downstream->get_response_state() == Downstream::MSG_COMPLETE) {
// For SSL tunneling // For SSL tunneling, we issue RST_STREAM. For other types of
// stream, we don't have to do anything since response was
// complete.
if(downstream->get_upgraded()) {
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR); upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
}
} else { } else {
if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) { if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR); upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);