drain backend socket/pipe bufs upon FDEVENT_HUP

(mod_cgi, mod_fastcgi, mod_scgi, mod_proxy)
This commit is contained in:
Glenn Strauss 2016-06-14 00:48:28 -04:00
parent 18a7b2be37
commit 923688d2da
4 changed files with 51 additions and 15 deletions

View File

@ -778,20 +778,29 @@ static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) {
/* perhaps this issue is already handled */
if (revents & FDEVENT_HUP) {
/* check if we still have a unfinished header package which is a body in reality */
if (con->file_started == 0 && !buffer_string_is_empty(hctx->response_header)) {
if (con->file_started) {
/* drain any remaining data from kernel pipe buffers
* even if (con->conf.stream_response_body
* & FDEVENT_STREAM_RESPONSE_BUFMIN)
* since event loop will spin on fd FDEVENT_HUP event
* until unregistered. */
handler_t rc;
do {
rc = cgi_recv_response(srv,hctx);/*(might invalidate hctx)*/
} while (rc == HANDLER_GO_ON); /*(unless HANDLER_GO_ON)*/
return rc; /* HANDLER_FINISHED or HANDLER_ERROR */
} else if (!buffer_string_is_empty(hctx->response_header)) {
/* unfinished header package which is a body in reality */
con->file_started = 1;
if (0 != http_chunk_append_buffer(srv, con, hctx->response_header)) {
cgi_connection_close(srv, hctx);
return HANDLER_ERROR;
}
}
} else {
# if 0
log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
# endif
/* rtsigs didn't liked the close */
}
cgi_connection_close(srv, hctx);
} else if (revents & FDEVENT_ERR) {
/* kill all connections to the cgi process */

View File

@ -3407,14 +3407,17 @@ static handler_t fcgi_handle_fdevent(server *srv, void *ctx, int revents) {
*
*/
fcgi_send_request(srv, hctx);
} else if (chunkqueue_is_empty(hctx->wb) &&
hctx->wb->bytes_in != 0 &&
hctx->proc->port == 0) {
/* FIXME:
*
* ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket
* even if the FCGI_FIN packet is not received yet
*/
} else if (con->file_started) {
/* drain any remaining data from kernel pipe buffers
* even if (con->conf.stream_response_body
* & FDEVENT_STREAM_RESPONSE_BUFMIN)
* since event loop will spin on fd FDEVENT_HUP event
* until unregistered. */
handler_t rc;
do {
rc = fcgi_recv_response(srv,hctx);/*(might invalidate hctx)*/
} while (rc == HANDLER_GO_ON); /*(unless HANDLER_GO_ON)*/
return rc; /* HANDLER_FINISHED or HANDLER_ERROR */
} else {
fcgi_proc *proc = hctx->proc;
log_error_write(srv, __FILE__, __LINE__, "sBSbsbsd",

View File

@ -855,6 +855,7 @@ static handler_t proxy_write_request(server *srv, handler_ctx *hctx) {
if (hctx->wb->bytes_out == hctx->wb_reqlen) {
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
shutdown(hctx->fd, SHUT_WR);/* future: remove if HTTP/1.1 request */
proxy_set_state(srv, hctx, PROXY_STATE_READ);
} else {
off_t wblen = hctx->wb->bytes_in - hctx->wb->bytes_out;
@ -1117,6 +1118,17 @@ static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) {
proxy_connection_close(srv, hctx);
con->http_status = 503;
}
} else if (con->file_started) {
/* drain any remaining data from kernel pipe buffers
* even if (con->conf.stream_response_body
* & FDEVENT_STREAM_RESPONSE_BUFMIN)
* since event loop will spin on fd FDEVENT_HUP event
* until unregistered. */
handler_t rc;
do {
rc = proxy_recv_response(srv,hctx);/*(might invalidate hctx)*/
} while (rc == HANDLER_GO_ON); /*(unless HANDLER_GO_ON)*/
return rc; /* HANDLER_FINISHED or HANDLER_ERROR */
} else {
proxy_connection_close(srv, hctx);
}

View File

@ -2442,6 +2442,7 @@ static handler_t scgi_write_request(server *srv, handler_ctx *hctx) {
if (hctx->wb->bytes_out == hctx->wb_reqlen) {
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
shutdown(hctx->fd, SHUT_WR);
scgi_set_state(srv, hctx, FCGI_STATE_READ);
} else {
off_t wblen = hctx->wb->bytes_in - hctx->wb->bytes_out;
@ -2728,6 +2729,17 @@ static handler_t scgi_handle_fdevent(server *srv, void *ctx, int revents) {
*
*/
scgi_send_request(srv, hctx);
} else if (con->file_started) {
/* drain any remaining data from kernel pipe buffers
* even if (con->conf.stream_response_body
* & FDEVENT_STREAM_RESPONSE_BUFMIN)
* since event loop will spin on fd FDEVENT_HUP event
* until unregistered. */
handler_t rc;
do {
rc = scgi_recv_response(srv,hctx);/*(might invalidate hctx)*/
} while (rc == HANDLER_GO_ON); /*(unless HANDLER_GO_ON)*/
return rc; /* HANDLER_FINISHED or HANDLER_ERROR */
} else {
scgi_extension_host *host= hctx->host;
log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",