rack-attack 4.1.1 → 4.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.
Potentially problematic release.
This version of rack-attack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +7 -6
- data/lib/rack/attack.rb +3 -3
- data/lib/rack/attack/throttle.rb +7 -5
- data/lib/rack/attack/version.rb +1 -1
- data/spec/rack_attack_throttle_spec.rb +24 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e99e6a7757d11626b6b7d078abe43e9fe123cc36
|
4
|
+
data.tar.gz: 77b5a17a9de1acd9692805e2e634d165d66f1506
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75e2f1b7c760cc33323618edf03dd6fb3f661b73d2ed2d2ce67e80f632942c369d4e4336c479ae68e99805c2c2910a51b54dc4fab545b54d295536c28811ca20
|
7
|
+
data.tar.gz: 5da774caa95cfe83eaeb1c42d759ac0761fc76c5c6137681101f658680b3bba9edde35862f9a84cd0a1f530ae294142663a619c3940fedc761345b0be5cd3542
|
data/README.md
CHANGED
@@ -73,9 +73,9 @@ def call(env)
|
|
73
73
|
if whitelisted?(req)
|
74
74
|
@app.call(env)
|
75
75
|
elsif blacklisted?(req)
|
76
|
-
blacklisted_response
|
76
|
+
self.class.blacklisted_response.call(env)
|
77
77
|
elsif throttled?(req)
|
78
|
-
throttled_response
|
78
|
+
self.class.throttled_response.call(env)
|
79
79
|
else
|
80
80
|
tracked?(req)
|
81
81
|
@app.call(env)
|
@@ -181,10 +181,11 @@ Rack::Attack.throttle('logins/email', :limit => 6, :period => 60.seconds) do |re
|
|
181
181
|
req.params['email'] if req.path == '/login' && req.post?
|
182
182
|
end
|
183
183
|
|
184
|
-
# You can also set a limit using a proc
|
185
|
-
#
|
186
|
-
|
187
|
-
|
184
|
+
# You can also set a limit and period using a proc. For instance, after
|
185
|
+
# Rack::Auth::Basic has authenticated the user:
|
186
|
+
limit_proc = proc {|req| req.env["REMOTE_USER"] == "admin" ? 100 : 1}
|
187
|
+
period_proc = proc {|req| req.env["REMOTE_USER"] == "admin" ? 1.second : 1.minute}
|
188
|
+
Rack::Attack.throttle('req/ip', :limit => limit_proc, :period => period_proc) do |req|
|
188
189
|
req.ip
|
189
190
|
end
|
190
191
|
```
|
data/lib/rack/attack.rb
CHANGED
@@ -82,7 +82,7 @@ class Rack::Attack
|
|
82
82
|
@notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
|
83
83
|
@blacklisted_response = lambda {|env| [403, {'Content-Type' => 'text/plain'}, ["Forbidden\n"]] }
|
84
84
|
@throttled_response = lambda {|env|
|
85
|
-
retry_after = env['rack.attack.match_data'][:period]
|
85
|
+
retry_after = (env['rack.attack.match_data'] || {})[:period]
|
86
86
|
[429, {'Content-Type' => 'text/plain', 'Retry-After' => retry_after.to_s}, ["Retry later\n"]]
|
87
87
|
}
|
88
88
|
|
@@ -96,9 +96,9 @@ class Rack::Attack
|
|
96
96
|
if whitelisted?(req)
|
97
97
|
@app.call(env)
|
98
98
|
elsif blacklisted?(req)
|
99
|
-
self.class.blacklisted_response
|
99
|
+
self.class.blacklisted_response.call(env)
|
100
100
|
elsif throttled?(req)
|
101
|
-
self.class.throttled_response
|
101
|
+
self.class.throttled_response.call(env)
|
102
102
|
else
|
103
103
|
tracked?(req)
|
104
104
|
@app.call(env)
|
data/lib/rack/attack/throttle.rb
CHANGED
@@ -9,7 +9,7 @@ module Rack
|
|
9
9
|
raise ArgumentError.new("Must pass #{opt.inspect} option") unless options[opt]
|
10
10
|
end
|
11
11
|
@limit = options[:limit]
|
12
|
-
@period = options[:period].to_i
|
12
|
+
@period = options[:period].respond_to?(:call) ? options[:period] : options[:period].to_i
|
13
13
|
@type = options.fetch(:type, :throttle)
|
14
14
|
end
|
15
15
|
|
@@ -21,12 +21,14 @@ module Rack
|
|
21
21
|
discriminator = block[req]
|
22
22
|
return false unless discriminator
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
current_period = period.respond_to?(:call) ? period.call(req) : period
|
25
|
+
current_limit = limit.respond_to?(:call) ? limit.call(req) : limit
|
26
|
+
key = "#{name}:#{discriminator}"
|
27
|
+
count = cache.count(key, current_period)
|
28
|
+
|
27
29
|
data = {
|
28
30
|
:count => count,
|
29
|
-
:period =>
|
31
|
+
:period => current_period,
|
30
32
|
:limit => current_limit
|
31
33
|
}
|
32
34
|
(req.env['rack.attack.throttle_data'] ||= {})[name] = data
|
data/lib/rack/attack/version.rb
CHANGED
@@ -44,7 +44,30 @@ describe 'Rack::Attack.throttle with limit as proc' do
|
|
44
44
|
before do
|
45
45
|
@period = 60 # Use a long period; failures due to cache key rotation less likely
|
46
46
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
47
|
-
Rack::Attack.throttle('ip/sec', :limit => lambda {|req| 1}, :period => @period) { |req| req.ip }
|
47
|
+
Rack::Attack.throttle('ip/sec', :limit => lambda { |req| 1 }, :period => @period) { |req| req.ip }
|
48
|
+
end
|
49
|
+
|
50
|
+
allow_ok_requests
|
51
|
+
|
52
|
+
describe 'a single request' do
|
53
|
+
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
54
|
+
it 'should set the counter for one request' do
|
55
|
+
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
56
|
+
Rack::Attack.cache.store.read(key).must_equal 1
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should populate throttle data' do
|
60
|
+
data = { :count => 1, :limit => 1, :period => @period }
|
61
|
+
last_request.env['rack.attack.throttle_data']['ip/sec'].must_equal data
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'Rack::Attack.throttle with period as proc' do
|
67
|
+
before do
|
68
|
+
@period = 60 # Use a long period; failures due to cache key rotation less likely
|
69
|
+
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
70
|
+
Rack::Attack.throttle('ip/sec', :limit => lambda { |req| 1 }, :period => lambda { |req| @period }) { |req| req.ip }
|
48
71
|
end
|
49
72
|
|
50
73
|
allow_ok_requests
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-attack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Suggs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -204,3 +204,4 @@ test_files:
|
|
204
204
|
- spec/rack_attack_throttle_spec.rb
|
205
205
|
- spec/rack_attack_track_spec.rb
|
206
206
|
- spec/spec_helper.rb
|
207
|
+
has_rdoc:
|