Need to be able to set timeouts / limits to handle misbehaving clients
If tower-web is exposed to the internet, it needs to be robust when handling misbehaving clients. I'm thinking of
- request header read timeout: max time it can take for the client to send all headers
- request body timeout
- request reply timeout (if a client simply doesn't read the reply)
- there should be a way for a request handler to reset/restart the timeouts, e.g. to facilitate large bodies or large replies.
- idle timeout for keepalive sessions
- max number of simultaneous requests per client (source ip address)
- max number of requests/sec per client
The last two could probably be implemented as middleware if there was a way to get the client's IP address.
It could be that this should be implemented in hyper instead of in tower, if so tell me and I will open an issue with hyper.
See also #10
- request header read timeout: max time it can take for the client to send all headers
- idle timeout for keepalive sessions
These would need to go in hyper. I would check to see if it is already possible.
- request body timeout
- request reply timeout (if a client simply doesn't read the reply)
- max number of simultaneous requests per client (source ip address)
- max number of requests/sec per client
Implemented as a middleware. It can start in this repo and eventually be moved into tower-http.
- if there was a way to get the client's IP address
Can be discussed in #71
- there should be a way for a request handler to reset/restart the timeouts, e.g. to facilitate large bodies or large replies.
You will have to elaborate more on this one.
If you want to take a stab at any of these items, I can help with some pointers.
there should be a way for a request handler to reset/restart the timeouts, e.g. to facilitate large bodies or large replies.
You will have to elaborate more on this one.
For example, when you set a request body timeout of 30 seconds, and after the timeout it turns out that 30 MB of body payload already has been received - in that case, yes, 30 seconds have passed, but progress is made, so you want to ignore this timeout and set a new one.
Either this, or 2 seperate types of timeout: absolute, with a hard limit (N minutes no matter what) and relative, one that fires if no progress is made (connection stalled) for a certain period of time.
If it is possible to implement this as middleware, even better, because that would allow more complicated strategies as well (say when max. number of clients is reached, close the oldest sessions that are idling in keepalive).
For completeness, a list of nginx's timeouts.
- client_body_timeout (60s) (relative)
- send_timeout (60s) (relative)
- client_header_timeout (60s) (absolute)
- keepalive_timeout (75s)