Class: Rack::Throttle::Rules
Instance Attribute Summary
Attributes inherited from Limiter
#app, #options
Instance Method Summary
collapse
Methods inherited from TimeWindow
#allowed?
Methods inherited from Limiter
#allowed?, #blacklisted?, #call
Constructor Details
#initialize(app, options = {}) ⇒ Rules
Returns a new instance of Rules.
10
11
12
|
# File 'lib/rack/throttle/rules.rb', line 10
def initialize(app, options = {})
super
end
|
Instance Method Details
#cache_key(request) ⇒ Object
92
93
94
|
# File 'lib/rack/throttle/rules.rb', line 92
def cache_key(request)
[super, Time.now.strftime(time_string)].join(':')
end
|
#client_identifier(request) ⇒ Object
68
69
70
71
72
73
74
|
# File 'lib/rack/throttle/rules.rb', line 68
def client_identifier(request)
if (rule = rule_for(request))
client_identifier_for_rule(request, rule)
else
ip(request)
end
end
|
#client_identifier_for_rule(request, rule) ⇒ Object
76
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/rack/throttle/rules.rb', line 76
def client_identifier_for_rule(request, rule)
if rule[:proc]
"#{rule[:method]}_#{rule[:proc].call(request)}"
elsif rule[:path]
"#{ip(request)}_#{rule[:method]}_#{rule[:path]}"
elsif rule[:method]
"#{ip(request)}_#{rule[:method]}"
else
raise NotImplementedError
end
end
|
#default_limit ⇒ Object
25
26
27
|
# File 'lib/rack/throttle/rules.rb', line 25
def default_limit
@default_limit ||= options[:default] || 1_000_000_000
end
|
#ip(request) ⇒ Object
88
89
90
|
# File 'lib/rack/throttle/rules.rb', line 88
def ip(request)
request.ip.to_s
end
|
#ip_whitelisted?(request_ip) ⇒ Boolean
39
40
41
|
# File 'lib/rack/throttle/rules.rb', line 39
def ip_whitelisted?(request_ip)
!!ips.find { |ip| ip.include?(request_ip) }
end
|
#ips ⇒ Object
29
30
31
|
# File 'lib/rack/throttle/rules.rb', line 29
def ips
@ips ||= (options[:ip_whitelist] || []).map { |ip| IPAddr.new(ip) } || []
end
|
#max_per_window(request) ⇒ Object
63
64
65
66
|
# File 'lib/rack/throttle/rules.rb', line 63
def max_per_window(request)
rule = rule_for(request)
rule ? rule[:limit] : default_limit
end
|
#path_matches?(rule, path) ⇒ Boolean
57
58
59
60
61
|
# File 'lib/rack/throttle/rules.rb', line 57
def path_matches?(rule, path)
return true unless rule[:path]
return true if path.to_s.match(rule[:path])
false
end
|
#retry_after ⇒ Object
21
22
23
|
# File 'lib/rack/throttle/rules.rb', line 21
def retry_after
@min ||= (options[:min] || 3600)
end
|
#rule_for(request) ⇒ Object
48
49
50
51
52
53
54
55
|
# File 'lib/rack/throttle/rules.rb', line 48
def rule_for(request)
rules.find do |rule|
next unless rule[:method] == request.request_method.to_s
next if rule[:proc] && rule[:proc].call(request) == false
next if rule[:path] && !path_matches?(rule, request.path.to_s)
rule
end
end
|
#rule_whitelisted?(request) ⇒ Boolean
43
44
45
46
|
# File 'lib/rack/throttle/rules.rb', line 43
def rule_whitelisted?(request)
rule = rule_for(request)
rule ? rule[:whitelisted] : false
end
|
#rules ⇒ Object
14
15
16
17
18
19
|
# File 'lib/rack/throttle/rules.rb', line 14
def rules
@rules ||= begin
rs = options[:rules]
rs.sort_by { |r| [r[:proc].to_s, r[:path].to_s] }.reverse
end
end
|
#time_string ⇒ Object
96
97
98
99
100
101
102
103
104
|
# File 'lib/rack/throttle/rules.rb', line 96
def time_string
@time_string ||= case options[:time_window]
when :second then '%Y-%m-%dT%H:%M:%S'
when :minute then '%Y-%m-%dT%H:%M'
when :hour then '%Y-%m-%dT%H'
when :day then '%Y-%m-%d'
else '%Y-%m-%dT%H:%M:%S'
end
end
|
#whitelisted?(request) ⇒ Boolean
33
34
35
36
37
|
# File 'lib/rack/throttle/rules.rb', line 33
def whitelisted?(request)
return true if ip_whitelisted?(IPAddr.new(ip(request)))
return true if rule_whitelisted?(request)
false
end
|