improved-rack-throttle-w-expiry 0.8.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.
- data/.document +5 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +57 -0
- data/README.md +247 -0
- data/ROADMAP.md +14 -0
- data/Rakefile +43 -0
- data/UNLICENSE +24 -0
- data/doc/.gitignore +2 -0
- data/etc/gdbm.ru +7 -0
- data/etc/hash.ru +6 -0
- data/etc/memcache-client.ru +8 -0
- data/etc/memcache.ru +8 -0
- data/etc/memcached.ru +8 -0
- data/etc/redis.ru +8 -0
- data/improved-rack-throttle-w-expiry.gemspec +94 -0
- data/lib/rack/throttle.rb +17 -0
- data/lib/rack/throttle/limiters/daily.rb +49 -0
- data/lib/rack/throttle/limiters/hourly.rb +49 -0
- data/lib/rack/throttle/limiters/interval.rb +63 -0
- data/lib/rack/throttle/limiters/limiter.rb +231 -0
- data/lib/rack/throttle/limiters/sliding_window.rb +86 -0
- data/lib/rack/throttle/limiters/time_window.rb +21 -0
- data/lib/rack/throttle/matchers/matcher.rb +32 -0
- data/lib/rack/throttle/matchers/method_matcher.rb +24 -0
- data/lib/rack/throttle/matchers/url_matcher.rb +24 -0
- data/lib/rack/throttle/matchers/user_agent_matcher.rb +23 -0
- data/lib/rack/throttle/version.rb +23 -0
- data/spec/limiters/daily_spec.rb +31 -0
- data/spec/limiters/hourly_spec.rb +32 -0
- data/spec/limiters/interval_spec.rb +45 -0
- data/spec/limiters/limiter_spec.rb +51 -0
- data/spec/limiters/sliding_window_spec.rb +67 -0
- data/spec/matchers/method_matcher_spec.rb +27 -0
- data/spec/matchers/url_matcher_spec.rb +28 -0
- data/spec/matchers/user_agent_matcher_spec.rb +28 -0
- data/spec/spec_helper.rb +51 -0
- metadata +215 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Rack::Throttle::MethodMatcher do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
@target_app ||= example_target_app
|
8
|
+
@app ||= Rack::Throttle::Limiter.new(@target_app, :rules => {:method => :post})
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not bother checking if the path doesn't match the rule" do
|
12
|
+
app.should_not_receive(:allowed?)
|
13
|
+
get "/foo"
|
14
|
+
last_response.body.should show_allowed_response
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should check if the path matches the rule" do
|
18
|
+
app.should_receive(:allowed?).and_return(false)
|
19
|
+
post "/foo"
|
20
|
+
last_response.body.should show_throttled_response
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should append the rule to the cache key" do
|
24
|
+
post "/foo"
|
25
|
+
app.send(:cache_key, last_request).should == "127.0.0.1:meth-post"
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Rack::Throttle::UrlMatcher do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
@target_app ||= example_target_app
|
8
|
+
@app ||= Rack::Throttle::Limiter.new(@target_app, :rules => {:url => /foo/})
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not bother checking if the path doesn't match the rule" do
|
12
|
+
app.should_not_receive(:allowed?)
|
13
|
+
get "/bar"
|
14
|
+
last_response.body.should show_allowed_response
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should check if the path matches the rule" do
|
18
|
+
app.should_receive(:allowed?).and_return(false)
|
19
|
+
get "/foo"
|
20
|
+
last_response.body.should show_throttled_response
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should append the rule to the cache key" do
|
24
|
+
get "/foo"
|
25
|
+
app.send(:cache_key, last_request).should == "127.0.0.1:url-/foo/"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Rack::Throttle::UserAgentMatcher do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
@target_app ||= example_target_app
|
8
|
+
@app ||= Rack::Throttle::Limiter.new(@target_app, :rules => {:user_agent => /google/i})
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not bother checking if the path doesn't match the rule" do
|
12
|
+
app.should_not_receive(:allowed?)
|
13
|
+
get "/foo"
|
14
|
+
last_response.body.should show_allowed_response
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should check if the path matches the rule" do
|
18
|
+
app.should_receive(:allowed?).and_return(false)
|
19
|
+
header 'User-Agent', 'blahdeblah GoogleBot owns your soul'
|
20
|
+
get "/foo"
|
21
|
+
last_response.body.should show_throttled_response
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should append the rule to the cache key" do
|
25
|
+
get "/foo"
|
26
|
+
app.send(:cache_key, last_request).should == "127.0.0.1:ua-/google/i"
|
27
|
+
end
|
28
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require "rspec"
|
2
|
+
require "rack/test"
|
3
|
+
require "rack/throttle"
|
4
|
+
require "timecop"
|
5
|
+
|
6
|
+
unless RUBY_VERSION.match(/1\.8/)
|
7
|
+
require 'simplecov'
|
8
|
+
SimpleCov.start
|
9
|
+
end
|
10
|
+
|
11
|
+
def example_target_app
|
12
|
+
@target_app = double("Example Rack App")
|
13
|
+
@target_app.stub(:call).with(any_args()).and_return([200, {}, "Example App Body"])
|
14
|
+
@target_app
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec::Matchers.define :show_allowed_response do
|
18
|
+
match do |body|
|
19
|
+
body.include?("Example App Body")
|
20
|
+
end
|
21
|
+
|
22
|
+
failure_message_for_should do
|
23
|
+
"expected response to show the allowed response"
|
24
|
+
end
|
25
|
+
|
26
|
+
failure_message_for_should_not do
|
27
|
+
"expected response not to show the allowed response"
|
28
|
+
end
|
29
|
+
|
30
|
+
description do
|
31
|
+
"expected the allowed response"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Matchers.define :show_throttled_response do
|
36
|
+
match do |body|
|
37
|
+
body.include?("Rate Limit Exceeded")
|
38
|
+
end
|
39
|
+
|
40
|
+
failure_message_for_should do
|
41
|
+
"expected response to show the throttled response"
|
42
|
+
end
|
43
|
+
|
44
|
+
failure_message_for_should_not do
|
45
|
+
"expected response not to show the throttled response"
|
46
|
+
end
|
47
|
+
|
48
|
+
description do
|
49
|
+
"expected the throttled response"
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: improved-rack-throttle-w-expiry
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ben Somers
|
9
|
+
- Arto Bendiken
|
10
|
+
- Brendon Murphy
|
11
|
+
- Shane Moore
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
date: 2013-06-17 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: rack
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.0.0
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: timecop
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.5.2
|
41
|
+
type: :development
|
42
|
+
prerelease: false
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.5.2
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rack-test
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ~>
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 0.6.2
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ~>
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 0.6.2
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: rspec
|
67
|
+
requirement: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ~>
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 2.11.0
|
73
|
+
type: :development
|
74
|
+
prerelease: false
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ~>
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 2.11.0
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: yard
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 0.5.5
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.5.5
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: redcarpet
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: rake
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: jeweler
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
type: :development
|
138
|
+
prerelease: false
|
139
|
+
version_requirements: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
description: Rack middleware for rate-limiting incoming HTTP requests.
|
146
|
+
email: shane@ninja.ie
|
147
|
+
executables: []
|
148
|
+
extensions: []
|
149
|
+
extra_rdoc_files:
|
150
|
+
- README.md
|
151
|
+
- ROADMAP.md
|
152
|
+
files:
|
153
|
+
- .document
|
154
|
+
- Gemfile
|
155
|
+
- Gemfile.lock
|
156
|
+
- README.md
|
157
|
+
- Rakefile
|
158
|
+
- UNLICENSE
|
159
|
+
- doc/.gitignore
|
160
|
+
- etc/gdbm.ru
|
161
|
+
- etc/hash.ru
|
162
|
+
- etc/memcache-client.ru
|
163
|
+
- etc/memcache.ru
|
164
|
+
- etc/memcached.ru
|
165
|
+
- etc/redis.ru
|
166
|
+
- improved-rack-throttle-w-expiry.gemspec
|
167
|
+
- lib/rack/throttle.rb
|
168
|
+
- lib/rack/throttle/limiters/daily.rb
|
169
|
+
- lib/rack/throttle/limiters/hourly.rb
|
170
|
+
- lib/rack/throttle/limiters/interval.rb
|
171
|
+
- lib/rack/throttle/limiters/limiter.rb
|
172
|
+
- lib/rack/throttle/limiters/sliding_window.rb
|
173
|
+
- lib/rack/throttle/limiters/time_window.rb
|
174
|
+
- lib/rack/throttle/matchers/matcher.rb
|
175
|
+
- lib/rack/throttle/matchers/method_matcher.rb
|
176
|
+
- lib/rack/throttle/matchers/url_matcher.rb
|
177
|
+
- lib/rack/throttle/matchers/user_agent_matcher.rb
|
178
|
+
- lib/rack/throttle/version.rb
|
179
|
+
- spec/limiters/daily_spec.rb
|
180
|
+
- spec/limiters/hourly_spec.rb
|
181
|
+
- spec/limiters/interval_spec.rb
|
182
|
+
- spec/limiters/limiter_spec.rb
|
183
|
+
- spec/limiters/sliding_window_spec.rb
|
184
|
+
- spec/matchers/method_matcher_spec.rb
|
185
|
+
- spec/matchers/url_matcher_spec.rb
|
186
|
+
- spec/matchers/user_agent_matcher_spec.rb
|
187
|
+
- spec/spec_helper.rb
|
188
|
+
- ROADMAP.md
|
189
|
+
homepage: http://github.com/Rooktone/improved-rack-throttle-w-expiry
|
190
|
+
licenses:
|
191
|
+
- Public Domain
|
192
|
+
post_install_message:
|
193
|
+
rdoc_options: []
|
194
|
+
require_paths:
|
195
|
+
- lib
|
196
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
197
|
+
none: false
|
198
|
+
requirements:
|
199
|
+
- - ! '>='
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
|
+
none: false
|
204
|
+
requirements:
|
205
|
+
- - ! '>='
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0'
|
208
|
+
requirements: []
|
209
|
+
rubyforge_project:
|
210
|
+
rubygems_version: 1.8.25
|
211
|
+
signing_key:
|
212
|
+
specification_version: 3
|
213
|
+
summary: HTTP request rate limiter for Rack applications.
|
214
|
+
test_files: []
|
215
|
+
has_rdoc:
|