Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
WAI Rate Limiting Middleware.
Rate limiting is configured by providing a function that maps a Request
to
a key
and providing a Rate
for it. The Rate
configures the maximum
number of requests to allow after a period of inactivity (or at the
beginning), and an average rate at which requests should be allowed.
Note that rate limiting state is maintained in memory by this module and a web server restart will reset all state. Thus, this module is more appropriate for limits that apply over shorter periods of time.
Synopsis
- data Rate = Rate {}
- mkRate :: Word64 -> (Word64, Word64) -> Rate
- infRate :: Rate
- data RateLimitSettings key
- newRateLimitSettings :: (Request -> IO (key, Rate)) -> IO (RateLimitSettings key)
- setRateLimitExceededResponse :: RateLimitSettings key -> Response -> RateLimitSettings key
- setResetInterval :: RateLimitSettings key -> Int -> IO (RateLimitSettings key)
- rateLimitMiddleware :: Hashable a => RateLimitSettings a -> Middleware
- stopResetThread :: RateLimitSettings key -> IO ()
- data Cache key
- newCache :: IO (Cache key)
- tryAllocate :: Hashable key => key -> Rate -> Word64 -> Cache key -> IO (Maybe Word64)
Types, constructors and setters
Rate represents token bucket parameters.
Rate | |
|
mkRate :: Word64 -> (Word64, Word64) -> Rate Source #
mkRate
creates a Rate
given the burst amount, and the number of
operations (must be > 0) to allow per number of seconds given.
infRate
creates a Rate
whose limit can never be exceeded. Useful to
never limit an operation.
data RateLimitSettings key Source #
RateLimitSetings
holds settings for the rate limiting middleware.
newRateLimitSettings :: (Request -> IO (key, Rate)) -> IO (RateLimitSettings key) Source #
Create new rate limit settings by providing a function to map a request to a key and a Rate. It sets up a default response for requests that exceed the rate limit that returns a 429 status code with a simple error message.
setRateLimitExceededResponse :: RateLimitSettings key -> Response -> RateLimitSettings key Source #
Set a custom error response.
setResetInterval :: RateLimitSettings key -> Int -> IO (RateLimitSettings key) Source #
setResetInterval
starts a thread to reset (clear) the token buckets map
after every given interval period of time (expressed in seconds). This is
useful if your webserver generates a lot of request key
s that go idle after
some activity. In this situation the token bucket cache memory usage grows as
it contains an entry every key seen. When the cache is reset, the memory can
be garbage collected. Though this will cause all rate limit token buckets to
go "full" (i.e. allow the full burst of requests immediately), this solution
is acceptable as this is the case when the webserver is restarted as well. By
default, there is no reset thread launched (unless this function is called).
Middleware
rateLimitMiddleware :: Hashable a => RateLimitSettings a -> Middleware Source #
rateLimitMiddleware
performs rate limiting according to the given
settings.
Other useful code
stopResetThread :: RateLimitSettings key -> IO () Source #
stopResetThread
stops the thread launched by setResetInterval
and is
provided for completeness. If your application automatically restarts the
web-server using the rate limit middleware, call this function in your web
server's shutdown handler to ensure that the reset thread is killed (and does
not leak).
A cache that maps request key
s to a TokenBucket
.
tryAllocate :: Hashable key => key -> Rate -> Word64 -> Cache key -> IO (Maybe Word64) Source #
tryAllocate
attempts to allocate the given amount
from the
TokenBucket
corresponding to the given key
and Rate
in the Cache
. On
success it returns Nothing
, otherwise it returns the minimum time (in
nanoseconds) to wait after which the allocation can succeed.