class Sinatra::RateLimiter::RateLimit
Attributes
options[RW]
request[RW]
settings[RW]
Public Class Methods
new(bucket, limits)
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 102 def initialize(bucket, limits) @bucket = bucket @limits = limits @time_prefix = get_min_time_prefix(@limits) end
Public Instance Methods
headers()
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 121 def headers headers = [] header_prefix = @options.header_prefix + (@bucket.eql?('default') ? '' : '-' + @bucket) limit_no = 0 if @limits.length > 1 @limits.each do |limit| limit_no = limit_no + 1 if limit_no headers << [header_prefix + (limit_no ? "-#{limit_no}" : '') + '-Limit', limit[:requests]] headers << [header_prefix + (limit_no ? "-#{limit_no}" : '') + '-Remaining', limit_remaining(limit)] headers << [header_prefix + (limit_no ? "-#{limit_no}" : '') + '-Reset', limit_reset(limit)] end return headers end
history(seconds=0)
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 117 def history(seconds=0) redis_history.select{|t| seconds.eql?(0) ? true : t > (Time.now.to_f - seconds)} end
identifier()
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 113 def identifier @identifier ||= @options.identifier.call(request) end
limit_remaining(limit)
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 136 def limit_remaining(limit) limit[:requests] - history(limit[:seconds]).length end
limit_reset(limit)
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 140 def limit_reset(limit) limit[:seconds] - (Time.now.to_f - history(limit[:seconds]).first.to_f).to_i end
limits_exceeded?()
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 144 def limits_exceeded? exceeded = @limits.select {|limit| limit_remaining(limit) < 1}.sort_by{|e| e[:seconds]}.last if exceeded try_again = limit_reset(exceeded) return exceeded.merge({try_again: try_again.to_i, bucket: @bucket}) end end
log_request()
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 153 def log_request redis.setex( [namespace, identifier, @bucket, Time.now.to_f.to_s].join('/'), @settings.rate_limiter_redis_expires, nil) end
options=(options)
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 108 def options=(options) options = settings.rate_limiter_default_options.merge(options) @options = Struct.new(*options.keys).new(*options.values) end
Private Instance Methods
get_min_time_prefix(limits)
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 176 def get_min_time_prefix(limits) now = Time.now.to_f oldest = Time.now.to_f - limits.sort_by{|l| -l[:seconds]}.first[:seconds] return now.to_s[0..((now/oldest).to_s.split(/^1\.|[1-9]+/)[1].length)].to_i.to_s end
namespace()
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 172 def namespace @settings.rate_limiter_redis_namespace end
redis()
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 168 def redis @settings.rate_limiter_redis_conn end
redis_history()
click to toggle source
# File lib/sinatra/rate-limiter.rb, line 162 def redis_history @history ||= redis. keys("#{[namespace,identifier,@bucket].join('/')}/#{@time_prefix}*"). map{|k| k.split('/')[3].to_f} end