diff --git a/lib/rack/attack.rb b/lib/rack/attack.rb index 5619c20..8c9df48 100644 --- a/lib/rack/attack.rb +++ b/lib/rack/attack.rb @@ -2,6 +2,9 @@ require 'rack' require 'forwardable' class Rack::Attack + class MisconfiguredStoreError < StandardError; end + class MissingStoreError < StandardError; end + autoload :Cache, 'rack/attack/cache' autoload :PathNormalizer, 'rack/attack/path_normalizer' autoload :Check, 'rack/attack/check' diff --git a/lib/rack/attack/cache.rb b/lib/rack/attack/cache.rb index c2dd06c..aec048b 100644 --- a/lib/rack/attack/cache.rb +++ b/lib/rack/attack/cache.rb @@ -46,15 +46,20 @@ module Rack end def do_count(key, expires_in) - result = store.increment(key, 1, :expires_in => expires_in) + if store.nil? + raise Rack::Attack::MissingStoreError + elsif !store.respond_to?(:increment) + raise Rack::Attack::MisconfiguredStoreError, "Store needs to respond to #increment" + else + result = store.increment(key, 1, :expires_in => expires_in) - # NB: Some stores return nil when incrementing uninitialized values - if result.nil? - store.write(key, 1, :expires_in => expires_in) + # NB: Some stores return nil when incrementing uninitialized values + if result.nil? + store.write(key, 1, :expires_in => expires_in) + end + result || 1 end - result || 1 end - end end end diff --git a/spec/rack_attack_store_config_spec.rb b/spec/rack_attack_store_config_spec.rb new file mode 100644 index 0000000..249f2ab --- /dev/null +++ b/spec/rack_attack_store_config_spec.rb @@ -0,0 +1,20 @@ +require_relative 'spec_helper' + +describe 'Store configuration' do + it "gives clear error when store it's not configured if it's needed" do + Rack::Attack.throttle('ip/sec', limit: 1, period: 60) { |req| req.ip } + + assert_raises(Rack::Attack::MissingStoreError) do + get '/' + end + end + + it "gives clear error when store isn't configured properly" do + Rack::Attack.cache.store = Object.new + Rack::Attack.throttle('ip/sec', limit: 1, period: 60) { |req| req.ip } + + assert_raises(Rack::Attack::MisconfiguredStoreError) do + get '/' + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b7d535f..78665a2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -19,7 +19,10 @@ class MiniTest::Spec include Rack::Test::Methods - after { Rack::Attack.clear! } + after do + Rack::Attack.clear! + Rack::Attack.instance_variable_set(:@cache, nil) + end def app Rack::Builder.new {