summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2016-06-14 00:48:28 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2016-06-19 23:34:16 -0400
commit923688d2da036f3cefc4fb494dcd770acaab1691 (patch)
treee03fcf275deb056287245723ec54469c542d5c6f /src
parent18a7b2be37041987c5bde264d03a7ee7440ae788 (diff)
downloadlighttpd-git-923688d2da036f3cefc4fb494dcd770acaab1691.tar.gz
drain backend socket/pipe bufs upon FDEVENT_HUP
(mod_cgi, mod_fastcgi, mod_scgi, mod_proxy)
Diffstat (limited to 'src')
-rw-r--r--src/mod_cgi.c23
-rw-r--r--src/mod_fastcgi.c19
-rw-r--r--src/mod_proxy.c12
-rw-r--r--src/mod_scgi.c12
4 files changed, 51 insertions, 15 deletions
diff --git a/src/mod_cgi.c b/src/mod_cgi.c
index 456e6f87..4b1235d1 100644
--- a/src/mod_cgi.c
+++ b/src/mod_cgi.c
@@ -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 */
diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
index 48efd37a..8a132587 100644
--- a/src/mod_fastcgi.c
+++ b/src/mod_fastcgi.c
@@ -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",
diff --git a/src/mod_proxy.c b/src/mod_proxy.c
index 823bb5b2..90003689 100644
--- a/src/mod_proxy.c
+++ b/src/mod_proxy.c
@@ -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);
}
diff --git a/src/mod_scgi.c b/src/mod_scgi.c
index 72057f8c..00653bf4 100644
--- a/src/mod_scgi.c
+++ b/src/mod_scgi.c
@@ -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",