rate-limiting 1.0.2 → 1.0.3
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.
- data/lib/rate-limiting/version.rb +1 -1
- data/lib/rule.rb +2 -1
- data/readme.md +51 -15
- data/spec/headers_spec.rb +2 -2
- data/spec/per_url_spec.rb +34 -0
- data/spec/spec_helper.rb +2 -0
- metadata +4 -2
data/lib/rule.rb
CHANGED
@@ -7,6 +7,7 @@ class Rule
|
|
7
7
|
:type => :frequency,
|
8
8
|
:limit => 100,
|
9
9
|
:per_ip => true,
|
10
|
+
:per_url => false,
|
10
11
|
:token => false
|
11
12
|
}
|
12
13
|
@options = default_options.merge(options)
|
@@ -48,7 +49,7 @@ class Rule
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def get_key(request)
|
51
|
-
key = request.path
|
52
|
+
key = (@options[:per_url] ? request.path : @options[:match].to_s)
|
52
53
|
key = key + request.ip.to_s if @options[:per_ip]
|
53
54
|
key = key + request.params[@options[:token].to_s] if @options[:token]
|
54
55
|
key
|
data/readme.md
CHANGED
@@ -1,32 +1,57 @@
|
|
1
1
|
Rate Limiting
|
2
2
|
===============
|
3
3
|
|
4
|
+
Rate Limiting is a rack middleware that rate-limit HTTP requests in many different ways.
|
5
|
+
It provides tools for creating rules which can rate-limit routes separately.
|
6
|
+
|
7
|
+
|
4
8
|
|
5
9
|
How to use it
|
6
10
|
----------------
|
7
11
|
|
8
12
|
**Adding to Rails 3.x**
|
9
13
|
|
10
|
-
|
14
|
+
Gemfile
|
15
|
+
|
16
|
+
gem 'rate-limiting'
|
17
|
+
|
18
|
+
config/application.rb
|
19
|
+
|
20
|
+
require "rate_limiting"
|
21
|
+
|
22
|
+
class Application < Rails::Application
|
23
|
+
|
24
|
+
config.middleware.use RateLimiting do |r|
|
25
|
+
|
26
|
+
# Add your rules here, ex:
|
27
|
+
|
28
|
+
r.define_rule( :match => '/resource', :type => :fixed, :metric => :rph, :limit => 300 )
|
29
|
+
r.define_rule(:match => '/html', :limit => 1)
|
30
|
+
r.define_rule(:match => '/json', :metric => :rph, :type => :frequency, :limit => 60)
|
31
|
+
r.define_rule(:match => '/xml', :metric => :rph, :type => :frequency, :limit => 60)
|
32
|
+
r.define_rule(:match => '/token/ip', :limit => 1, :token => :id, :per_ip => true)
|
33
|
+
r.define_rule(:match => '/token', :limit => 1, :token => :id, :per_ip => false)
|
34
|
+
r.define_rule(:match => '/fixed/rpm', :metric => :rpm, :type => :fixed, :limit => 1)
|
35
|
+
r.define_rule(:match => '/fixed/rph', :metric => :rph, :type => :fixed, :limit => 1)
|
36
|
+
r.define_rule(:match => '/fixed/rpd', :metric => :rpd, :type => :fixed, :limit => 1)
|
37
|
+
r.define_rule(:match => '/freq/rpm', :metric => :rpm, :type => :frequency, :limit => 1)
|
38
|
+
r.define_rule(:match => '/freq/rph', :metric => :rph, :type => :frequency, :limit => 60)
|
39
|
+
r.define_rule(:match => '/freq/rpd', :metric => :rpd, :type => :frequency, :limit => 1440)
|
40
|
+
r.define_rule(:match => '/header', :metric => :rph, :type => :frequency, :limit => 60)
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
11
45
|
|
12
|
-
> class Application < Rails::Application
|
13
|
-
>
|
14
|
-
> config.middleware.use RateLimiting do |r|
|
15
|
-
>
|
16
|
-
> r.define_rule( :match => '/resource', :type => :fixed, :metric => :rph, :limit => 300 )
|
17
|
-
>
|
18
|
-
> end
|
19
|
-
>
|
20
|
-
> end
|
21
46
|
|
22
47
|
Rule Options
|
23
48
|
----------------
|
24
49
|
|
25
|
-
|
50
|
+
### match
|
26
51
|
|
27
52
|
Accepts aimed resource path or Regexp like '/resource' or "/resource/.*"
|
28
53
|
|
29
|
-
|
54
|
+
### metric
|
30
55
|
|
31
56
|
:rpd - Requests per Day
|
32
57
|
|
@@ -34,17 +59,28 @@ Accepts aimed resource path or Regexp like '/resource' or "/resource/.*"
|
|
34
59
|
|
35
60
|
:rpm - Requests per Minute
|
36
61
|
|
37
|
-
|
62
|
+
### type
|
38
63
|
|
39
64
|
:frequency - 1 request per (time/limit)
|
40
65
|
|
41
66
|
:fixed - limit requests per time
|
42
67
|
|
43
|
-
|
68
|
+
Examples:
|
69
|
+
|
70
|
+
r.define_rule(:match => "/resource", :metric => :rph, :type => :frequency, :limit => 3)
|
71
|
+
|
72
|
+
=> 1 request every 20 min
|
73
|
+
|
74
|
+
r.define_rule(:match => "/resource", :metric => :rph, :type => :fixed, :limit => 3)
|
75
|
+
|
76
|
+
=> 3 request every 60 min
|
77
|
+
|
78
|
+
|
79
|
+
### token
|
44
80
|
|
45
81
|
:foo - limit by request parameter 'foo'
|
46
82
|
|
47
|
-
|
83
|
+
### per_ip
|
48
84
|
|
49
85
|
Boolean, true = limit by IP
|
50
86
|
|
data/spec/headers_spec.rb
CHANGED
@@ -21,11 +21,11 @@ describe "response headers" do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'should have the right limit' do
|
24
|
-
last_response.header['x-RateLimit-Limit'].should == 1
|
24
|
+
last_response.header['x-RateLimit-Limit'].should == "1"
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should have the right remaining' do
|
28
|
-
last_response.header['x-RateLimit-Remaining'].should == 0
|
28
|
+
last_response.header['x-RateLimit-Remaining'].should == "0"
|
29
29
|
end
|
30
30
|
|
31
31
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "per_url rule" do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
context "true" do
|
7
|
+
|
8
|
+
it 'should not allow equal urls' do
|
9
|
+
get '/per_url/url1', {}, {'HTTP_ACCEPT' => "text/html"}
|
10
|
+
get '/per_url/url1', {}, {'HTTP_ACCEPT' => "text/html"}
|
11
|
+
last_response.body.should show_not_allowed_response
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should allow different urls' do
|
15
|
+
get '/per_url/url1', {}, {'HTTP_ACCEPT' => "text/html"}
|
16
|
+
get '/per_url/url2', {}, {'HTTP_ACCEPT' => "text/html"}
|
17
|
+
last_response.body.should show_allowed_response
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
context "false" do
|
23
|
+
|
24
|
+
it 'should not allow different urls' do
|
25
|
+
get '/per_match/url1', {}, {'HTTP_ACCEPT' => "text/html"}
|
26
|
+
get '/per_match/url2', {}, {'HTTP_ACCEPT' => "text/html"}
|
27
|
+
last_response.body.should show_not_allowed_response
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -23,6 +23,8 @@ def app
|
|
23
23
|
r.define_rule(:match => '/freq/rph', :metric => :rph, :type => :frequency, :limit => 60)
|
24
24
|
r.define_rule(:match => '/freq/rpd', :metric => :rpd, :type => :frequency, :limit => 1440)
|
25
25
|
r.define_rule(:match => '/header', :metric => :rph, :type => :frequency, :limit => 60)
|
26
|
+
r.define_rule(:match => '/per_match/.*', :metric => :rph, :type => :frequency, :limit => 60, :per_url => false)
|
27
|
+
r.define_rule(:match => '/per_url/.*', :metric => :rph, :type => :frequency, :limit => 60, :per_url => true)
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rate-limiting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- spec/headers_spec.rb
|
86
86
|
- spec/html_request_spec.rb
|
87
87
|
- spec/json_request_spec.rb
|
88
|
+
- spec/per_url_spec.rb
|
88
89
|
- spec/spec_helper.rb
|
89
90
|
- spec/token_spec.rb
|
90
91
|
- spec/xml_request_spec.rb
|
@@ -122,6 +123,7 @@ test_files:
|
|
122
123
|
- spec/headers_spec.rb
|
123
124
|
- spec/html_request_spec.rb
|
124
125
|
- spec/json_request_spec.rb
|
126
|
+
- spec/per_url_spec.rb
|
125
127
|
- spec/spec_helper.rb
|
126
128
|
- spec/token_spec.rb
|
127
129
|
- spec/xml_request_spec.rb
|