【发布时间】:2014-09-08 03:23:51
【问题描述】:
我有一个旧的龙卷风服务器来处理普通的 WebSocket 连接。我通过 Nginx 代理这些连接,从 wss://info.mydomain.com 到 wss://mydomain.com:8080,以绕过阻止非标准端口的客户代理。
在最近升级到 Tornado 4.0 后,所有连接都被拒绝并出现 403。是什么导致了这个问题,我该如何解决?
【问题讨论】:
我有一个旧的龙卷风服务器来处理普通的 WebSocket 连接。我通过 Nginx 代理这些连接,从 wss://info.mydomain.com 到 wss://mydomain.com:8080,以绕过阻止非标准端口的客户代理。
在最近升级到 Tornado 4.0 后,所有连接都被拒绝并出现 403。是什么导致了这个问题,我该如何解决?
【问题讨论】:
我想提出替代解决方案,而不是弄乱tornado应用程序代码,我通过告诉nginx修复主机头来解决了这个问题:
location /ws {
proxy_set_header Host $host;
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
【讨论】:
Tornado 4.0 在默认情况下引入了同源检查。这会检查浏览器设置的源头是否与主机头相同
def check_origin(self, origin):
"""Override to enable support for allowing alternate origins.
The ``origin`` argument is the value of the ``Origin`` HTTP header,
the url responsible for initiating this request.
.. versionadded:: 4.0
"""
parsed_origin = urlparse(origin)
origin = parsed_origin.netloc
origin = origin.lower()
host = self.request.headers.get("Host")
# Check to see that origin matches host directly, including ports
return origin == host
为了让您的代理 websocket 连接仍然有效,您需要覆盖 WebSocketHandler 上的检查源并将您关心的域列入白名单。像这样的东西。
import re
from tornado import websocket
class YouConnection(websocket.WebSocketHandler):
def check_origin(self, origin):
return bool(re.match(r'^.*?\.mydomain\.com', origin))
这将使来自info.mydomain.com 的连接像以前一样通过。
【讨论】: