diff options
-rw-r--r-- | FEATURES | 2 | ||||
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | hittpd.c | 19 |
3 files changed, 19 insertions, 4 deletions
diff --git a/FEATURES b/FEATURES index 5524dd8..8afda8a 100644 --- a/FEATURES +++ b/FEATURES @@ -6,7 +6,7 @@ Features of hittpd: - HTTP 1.0 and HTTP 1.1 support - Ranges (basic variants only) - If-Modified-Since -- Keep-Alive +- Keep-Alive (but no pipelining) - IPv6 - sendfile(2) on Linux - Virtual Hosts diff --git a/LICENSE b/LICENSE index 5d980d9..cb12f14 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020, 2021 Leah Neukirchen <leah@vuxu.org> +Copyright 2020, 2021, 2022 Leah Neukirchen <leah@vuxu.org> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/hittpd.c b/hittpd.c index e5114d6..9ddd2c4 100644 --- a/hittpd.c +++ b/hittpd.c @@ -1,6 +1,6 @@ /* hittpd - efficient, no-frills HTTP 1.1 server */ -/* Copyright 2020, 2021 Leah Neukirchen <leah@vuxu.org> +/* Copyright 2020, 2021, 2022 Leah Neukirchen <leah@vuxu.org> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -516,6 +516,7 @@ on_message_complete(http_parser *p) { struct conn_data *data = p->data; data->state = SENDING; + http_parser_pause(p, 1); // can't do more than one request at a time if (p->http_major == 0 && p->http_minor == 9) return send_error(p, 400, "Bad Request"); @@ -919,7 +920,21 @@ read_client(int i) } else if (n == 0) { close_connection(i); } else { - http_parser_execute(&parsers[i], &settings, buf, n); + size_t r = http_parser_execute(&parsers[i], &settings, buf, n); + + if ((size_t)n == r && + HTTP_PARSER_ERRNO(&parsers[i]) == HPE_PAUSED) { + // we handled a complete request, we can reuse + // the parser + http_parser_pause(&parsers[i], 0); + } else { + // the read data was longer than a single request + // drop the rest and make sure we close the connection, + // so the client tries without pipelining + // (this is conformant) + http_parser_pause(&parsers[i], 0); + parsers[i].flags |= F_CONNECTION_CLOSE; + } if (parsers[i].http_errno) { printf("err=%s\n", |