class Rack::Attack::Cache
Attributes
last_epoch_time[R]
prefix[RW]
store[R]
Public Class Methods
default_store()
click to toggle source
# File lib/rack/attack/cache.rb, line 9 def self.default_store if Object.const_defined?(:Rails) && Rails.respond_to?(:cache) ::Rails.cache end end
new(store: self.class.default_store)
click to toggle source
# File lib/rack/attack/cache.rb, line 15 def initialize(store: self.class.default_store) self.store = store @prefix = 'rack::attack' end
Public Instance Methods
count(unprefixed_key, period)
click to toggle source
# File lib/rack/attack/cache.rb, line 31 def count(unprefixed_key, period) key, expires_in = key_and_expiry(unprefixed_key, period) do_count(key, expires_in) end
delete(unprefixed_key)
click to toggle source
# File lib/rack/attack/cache.rb, line 52 def delete(unprefixed_key) store.delete("#{prefix}:#{unprefixed_key}") end
read(unprefixed_key)
click to toggle source
# File lib/rack/attack/cache.rb, line 36 def read(unprefixed_key) enforce_store_presence! enforce_store_method_presence!(:read) store.read("#{prefix}:#{unprefixed_key}") end
reset!()
click to toggle source
# File lib/rack/attack/cache.rb, line 56 def reset! if store.respond_to?(:delete_matched) store.delete_matched("#{prefix}*") else raise( Rack::Attack::IncompatibleStoreError, "Configured store #{store.class.name} doesn't respond to #delete_matched method" ) end end
reset_count(unprefixed_key, period)
click to toggle source
# File lib/rack/attack/cache.rb, line 47 def reset_count(unprefixed_key, period) key, _ = key_and_expiry(unprefixed_key, period) store.delete(key) end
store=(store)
click to toggle source
# File lib/rack/attack/cache.rb, line 22 def store=(store) @store = if (proxy = BaseProxy.lookup(store)) proxy.new(store) else store end end
write(unprefixed_key, value, expires_in)
click to toggle source
# File lib/rack/attack/cache.rb, line 43 def write(unprefixed_key, value, expires_in) store.write("#{prefix}:#{unprefixed_key}", value, expires_in: expires_in) end
Private Instance Methods
do_count(key, expires_in)
click to toggle source
# File lib/rack/attack/cache.rb, line 76 def do_count(key, expires_in) enforce_store_presence! enforce_store_method_presence!(:increment) result = store.increment(key, 1, expires_in: expires_in) # NB: Some stores return nil when incrementing uninitialized values if result.nil? enforce_store_method_presence!(:write) store.write(key, 1, expires_in: expires_in) end result || 1 end
enforce_store_method_presence!(method_name)
click to toggle source
# File lib/rack/attack/cache.rb, line 97 def enforce_store_method_presence!(method_name) if !store.respond_to?(method_name) raise( Rack::Attack::MisconfiguredStoreError, "Configured store #{store.class.name} doesn't respond to ##{method_name} method" ) end end
enforce_store_presence!()
click to toggle source
# File lib/rack/attack/cache.rb, line 91 def enforce_store_presence! if store.nil? raise Rack::Attack::MissingStoreError end end
key_and_expiry(unprefixed_key, period)
click to toggle source
# File lib/rack/attack/cache.rb, line 69 def key_and_expiry(unprefixed_key, period) @last_epoch_time = Time.now.to_i # Add 1 to expires_in to avoid timing error: https://github.com/rack/rack-attack/pull/85 expires_in = (period - (@last_epoch_time % period) + 1).to_i ["#{prefix}:#{(@last_epoch_time / period).to_i}:#{unprefixed_key}", expires_in] end