Python3环境下gevent WSGIServer无法正常处理HTTPS请求问题
问题原因
你看到的Invalid HTTP method: '\x16\x03\x01...'报错和编码无关,\x16\x03\x01是TLS握手阶段Client Hello报文的固定开头,说明服务端收到了HTTPS的加密流量,但是没有做SSL解密,直接把加密内容当成普通HTTP请求解析,才会把报文头识别为非法的HTTP方法。
你Python2版本HTTPS访问正常,Python3版本异常,大概率是升级后gevent版本迭代,SSL配置的传入方式发生了变化,原有配置失效导致。
修复方案
根据你的部署架构选择对应方案即可:
场景1:服务端直接处理HTTPS请求
需要给WSGIServer配置SSL上下文,代码示例如下:
import ssl import logging from gevent import pywsgi from geventwebsocket.handler import WebSocketHandler log = logging.getLogger(__name__) def apphandler(request, start_response): log.info("ATTENTION: request is {}".format(request)) # 原有业务逻辑保持不变 # 构造SSL上下文,加载证书和私钥 ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) # 替换为你实际的证书、私钥文件路径,如有私钥密码可以加password参数 ssl_ctx.load_cert_chain(certfile="./server.crt", keyfile="./server.key") # 初始化服务时传入ssl_context参数 server = pywsgi.WSGIServer(('', port), apphandler, handler_class=WebSocketHandler, ssl_context=ssl_ctx) server.serve_forever()
注意:适配Python3的新版本gevent不再推荐直接在WSGIServer初始化时传
certfile、keyfile参数,统一改用ssl_context传入SSL配置,原有Python2版本的单独传参方式会失效。
场景2:前端有Nginx等反向代理做SSL卸载
不需要修改服务代码,检查反向代理配置即可:确认代理侧已经完成HTTPS流量解密,将解密后的普通HTTP请求转发到你的WSGI服务端口,不要直接透传443端口的加密流量到服务端口。
额外说明
不需要调整Python3的全局编码设置,该问题和编码完全无关。
内容的提问来源于stack exchange,提问作者Erin L
相关产品推荐
相关产品推荐

