|
@@ -45,6 +45,16 @@ if sys.version_info[0] == 3:
|
|
|
logger = logger.getChild('search')
|
|
|
|
|
|
number_of_searches = 0
|
|
|
+max_request_timeout = settings.get('outgoing', {}).get('max_request_timeout' or None)
|
|
|
+if max_request_timeout is None:
|
|
|
+ logger.info('max_request_timeout={0}'.format(max_request_timeout))
|
|
|
+else:
|
|
|
+ if isinstance(max_request_timeout, float):
|
|
|
+ logger.info('max_request_timeout={0} second(s)'.format(max_request_timeout))
|
|
|
+ else:
|
|
|
+ logger.critical('outgoing.max_request_timeout if defined has to be float')
|
|
|
+ from sys import exit
|
|
|
+ exit(1)
|
|
|
|
|
|
|
|
|
def send_http_request(engine, request_params):
|
|
@@ -265,6 +275,15 @@ def get_search_query_from_webapp(preferences, form):
|
|
|
# query_engines
|
|
|
query_engines = raw_text_query.engines
|
|
|
|
|
|
+ # timeout_limit
|
|
|
+ query_timeout = raw_text_query.timeout_limit
|
|
|
+ if query_timeout is None and 'timeout_limit' in form:
|
|
|
+ raw_time_limit = form.get('timeout_limit')
|
|
|
+ try:
|
|
|
+ query_timeout = float(raw_time_limit)
|
|
|
+ except ValueError:
|
|
|
+ raise SearxParameterException('timeout_limit', raw_time_limit)
|
|
|
+
|
|
|
# query_categories
|
|
|
query_categories = []
|
|
|
|
|
@@ -338,7 +357,8 @@ def get_search_query_from_webapp(preferences, form):
|
|
|
query_engines = deduplicate_query_engines(query_engines)
|
|
|
|
|
|
return (SearchQuery(query, query_engines, query_categories,
|
|
|
- query_lang, query_safesearch, query_pageno, query_time_range),
|
|
|
+ query_lang, query_safesearch, query_pageno,
|
|
|
+ query_time_range, query_timeout),
|
|
|
raw_text_query)
|
|
|
|
|
|
|
|
@@ -351,6 +371,7 @@ class Search(object):
|
|
|
super(Search, self).__init__()
|
|
|
self.search_query = search_query
|
|
|
self.result_container = ResultContainer()
|
|
|
+ self.actual_timeout = None
|
|
|
|
|
|
# do search-request
|
|
|
def search(self):
|
|
@@ -380,7 +401,7 @@ class Search(object):
|
|
|
search_query = self.search_query
|
|
|
|
|
|
# max of all selected engine timeout
|
|
|
- timeout_limit = 0
|
|
|
+ default_timeout = 0
|
|
|
|
|
|
# start search-reqest for all selected engines
|
|
|
for selected_engine in search_query.engines:
|
|
@@ -420,12 +441,32 @@ class Search(object):
|
|
|
# append request to list
|
|
|
requests.append((selected_engine['name'], search_query.query, request_params))
|
|
|
|
|
|
- # update timeout_limit
|
|
|
- timeout_limit = max(timeout_limit, engine.timeout)
|
|
|
-
|
|
|
+ # update default_timeout
|
|
|
+ default_timeout = max(default_timeout, engine.timeout)
|
|
|
+
|
|
|
+ # adjust timeout
|
|
|
+ self.actual_timeout = default_timeout
|
|
|
+ query_timeout = self.search_query.timeout_limit
|
|
|
+
|
|
|
+ if max_request_timeout is None and query_timeout is None:
|
|
|
+ # No max, no user query: default_timeout
|
|
|
+ pass
|
|
|
+ elif max_request_timeout is None and query_timeout is not None:
|
|
|
+ # No max, but user query: From user query except if above default
|
|
|
+ self.actual_timeout = min(default_timeout, query_timeout)
|
|
|
+ elif max_request_timeout is not None and query_timeout is None:
|
|
|
+ # Max, no user query: Default except if above max
|
|
|
+ self.actual_timeout = min(default_timeout, max_request_timeout)
|
|
|
+ elif max_request_timeout is not None and query_timeout is not None:
|
|
|
+ # Max & user query: From user query except if above max
|
|
|
+ self.actual_timeout = min(query_timeout, max_request_timeout)
|
|
|
+
|
|
|
+ logger.debug("actual_timeout={0} (default_timeout={1}, ?timeout_limit={2}, max_request_timeout={3})"
|
|
|
+ .format(self.actual_timeout, default_timeout, query_timeout, max_request_timeout))
|
|
|
+
|
|
|
+ # send all search-request
|
|
|
if requests:
|
|
|
- # send all search-request
|
|
|
- search_multiple_requests(requests, self.result_container, start_time, timeout_limit)
|
|
|
+ search_multiple_requests(requests, self.result_container, start_time, self.actual_timeout)
|
|
|
start_new_thread(gc.collect, tuple())
|
|
|
|
|
|
# return results, suggestions, answers and infoboxes
|