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:
parent
d830e099a6
commit
e28f169228
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue