From 8d124d868ef834332912544106b828c75b38f52a Mon Sep 17 00:00:00 2001 From: Vincent Boisard Date: Thu, 7 Jan 2016 21:16:35 +0100 Subject: [PATCH] refactor unwieldy Rack::Attack::StoreProxy.build method --- lib/rack/attack/store_proxy.rb | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/rack/attack/store_proxy.rb b/lib/rack/attack/store_proxy.rb index d88ad67..c88fb6b 100644 --- a/lib/rack/attack/store_proxy.rb +++ b/lib/rack/attack/store_proxy.rb @@ -2,25 +2,30 @@ module Rack class Attack module StoreProxy PROXIES = [DalliProxy, MemCacheProxy, RedisStoreProxy] + USE_BASE_CLIENT = ['Redis::Store', 'Dalli::Client', 'MemCache'] def self.build(store) # RedisStore#increment needs different behavior, so detect that # (method has an arity of 2; must call #expire separately - if (defined?(::ActiveSupport::Cache::RedisStore) && store.is_a?(::ActiveSupport::Cache::RedisStore)) || - (defined?(::ActiveSupport::Cache::MemCacheStore) && store.is_a?(::ActiveSupport::Cache::MemCacheStore)) + client = fetch_client(store) + klass = PROXIES.find { |proxy| proxy.handle?(client) } + klass ? klass.new(client) : client + end - # 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 - client = store.instance_variable_get(:@data) - if (defined?(::Redis::Store) && client.is_a?(Redis::Store)) || - (defined?(Dalli::Client) && client.is_a?(Dalli::Client)) || (defined?(MemCache) && client.is_a?(MemCache)) - store = store.instance_variable_get(:@data) - end + def self.fetch_client(store) + client = store.instance_variable_get(:@data) + # RedisStore#increment needs different behavior, so detect that + # (method has an arity of 2; must call #expire separately + # + # 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 + USE_BASE_CLIENT.each do |klass| + return client if !client.nil? && Object.const_defined?(klass) && client.is_a?(Object.const_get(klass)) end - klass = PROXIES.find { |proxy| proxy.handle?(store) } - klass ? klass.new(store) : store + return store end end