commit f1892c4dffa7df6995cd8c9ebd47e0ce7f0e457e
Author:     Laslo Hunhold <[email protected]>
AuthorDate: Sun Jan 31 00:39:11 2021 +0100
Commit:     Laslo Hunhold <[email protected]>
CommitDate: Sun Jan 31 00:39:11 2021 +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 <[email protected]>

diff --git a/http.c b/http.c
index f52da8a..1e43035 100644
--- 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;
 

Reply via email to