shrpx: More backend EOF handling

Now we set Downstream::set_response_connection_close(true) for
tunneled connections. Also call
Upstream::on_downstream_body_complete() callback when setting
MSG_COMPLETE in SpdySession when RST_STREAM is caught.  Clean up EOF
handling in https_downstream_readcb.
This commit is contained in:
Tatsuhiro Tsujikawa 2013-02-11 17:20:52 +09:00
parent d830e099a6
commit e28f169228
3 changed files with 25 additions and 15 deletions

View File

@ -356,6 +356,9 @@ int htp_hdrs_completecb(http_parser *htp)
downstream->set_response_minor(htp->http_minor); downstream->set_response_minor(htp->http_minor);
downstream->set_response_connection_close(!http_should_keep_alive(htp)); downstream->set_response_connection_close(!http_should_keep_alive(htp));
downstream->set_response_state(Downstream::HEADER_COMPLETE); downstream->set_response_state(Downstream::HEADER_COMPLETE);
if(downstream->tunnel_established()) {
downstream->set_response_connection_close(true);
}
if(downstream->get_upstream()->on_downstream_header_complete(downstream) if(downstream->get_upstream()->on_downstream_header_complete(downstream)
!= 0) { != 0) {
return -1; return -1;

View File

@ -378,20 +378,6 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
delete upstream->get_client_handler(); delete upstream->get_client_handler();
} else if(rv == 0) { } else if(rv == 0) {
if(downstream->get_response_state() == Downstream::MSG_COMPLETE) { if(downstream->get_response_state() == Downstream::MSG_COMPLETE) {
if(get_config()->client_mode && downstream->tunnel_established()) {
// For tunneled connection, if there is no pending data,
// delete handler because on_write will not be called.
ClientHandler *handler = upstream->get_client_handler();
if(handler->get_pending_write_length() == 0) {
delete handler;
} else {
if(LOG_ENABLED(INFO)) {
DLOG(INFO, downstream) << "Tunneled connection has pending data";
}
handler->set_should_close_after_write(true);
}
return;
}
if(downstream->get_response_connection_close()) { if(downstream->get_response_connection_close()) {
// Connection close // Connection close
downstream->set_downstream_connection(0); downstream->set_downstream_connection(0);
@ -401,8 +387,8 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
// Keep-alive // Keep-alive
dconn->detach_downstream(downstream); dconn->detach_downstream(downstream);
} }
ClientHandler *handler = upstream->get_client_handler();
if(downstream->get_request_state() == Downstream::MSG_COMPLETE) { if(downstream->get_request_state() == Downstream::MSG_COMPLETE) {
ClientHandler *handler = upstream->get_client_handler();
if(handler->get_should_close_after_write() && if(handler->get_should_close_after_write() &&
handler->get_pending_write_length() == 0) { handler->get_pending_write_length() == 0) {
// If all upstream response body has already written out to // If all upstream response body has already written out to
@ -417,6 +403,23 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
return; return;
} }
} }
} else if(downstream->tunnel_established()) {
// This path is effectively only taken for SPDY downstream
// because only SPDY downstream sets response_state to
// MSG_COMPLETE and this function. For HTTP downstream, EOF
// from tunnel connection is handled on
// https_downstream_eventcb.
//
// Tunneled connection always indicates connection close.
if(handler->get_pending_write_length() == 0) {
// For tunneled connection, if there is no pending data,
// delete handler because on_write will not be called.
delete handler;
} else {
if(LOG_ENABLED(INFO)) {
DLOG(INFO, downstream) << "Tunneled connection has pending data";
}
}
} }
} else { } else {
ClientHandler *handler = upstream->get_client_handler(); ClientHandler *handler = upstream->get_client_handler();

View File

@ -707,6 +707,7 @@ void on_ctrl_recv_callback
<< "stream_id=" << "stream_id="
<< frame->rst_stream.stream_id; << frame->rst_stream.stream_id;
} }
downstream->get_upstream()->on_downstream_body_complete(downstream);
downstream->set_response_state(Downstream::MSG_COMPLETE); downstream->set_response_state(Downstream::MSG_COMPLETE);
} else { } else {
// If we got RST_STREAM, just flag MSG_RESET to indicate // If we got RST_STREAM, just flag MSG_RESET to indicate
@ -801,6 +802,9 @@ void on_ctrl_recv_callback
Upstream *upstream = downstream->get_upstream(); Upstream *upstream = downstream->get_upstream();
downstream->set_response_state(Downstream::HEADER_COMPLETE); downstream->set_response_state(Downstream::HEADER_COMPLETE);
if(downstream->tunnel_established()) {
downstream->set_response_connection_close(true);
}
rv = upstream->on_downstream_header_complete(downstream); rv = upstream->on_downstream_header_complete(downstream);
if(rv != 0) { if(rv != 0) {
spdylay_submit_rst_stream(session, frame->syn_reply.stream_id, spdylay_submit_rst_stream(session, frame->syn_reply.stream_id,