@@ -32,7 +32,8 @@ from searx.utils import gen_useragent
3232from searx.results import ResultContainer
3333from searx import logger
3434from searx.plugins import plugins
35−from searx.exceptions import SearxEngineCaptchaException
35+from searx.exceptions import (SearxEngineAccessDeniedException, SearxEngineCaptchaException,
36+ SearxEngineTooManyRequestsException,)
3637from searx.metrology.error_recorder import record_exception, record_error
3738
3839
@@ -131,6 +132,9 @@ def send_http_request(engine, request_params):
131132 # soft_max_redirects
132133 soft_max_redirects = request_params.get('soft_max_redirects', max_redirects or 0)
133134
135+ # raise_for_status
136+ request_args['raise_for_httperror'] = request_params.get('raise_for_httperror', False)
137+
134138 # specific type of request (GET or POST)
135139 if request_params['method'] == 'GET':
136140 req = requests_lib.get
@@ -142,10 +146,6 @@ def send_http_request(engine, request_params):
142146 # send the request
143147 response = req(request_params['url'], **request_args)
144148
145− # check HTTP status
146− if request_params.get('raise_for_status'):
147− response.raise_for_status()
148−
149149 # check soft limit of the redirect count
150150 if len(response.history) > soft_max_redirects:
151151 # unexpected redirect : record an error
@@ -191,6 +191,7 @@ def search_one_http_request_safe(engine_name, query, request_params, result_cont
191191
192192 # suppose everything will be alright
193193 requests_exception = False
194+ suspended_time = None
194195
195196 try:
196197 # send requests and parse the results
@@ -240,6 +241,15 @@ def search_one_http_request_safe(engine_name, query, request_params, result_cont
240241 elif (issubclass(e.__class__, SearxEngineCaptchaException)):
241242 result_container.add_unresponsive_engine(engine_name, 'CAPTCHA required')
242243 logger.exception('engine {0} : CAPTCHA')
244+ suspended_time = e.suspended_time # pylint: disable=no-member
245+ elif (issubclass(e.__class__, SearxEngineTooManyRequestsException)):
246+ result_container.add_unresponsive_engine(engine_name, 'too many requests')
247+ logger.exception('engine {0} : Too many requests')
248+ suspended_time = e.suspended_time # pylint: disable=no-member
249+ elif (issubclass(e.__class__, SearxEngineAccessDeniedException)):
250+ result_container.add_unresponsive_engine(engine_name, 'blocked')
251+ logger.exception('engine {0} : Searx is blocked')
252+ suspended_time = e.suspended_time # pylint: disable=no-member
243253 else:
244254 result_container.add_unresponsive_engine(engine_name, 'unexpected crash')
245255 # others errors
@@ -248,16 +258,18 @@ def search_one_http_request_safe(engine_name, query, request_params, result_cont
248258 if getattr(threading.current_thread(), '_timeout', False):
249259 record_error(engine_name, 'Timeout')
250260
251− # suspend or not the engine if there are HTTP errors
261+ # suspend the engine if there is an HTTP error
262+ # or suspended_time is defined
252263 with threading.RLock():
253− if requests_exception:
264+ if requests_exception or suspended_time:
254265 # update continuous_errors / suspend_end_time
255266 engine.continuous_errors += 1
256− engine.suspend_end_time = time() + min(settings['search']['max_ban_time_on_fail'],
257− engine.continuous_errors * settings['search']['ban_time_on_fail'])
267+ if suspended_time is None:
268+ suspended_time = min(settings['search']['max_ban_time_on_fail'],
269+ engine.continuous_errors * settings['search']['ban_time_on_fail'])
270+ engine.suspend_end_time = time() + suspended_time
258271 else:
259− # no HTTP error (perhaps an engine error)
260− # anyway, reset the suspend variables
272+ # reset the suspend variables
261273 engine.continuous_errors = 0
262274 engine.suspend_end_time = 0
263275
@@ -342,7 +354,7 @@ def default_request_params():
342354 'cookies': {},
343355 'verify': True,
344356 'auth': None,
345− 'raise_for_status': True
357+ 'raise_for_httperror': True
346358 }
347359
348360