mirror of
https://github.com/samsonjs/rack-attack.git
synced 2026-03-25 09:25:49 +00:00
While a cache-store proxy exists for the redis-store gem, no such proxy existed for using the redis gem itself. This fills that gap by adding such a proxy. Resolves kickstarter/rack-attack#190
35 lines
1.2 KiB
Ruby
35 lines
1.2 KiB
Ruby
module Rack
|
|
class Attack
|
|
module StoreProxy
|
|
PROXIES = [DalliProxy, MemCacheProxy, RedisStoreProxy, RedisProxy].freeze
|
|
|
|
ACTIVE_SUPPORT_WRAPPER_CLASSES = Set.new(['ActiveSupport::Cache::MemCacheStore', 'ActiveSupport::Cache::RedisStore']).freeze
|
|
ACTIVE_SUPPORT_CLIENTS = Set.new(['Redis::Store', 'Redis', 'Dalli::Client', 'MemCache']).freeze
|
|
|
|
def self.build(store)
|
|
client = unwrap_active_support_stores(store)
|
|
klass = PROXIES.find { |proxy| proxy.handle?(client) }
|
|
klass ? klass.new(client) : client
|
|
end
|
|
|
|
|
|
private
|
|
def self.unwrap_active_support_stores(store)
|
|
# ActiveSupport::Cache::RedisStore doesn't expose any way to set an expiry,
|
|
# so use the raw Redis::Store instead.
|
|
# We also want to use the underlying Dalli client instead of ::ActiveSupport::Cache::MemCacheStore,
|
|
# and the MemCache client if using Rails 3.x
|
|
|
|
if store.instance_variable_defined?(:@data)
|
|
client = store.instance_variable_get(:@data)
|
|
end
|
|
|
|
if ACTIVE_SUPPORT_WRAPPER_CLASSES.include?(store.class.to_s) && ACTIVE_SUPPORT_CLIENTS.include?(client.class.to_s)
|
|
client
|
|
else
|
|
store
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|