@@ -94,7 +94,7 @@ from searx.plugins import plugins
94from searx.plugins.oa_doi_rewrite import get_doi_resolver
94from searx.plugins.oa_doi_rewrite import get_doi_resolver
95from searx.preferences import Preferences, ValidationException, LANGUAGE_CODES
95from searx.preferences import Preferences, ValidationException, LANGUAGE_CODES
96from searx.answerers import answerers
96from searx.answerers import answerers
97−from searx.network import stream as http_stream
97+from searx.network import stream as http_stream, set_context_network_name
98from searx.answerers import ask
98from searx.answerers import ask
99from searx.metrology.error_recorder import errors_per_engines
99from searx.metrology.error_recorder import errors_per_engines
100from searx.settings_loader import get_default_settings_path
100from searx.settings_loader import get_default_settings_path
@@ -921,6 +921,8 @@ def _is_selected_language_supported(engine, preferences):
922@app.route('/image_proxy', methods=['GET'])
922@app.route('/image_proxy', methods=['GET'])
923def image_proxy():
923def image_proxy():
924+ # pylint: disable=too-many-return-statements, too-many-branches
924 url = request.args.get('url')
926 url = request.args.get('url')
926 if not url:
928 if not url:
@@ -932,14 +934,21 @@ def image_proxy():
932 return '', 400
934 return '', 400
934 maximum_size = 5 * 1024 * 1024
936 maximum_size = 5 * 1024 * 1024
935−
937+ forward_resp = False
937− headers = dict_subset(request.headers, {'If-Modified-Since', 'If-None-Match'})
940+ request_headers = {
938− headers['User-Agent'] = gen_useragent()
941+ 'User-Agent': gen_useragent(),
942+ 'Accept': 'image/webp,*/*',
943+ 'Accept-Encoding': 'gzip, deflate',
947+ set_context_network_name('image_proxy')
939 stream = http_stream(
948 stream = http_stream(
940 method='GET',
949 method='GET',
942− headers=headers,
951+ headers=request_headers,
943 timeout=settings['outgoing']['request_timeout'],
952 timeout=settings['outgoing']['request_timeout'],
944 follow_redirects=True,
953 follow_redirects=True,
945 max_redirects=20)
954 max_redirects=20)
@@ -949,25 +958,37 @@ def image_proxy():
949 if content_length and content_length.isdigit() and int(content_length) > maximum_size:
958 if content_length and content_length.isdigit() and int(content_length) > maximum_size:
950 return 'Max size', 400
959 return 'Max size', 400
952− if resp.status_code == 304:
953− return '', resp.status_code
955 if resp.status_code != 200:
961 if resp.status_code != 200:
956 logger.debug('image-proxy: wrong response code: {0}'.format(resp.status_code))
962 logger.debug('image-proxy: wrong response code: {0}'.format(resp.status_code))
957 if resp.status_code >= 400:
963 if resp.status_code >= 400:
958 return '', resp.status_code
964 return '', resp.status_code
959 return '', 400
965 return '', 400
961− if not resp.headers.get('content-type', '').startswith('image/'):
967+ if not resp.headers.get('Content-Type', '').startswith('image/'):
962− logger.debug('image-proxy: wrong content-type: {0}'.format(resp.headers.get('content-type')))
968+ logger.debug('image-proxy: wrong content-type: %s', resp.headers.get('Content-Type', ''))
963 return '', 400
969 return '', 400
965− headers = dict_subset(resp.headers, {'Content-Length', 'Length', 'Date', 'Last-Modified', 'Expires', 'Etag'})
971+ forward_resp = True
972+ except httpx.HTTPError:
973+ logger.exception('HTTP error')
976+ if resp and not forward_resp:
977+ # the code is about to return an HTTP 400 error to the browser
978+ # we make sure to close the response between searxng and the HTTP server
981+ except httpx.HTTPError:
982+ logger.exception('HTTP error on closing')
967− total_length = 0
984+ try:
985+ headers = dict_subset(
987+ {'Content-Type', 'Content-Encoding', 'Content-Length', 'Length'}
969 def forward_chunk():
990 def forward_chunk():
970− nonlocal total_length
991+ total_length = 0
971 for chunk in stream:
992 for chunk in stream:
972 total_length += len(chunk)
993 total_length += len(chunk)
973 if total_length > maximum_size:
994 if total_length > maximum_size:
@@ -1148,6 +1169,13 @@ def run():
1172+def patch_application(app):
1173+ # serve pages with HTTP/1.1
1174+ WSGIRequestHandler.protocol_version = "HTTP/{}".format(settings['server']['http_protocol_version'])
1175+ # patch app to handle non root url-s behind proxy & wsgi
1176+ app.wsgi_app = ReverseProxyPathFix(ProxyFix(app.wsgi_app))
1151class ReverseProxyPathFix:
1179class ReverseProxyPathFix:
1152 '''Wrap the application in this middleware and configure the
1180 '''Wrap the application in this middleware and configure the
1153 front-end server to add these headers, to let you quietly bind
1181 front-end server to add these headers, to let you quietly bind