rack-attack 5.2.0 → 5.3.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -24
  3. data/Rakefile +1 -1
  4. data/lib/rack/attack.rb +28 -23
  5. data/lib/rack/attack/allow2ban.rb +1 -0
  6. data/lib/rack/attack/blocklist.rb +0 -1
  7. data/lib/rack/attack/cache.rb +1 -2
  8. data/lib/rack/attack/check.rb +1 -2
  9. data/lib/rack/attack/fail2ban.rb +2 -1
  10. data/lib/rack/attack/path_normalizer.rb +6 -8
  11. data/lib/rack/attack/safelist.rb +0 -1
  12. data/lib/rack/attack/store_proxy.rb +2 -4
  13. data/lib/rack/attack/store_proxy/dalli_proxy.rb +2 -3
  14. data/lib/rack/attack/store_proxy/mem_cache_proxy.rb +4 -5
  15. data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +30 -0
  16. data/lib/rack/attack/store_proxy/redis_store_proxy.rb +4 -11
  17. data/lib/rack/attack/version.rb +1 -1
  18. data/spec/acceptance/cache_store_config_for_allow2ban_spec.rb +2 -2
  19. data/spec/acceptance/cache_store_config_for_fail2ban_spec.rb +2 -2
  20. data/spec/acceptance/cache_store_config_for_throttle_spec.rb +1 -1
  21. data/spec/acceptance/customizing_blocked_response_spec.rb +1 -1
  22. data/spec/acceptance/customizing_throttled_response_spec.rb +1 -1
  23. data/spec/acceptance/safelisting_ip_spec.rb +0 -1
  24. data/spec/acceptance/stores/mem_cache_store_spec.rb +38 -0
  25. data/spec/acceptance/stores/redis_cache_store_spec.rb +41 -0
  26. data/spec/allow2ban_spec.rb +6 -6
  27. data/spec/fail2ban_spec.rb +7 -7
  28. data/spec/integration/rack_attack_cache_spec.rb +4 -1
  29. data/spec/rack_attack_dalli_proxy_spec.rb +0 -2
  30. data/spec/rack_attack_spec.rb +6 -6
  31. data/spec/rack_attack_throttle_spec.rb +7 -7
  32. data/spec/rack_attack_track_spec.rb +5 -5
  33. data/spec/spec_helper.rb +3 -4
  34. data/spec/support/cache_store_helper.rb +58 -0
  35. metadata +65 -44
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Attack
3
- VERSION = '5.2.0'
3
+ VERSION = '5.3.0'
4
4
  end
5
5
  end
@@ -81,11 +81,11 @@ describe "Cache store config when using allow2ban" do
81
81
  @backend[key]
82
82
  end
83
83
 
84
- def write(key, value, options = {})
84
+ def write(key, value, _options = {})
85
85
  @backend[key] = value
86
86
  end
87
87
 
88
- def increment(key, count, options = {})
88
+ def increment(key, _count, _options = {})
89
89
  @backend[key] ||= 0
90
90
  @backend[key] += 1
91
91
  end
@@ -81,11 +81,11 @@ describe "Cache store config when using fail2ban" do
81
81
  @backend[key]
82
82
  end
83
83
 
84
- def write(key, value, options = {})
84
+ def write(key, value, _options = {})
85
85
  @backend[key] = value
86
86
  end
87
87
 
88
- def increment(key, count, options = {})
88
+ def increment(key, _count, _options = {})
89
89
  @backend[key] ||= 0
90
90
  @backend[key] += 1
91
91
  end
@@ -29,7 +29,7 @@ describe "Cache store config when throttling without Rails" do
29
29
  @counts = {}
30
30
  end
31
31
 
32
- def increment(key, count, options)
32
+ def increment(key, _count, _options)
33
33
  @counts[key] ||= 0
34
34
  @counts[key] += 1
35
35
  end
@@ -12,7 +12,7 @@ describe "Customizing block responses" do
12
12
 
13
13
  assert_equal 403, last_response.status
14
14
 
15
- Rack::Attack.blocklisted_response = lambda do |env|
15
+ Rack::Attack.blocklisted_response = lambda do |_env|
16
16
  [503, {}, ["Blocked"]]
17
17
  end
18
18
 
@@ -18,7 +18,7 @@ describe "Customizing throttled response" do
18
18
 
19
19
  assert_equal 429, last_response.status
20
20
 
21
- Rack::Attack.throttled_response = lambda do |env|
21
+ Rack::Attack.throttled_response = lambda do |_env|
22
22
  [503, {}, ["Throttled"]]
23
23
  end
24
24
 
@@ -46,4 +46,3 @@ describe "Safelist an IP" do
46
46
  assert_equal :safelist, notification_type
47
47
  end
48
48
  end
49
-
@@ -0,0 +1,38 @@
1
+ require_relative "../../spec_helper"
2
+ require_relative "../../support/cache_store_helper"
3
+
4
+ require "timecop"
5
+
6
+ describe "MemCacheStore as a cache backend" do
7
+ before do
8
+ Rack::Attack.cache.store = ActiveSupport::Cache::MemCacheStore.new
9
+ end
10
+
11
+ after do
12
+ Rack::Attack.cache.store.flush_all
13
+ end
14
+
15
+ it_works_for_cache_backed_features
16
+
17
+ it "doesn't leak keys" do
18
+ Rack::Attack.throttle("by ip", limit: 1, period: 1) do |request|
19
+ request.ip
20
+ end
21
+
22
+ key = nil
23
+
24
+ # Freeze time during these statement to be sure that the key used by rack attack is the same
25
+ # we pre-calculate in local variable `key`
26
+ Timecop.freeze do
27
+ key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
28
+
29
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
30
+ end
31
+
32
+ assert Rack::Attack.cache.store.get(key)
33
+
34
+ sleep 2.1
35
+
36
+ assert_nil Rack::Attack.cache.store.get(key)
37
+ end
38
+ end
@@ -0,0 +1,41 @@
1
+ require_relative "../../spec_helper"
2
+ require_relative "../../support/cache_store_helper"
3
+
4
+ require "timecop"
5
+
6
+ if ActiveSupport.version >= Gem::Version.new("5.2.0")
7
+ describe "RedisCacheStore as a cache backend" do
8
+ before do
9
+ Rack::Attack.cache.store = ActiveSupport::Cache::RedisCacheStore.new
10
+ end
11
+
12
+ after do
13
+ Rack::Attack.cache.store.clear
14
+ end
15
+
16
+ it_works_for_cache_backed_features
17
+
18
+ it "doesn't leak keys" do
19
+ Rack::Attack.throttle("by ip", limit: 1, period: 1) do |request|
20
+ request.ip
21
+ end
22
+
23
+ key = nil
24
+
25
+ # Freeze time during these statement to be sure that the key used by rack attack is the same
26
+ # we pre-calculate in local variable `key`
27
+ Timecop.freeze do
28
+ key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
29
+
30
+ # puts key
31
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
32
+ end
33
+
34
+ assert Rack::Attack.cache.store.fetch(key)
35
+
36
+ sleep 2.1
37
+
38
+ assert_nil Rack::Attack.cache.store.fetch(key)
39
+ end
40
+ end
41
+ end
@@ -7,10 +7,10 @@ describe 'Rack::Attack.Allow2Ban' do
7
7
  @findtime = 60
8
8
  @bantime = 60
9
9
  Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
10
- @f2b_options = {:bantime => @bantime, :findtime => @findtime, :maxretry => 2}
10
+ @f2b_options = { :bantime => @bantime, :findtime => @findtime, :maxretry => 2 }
11
11
 
12
12
  Rack::Attack.blocklist('pentest') do |req|
13
- Rack::Attack::Allow2Ban.filter(req.ip, @f2b_options){req.query_string =~ /OMGHAX/}
13
+ Rack::Attack::Allow2Ban.filter(req.ip, @f2b_options) { req.query_string =~ /OMGHAX/ }
14
14
  end
15
15
  end
16
16
 
@@ -31,7 +31,7 @@ describe 'Rack::Attack.Allow2Ban' do
31
31
  end
32
32
 
33
33
  it 'increases fail count' do
34
- key = "rack::attack:#{Time.now.to_i/@findtime}:allow2ban:count:1.2.3.4"
34
+ key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
35
35
  @cache.store.read(key).must_equal 1
36
36
  end
37
37
 
@@ -53,7 +53,7 @@ describe 'Rack::Attack.Allow2Ban' do
53
53
  end
54
54
 
55
55
  it 'increases fail count' do
56
- key = "rack::attack:#{Time.now.to_i/@findtime}:allow2ban:count:1.2.3.4"
56
+ key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
57
57
  @cache.store.read(key).must_equal 2
58
58
  end
59
59
 
@@ -89,7 +89,7 @@ describe 'Rack::Attack.Allow2Ban' do
89
89
  end
90
90
 
91
91
  it 'does not increase fail count' do
92
- key = "rack::attack:#{Time.now.to_i/@findtime}:allow2ban:count:1.2.3.4"
92
+ key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
93
93
  @cache.store.read(key).must_equal 2
94
94
  end
95
95
 
@@ -109,7 +109,7 @@ describe 'Rack::Attack.Allow2Ban' do
109
109
  end
110
110
 
111
111
  it 'does not increase fail count' do
112
- key = "rack::attack:#{Time.now.to_i/@findtime}:allow2ban:count:1.2.3.4"
112
+ key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
113
113
  @cache.store.read(key).must_equal 2
114
114
  end
115
115
 
@@ -7,10 +7,10 @@ describe 'Rack::Attack.Fail2Ban' do
7
7
  @findtime = 60
8
8
  @bantime = 60
9
9
  Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
10
- @f2b_options = {:bantime => @bantime, :findtime => @findtime, :maxretry => 2}
10
+ @f2b_options = { :bantime => @bantime, :findtime => @findtime, :maxretry => 2 }
11
11
 
12
12
  Rack::Attack.blocklist('pentest') do |req|
13
- Rack::Attack::Fail2Ban.filter(req.ip, @f2b_options){req.query_string =~ /OMGHAX/}
13
+ Rack::Attack::Fail2Ban.filter(req.ip, @f2b_options) { req.query_string =~ /OMGHAX/ }
14
14
  end
15
15
  end
16
16
 
@@ -31,7 +31,7 @@ describe 'Rack::Attack.Fail2Ban' do
31
31
  end
32
32
 
33
33
  it 'increases fail count' do
34
- key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
34
+ key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
35
35
  @cache.store.read(key).must_equal 1
36
36
  end
37
37
 
@@ -53,7 +53,7 @@ describe 'Rack::Attack.Fail2Ban' do
53
53
  end
54
54
 
55
55
  it 'increases fail count' do
56
- key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
56
+ key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
57
57
  @cache.store.read(key).must_equal 2
58
58
  end
59
59
 
@@ -75,7 +75,7 @@ describe 'Rack::Attack.Fail2Ban' do
75
75
  end
76
76
 
77
77
  it 'resets fail count' do
78
- key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
78
+ key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
79
79
  assert_nil @cache.store.read(key)
80
80
  end
81
81
 
@@ -110,7 +110,7 @@ describe 'Rack::Attack.Fail2Ban' do
110
110
  end
111
111
 
112
112
  it 'does not increase fail count' do
113
- key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
113
+ key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
114
114
  @cache.store.read(key).must_equal 2
115
115
  end
116
116
 
@@ -130,7 +130,7 @@ describe 'Rack::Attack.Fail2Ban' do
130
130
  end
131
131
 
132
132
  it 'does not increase fail count' do
133
- key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
133
+ key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
134
134
  @cache.store.read(key).must_equal 2
135
135
  end
136
136
 
@@ -2,7 +2,7 @@ require_relative '../spec_helper'
2
2
 
3
3
  describe Rack::Attack::Cache do
4
4
  # A convenience method for deleting a key from cache.
5
- # Slightly differnet than @cache.delete, which adds a prefix.
5
+ # Slightly different than @cache.delete, which adds a prefix.
6
6
  def delete(key)
7
7
  if @cache.store.respond_to?(:delete)
8
8
  @cache.store.delete(key)
@@ -18,6 +18,7 @@ describe Rack::Attack::Cache do
18
18
  require 'active_support/cache/dalli_store'
19
19
  require 'active_support/cache/mem_cache_store'
20
20
  require 'active_support/cache/redis_store'
21
+ require 'active_support/cache/redis_cache_store' if ActiveSupport.version.to_s.to_f >= 5.2
21
22
  require 'connection_pool'
22
23
 
23
24
  cache_stores = [
@@ -30,6 +31,8 @@ describe Rack::Attack::Cache do
30
31
  Redis::Store.new
31
32
  ]
32
33
 
34
+ cache_stores << ActiveSupport::Cache::RedisCacheStore.new if defined?(ActiveSupport::Cache::RedisCacheStore)
35
+
33
36
  cache_stores.each do |store|
34
37
  store = Rack::Attack::StoreProxy.build(store)
35
38
 
@@ -1,10 +1,8 @@
1
1
  require_relative 'spec_helper'
2
2
 
3
3
  describe Rack::Attack::StoreProxy::DalliProxy do
4
-
5
4
  it 'should stub Dalli::Client#with on older clients' do
6
5
  proxy = Rack::Attack::StoreProxy::DalliProxy.new(Class.new)
7
6
  proxy.with {} # will not raise an error
8
7
  end
9
-
10
8
  end
@@ -5,7 +5,7 @@ describe 'Rack::Attack' do
5
5
 
6
6
  describe 'normalizing paths' do
7
7
  before do
8
- Rack::Attack.blocklist("banned_path") {|req| req.path == '/foo' }
8
+ Rack::Attack.blocklist("banned_path") { |req| req.path == '/foo' }
9
9
  end
10
10
 
11
11
  it 'blocks requests with trailing slash' do
@@ -17,7 +17,7 @@ describe 'Rack::Attack' do
17
17
  describe 'blocklist' do
18
18
  before do
19
19
  @bad_ip = '1.2.3.4'
20
- Rack::Attack.blocklist("ip #{@bad_ip}") {|req| req.ip == @bad_ip }
20
+ Rack::Attack.blocklist("ip #{@bad_ip}") { |req| req.ip == @bad_ip }
21
21
  end
22
22
 
23
23
  it('has a blocklist') {
@@ -25,7 +25,7 @@ describe 'Rack::Attack' do
25
25
  }
26
26
 
27
27
  it('has a blacklist with a deprication warning') {
28
- _, stderror = capture_io do
28
+ _, stderror = capture_io do
29
29
  Rack::Attack.blacklists.key?("ip #{@bad_ip}").must_equal true
30
30
  end
31
31
  assert_match "[DEPRECATION] 'Rack::Attack.blacklists' is deprecated. Please use 'blocklists' instead.", stderror
@@ -50,13 +50,13 @@ describe 'Rack::Attack' do
50
50
  describe "and safelist" do
51
51
  before do
52
52
  @good_ua = 'GoodUA'
53
- Rack::Attack.safelist("good ua") {|req| req.user_agent == @good_ua }
53
+ Rack::Attack.safelist("good ua") { |req| req.user_agent == @good_ua }
54
54
  end
55
55
 
56
56
  it('has a safelist') { Rack::Attack.safelists.key?("good ua") }
57
57
 
58
58
  it('has a whitelist with a deprication warning') {
59
- _, stderror = capture_io do
59
+ _, stderror = capture_io do
60
60
  Rack::Attack.whitelists.key?("good ua")
61
61
  end
62
62
  assert_match "[DEPRECATION] 'Rack::Attack.whitelists' is deprecated. Please use 'safelists' instead.", stderror
@@ -82,7 +82,7 @@ describe 'Rack::Attack' do
82
82
  end
83
83
 
84
84
  it 'should give a deprication warning for blacklisted_response' do
85
- _, stderror = capture_io do
85
+ _, stderror = capture_io do
86
86
  Rack::Attack.blacklisted_response
87
87
  end
88
88
  assert_match "[DEPRECATION] 'Rack::Attack.blacklisted_response' is deprecated. Please use 'blocklisted_response' instead.", stderror
@@ -15,7 +15,7 @@ describe 'Rack::Attack.throttle' do
15
15
  before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
16
16
 
17
17
  it 'should set the counter for one request' do
18
- key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
18
+ key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
19
19
  Rack::Attack.cache.store.read(key).must_equal 1
20
20
  end
21
21
 
@@ -37,7 +37,7 @@ describe 'Rack::Attack.throttle' do
37
37
  it 'should tag the env' do
38
38
  last_request.env['rack.attack.matched'].must_equal 'ip/sec'
39
39
  last_request.env['rack.attack.match_type'].must_equal :throttle
40
- last_request.env['rack.attack.match_data'].must_equal({:count => 2, :limit => 1, :period => @period})
40
+ last_request.env['rack.attack.match_data'].must_equal({ :count => 2, :limit => 1, :period => @period })
41
41
  last_request.env['rack.attack.match_discriminator'].must_equal('1.2.3.4')
42
42
  end
43
43
 
@@ -51,7 +51,7 @@ describe 'Rack::Attack.throttle with limit as proc' do
51
51
  before do
52
52
  @period = 60 # Use a long period; failures due to cache key rotation less likely
53
53
  Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
54
- Rack::Attack.throttle('ip/sec', :limit => lambda { |req| 1 }, :period => @period) { |req| req.ip }
54
+ Rack::Attack.throttle('ip/sec', :limit => lambda { |_req| 1 }, :period => @period) { |req| req.ip }
55
55
  end
56
56
 
57
57
  it_allows_ok_requests
@@ -60,7 +60,7 @@ describe 'Rack::Attack.throttle with limit as proc' do
60
60
  before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
61
61
 
62
62
  it 'should set the counter for one request' do
63
- key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
63
+ key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
64
64
  Rack::Attack.cache.store.read(key).must_equal 1
65
65
  end
66
66
 
@@ -75,7 +75,7 @@ describe 'Rack::Attack.throttle with period as proc' do
75
75
  before do
76
76
  @period = 60 # Use a long period; failures due to cache key rotation less likely
77
77
  Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
78
- Rack::Attack.throttle('ip/sec', :limit => lambda { |req| 1 }, :period => lambda { |req| @period }) { |req| req.ip }
78
+ Rack::Attack.throttle('ip/sec', :limit => lambda { |_req| 1 }, :period => lambda { |_req| @period }) { |req| req.ip }
79
79
  end
80
80
 
81
81
  it_allows_ok_requests
@@ -84,7 +84,7 @@ describe 'Rack::Attack.throttle with period as proc' do
84
84
  before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
85
85
 
86
86
  it 'should set the counter for one request' do
87
- key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
87
+ key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
88
88
  Rack::Attack.cache.store.read(key).must_equal 1
89
89
  end
90
90
 
@@ -108,7 +108,7 @@ describe 'Rack::Attack.throttle with block retuning nil' do
108
108
  before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
109
109
 
110
110
  it 'should not set the counter' do
111
- key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
111
+ key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
112
112
  assert_nil Rack::Attack.cache.store.read(key)
113
113
  end
114
114
 
@@ -16,7 +16,7 @@ describe 'Rack::Attack.track' do
16
16
  end
17
17
 
18
18
  before do
19
- Rack::Attack.track("everything"){ |req| true }
19
+ Rack::Attack.track("everything") { |_req| true }
20
20
  end
21
21
 
22
22
  it_allows_ok_requests
@@ -31,9 +31,9 @@ describe 'Rack::Attack.track' do
31
31
  before do
32
32
  Counter.reset
33
33
  # A second track
34
- Rack::Attack.track("homepage"){ |req| req.path == "/"}
34
+ Rack::Attack.track("homepage") { |req| req.path == "/" }
35
35
 
36
- ActiveSupport::Notifications.subscribe("rack.attack") do |*args|
36
+ ActiveSupport::Notifications.subscribe("rack.attack") do |*_args|
37
37
  Counter.incr
38
38
  end
39
39
 
@@ -47,14 +47,14 @@ describe 'Rack::Attack.track' do
47
47
 
48
48
  describe "without limit and period options" do
49
49
  it "should assign the track filter to a Check instance" do
50
- tracker = Rack::Attack.track("homepage") { |req| req.path == "/"}
50
+ tracker = Rack::Attack.track("homepage") { |req| req.path == "/" }
51
51
  tracker.filter.class.must_equal Rack::Attack::Check
52
52
  end
53
53
  end
54
54
 
55
55
  describe "with limit and period options" do
56
56
  it "should assign the track filter to a Throttle instance" do
57
- tracker = Rack::Attack.track("homepage", :limit => 10, :period => 10) { |req| req.path == "/"}
57
+ tracker = Rack::Attack.track("homepage", :limit => 10, :period => 10) { |req| req.path == "/" }
58
58
  tracker.filter.class.must_equal Rack::Attack::Throttle
59
59
  end
60
60
  end
@@ -12,7 +12,7 @@ require "rack/attack"
12
12
  begin
13
13
  require 'pry'
14
14
  rescue LoadError
15
- #nothing to do here
15
+ # nothing to do here
16
16
  end
17
17
 
18
18
  if RUBY_ENGINE == "ruby"
@@ -20,7 +20,6 @@ if RUBY_ENGINE == "ruby"
20
20
  end
21
21
 
22
22
  class MiniTest::Spec
23
-
24
23
  include Rack::Test::Methods
25
24
 
26
25
  before do
@@ -29,7 +28,7 @@ class MiniTest::Spec
29
28
  end
30
29
 
31
30
  after do
32
- Rack::Attack.clear!
31
+ Rack::Attack.clear_configuration
33
32
  Rack::Attack.instance_variable_set(:@cache, nil)
34
33
 
35
34
  Rack::Attack.throttled_response = @_original_throttled_response
@@ -43,7 +42,7 @@ class MiniTest::Spec
43
42
  use Rack::Attack
44
43
  use Rack::Lint
45
44
 
46
- run lambda {|env| [200, {}, ['Hello World']]}
45
+ run lambda { |_env| [200, {}, ['Hello World']] }
47
46
  }.to_app
48
47
  end
49
48