rack-throttle 0.5.0 → 0.6.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.
- checksums.yaml +5 -5
- data/README +1 -1
- data/VERSION +1 -1
- data/lib/rack/throttle.rb +1 -0
- data/lib/rack/throttle/rules.rb +95 -0
- data/lib/rack/throttle/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a65f5195779a2af8c7340f1e52dd0c19e6036e234eeaf934518a307b05a208e4
|
4
|
+
data.tar.gz: e69a0f3ee004f59b3a6808f9165a2c82b1729dde0ed344e7192998eb5c522f3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e0a36ff42888850b8e1532133706342637e070998d815ff5358a7a36235a3c7a4eabe5f0514ad463bdb7fea13e84ce4ce21b63e47f7352be5c03877c4c3ffb1
|
7
|
+
data.tar.gz: 4d84b627410ff12bf7a81ac3ad19c681397287748d4d9306d1d5f447a918849488b04bb1b33f1057018a4519abbc309460aa109772193c7c4a81e13c23fe65bf
|
data/README
CHANGED
@@ -1 +1 @@
|
|
1
|
-
README.md
|
1
|
+
./README.md
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/lib/rack/throttle.rb
CHANGED
@@ -9,6 +9,7 @@ module Rack
|
|
9
9
|
autoload :Hourly, ::File.expand_path(::File.dirname(__FILE__)) + '/throttle/hourly'
|
10
10
|
autoload :Minute, ::File.expand_path(::File.dirname(__FILE__)) + '/throttle/minute'
|
11
11
|
autoload :Second, ::File.expand_path(::File.dirname(__FILE__)) + '/throttle/second'
|
12
|
+
autoload :Rules, ::File.expand_path(::File.dirname(__FILE__)) + '/throttle/rules'
|
12
13
|
autoload :VERSION, ::File.expand_path(::File.dirname(__FILE__)) + '/throttle/version'
|
13
14
|
end
|
14
15
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "ipaddr"
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module Throttle
|
5
|
+
class Rules < TimeWindow
|
6
|
+
##
|
7
|
+
# @param [#call] app
|
8
|
+
# @param [Hash{Symbol => Object}] options
|
9
|
+
# @option options [Integer] :max (1)
|
10
|
+
def initialize(app, options = {})
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def rules
|
15
|
+
@rules ||= begin
|
16
|
+
rs = options[:rules]
|
17
|
+
rs.sort_by { |r| r[:path].to_s }.reverse
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def retry_after
|
22
|
+
@min ||= (options[:min] || 3600)
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_limit
|
26
|
+
@default_limit ||= options[:default] || 1_000_000_000
|
27
|
+
end
|
28
|
+
|
29
|
+
def ips
|
30
|
+
@ips ||= (options[:ip_whitelist] || []).map { |ip| IPAddr.new(ip) } || []
|
31
|
+
end
|
32
|
+
|
33
|
+
def whitelisted?(request)
|
34
|
+
return true if ip_whitelisted?(IPAddr.new(ip(request)))
|
35
|
+
return true if path_whitelisted?(request)
|
36
|
+
false
|
37
|
+
end
|
38
|
+
|
39
|
+
def ip_whitelisted?(request_ip)
|
40
|
+
!!ips.find { |ip| ip.include?(request_ip) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def path_whitelisted?(request)
|
44
|
+
rule = rule_for(request)
|
45
|
+
rule ? rule[:whitelisted] : false
|
46
|
+
end
|
47
|
+
|
48
|
+
def rule_for(request)
|
49
|
+
rules.find do |rule|
|
50
|
+
next unless rule[:method] == request.request_method.to_s
|
51
|
+
next unless path_matches?(rule, request.path.to_s)
|
52
|
+
rule
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def path_matches?(rule, path)
|
57
|
+
return true unless rule[:path]
|
58
|
+
return true if path.to_s.match(rule[:path])
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
def max_per_window(request)
|
63
|
+
rule = rule_for(request)
|
64
|
+
rule ? rule[:limit] : default_limit
|
65
|
+
end
|
66
|
+
|
67
|
+
def client_identifier(request)
|
68
|
+
if (rule = rule_for(request))
|
69
|
+
"#{ip(request)}_#{rule[:method]}_#{rule[:path]}"
|
70
|
+
else
|
71
|
+
ip(request)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def ip(request)
|
76
|
+
request.ip.to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
def cache_key(request)
|
80
|
+
[super, Time.now.strftime(time_string)].join(':')
|
81
|
+
end
|
82
|
+
|
83
|
+
def time_string
|
84
|
+
@time_string ||= case options[:time_window]
|
85
|
+
when :second then '%Y-%m-%dT%H:%M:%S'
|
86
|
+
when :minute then '%Y-%m-%dT%H:%M'
|
87
|
+
when :hour then '%Y-%m-%dT%H'
|
88
|
+
when :day then '%Y-%m-%d'
|
89
|
+
else '%Y-%m-%dT%H:%M:%S'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-throttle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arto Bendiken
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- lib/rack/throttle/interval.rb
|
111
111
|
- lib/rack/throttle/limiter.rb
|
112
112
|
- lib/rack/throttle/minute.rb
|
113
|
+
- lib/rack/throttle/rules.rb
|
113
114
|
- lib/rack/throttle/second.rb
|
114
115
|
- lib/rack/throttle/time_window.rb
|
115
116
|
- lib/rack/throttle/version.rb
|
@@ -133,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
134
|
version: '0'
|
134
135
|
requirements: []
|
135
136
|
rubyforge_project:
|
136
|
-
rubygems_version: 2.
|
137
|
+
rubygems_version: 2.7.6
|
137
138
|
signing_key:
|
138
139
|
specification_version: 4
|
139
140
|
summary: HTTP request rate limiter for Rack applications.
|