Fix handling of unexpected hangups - quark - quark web server | |
git clone git://git.suckless.org/quark | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit f1892c4dffa7df6995cd8c9ebd47e0ce7f0e457e | |
parent 3729e7222aafc4c4ca30351748a89e05f78e2230 | |
Author: Laslo Hunhold <[email protected]> | |
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 <[email protected]> | |
Diffstat: | |
M http.c | 10 +++++++++- | |
1 file changed, 9 insertions(+), 1 deletion(-) | |
--- | |
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; | |