Class: Galago::RateLimiter
- Inherits:
-
Object
- Object
- Galago::RateLimiter
- Defined in:
- lib/galago/rate_limiter.rb,
lib/galago/rate_limiter/configuration.rb,
lib/galago/rate_limiter/redis_counter.rb,
lib/galago/rate_limiter/memcached_counter.rb
Defined Under Namespace
Classes: Configuration, MemcachedCounter, Railtie, RedisCounter
Constant Summary collapse
- X_LIMIT_HEADER =
'X-RateLimit-Limit'.freeze
- X_RESET_HEADER =
'X-RateLimit-Reset'.freeze
- X_REMAINING_HEADER =
'X-RateLimit-Remaining'.freeze
Class Method Summary collapse
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app) ⇒ RateLimiter
constructor
A new instance of RateLimiter.
Constructor Details
#initialize(app) ⇒ RateLimiter
Returns a new instance of RateLimiter.
17 18 19 20 21 |
# File 'lib/galago/rate_limiter.rb', line 17 def initialize(app) @app = app @config = Configuration.instance @counter = @config.counter end |
Class Method Details
.configure {|Configuration.instance| ... } ⇒ Object
13 14 15 |
# File 'lib/galago/rate_limiter.rb', line 13 def self.configure yield Configuration.instance end |
Instance Method Details
#call(env) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/galago/rate_limiter.rb', line 23 def call(env) api_key = env[@config.api_key_header] return @app.call(env) if api_key.nil? throughput = @counter.increment(api_key, 1, expires_in: expires_in) if limit_exceeded?(throughput) execute_callback(api_key) status = 403 headers = { X_LIMIT_HEADER => @config.limit.to_s, X_REMAINING_HEADER => "0", X_RESET_HEADER => limit_resets_at.to_s } body = [JSON(message: "API rate limit exceeded for #{api_key}")] else status, headers, body = @app.call(env) headers[X_LIMIT_HEADER] = @config.limit.to_s headers[X_REMAINING_HEADER] = (@config.limit - throughput).to_s headers[X_RESET_HEADER] = limit_resets_at.to_s end [status, headers, body] end |