rack-attack 4.0.1 → 4.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2ad64c34913ec247b9f1952ec77a38762742151
4
- data.tar.gz: f953e23413add27445c65ef5d058afc0c5dc2cb7
3
+ metadata.gz: 459c5b823f0b03b1d839e5577d1d57fc14332d2c
4
+ data.tar.gz: e8e15fe0e7619b07a9710160cd429dab4499f6c1
5
5
  SHA512:
6
- metadata.gz: e2c8ebf7e34dae93d31c300ca035723794f1f185fecaa008fdf1f305697c6d1f36614ae6e5c1135be3722cbfd68b7ea1ef809d6f045f7858e6674dca837cbcc0
7
- data.tar.gz: 6b8d3632cae6db709922e400e681b7e0742067baaf3596957af962ab13be55a5a445fee534b40279ae19ab3f50ae2cd8776d473359e06d8889c4b8b5e0b3dab0
6
+ metadata.gz: 67aad493c5a2b719de12f17a099e9e3ffabfe32fb33ba2d11b9c8149918a78e300fad9c56b786fcca2e328f898a022f0da158becf81304eba42928f1119a5f74
7
+ data.tar.gz: 4cc797bcb7a7e88fe7b9df2c016b6aeb766dc71007d8124b3d3cd4b1e7da4e6d0695de0465f21afc798aafc81f0b6ac3dbe5f8cdc4f05e856bca49a69e49ce70
data/README.md CHANGED
@@ -39,7 +39,7 @@ use Rack::Attack
39
39
  Add a `rack-attack.rb` file to `config/initalizers/`:
40
40
  ```ruby
41
41
  # In config/initializers/rack-attack.rb
42
- module Rack::Attack
42
+ class Rack::Attack
43
43
  # your custom configuration...
44
44
  end
45
45
  ```
@@ -188,11 +188,16 @@ end
188
188
  ### Tracks
189
189
 
190
190
  ```ruby
191
- # Track requests from a special user agent
191
+ # Track requests from a special user agent.
192
192
  Rack::Attack.track("special_agent") do |req|
193
193
  req.user_agent == "SpecialAgent"
194
194
  end
195
195
 
196
+ # Supports optional limit and period, triggers the notification only when the limit is reached.
197
+ Rack::Attack.track("special_agent", :limit 6, :period => 60.seconds) do |req|
198
+ req.user_agent == "SpecialAgent"
199
+ end
200
+
196
201
  # Track it using ActiveSupport::Notification
197
202
  ActiveSupport::Notifications.subscribe("rack.attack") do |name, start, finish, request_id, req|
198
203
  if req.env['rack.attack.matched'] == "special_agent" && req.env['rack.attack.match_type'] == :track
@@ -31,8 +31,8 @@ class Rack::Attack
31
31
  self.throttles[name] = Throttle.new(name, options, block)
32
32
  end
33
33
 
34
- def track(name, &block)
35
- self.tracks[name] = Track.new(name, block)
34
+ def track(name, options = {}, &block)
35
+ self.tracks[name] = Track.new(name, options, block)
36
36
  end
37
37
 
38
38
  def whitelists; @whitelists ||= {}; end
@@ -73,17 +73,17 @@ class Rack::Attack
73
73
  end
74
74
 
75
75
  def clear!
76
- @whitelists, @blacklists, @throttles = {}, {}, {}
76
+ @whitelists, @blacklists, @throttles, @tracks = {}, {}, {}, {}
77
77
  end
78
78
 
79
79
  end
80
80
 
81
81
  # Set defaults
82
82
  @notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
83
- @blacklisted_response = lambda {|env| [403, {}, ["Forbidden\n"]] }
83
+ @blacklisted_response = lambda {|env| [403, {'Content-Type' => 'text/plain'}, ["Forbidden\n"]] }
84
84
  @throttled_response = lambda {|env|
85
85
  retry_after = env['rack.attack.match_data'][:period] rescue nil
86
- [429, {'Retry-After' => retry_after.to_s}, ["Retry later\n"]]
86
+ [429, {'Content-Type' => 'text/plain', 'Retry-After' => retry_after.to_s}, ["Retry later\n"]]
87
87
  }
88
88
 
89
89
  def initialize(app)
@@ -2,9 +2,9 @@ module Rack
2
2
  class Attack
3
3
  class Check
4
4
  attr_reader :name, :block, :type
5
- def initialize(name, block)
5
+ def initialize(name, options = {}, block)
6
6
  @name, @block = name, block
7
- @type = nil
7
+ @type = options.fetch(:type, nil)
8
8
  end
9
9
 
10
10
  def [](req)
@@ -2,7 +2,7 @@ module Rack
2
2
  class Attack
3
3
  class Throttle
4
4
  MANDATORY_OPTIONS = [:limit, :period]
5
- attr_reader :name, :limit, :period, :block
5
+ attr_reader :name, :limit, :period, :block, :type
6
6
  def initialize(name, options, block)
7
7
  @name, @block = name, block
8
8
  MANDATORY_OPTIONS.each do |opt|
@@ -10,6 +10,7 @@ module Rack
10
10
  end
11
11
  @limit = options[:limit]
12
12
  @period = options[:period].to_i
13
+ @type = options.fetch(:type, :throttle)
13
14
  end
14
15
 
15
16
  def cache
@@ -34,7 +35,7 @@ module Rack
34
35
  if throttled
35
36
  req.env['rack.attack.matched'] = name
36
37
  req.env['rack.attack.match_discriminator'] = discriminator
37
- req.env['rack.attack.match_type'] = :throttle
38
+ req.env['rack.attack.match_type'] = type
38
39
  req.env['rack.attack.match_data'] = data
39
40
  Rack::Attack.instrument(req)
40
41
  end
@@ -1,10 +1,21 @@
1
1
  module Rack
2
2
  class Attack
3
- class Track < Check
4
- def initialize(name, block)
5
- super
6
- @type = :track
3
+ class Track
4
+ extend Forwardable
5
+
6
+ attr_reader :filter
7
+
8
+ def initialize(name, options = {}, block)
9
+ options[:type] = :track
10
+
11
+ if options[:limit] && options[:period]
12
+ @filter = Throttle.new(name, options, block)
13
+ else
14
+ @filter = Check.new(name, options, block)
15
+ end
7
16
  end
17
+
18
+ def_delegator :@filter, :[]
8
19
  end
9
20
  end
10
21
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Attack
3
- VERSION = '4.0.1'
3
+ VERSION = '4.1.0'
4
4
  end
5
5
  end
@@ -41,4 +41,18 @@ describe 'Rack::Attack.track' do
41
41
  Counter.check.must_equal 2
42
42
  end
43
43
  end
44
+
45
+ describe "without limit and period options" do
46
+ it "should assign the track filter to a Check instance" do
47
+ tracker = Rack::Attack.track("homepage") { |req| req.path == "/"}
48
+ tracker.filter.class.must_equal Rack::Attack::Check
49
+ end
50
+ end
51
+
52
+ describe "with limit and period options" do
53
+ it "should assign the track filter to a Throttle instance" do
54
+ tracker = Rack::Attack.track("homepage", :limit => 10, :period => 10) { |req| req.path == "/"}
55
+ tracker.filter.class.must_equal Rack::Attack::Throttle
56
+ end
57
+ end
44
58
  end
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.0.1
4
+ version: 4.1.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-05-14 00:00:00.000000000 Z
11
+ date: 2014-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack