如果我的应用程序的困惑用户意外地对运行 gevent 的“普通”flask 服务器(期望 HTTP 请求)进行 HTTPS 调用,我会收到一条日志消息,但我不知道如何删除,甚至添加额外的日志留言解释一下。
我认为异常不会到达Python代码,所以我无法捕获异常。
代码示例(只是一个普通的 Flask 服务器):
from flask import Flask
from gevent.pywsgi import WSGIServer
app = Flask(__name__)
@app.route("/")
def hello_world():
return "Hello, World!"
if __name__ == "__main__":
http_server = WSGIServer(("0.0.0.0", 8000), app)
http_server.serve_forever()
触发问题:
curl https://localhost:8000
日志输出(我想要摆脱的东西,或者至少能够添加一些上下文供我的用户理解):
<gevent._socket3.socket at 0x10272dbe0 object, fd=9, family=2, type=1, proto=0>: (from ('127.0.0.1', 63996)) Invalid HTTP method: "\x16\x03\x01\x01:\x01\x00\x016\x03\x035o;OÀ|¶\x9aã[3F\x81>?ÞB1f'ø×ÈùG\x0eAV\x9c\x1cÿ\x9f I+Hýò¶\x9aݽL\r{p\n"
{p" 400 - 0.0005314-05-17 08:09:57] ":65o;OÀ|¶ã[3F>?ÞB1f'ø×ÈùGAVÿò¶Ý½L
目标是接受连接而不执行任何操作。让用户收到 https 证书错误,但这应该会阻止您的服务器上的错误。
更改为:
https_server = WSGIServer(("0.0.0.0", 443), app, do_handshake_on_connect=False)
try:
https_server.start()
except as err:
# you may want to autoredirect to http here
pass
while True:
gevent_sleep(60)
更新:
from gevent.pywsgi import WSGIServer
def redirection_app(environ, start_response):
url = environ['HTTP_HOST'] + environ['PATH_INFO']
if environ.get('QUERY_STRING'):
url += '?' + environ['QUERY_STRING']
start_response('301 Moved Permanently', [('Location', 'https://' + url)])
return []
def https_enforcer(app):
def middleware(environ, start_response):
if environ['wsgi.url_scheme'] == 'https':
return redirection_app(environ, start_response)
return app(environ, start_response)
return middleware
def my_app(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [b"Hello world!"]
wrapped_app = https_enforcer(my_app)
WSGIServer(('', 8089), wrapped_app).serve_forever()