@@ -40,7 +40,7 @@ from datetime import datetime, timedelta
40from time import time
40from time import time
41from html import escape
41from html import escape
42from io import StringIO
42from io import StringIO
43−from urllib.parse import urlencode, urljoin, urlparse
43+from urllib.parse import urlencode, urlparse
45from pygments import highlight
45from pygments import highlight
46from pygments.lexers import get_lexer_by_name
46from pygments.lexers import get_lexer_by_name
@@ -270,14 +270,7 @@ def extract_domain(url):
272def get_base_url():
272def get_base_url():
273− if settings['server']['base_url']:
274− hostname = settings['server']['base_url']
277− if request.is_secure:
279− hostname = url_for('index', _external=True, _scheme=scheme)
273+ return url_for('index', _external=True)
283def get_current_theme_name(override=None):
276def get_current_theme_name(override=None):
@@ -310,10 +303,6 @@ def url_for_theme(endpoint, override_theme=None, **values):
310 if filename_with_theme in static_files:
303 if filename_with_theme in static_files:
311 values['filename'] = filename_with_theme
304 values['filename'] = filename_with_theme
312 url = url_for(endpoint, **values)
305 url = url_for(endpoint, **values)
313− if settings['server']['base_url']:
314− if url.startswith('/'):
316− url = urljoin(settings['server']['base_url'], url)
317 return url
306 return url
@@ -824,7 +813,7 @@ def preferences():
825 # save preferences
814 # save preferences
826 if request.method == 'POST':
815 if request.method == 'POST':
827− resp = make_response(redirect(urljoin(settings['server']['base_url'], url_for('index'))))
816+ resp = make_response(url_for('index', _external=True))
829 request.preferences.parse_form(request.form)
818 request.preferences.parse_form(request.form)
830 except ValidationException:
819 except ValidationException:
@@ -1013,11 +1002,11 @@ def opensearch():
1013 if request.headers.get('User-Agent', '').lower().find('webkit') >= 0:
1002 if request.headers.get('User-Agent', '').lower().find('webkit') >= 0:
1014 method = 'get'
1003 method = 'get'
1016− ret = render('opensearch.xml',
1006+ 'opensearch.xml',
1017− opensearch_method=method,
1007+ opensearch_method=method,
1018− host=get_base_url(),
1020− override_theme='__common__')
1008+ override_theme='__common__'
1022 resp = Response(response=ret,
1011 resp = Response(response=ret,
1023 status=200,
1012 status=200,
@@ -1038,7 +1027,7 @@ def favicon():
1039@app.route('/clear_cookies')
1028@app.route('/clear_cookies')
1040def clear_cookies():
1029def clear_cookies():
1041− resp = make_response(redirect(urljoin(settings['server']['base_url'], url_for('index'))))
1030+ resp = make_response(redirect(url_for('index', _external=True)))
1042 for cookie_name in request.cookies:
1031 for cookie_name in request.cookies:
1043 resp.delete_cookie(cookie_name)
1032 resp.delete_cookie(cookie_name)
1044 return resp
1033 return resp
@@ -1131,19 +1120,38 @@ class ReverseProxyPathFix:
1133 def __init__(self, app):
1122 def __init__(self, app):
1134 self.app = app
1124 self.app = app
1125+ self.script_name = None
1129+ if settings['server']['base_url']:
1131+ # If base_url is specified, then these values from are given
1132+ # preference over any Flask's generics.
1134+ base_url = urlparse(settings['server']['base_url'])
1135+ self.script_name = base_url.path
1136+ self.scheme = base_url.scheme
1137+ self.server = base_url.netloc
1136 def __call__(self, environ, start_response):
1139 def __call__(self, environ, start_response):
1137− script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
1141+ script_name = self.script_name or environ.get('HTTP_X_SCRIPT_NAME', '')
1138 if script_name:
1142 if script_name:
1139 environ['SCRIPT_NAME'] = script_name
1143 environ['SCRIPT_NAME'] = script_name
1140 path_info = environ['PATH_INFO']
1144 path_info = environ['PATH_INFO']
1141 if path_info.startswith(script_name):
1145 if path_info.startswith(script_name):
1142 environ['PATH_INFO'] = path_info[len(script_name):]
1146 environ['PATH_INFO'] = path_info[len(script_name):]
1144− scheme = environ.get('HTTP_X_SCHEME', '')
1148+ scheme = self.scheme or environ.get('HTTP_X_SCHEME', '')
1145 if scheme:
1149 if scheme:
1146 environ['wsgi.url_scheme'] = scheme
1150 environ['wsgi.url_scheme'] = scheme
1152+ server = self.server or environ.get('HTTP_X_FORWARDED_HOST', '')
1154+ environ['HTTP_HOST'] = server
1147 return self.app(environ, start_response)
1155 return self.app(environ, start_response)