@@ -14,6 +14,7 @@ class Error < StandardError; end
1414 class MisconfiguredStoreError < Error ; end
1515 class MissingStoreError < Error ; end
1616
17+ autoload :Configuration , 'rack/attack/configuration'
1718 autoload :Cache , 'rack/attack/cache'
1819 autoload :Check , 'rack/attack/check'
1920 autoload :Throttle , 'rack/attack/throttle'
@@ -31,82 +32,8 @@ class MissingStoreError < Error; end
3132 autoload :Allow2Ban , 'rack/attack/allow2ban'
3233
3334 class << self
34- attr_accessor :enabled , :notifier , :blocklisted_response , :throttled_response ,
35- :anonymous_blocklists , :anonymous_safelists
36-
37- def safelist ( name = nil , &block )
38- safelist = Safelist . new ( name , &block )
39-
40- if name
41- safelists [ name ] = safelist
42- else
43- anonymous_safelists << safelist
44- end
45- end
46-
47- def blocklist ( name = nil , &block )
48- blocklist = Blocklist . new ( name , &block )
49-
50- if name
51- blocklists [ name ] = blocklist
52- else
53- anonymous_blocklists << blocklist
54- end
55- end
56-
57- def blocklist_ip ( ip_address )
58- anonymous_blocklists << Blocklist . new { |request | IPAddr . new ( ip_address ) . include? ( IPAddr . new ( request . ip ) ) }
59- end
60-
61- def safelist_ip ( ip_address )
62- anonymous_safelists << Safelist . new { |request | IPAddr . new ( ip_address ) . include? ( IPAddr . new ( request . ip ) ) }
63- end
64-
65- def throttle ( name , options , &block )
66- throttles [ name ] = Throttle . new ( name , options , &block )
67- end
68-
69- def track ( name , options = { } , &block )
70- tracks [ name ] = Track . new ( name , options , &block )
71- end
72-
73- def safelists
74- @safelists ||= { }
75- end
76-
77- def blocklists
78- @blocklists ||= { }
79- end
80-
81- def throttles
82- @throttles ||= { }
83- end
84-
85- def tracks
86- @tracks ||= { }
87- end
88-
89- def safelisted? ( request )
90- anonymous_safelists . any? { |safelist | safelist . matched_by? ( request ) } ||
91- safelists . any? { |_name , safelist | safelist . matched_by? ( request ) }
92- end
93-
94- def blocklisted? ( request )
95- anonymous_blocklists . any? { |blocklist | blocklist . matched_by? ( request ) } ||
96- blocklists . any? { |_name , blocklist | blocklist . matched_by? ( request ) }
97- end
98-
99- def throttled? ( request )
100- throttles . any? do |_name , throttle |
101- throttle . matched_by? ( request )
102- end
103- end
104-
105- def tracked? ( request )
106- tracks . each_value do |track |
107- track . matched_by? ( request )
108- end
109- end
35+ attr_accessor :enabled , :notifier
36+ attr_reader :config
11037
11138 def instrument ( request )
11239 if notifier
@@ -122,34 +49,31 @@ def cache
12249 @cache ||= Cache . new
12350 end
12451
125- def clear_configuration
126- @safelists = { }
127- @blocklists = { }
128- @throttles = { }
129- @tracks = { }
130- self . anonymous_blocklists = [ ]
131- self . anonymous_safelists = [ ]
132- end
133-
13452 def clear!
13553 warn "[DEPRECATION] Rack::Attack.clear! is deprecated. Please use Rack::Attack.clear_configuration instead"
136- clear_configuration
54+ @config . clear_configuration
13755 end
56+
57+ extend Forwardable
58+ def_delegators :@config , :safelist , :blocklist , :blocklist_ip , :safelist_ip , :throttle , :track ,
59+ :blocklisted_response , :blocklisted_response= , :throttled_response , :throttled_response= ,
60+ :clear_configuration , :safelists , :blocklists , :throttles , :tracks
13861 end
13962
14063 # Set defaults
14164 @enabled = true
142- @anonymous_blocklists = [ ]
143- @anonymous_safelists = [ ]
14465 @notifier = ActiveSupport ::Notifications if defined? ( ActiveSupport ::Notifications )
145- @blocklisted_response = lambda { |_env | [ 403 , { 'Content-Type' => 'text/plain' } , [ "Forbidden\n " ] ] }
146- @throttled_response = lambda do |env |
147- retry_after = ( env [ 'rack.attack.match_data' ] || { } ) [ :period ]
148- [ 429 , { 'Content-Type' => 'text/plain' , 'Retry-After' => retry_after . to_s } , [ "Retry later\n " ] ]
149- end
66+ @config = Configuration . new
15067
151- def initialize ( app )
68+ def initialize ( app , & config_block )
15269 @app = app
70+ @config =
71+ if block_given?
72+ config = Configuration . new
73+ config . instance_exec ( &config_block )
74+ else
75+ self . class . config
76+ end
15377 end
15478
15579 def call ( env )
@@ -158,19 +82,16 @@ def call(env)
15882 env [ 'PATH_INFO' ] = PathNormalizer . normalize_path ( env [ 'PATH_INFO' ] )
15983 request = Rack ::Attack ::Request . new ( env )
16084
161- if safelisted? ( request )
85+ if @config . safelisted? ( request )
16286 @app . call ( env )
163- elsif blocklisted? ( request )
164- self . class . blocklisted_response . call ( env )
165- elsif throttled? ( request )
166- self . class . throttled_response . call ( env )
87+ elsif @config . blocklisted? ( request )
88+ @config . blocklisted_response . call ( env )
89+ elsif @config . throttled? ( request )
90+ @config . throttled_response . call ( env )
16791 else
168- tracked? ( request )
92+ @config . tracked? ( request )
16993 @app . call ( env )
17094 end
17195 end
172-
173- extend Forwardable
174- def_delegators self , :safelisted? , :blocklisted? , :throttled? , :tracked?
17596 end
17697end
0 commit comments