rack-attack 6.1.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -2
- data/lib/rack/attack.rb +136 -124
- data/lib/rack/attack/cache.rb +4 -1
- data/lib/rack/attack/check.rb +2 -1
- data/lib/rack/attack/path_normalizer.rb +20 -18
- data/lib/rack/attack/railtie.rb +21 -0
- data/lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb +3 -1
- data/lib/rack/attack/store_proxy/mem_cache_store_proxy.rb +3 -1
- data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +22 -6
- data/lib/rack/attack/throttle.rb +3 -2
- data/lib/rack/attack/track.rb +6 -5
- data/lib/rack/attack/version.rb +1 -1
- data/spec/acceptance/rails_middleware_spec.rb +41 -0
- data/spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb +1 -3
- data/spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb +7 -1
- data/spec/acceptance/stores/active_support_redis_cache_store_spec.rb +6 -1
- data/spec/acceptance/stores/connection_pool_dalli_client_spec.rb +3 -3
- data/spec/allow2ban_spec.rb +17 -14
- data/spec/fail2ban_spec.rb +17 -16
- data/spec/rack_attack_instrumentation_spec.rb +1 -1
- data/spec/rack_attack_path_normalizer_spec.rb +2 -2
- data/spec/rack_attack_spec.rb +36 -13
- data/spec/rack_attack_throttle_spec.rb +12 -12
- data/spec/rack_attack_track_spec.rb +8 -5
- data/spec/spec_helper.rb +5 -4
- metadata +30 -21
@@ -15,17 +15,33 @@ module Rack
|
|
15
15
|
#
|
16
16
|
# So in order to workaround this we use RedisCacheStore#write (which sets expiration) to initialize
|
17
17
|
# the counter. After that we continue using the original RedisCacheStore#increment.
|
18
|
-
|
19
|
-
|
18
|
+
rescuing do
|
19
|
+
if options[:expires_in] && !read(name)
|
20
|
+
write(name, amount, options)
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
amount
|
23
|
+
else
|
24
|
+
super
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
29
|
+
def read(*_args)
|
30
|
+
rescuing { super }
|
31
|
+
end
|
32
|
+
|
27
33
|
def write(name, value, options = {})
|
28
|
-
|
34
|
+
rescuing do
|
35
|
+
super(name, value, options.merge!(raw: true))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def rescuing
|
42
|
+
yield
|
43
|
+
rescue Redis::BaseError
|
44
|
+
nil
|
29
45
|
end
|
30
46
|
end
|
31
47
|
end
|
data/lib/rack/attack/throttle.rb
CHANGED
@@ -7,11 +7,12 @@ module Rack
|
|
7
7
|
|
8
8
|
attr_reader :name, :limit, :period, :block, :type
|
9
9
|
def initialize(name, options, &block)
|
10
|
-
@name
|
10
|
+
@name = name
|
11
|
+
@block = block
|
11
12
|
MANDATORY_OPTIONS.each do |opt|
|
12
13
|
raise ArgumentError, "Must pass #{opt.inspect} option" unless options[opt]
|
13
14
|
end
|
14
|
-
@limit
|
15
|
+
@limit = options[:limit]
|
15
16
|
@period = options[:period].respond_to?(:call) ? options[:period] : options[:period].to_i
|
16
17
|
@type = options.fetch(:type, :throttle)
|
17
18
|
end
|
data/lib/rack/attack/track.rb
CHANGED
@@ -8,11 +8,12 @@ module Rack
|
|
8
8
|
def initialize(name, options = {}, &block)
|
9
9
|
options[:type] = :track
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
@filter =
|
12
|
+
if options[:limit] && options[:period]
|
13
|
+
Throttle.new(name, options, &block)
|
14
|
+
else
|
15
|
+
Check.new(name, options, &block)
|
16
|
+
end
|
16
17
|
end
|
17
18
|
|
18
19
|
def matched_by?(request)
|
data/lib/rack/attack/version.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../spec_helper"
|
4
|
+
|
5
|
+
if defined?(Rails)
|
6
|
+
describe "Middleware for Rails" do
|
7
|
+
before do
|
8
|
+
@app = Class.new(Rails::Application) do
|
9
|
+
config.eager_load = false
|
10
|
+
config.logger = Logger.new(nil) # avoid creating the log/ directory automatically
|
11
|
+
config.cache_store = :null_store # avoid creating tmp/ directory for cache
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new("5.1")
|
16
|
+
it "is used by default" do
|
17
|
+
@app.initialize!
|
18
|
+
assert_equal 1, @app.middleware.count(Rack::Attack)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "is not added when it was added explicitly" do
|
22
|
+
@app.config.middleware.use(Rack::Attack)
|
23
|
+
@app.initialize!
|
24
|
+
assert_equal 1, @app.middleware.count(Rack::Attack)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "is not added when it was explicitly deleted" do
|
28
|
+
@app.config.middleware.delete(Rack::Attack)
|
29
|
+
@app.initialize!
|
30
|
+
refute @app.middleware.include?(Rack::Attack)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new("5.1")
|
35
|
+
it "is not used by default" do
|
36
|
+
@app.initialize!
|
37
|
+
assert_equal 0, @app.middleware.count(Rack::Attack)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -15,8 +15,6 @@ if defined?(::ConnectionPool) && defined?(::Dalli)
|
|
15
15
|
Rack::Attack.cache.store.clear
|
16
16
|
end
|
17
17
|
|
18
|
-
it_works_for_cache_backed_features(fetch_from_store: ->(key) {
|
19
|
-
Rack::Attack.cache.store.read(key)
|
20
|
-
})
|
18
|
+
it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.read(key) })
|
21
19
|
end
|
22
20
|
end
|
@@ -2,7 +2,13 @@
|
|
2
2
|
|
3
3
|
require_relative "../../spec_helper"
|
4
4
|
|
5
|
-
|
5
|
+
should_run =
|
6
|
+
defined?(::ConnectionPool) &&
|
7
|
+
defined?(::Redis) &&
|
8
|
+
Gem::Version.new(::Redis::VERSION) >= Gem::Version.new("4") &&
|
9
|
+
defined?(::ActiveSupport::Cache::RedisCacheStore)
|
10
|
+
|
11
|
+
if should_run
|
6
12
|
require_relative "../../support/cache_store_helper"
|
7
13
|
require "timecop"
|
8
14
|
|
@@ -2,7 +2,12 @@
|
|
2
2
|
|
3
3
|
require_relative "../../spec_helper"
|
4
4
|
|
5
|
-
|
5
|
+
should_run =
|
6
|
+
defined?(::Redis) &&
|
7
|
+
Gem::Version.new(::Redis::VERSION) >= Gem::Version.new("4") &&
|
8
|
+
defined?(::ActiveSupport::Cache::RedisCacheStore)
|
9
|
+
|
10
|
+
if should_run
|
6
11
|
require_relative "../../support/cache_store_helper"
|
7
12
|
require "timecop"
|
8
13
|
|
@@ -17,8 +17,8 @@ if defined?(::Dalli) && defined?(::ConnectionPool)
|
|
17
17
|
Rack::Attack.cache.store.with { |client| client.flush_all }
|
18
18
|
end
|
19
19
|
|
20
|
-
it_works_for_cache_backed_features(
|
21
|
-
Rack::Attack.cache.store.with { |client| client.fetch(key) }
|
22
|
-
|
20
|
+
it_works_for_cache_backed_features(
|
21
|
+
fetch_from_store: ->(key) { Rack::Attack.cache.store.with { |client| client.fetch(key) } }
|
22
|
+
)
|
23
23
|
end
|
24
24
|
end
|
data/spec/allow2ban_spec.rb
CHANGED
@@ -20,7 +20,8 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
20
20
|
describe 'making ok request' do
|
21
21
|
it 'succeeds' do
|
22
22
|
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
23
|
-
|
23
|
+
|
24
|
+
_(last_response.status).must_equal 200
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
@@ -29,17 +30,18 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
29
30
|
before { get '/?foo=OMGHAX', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
30
31
|
|
31
32
|
it 'succeeds' do
|
32
|
-
last_response.status.must_equal 200
|
33
|
+
_(last_response.status).must_equal 200
|
33
34
|
end
|
34
35
|
|
35
36
|
it 'increases fail count' do
|
36
37
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
37
|
-
|
38
|
+
|
39
|
+
_(@cache.store.read(key)).must_equal 1
|
38
40
|
end
|
39
41
|
|
40
42
|
it 'is not banned' do
|
41
43
|
key = "rack::attack:allow2ban:1.2.3.4"
|
42
|
-
@cache.store.read(key).must_be_nil
|
44
|
+
_(@cache.store.read(key)).must_be_nil
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
@@ -51,17 +53,17 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
51
53
|
end
|
52
54
|
|
53
55
|
it 'succeeds' do
|
54
|
-
last_response.status.must_equal 200
|
56
|
+
_(last_response.status).must_equal 200
|
55
57
|
end
|
56
58
|
|
57
59
|
it 'increases fail count' do
|
58
60
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
59
|
-
@cache.store.read(key).must_equal 2
|
61
|
+
_(@cache.store.read(key)).must_equal 2
|
60
62
|
end
|
61
63
|
|
62
64
|
it 'is banned' do
|
63
65
|
key = "rack::attack:allow2ban:ban:1.2.3.4"
|
64
|
-
@cache.store.read(key).must_equal 1
|
66
|
+
_(@cache.store.read(key)).must_equal 1
|
65
67
|
end
|
66
68
|
end
|
67
69
|
end
|
@@ -77,7 +79,8 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
77
79
|
describe 'making request for other discriminator' do
|
78
80
|
it 'succeeds' do
|
79
81
|
get '/', {}, 'REMOTE_ADDR' => '2.2.3.4'
|
80
|
-
|
82
|
+
|
83
|
+
_(last_response.status).must_equal 200
|
81
84
|
end
|
82
85
|
end
|
83
86
|
|
@@ -87,17 +90,17 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
87
90
|
end
|
88
91
|
|
89
92
|
it 'fails' do
|
90
|
-
last_response.status.must_equal 403
|
93
|
+
_(last_response.status).must_equal 403
|
91
94
|
end
|
92
95
|
|
93
96
|
it 'does not increase fail count' do
|
94
97
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
95
|
-
@cache.store.read(key).must_equal 2
|
98
|
+
_(@cache.store.read(key)).must_equal 2
|
96
99
|
end
|
97
100
|
|
98
101
|
it 'is still banned' do
|
99
102
|
key = "rack::attack:allow2ban:ban:1.2.3.4"
|
100
|
-
@cache.store.read(key).must_equal 1
|
103
|
+
_(@cache.store.read(key)).must_equal 1
|
101
104
|
end
|
102
105
|
end
|
103
106
|
|
@@ -107,17 +110,17 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
107
110
|
end
|
108
111
|
|
109
112
|
it 'fails' do
|
110
|
-
last_response.status.must_equal 403
|
113
|
+
_(last_response.status).must_equal 403
|
111
114
|
end
|
112
115
|
|
113
116
|
it 'does not increase fail count' do
|
114
117
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
115
|
-
@cache.store.read(key).must_equal 2
|
118
|
+
_(@cache.store.read(key)).must_equal 2
|
116
119
|
end
|
117
120
|
|
118
121
|
it 'is still banned' do
|
119
122
|
key = "rack::attack:allow2ban:ban:1.2.3.4"
|
120
|
-
@cache.store.read(key).must_equal 1
|
123
|
+
_(@cache.store.read(key)).must_equal 1
|
121
124
|
end
|
122
125
|
end
|
123
126
|
end
|
data/spec/fail2ban_spec.rb
CHANGED
@@ -20,7 +20,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
20
20
|
describe 'making ok request' do
|
21
21
|
it 'succeeds' do
|
22
22
|
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
23
|
-
last_response.status.must_equal 200
|
23
|
+
_(last_response.status).must_equal 200
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -29,17 +29,17 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
29
29
|
before { get '/?foo=OMGHAX', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
30
30
|
|
31
31
|
it 'fails' do
|
32
|
-
last_response.status.must_equal 403
|
32
|
+
_(last_response.status).must_equal 403
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'increases fail count' do
|
36
36
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
37
|
-
@cache.store.read(key).must_equal 1
|
37
|
+
_(@cache.store.read(key)).must_equal 1
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'is not banned' do
|
41
41
|
key = "rack::attack:fail2ban:1.2.3.4"
|
42
|
-
@cache.store.read(key).must_be_nil
|
42
|
+
_(@cache.store.read(key)).must_be_nil
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -51,17 +51,17 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'fails' do
|
54
|
-
last_response.status.must_equal 403
|
54
|
+
_(last_response.status).must_equal 403
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'increases fail count' do
|
58
58
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
59
|
-
@cache.store.read(key).must_equal 2
|
59
|
+
_(@cache.store.read(key)).must_equal 2
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'is banned' do
|
63
63
|
key = "rack::attack:fail2ban:ban:1.2.3.4"
|
64
|
-
@cache.store.read(key).must_equal 1
|
64
|
+
_(@cache.store.read(key)).must_equal 1
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -73,7 +73,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'succeeds' do
|
76
|
-
last_response.status.must_equal 200
|
76
|
+
_(last_response.status).must_equal 200
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'resets fail count' do
|
@@ -82,7 +82,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'IP is not banned' do
|
85
|
-
Rack::Attack::Fail2Ban.banned?('1.2.3.4').must_equal false
|
85
|
+
_(Rack::Attack::Fail2Ban.banned?('1.2.3.4')).must_equal false
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
@@ -98,7 +98,8 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
98
98
|
describe 'making request for other discriminator' do
|
99
99
|
it 'succeeds' do
|
100
100
|
get '/', {}, 'REMOTE_ADDR' => '2.2.3.4'
|
101
|
-
|
101
|
+
|
102
|
+
_(last_response.status).must_equal 200
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
@@ -108,17 +109,17 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
108
109
|
end
|
109
110
|
|
110
111
|
it 'fails' do
|
111
|
-
last_response.status.must_equal 403
|
112
|
+
_(last_response.status).must_equal 403
|
112
113
|
end
|
113
114
|
|
114
115
|
it 'does not increase fail count' do
|
115
116
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
116
|
-
@cache.store.read(key).must_equal 2
|
117
|
+
_(@cache.store.read(key)).must_equal 2
|
117
118
|
end
|
118
119
|
|
119
120
|
it 'is still banned' do
|
120
121
|
key = "rack::attack:fail2ban:ban:1.2.3.4"
|
121
|
-
@cache.store.read(key).must_equal 1
|
122
|
+
_(@cache.store.read(key)).must_equal 1
|
122
123
|
end
|
123
124
|
end
|
124
125
|
|
@@ -128,17 +129,17 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
128
129
|
end
|
129
130
|
|
130
131
|
it 'fails' do
|
131
|
-
last_response.status.must_equal 403
|
132
|
+
_(last_response.status).must_equal 403
|
132
133
|
end
|
133
134
|
|
134
135
|
it 'does not increase fail count' do
|
135
136
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
136
|
-
@cache.store.read(key).must_equal 2
|
137
|
+
_(@cache.store.read(key)).must_equal 2
|
137
138
|
end
|
138
139
|
|
139
140
|
it 'is still banned' do
|
140
141
|
key = "rack::attack:fail2ban:ban:1.2.3.4"
|
141
|
-
@cache.store.read(key).must_equal 1
|
142
|
+
_(@cache.store.read(key)).must_equal 1
|
142
143
|
end
|
143
144
|
end
|
144
145
|
end
|
@@ -6,14 +6,14 @@ describe Rack::Attack::PathNormalizer do
|
|
6
6
|
subject { Rack::Attack::PathNormalizer }
|
7
7
|
|
8
8
|
it 'should have a normalize_path method' do
|
9
|
-
subject.normalize_path('/foo').must_equal '/foo'
|
9
|
+
_(subject.normalize_path('/foo')).must_equal '/foo'
|
10
10
|
end
|
11
11
|
|
12
12
|
describe 'FallbackNormalizer' do
|
13
13
|
subject { Rack::Attack::FallbackPathNormalizer }
|
14
14
|
|
15
15
|
it '#normalize_path does not change the path' do
|
16
|
-
subject.normalize_path('').must_equal ''
|
16
|
+
_(subject.normalize_path('')).must_equal ''
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
data/spec/rack_attack_spec.rb
CHANGED
@@ -12,7 +12,7 @@ describe 'Rack::Attack' do
|
|
12
12
|
|
13
13
|
it 'blocks requests with trailing slash' do
|
14
14
|
get '/foo/'
|
15
|
-
last_response.status.must_equal 403
|
15
|
+
_(last_response.status).must_equal 403
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -22,21 +22,21 @@ describe 'Rack::Attack' do
|
|
22
22
|
Rack::Attack.blocklist("ip #{@bad_ip}") { |req| req.ip == @bad_ip }
|
23
23
|
end
|
24
24
|
|
25
|
-
it
|
26
|
-
Rack::Attack.blocklists.key?("ip #{@bad_ip}").must_equal true
|
27
|
-
|
25
|
+
it 'has a blocklist' do
|
26
|
+
_(Rack::Attack.blocklists.key?("ip #{@bad_ip}")).must_equal true
|
27
|
+
end
|
28
28
|
|
29
29
|
describe "a bad request" do
|
30
30
|
before { get '/', {}, 'REMOTE_ADDR' => @bad_ip }
|
31
31
|
|
32
32
|
it "should return a blocklist response" do
|
33
|
-
last_response.status.must_equal 403
|
34
|
-
last_response.body.must_equal "Forbidden\n"
|
33
|
+
_(last_response.status).must_equal 403
|
34
|
+
_(last_response.body).must_equal "Forbidden\n"
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should tag the env" do
|
38
|
-
last_request.env['rack.attack.matched'].must_equal "ip #{@bad_ip}"
|
39
|
-
last_request.env['rack.attack.match_type'].must_equal :blocklist
|
38
|
+
_(last_request.env['rack.attack.matched']).must_equal "ip #{@bad_ip}"
|
39
|
+
_(last_request.env['rack.attack.match_type']).must_equal :blocklist
|
40
40
|
end
|
41
41
|
|
42
42
|
it_allows_ok_requests
|
@@ -54,25 +54,48 @@ describe 'Rack::Attack' do
|
|
54
54
|
before { get '/', {}, 'REMOTE_ADDR' => @bad_ip, 'HTTP_USER_AGENT' => @good_ua }
|
55
55
|
|
56
56
|
it "should allow safelists before blocklists" do
|
57
|
-
last_response.status.must_equal 200
|
57
|
+
_(last_response.status).must_equal 200
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should tag the env" do
|
61
|
-
last_request.env['rack.attack.matched'].must_equal 'good ua'
|
62
|
-
last_request.env['rack.attack.match_type'].must_equal :safelist
|
61
|
+
_(last_request.env['rack.attack.matched']).must_equal 'good ua'
|
62
|
+
_(last_request.env['rack.attack.match_type']).must_equal :safelist
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
67
|
describe '#blocklisted_response' do
|
68
68
|
it 'should exist' do
|
69
|
-
Rack::Attack.blocklisted_response.must_respond_to :call
|
69
|
+
_(Rack::Attack.blocklisted_response).must_respond_to :call
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
73
|
describe '#throttled_response' do
|
74
74
|
it 'should exist' do
|
75
|
-
Rack::Attack.throttled_response.must_respond_to :call
|
75
|
+
_(Rack::Attack.throttled_response).must_respond_to :call
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'enabled' do
|
81
|
+
it 'should be enabled by default' do
|
82
|
+
_(Rack::Attack.enabled).must_equal true
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should directly pass request when disabled' do
|
86
|
+
bad_ip = '1.2.3.4'
|
87
|
+
Rack::Attack.blocklist("ip #{bad_ip}") { |req| req.ip == bad_ip }
|
88
|
+
|
89
|
+
get '/', {}, 'REMOTE_ADDR' => bad_ip
|
90
|
+
_(last_response.status).must_equal 403
|
91
|
+
|
92
|
+
prev_enabled = Rack::Attack.enabled
|
93
|
+
begin
|
94
|
+
Rack::Attack.enabled = false
|
95
|
+
get '/', {}, 'REMOTE_ADDR' => bad_ip
|
96
|
+
_(last_response.status).must_equal 200
|
97
|
+
ensure
|
98
|
+
Rack::Attack.enabled = prev_enabled
|
76
99
|
end
|
77
100
|
end
|
78
101
|
end
|