Added config option to address instance behind reverse proxy

Config options now allow setting a "root url", which defaults to the
request url root. Saving a new url in this field will allow for proper
redirects and usage of the opensearch element.

Also provides a possible solution for #17, where the default flask redirect method redirects to
http instead of https.
このコミットが含まれているのは:
Ben Busby 2020-05-10 13:27:02 -06:00
コミット 7ccad2799e
4個のファイルの変更29行の追加20行の削除

ファイルの表示

@ -19,12 +19,17 @@ CONFIG_PATH = app.config['STATIC_FOLDER'] + '/config.json'
@app.before_request @app.before_request
def before_request_func(): def before_request_func():
g.user_request = Request(request.headers.get('User-Agent')) g.user_request = Request(request.headers.get('User-Agent'))
g.user_config = json.load(open(CONFIG_PATH)) if os.path.exists(CONFIG_PATH) else {} g.user_config = json.load(open(CONFIG_PATH)) if os.path.exists(CONFIG_PATH) else {'url': request.url_root}
if 'url' not in g.user_config or not g.user_config['url']:
g.user_config['url'] = request.url_root
g.app_location = g.user_config['url']
@app.errorhandler(404) @app.errorhandler(404)
def unknown_page(e): def unknown_page(e):
return redirect('/') return redirect(g.app_location)
@app.route('/', methods=['GET']) @app.route('/', methods=['GET'])
@ -35,11 +40,11 @@ def index():
@app.route('/opensearch.xml', methods=['GET']) @app.route('/opensearch.xml', methods=['GET'])
def opensearch(): def opensearch():
url_root = request.url_root opensearch_url = g.app_location
if url_root.endswith('/'): if opensearch_url.endswith('/'):
url_root = url_root[:-1] opensearch_url = opensearch_url[:-1]
template = render_template('opensearch.xml', main_url=url_root) template = render_template('opensearch.xml', main_url=opensearch_url)
response = make_response(template) response = make_response(template)
response.headers['Content-Type'] = 'application/xml' response.headers['Content-Type'] = 'application/xml'
return response return response
@ -78,11 +83,14 @@ def config():
return json.dumps(g.user_config) return json.dumps(g.user_config)
else: else:
config_data = request.form.to_dict() config_data = request.form.to_dict()
if 'url' not in config_data or not config_data['url']:
config_data['url'] = request.url_root
with open(app.config['STATIC_FOLDER'] + '/config.json', 'w') as config_file: with open(app.config['STATIC_FOLDER'] + '/config.json', 'w') as config_file:
config_file.write(json.dumps(config_data, indent=4)) config_file.write(json.dumps(config_data, indent=4))
config_file.close() config_file.close()
return redirect('/') return redirect(config_data['url'])
@app.route('/url', methods=['GET']) @app.route('/url', methods=['GET'])

ファイルの表示

@ -113,3 +113,7 @@ button::-moz-focus-inner {
-webkit-box-decoration-break: clone; -webkit-box-decoration-break: clone;
box-decoration-break: clone; box-decoration-break: clone;
} }
.hidden {
display: none;
}

ファイルの表示

@ -15,7 +15,7 @@ const setupSearchLayout = () => {
}); });
} }
const fillConfigValues = (near, nojs, dark) => { const fillConfigValues = (near, nojs, dark, url) => {
// Request existing config info // Request existing config info
let xhrGET = new XMLHttpRequest(); let xhrGET = new XMLHttpRequest();
xhrGET.open("GET", "/config"); xhrGET.open("GET", "/config");
@ -29,19 +29,11 @@ const fillConfigValues = (near, nojs, dark) => {
let configSettings = JSON.parse(xhrGET.responseText); let configSettings = JSON.parse(xhrGET.responseText);
near.value = configSettings["near"] ? configSettings["near"] : ""; near.value = configSettings["near"] ? configSettings["near"] : "";
near.addEventListener("keyup", function() {
configSettings["near"] = near.value;
});
nojs.checked = !!configSettings["nojs"]; nojs.checked = !!configSettings["nojs"];
nojs.addEventListener("change", function() {
configSettings["nojs"] = nojs.checked ? 1 : 0;
});
dark.checked = !!configSettings["dark"]; dark.checked = !!configSettings["dark"];
dark.addEventListener("change", function() {
configSettings["dark"] = dark.checked ? 1 : 0; // Addresses the issue of incorrect URL being used behind reverse proxy
}); url.value = configSettings["url"] ? configSettings["url"] : "";
}; };
xhrGET.send(); xhrGET.send();
@ -65,8 +57,9 @@ const setupConfigLayout = () => {
const near = document.getElementById("config-near"); const near = document.getElementById("config-near");
const noJS = document.getElementById("config-nojs"); const noJS = document.getElementById("config-nojs");
const dark = document.getElementById("config-dark"); const dark = document.getElementById("config-dark");
const url = document.getElementById("config-url");
fillConfigValues(near, noJS, dark); fillConfigValues(near, noJS, dark, url);
} }
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {

ファイルの表示

@ -53,6 +53,10 @@
<label for="config-dark">Dark Mode: </label> <label for="config-dark">Dark Mode: </label>
<input type="checkbox" name="dark" id="config-dark"> <input type="checkbox" name="dark" id="config-dark">
</div> </div>
<div class="config-div">
<label for="config-url">Root URL: </label>
<input type="text" name="url" id="config-url" value="">
</div>
<div class="config-div"> <div class="config-div">
<input type="submit" id="config-submit" value="Save"> <input type="submit" id="config-submit" value="Save">
</div> </div>