Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/jeremy/rack-ratelimit

Flexible rate limiting for your Rack apps
https://github.com/jeremy/rack-ratelimit

rack ruby

Last synced: 8 days ago
JSON representation

Flexible rate limiting for your Rack apps

Awesome Lists containing this project

README

        

Rack::Ratelimit
===============

* Run multiple rate limiters in a single app
* Scope each rate limit to certain requests: API, files, GET vs POST, etc.
* Apply each rate limit by request characteristics: IP, subdomain, OAuth2 token, etc.
* Flexible time window to limit burst traffic vs hourly or daily traffic:
100 requests per 10 sec, 500 req/minute, 10000 req/hour, etc.
* Fast, low-overhead implementation in memcache using counters for discrete timeslices:
timeslice = window * ceiling(current time / window)
memcache.incr(counter for timeslice)

Configuration
-------------

Takes a block that classifies requests for rate limiting. Given a
Rack env, return a string such as IP address, API token, etc. If the
block returns nil, the request won't be rate-limited. If a block is
not given, all requests get the same limits.

Required configuration:
* rate: an array of [max requests, period in seconds]: [500, 5.minutes]

and one of
* cache: a Dalli::Client instance
* redis: a Redis instance
* counter: Your own custom counter. Must respond to `#increment(classification_string, end_of_time_window_timestamp)` and return the counter value after increment.

Optional configuration:
* name: name of the rate limiter. Defaults to 'HTTP'. Used in messages.
* conditions: array of procs that take a rack env, all of which must
return true to rate-limit the request.
* exceptions: array of procs that take a rack env, any of which may
return true to exclude the request from rate limiting.
* logger: responds to #info(message). If provided, the rate limiter
logs the first request that hits the rate limit, but none of the
subsequently blocked requests.
* error_message: the message returned in the response body when the rate
limit is exceeded. Defaults to " rate limit exceeded. Please
wait seconds then retry your request."

Examples
--------

Rate-limit bursts of POST/PUT/DELETE requests by IP address

use(Rack::Ratelimit, name: 'POST',
exceptions: ->(env) { env['REQUEST_METHOD'] == 'GET' },
rate: [50, 10.seconds],
cache: Dalli::Client.new,
logger: Rails.logger) { |env| Rack::Request.new(env).ip }

Rate-limit API traffic by user (set by Rack::Auth::Basic)

use(Rack::Ratelimit, name: 'API',
conditions: ->(env) { env['REMOTE_USER'] },
rate: [1000, 1.hour],
redis: Redis.new(ratelimit_redis_config),
logger: Rails.logger) { |env| env['REMOTE_USER'] }