[mod_cgi,fastcgi,scgi,proxy] fix streaming response (fixes #2796)

fix streaming response when server.stream-response-body = 2
and client catches up to stream from backend

(thx horgh)

x-ref:
  "mod_fastcgi can fail to read entire response from server"
  https://redmine.lighttpd.net/issues/2796
personal/stbuehler/mod-csrf
Glenn Strauss 6 years ago
parent f94d666d15
commit e4bb56222f
  1. 4
      src/mod_cgi.c
  2. 6
      src/mod_fastcgi.c
  3. 6
      src/mod_proxy.c
  4. 4
      src/mod_scgi.c

@ -426,7 +426,6 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
if (errno == EAGAIN || errno == EINTR) {
/* would block, wait for signal */
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
return FDEVENT_HANDLED_NOT_FINISHED;
}
/* error */
@ -1486,9 +1485,10 @@ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
if (chunkqueue_length(con->write_queue) > 65536 - 4096) {
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
} else if (!(fdevent_event_get_interest(srv->ev, hctx->fd) & FDEVENT_IN)) {
/* optimistic read from backend, which might re-enable FDEVENT_IN */
/* optimistic read from backend */
handler_t rc = cgi_recv_response(srv, hctx); /*(might invalidate hctx)*/
if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
}
}

@ -2409,7 +2409,6 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
#if !defined(_WIN32) && !defined(__CYGWIN__)
if (ioctl(hctx->fd, FIONREAD, &toread)) {
if (errno == EAGAIN) {
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
return 0;
}
log_error_write(srv, __FILE__, __LINE__, "sd",
@ -2442,7 +2441,6 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
if (-1 == r) {
if (errno == EAGAIN) {
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
return 0;
}
log_error_write(srv, __FILE__, __LINE__, "sds",
@ -2452,6 +2450,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
}
}
if (0 == r) {
if (!(fdevent_event_get_interest(srv->ev, hctx->fd) & FDEVENT_IN)) return 0;
log_error_write(srv, __FILE__, __LINE__, "ssdsb",
"unexpected end-of-file (perhaps the fastcgi process died):",
"pid:", proc->pid,
@ -2966,9 +2965,10 @@ SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) {
if (chunkqueue_length(con->write_queue) > 65536 - 4096) {
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
} else if (!(fdevent_event_get_interest(srv->ev, hctx->fd) & FDEVENT_IN)) {
/* optimistic read from backend, which might re-enable FDEVENT_IN */
/* optimistic read from backend */
handler_t rc = fcgi_recv_response(srv, hctx); /*(might invalidate hctx)*/
if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
}
}

@ -839,7 +839,6 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
#if !defined(_WIN32) && !defined(__CYGWIN__)
if (ioctl(hctx->fd, FIONREAD, &b)) {
if (errno == EAGAIN) {
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
return 0;
}
log_error_write(srv, __FILE__, __LINE__, "sd",
@ -878,7 +877,6 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
if (-1 == (r = read(hctx->fd, hctx->response->ptr + buffer_string_length(hctx->response), buffer_string_space(hctx->response)))) {
if (errno == EAGAIN) {
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
return 0;
}
log_error_write(srv, __FILE__, __LINE__, "sds",
@ -951,6 +949,7 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
buffer_reset(hctx->response);
}
} else {
if (!(fdevent_event_get_interest(srv->ev, hctx->fd) & FDEVENT_IN)) return 0;
/* reading from upstream done */
fin = 1;
}
@ -1179,9 +1178,10 @@ SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
if (chunkqueue_length(con->write_queue) > 65536 - 4096) {
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
} else if (!(fdevent_event_get_interest(srv->ev, hctx->fd) & FDEVENT_IN)) {
/* optimistic read from backend, which might re-enable FDEVENT_IN */
/* optimistic read from backend */
handler_t rc = proxy_recv_response(srv, hctx); /*(might invalidate hctx)*/
if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
}
}

@ -1814,7 +1814,6 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
if (errno == EAGAIN || errno == EINTR) {
/* would block, wait for signal */
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
return 0;
}
/* error */
@ -2430,9 +2429,10 @@ SUBREQUEST_FUNC(mod_scgi_handle_subrequest) {
if (chunkqueue_length(con->write_queue) > 65536 - 4096) {
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
} else if (!(fdevent_event_get_interest(srv->ev, hctx->fd) & FDEVENT_IN)) {
/* optimistic read from backend, which might re-enable FDEVENT_IN */
/* optimistic read from backend */
handler_t rc = scgi_recv_response(srv, hctx); /*(might invalidate hctx)*/
if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
}
}

Loading…
Cancel
Save