tower-web icon indicating copy to clipboard operation
tower-web copied to clipboard

Need to be able to set timeouts / limits to handle misbehaving clients

Open miquels opened this issue 7 years ago • 3 comments

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.

miquels avatar Aug 20 '18 08:08 miquels

See also #10

shepmaster avatar Aug 22 '18 01:08 shepmaster

  • 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.

carllerche avatar Aug 22 '18 03:08 carllerche

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.

miquels avatar Aug 28 '18 08:08 miquels