Bound the request head by the read timeout as a whole

The read timeout applied to each read of the request line and headers,
so a client that sent them a byte now and then held a worker for as
long as it liked, and enough such clients left no worker for anyone
else. Bound the whole head by the read timeout, as the TLS handshake
already is, through a new Stream::set_max_timeout() that the socket
streams implement with their existing max timeout.

A request body is still bounded per read, and a WebSocket holds its
worker for its whole life. The README says so, and points to a
reverse proxy and the pre-request handler for untrusted clients.
This commit is contained in:
yhirose committed 2026-10-16 19:13:03 -04:00
1 parent ae169c6253
commit bc837b87fc
4 files changed
+134 -34

No files matched your search

+4
View File
@@ -898,6 +898,8 @@ svr.set_read_timeout(std::chrono::seconds(5));
svr.set_keep_alive_timeout(std::chrono::seconds(10));
```
The read timeout bounds the request line and headers as a whole, and each read of a request body.
### Set maximum payload length for reading a request body
```c++
@@ -917,6 +919,8 @@ Please see [Server example](https://github.com/yhirose/cpp-httplib/blob/master/e
When all threads are busy and a new task arrives, a temporary thread is spawned (up to the maximum). A dynamic thread exits automatically once it has waited for the idle timeout without receiving a task. The idle timeout defaults to 3 seconds, configurable via `CPPHTTPLIB_THREAD_POOL_IDLE_TIMEOUT`.
A connection holds its thread while it is served: between requests up to the keep-alive timeout, through a request body sent slowly but within the read timeout, and for the whole life of a WebSocket. Enough of them leave no thread for anyone else, so in front of untrusted clients, put a reverse proxy that limits connections per client, and reject unwanted WebSocket upgrades in the pre-request handler.
If you want to set the thread counts at runtime:
```cpp