class Rack::ApiKeyLimit::Base

Public Class Methods

new(app, options) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 4
def initialize(app, options)
  @app = app
  @options = options
end

Public Instance Methods

allowed?(request, key) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 74
def allowed?(request, key)
  return true unless has_param?(request) # always allowed if no key present
  cache.increment(key, limit_seconds) and return true if remaining(key) > 0
end
cache() click to toggle source
# File lib/rack_api_key_limit/base.rb, line 13
def cache
  @options[:cache]
end
call(env) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 17
def call(env)
  request = Rack::Request.new(env)
  key = get_key(request, cache)
  allowed?(request, key) ? not_rate_limited(env, request, key) : rate_limit_exceeded(key)
end
get_key(request, cache) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 35
def get_key(request, cache)
  raise NotImplementedError.new("You must implement get_key.")
end
has_param?(request) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 31
def has_param?(request)
  request.params.has_key?(param_name)
end
http_error(code, message = nil, headers = {}) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 79
def http_error(code, message = nil, headers = {})
  [code, {'Content-Type' => 'text/plain; charset=utf-8'}.merge(headers),
    [http_status(code) + (message.nil? ? "\n" : " (#{message})\n")]
  ]
end
http_status(code) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 85
def http_status(code)
  [code, Rack::Utils::HTTP_STATUS_CODES[code]].join(' ')
end
limit_seconds() click to toggle source
# File lib/rack_api_key_limit/base.rb, line 49
def limit_seconds
  raise NotImplementedError.new("You must implement limit_seconds.")
end
not_rate_limited(env, request, key) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 39
def not_rate_limited(env, request, key)
  status, headers, response = @app.call(env)
  headers = headers.merge(rate_limit_headers(key)) if has_param?(request)
  [status, headers, response]
end
options() click to toggle source
# File lib/rack_api_key_limit/base.rb, line 9
def options
  @options || {}
end
param(request) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 27
def param(request)
  request.params[param_name]
end
param_name() click to toggle source
# File lib/rack_api_key_limit/base.rb, line 23
def param_name
  options[:param_name] || "api_key"
end
rate_limit_exceeded(key) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 61
def rate_limit_exceeded(key)
  http_error(options[:status] || 429, options[:message] || 'Rate Limit Exceeded', rate_limit_headers(key))
end
rate_limit_headers(key) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 53
def rate_limit_headers(key)
  headers = {}
  headers["X-RateLimit-Limit"] = request_limit.to_s
  headers["X-RateLimit-Remaining"] = remaining(key).to_s
  headers["X-RateLimit-Reset"] = retry_after.to_f.ceil.to_s if respond_to?(:retry_after)
  headers
end
remaining(key) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 70
def remaining(key)
  request_limit - request_count(key)
end
request_count(key) click to toggle source
# File lib/rack_api_key_limit/base.rb, line 65
def request_count(key)
  request_count = cache.get(key)
  (request_count.to_i if request_count) || 0
end
request_limit() click to toggle source
# File lib/rack_api_key_limit/base.rb, line 45
def request_limit
  options[:request_limit] || 150
end