commit 5add7f42e1397d136860680e1f0411db17b4f22c from: Omar Polo date: Fri Mar 10 17:44:48 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 - 6cc8a118a74d4c7a3f037ad0f755a3aadf5288d6 commit + 5add7f42e1397d136860680e1f0411db17b4f22c blob - dd6dbe5f5b29eee48c7bcc972741e3a471d95c6b blob + ba1803b45941d2c4b83b31f232b8e7edfb92df63 --- gotwebd/fcgi.c +++ gotwebd/fcgi.c @@ -95,14 +95,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); @@ -504,7 +504,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 - cfba5dfb0e7368b0b37738d2eb71b53d437db169 blob + ecb88027e072a125a309c08b985733a77ab2a26d --- gotwebd/sockets.c +++ gotwebd/sockets.c @@ -637,7 +637,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);