class Rack::PooledThrottle::Throttle
Attributes
app[R]
options[R]
Public Class Methods
new(app, options = {})
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 6 def initialize(app, options = {}) @app, @options = app, options end
Public Instance Methods
call(env)
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 10 def call(env) request = Rack::Request.new(env) allowed?(request) ? app.call(env) : rate_limit_exceeded(request) end
Protected Instance Methods
allowed?(request)
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 25 def allowed?(request) if throttled_request?(request) case when whitelisted?(request) then true when blacklisted?(request) then false else query_cache?(request) end else true end end
blacklisted?(request)
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 50 def blacklisted?(request) if bl = options[:blacklisted] bl.call(request) else false end end
cache_key(request)
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 58 def cache_key(request) "#{namespace}:#{key_prefix}#{client_identifier(request)}" end
client_identifier(request)
click to toggle source
@param [Rack::Request] request @return [String]
# File lib/rack/pooledthrottle/throttle.rb, line 66 def client_identifier(request) if cio = options[:client_identifier] cio.call(request) else request.ip.to_s end end
http_error(code, message = nil, headers = {})
click to toggle source
Outputs an HTTP `4xx` or `5xx` response.
@param [Integer] code @param [String, to_s] message @param [Hash{String => String}] headers @return [Array(Integer, Hash, each)]
# File lib/rack/pooledthrottle/throttle.rb, line 111 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
Returns the standard HTTP status message for the given status `code`.
@param [Integer] code @return [String]
# File lib/rack/pooledthrottle/throttle.rb, line 121 def http_status(code) [code, Rack::Utils::HTTP_STATUS_CODES[code]].join(' ') end
key_prefix()
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 78 def key_prefix options[:key_prefix] end
max()
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 86 def max (options[:max] || 10).to_i end
namespace()
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 74 def namespace options[:namespace] || 'rpt' end
pool()
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 82 def pool options[:pool] end
query_cache?(request)
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 38 def query_cache?(request) false end
rate_limit_exceeded(request)
click to toggle source
Outputs a `Rate Limit Exceeded` error.
@return [Array(Integer, Hash, each)]
# File lib/rack/pooledthrottle/throttle.rb, line 98 def rate_limit_exceeded(request) options[:rate_limit_exceeded_callback].call(request) if options[:rate_limit_exceeded_callback] headers = respond_to?(:retry_after) ? {'Retry-After' => retry_after.to_f.ceil.to_s} : {} http_error(options[:code] || 403, options[:message] || 'Rate Limit Exceeded', headers) end
throttled_request?(request)
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 17 def throttled_request?(request) if f = options[:throttled_request] f.call(request) else true end end
ttl()
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 90 def ttl (options[:ttl] || 60).to_i end
whitelisted?(request)
click to toggle source
# File lib/rack/pooledthrottle/throttle.rb, line 42 def whitelisted?(request) if wl = options[:whitelisted] wl.call(request) else false end end