Fix handling of unexpected hangups - quark - quark web server
 (HTM) git clone git://git.suckless.org/quark
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit f1892c4dffa7df6995cd8c9ebd47e0ce7f0e457e
 (DIR) parent 3729e7222aafc4c4ca30351748a89e05f78e2230
 (HTM) Author: Laslo Hunhold <dev@frign.de>
       Date:   Sun, 31 Jan 2021 00:39:11 +0100
       
       Fix handling of unexpected hangups
       
       During slowloris-stress-testing I noticed that closing the tool would
       pretty reliably trigger a case where quark was continuously getting
       edge-triggered on EPOLLIN and notified that there was something to read
       on the now definitely closed client-sockets.
       
       This was wrong and due to the fact that I mishandled the case when
       read() returns 0 in http_recv_header(). The condition read()==0 and
       EPOLL or EWOULDBLOCK does not indicate that you should try again. It's
       an EOF-condition and should be handled as such.
       
       Given the request is incomplete at this point, this is handled as a
       bad request (HTTP status 400) mostly for the logs at this point, as
       being able to transmit the error page itself is highly unlikely.
       
       Signed-off-by: Laslo Hunhold <dev@frign.de>
       
       Diffstat:
         M http.c                              |      10 +++++++++-
       
       1 file changed, 9 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/http.c b/http.c
       @@ -154,7 +154,7 @@ http_recv_header(int fd, struct buffer *buf, int *done)
        
                while (1) {
                        if ((r = read(fd, buf->data + buf->len,
       -                              sizeof(buf->data) - buf->len)) <= 0) {
       +                              sizeof(buf->data) - buf->len)) < 0) {
                                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                                        /*
                                         * socket is drained, return normally,
       @@ -166,6 +166,14 @@ http_recv_header(int fd, struct buffer *buf, int *done)
                                        s = S_REQUEST_TIMEOUT;
                                        goto err;
                                }
       +                } else if (r == 0) {
       +                        /*
       +                         * unexpected EOF because the client probably
       +                         * hung up. This is technically a bad request,
       +                         * because it's incomplete
       +                         */
       +                        s = S_BAD_REQUEST;
       +                        goto err;
                        }
                        buf->len += r;