commit 2e9bd5cb1a3122326a3b347a6febc7da047b58ad from: Omar Polo via: Thomas Adam date: Fri Mar 10 21:44:31 2023 UTC gotwebd: handle short reads and timeouts If a short read happens, or if all the fastcgi record to read don't fit in the buffer, gotwebd fails to continue reading and hits the timeout. If this happens before gotweb_process_request is called, it will crash in gotweb_free_transport since c->t will be NULL. This register the event with EV_PERSIST so fcgi_request is called again when there's more to read and guards gotweb_free_transport. It also makes spaces for the records as soon as they're successfully parsed. With lots of help from stsp ok stsp@ commit - a928faa132d1d2e179dcfc5d3f3210263b067ac9 commit + 2e9bd5cb1a3122326a3b347a6febc7da047b58ad blob - 0ca99d2850d2590cd57a086459f7e8e5b2e77a74 blob + a2a198890cf78469d183c3223cdce1833f9e6be9 --- gotwebd/fcgi.c +++ gotwebd/fcgi.c @@ -97,14 +97,14 @@ fcgi_request(int fd, short events, void *arg) c->buf_pos += parsed; c->buf_len -= parsed; } - } while (parsed > 0 && c->buf_len > 0); - /* Make space for further reads */ - if (parsed != 0) - if (c->buf_len > 0) { + /* drop the parsed record */ + if (parsed != 0 && c->buf_len > 0) { bcopy(c->buf + c->buf_pos, c->buf, c->buf_len); c->buf_pos = 0; } + } while (parsed > 0 && c->buf_len > 0); + return; fail: fcgi_cleanup_request(c); @@ -506,7 +506,8 @@ fcgi_cleanup_request(struct request *c) close(c->fd); template_free(c->tp); - gotweb_free_transport(c->t); + if (c->t != NULL) + gotweb_free_transport(c->t); free(c); } blob - b57ade9f4b857c2f3544b8ba769c7a33509fac96 blob + c70fe81742e688cd82a6449ebb48174fdc111dc1 --- gotwebd/sockets.c +++ gotwebd/sockets.c @@ -647,7 +647,7 @@ sockets_socket_accept(int fd, short event, void *arg) c->request_started = 0; c->sock->client_status = CLIENT_CONNECT; - event_set(&c->ev, s, EV_READ, fcgi_request, c); + event_set(&c->ev, s, EV_READ|EV_PERSIST, fcgi_request, c); event_add(&c->ev, NULL); evtimer_set(&c->tmo, fcgi_timeout, c);