Hi,
I've recently experienced an issue when I wanted to enforce HTTPS traffic for my Wikinity tool.
Reason
My new Wikinity tool (https://tools.wmflabs.org/wikinity) includes another page over HTTPS by JavaScript. But when it get loaded over HTTP the browser complains about "No 'Access-Control-Allow-Origin' header is present on the requested resource" (http://tools.wmflabs.org is another origin than https://tools.wmflabs.org) and do not work. The only one solution I've found out are to send Access-Control-Allow-Origin header from the included page but I think loading over HTTPS is better as it protect the traffic over manipulating on the way to the user.
There could be scope to enforce HTTPS for all tools (which can and will break some tools which are including some HTTP page, when this tool will be loaded using HTTPS stuff breaks) but at least, tool maintainers should have ability to enforce HTTPS for their tool.
Thank you in advance,
Martin Urbanec
Answer
Check the X-Forwarded-Proto HTTP request header that your application will receive in each request. This header is added by the nginx proxy that figures out where to send requests for your tool's path. If the value of that header is http then send a redirect to the browser telling it to use https.
Check and redirect in PHP
if ( $_SERVER["HTTP_X_FORWARDED_PROTO"] === "http" ) { header( "Location: https://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}" ); return; }
Check and redirect in Python Flask
@app.before_request def force_https(): if request.headers.get('X-Forwarded-Proto') == 'http': return redirect( 'https://' + request.headers['Host'] + request.headers['X-Original-URI'], code=301 )