I'm trying to create a simple flask server that redirects any http requests to https. I've created a certificate and key file and registered a before_request
hook to see if the request is secure and redirect appropriately, following advise this SO answer.
The flask server responds to https requests as expected. However, when I send an http request, the before_request
hook never gets called and ther server hangs forever. If I send the http request from the browser, I see an "ERR_EMPTY_RESPONSE". The server doesn't even respond to https requests afterwards. No logs are printed either.
Running the app with gunicorn didn't help either. The only difference was that gunicorn is able to detect that the worker is frozen and eventually kills and replaces it. I've also tried using flask-talisman
, with the same results.
Below is the code I'm running
### server.py
from flask import Flask, request, redirect
def verify_https():
if not request.is_secure:
url = request.url.replace("http://", "https://", 1)
return redirect(url, 301)
def create_flask_app():
app = Flask(__name__)
app.before_request(verify_https)
app.add_url_rule('/', 'root', lambda: "Hello World")
return app
if __name__ == '__main__':
app = create_flask_app()
app.run(
host="0.0.0.0",
port=5000,
ssl_context=('server.crt', 'server.key')
)
Running it with either python3.8 server.py
or gunicorn --keyfile 'server.key' --certfile 'server.crt' --bind '0.0.0.0:5000' 'server:create_flask_app()'
and opening a browser window to localhost:5000
causes the server to hang.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt
, (2) run the script in the question,python server.py
, (3) observe that both browser (Chrome) andcurl -k https://localhost:5000
both work, (4) open localhost:5000 in browser (Chrome), and observe "This page isn't working". Now if you return to step (3) and try the https URL in curl or browser, there's no response and the server has hung. – Appropriatepython --version
→ Python 3.8.6 andpython -c 'import flask;print(flask.__version__)'
→ 2.1.2. – Appropriate