diff --git a/lib/rack/attack.rb b/lib/rack/attack.rb index 5619c20b..346fbe58 100644 --- a/lib/rack/attack.rb +++ b/lib/rack/attack.rb @@ -13,6 +13,7 @@ class Rack::Attack autoload :DalliProxy, 'rack/attack/store_proxy/dalli_proxy' autoload :MemCacheProxy, 'rack/attack/store_proxy/mem_cache_proxy' autoload :RedisStoreProxy, 'rack/attack/store_proxy/redis_store_proxy' + autoload :RedisProxy, 'rack/attack/store_proxy/redis_proxy' autoload :Fail2Ban, 'rack/attack/fail2ban' autoload :Allow2Ban, 'rack/attack/allow2ban' autoload :Request, 'rack/attack/request' diff --git a/lib/rack/attack/store_proxy.rb b/lib/rack/attack/store_proxy.rb index 5ce0f52f..d41ddac9 100644 --- a/lib/rack/attack/store_proxy.rb +++ b/lib/rack/attack/store_proxy.rb @@ -1,10 +1,10 @@ module Rack class Attack module StoreProxy - PROXIES = [DalliProxy, MemCacheProxy, RedisStoreProxy].freeze + 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', 'Dalli::Client', 'MemCache']).freeze + ACTIVE_SUPPORT_CLIENTS = Set.new(['Redis::Store', 'Redis', 'Dalli::Client', 'MemCache']).freeze def self.build(store) client = unwrap_active_support_stores(store) diff --git a/lib/rack/attack/store_proxy/redis_proxy.rb b/lib/rack/attack/store_proxy/redis_proxy.rb new file mode 100644 index 00000000..ca2786c1 --- /dev/null +++ b/lib/rack/attack/store_proxy/redis_proxy.rb @@ -0,0 +1,44 @@ +require 'delegate' + +module Rack + class Attack + module StoreProxy + class RedisProxy < SimpleDelegator + def self.handle?(store) + defined?(::Redis) && store.is_a?(::Redis) + end + + def initialize(store) + super(store) + end + + def read(key) + get(key) + end + + def write(key, value, options={}) + if (expires_in = options[:expires_in]) + setex(key, expires_in, value) + else + set(key, value) + end + end + + def increment(key, amount, options={}) + count = nil + + pipelined do + count = incrby(key, amount) + expire(key, options[:expires_in]) if options[:expires_in] + end + + count.value if count + end + + def delete(key, options={}) + del(key) + end + end + end + end +end diff --git a/spec/integration/rack_attack_cache_spec.rb b/spec/integration/rack_attack_cache_spec.rb index 86e40237..354e4ba4 100644 --- a/spec/integration/rack_attack_cache_spec.rb +++ b/spec/integration/rack_attack_cache_spec.rb @@ -27,7 +27,8 @@ def sleep_until_expired ActiveSupport::Cache::MemCacheStore.new("127.0.0.1"), Dalli::Client.new, ConnectionPool.new { Dalli::Client.new }, - Redis::Store.new + Redis::Store.new, + Redis.new ] cache_stores.each do |store|