Sat, 10 Jun 2023 18:12:04 +0200
fix cgi-send inactive write event blocking request termination
src/server/safs/cgi.c | file | annotate | diff | comparison | revisions | |
src/server/safs/cgi.h | file | annotate | diff | comparison | revisions |
--- a/src/server/safs/cgi.c Wed Jun 07 15:59:00 2023 +0200 +++ b/src/server/safs/cgi.c Sat Jun 10 18:12:04 2023 +0200 @@ -227,12 +227,16 @@ if(errno != EWOULDBLOCK) { handler->result = REQ_ABORTED; } + handler->wait_write = TRUE; return 1; + } else { + handler->wait_write = FALSE; } return 0; } static int cgi_try_write(CGIHandler *handler, EventHandler *ev, Session *sn, char *buf, size_t size) { + handler->wait_write = FALSE; size_t pos = 0; ssize_t wr = 0; while(size - pos > 0 && (wr = net_write(sn->csd, buf + pos, size - pos)) > 0) { @@ -264,6 +268,7 @@ handler->events++; handler->poll_out = TRUE; } + handler->wait_write = TRUE; } else { handler->result = REQ_ABORTED; log_ereport(LOG_FAILURE, "cgi_try_write: %s", strerror(errno)); @@ -298,7 +303,7 @@ // if writebuf is empty, this does nothing and returns 0 if(cgi_try_write_flush(handler, sn)) { if(handler->result == REQ_ABORTED) { - log_ereport(LOG_DEBUG, "cgi-send: req: %p write failed: abort", rq); + log_ereport(LOG_DEBUG, "cgi-send: req: %p write failed: %s: abort", strerror(errno), rq); return 0; } else { return 1; @@ -370,7 +375,7 @@ if(r < 0 && errno == EWOULDBLOCK) { return 1; } - + return 0; } @@ -467,10 +472,17 @@ CGIResponseParser *parser = handler->parser; Session *sn = parser->sn; Request *rq = parser->rq; - - log_ereport(LOG_DEBUG, "cgi-send: req: %p event-finish %d", rq, handler->events); + if(--handler->events > 0) { - return 0; + if(handler->events == 1 && handler->poll_out && !handler->wait_write) { + // write event registered, however it will not be activated anymore + // we can safely remove the event + if(event_removepoll(ev, sn->csd)) { + log_ereport(LOG_FAILURE, "cgi_event_finish: event_removepoll: %s", strerror(errno)); + } + } else { + return 0; + } } if(handler->result == REQ_ABORTED && handler->process.pid != 0) {
--- a/src/server/safs/cgi.h Wed Jun 07 15:59:00 2023 +0200 +++ b/src/server/safs/cgi.h Sat Jun 10 18:12:04 2023 +0200 @@ -109,6 +109,12 @@ WSBool poll_out; /* + * last write returned EWOULDBLOCK + * waiting for the next write event + */ + WSBool wait_write; + + /* * number of currently open events (stdout, stderr, [stdout]) */ int events;