带有 ssl_context 的 Flask 服务器如果收到 http 请求就会冻结

Cno*_*171 8 python https flask gunicorn

我正在尝试创建一个简单的 Flask 服务器,将任何 http 请求重定向到 https。我已经创建了一个证书和密钥文件,并注册了一个before_request钩子来查看请求是否安全并适当重定向,遵循建议此 SO 答案

Flask 服务器按预期响应 https 请求。但是,当我发送 http 请求时,挂钩before_request永远不会被调用,并且服务器永远挂起。如果我从浏览器发送 http 请求,我会看到“ERR_EMPTY_RESPONSE”。之后服务器甚至不响应 https 请求。也没有打印任何日志。

使用 Gunicorn 运行应用程序也没有帮助。唯一的区别是,gunicorn 能够检测到工人被冻结并最终杀死并取代它。我也尝试过使用flask-talisman, 得到相同的结果。

下面是我正在运行的代码

### 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')
    )
Run Code Online (Sandbox Code Playgroud)

python3.8 server.py使用或运行它gunicorn --keyfile 'server.key' --certfile 'server.crt' --bind '0.0.0.0:5000' 'server:create_flask_app()'并打开浏览器窗口会localhost:5000导致服务器挂起。

CSE*_*erd 1

通常,服务器不会在同一端口上同时侦听 http 和 https。我对我的个人作品集有类似的要求,但我使用 nginx 将 http 请求(端口 80)转发到 https(端口 443),然后 https 服务器将其传递到我的 uwsgi 后端,该后端侦听端口 3031。这可能更多比您需要的复杂,但是是一个可能的解决方案。如果您选择这条路线,我会建议您使用 LetEncrypt 来满足您的证书需求。它将为您设置证书和 nginx.conf。

如果您不想走完整的 nginx/apache 路线,我认为您最简单的解决方案是在您链接的同一线程上建议的解决方案