【问题标题】:Why don't current websocket client implementations support proxies?为什么当前的 websocket 客户端实现不支持代理?
【发布时间】:2011-01-13 03:58:45
【问题描述】:

Web Socket 检测代理服务器的存在并自动设置隧道以通过代理。通过向代理服务器发出 HTTP CONNECT 语句来建立隧道,该语句请求代理服务器打开到特定主机和端口的 TCP/IP 连接。一旦建立了隧道,通信就可以畅通无阻地通过代理。由于 HTTP/S 以类似的方式工作,因此 SSL 上的安全 Web 套接字可以利用相同的 HTTP CONNECT 技术。 [1]

好的,听起来很有用!但是,在我迄今为止看到的客户端实现(Go [2]、Java [3])中,我没有看到任何与代理检测相关的内容。

是我遗漏了什么还是这些实现还很年轻?我知道 WebSockets 是非常新的,客户端实现可能同样年轻和不成熟。我只是想知道我是否遗漏了有关代理检测和处理的内容。

[1]http://www.kaazing.org/confluence/display/KAAZING/What+is+an+HTML+5+WebSocket

[2]http://golang.org/src/pkg/websocket/client.go

[3]http://github.com/adamac/Java-WebSocket-client/raw/master/src/com/sixfire/websocket/WebSocket.java

【问题讨论】:

  • 他们没有?啊啊啊!我一直想知道为什么我的代码不起作用!浪费了一整个上午,但现在它似乎工作了,因为我删除了代理。感谢您提出这个问题!
  • @Tieme 证明问题与答案同样重要

标签: websocket


【解决方案1】:

在 WebSocket 协议进入场景时,通信通道已经建立。 WebSocket 建立在 TCP 和 HTTP 之上,因此您不必关心这些协议已经完成的事情,包括代理。

当建立 WebSocket 连接时,它总是以 HTTP/TCP 连接开始,该连接随后在 WebSocket 的“握手”阶段“升级”。此时隧道已建立,因此代理是透明的,无需关心它们。

【讨论】:

  • 那么http连接什么?
  • @z8000 HTTP CONNECT 建立 HTTP 连接。这是一个普通的 GET 请求,如果服务器支持 WebSochet 协议,稍后会升级。 WebSocket 协议使用 HTTP 来协商连接,并按照您的建议绕过代理。
  • 什么 HTTP 连接?不是什么IS HTTP CONNECT?根据维基百科:“另一种基于 HTTP 的隧道方法使用 HTTP CONNECT 方法/命令。客户端向 HTTP 代理发出 HTTP CONNECT 命令。然后代理与特定服务器建立 TCP 连接:端口,并在该端口之间中继数据服务器:端口和客户端连接。”我在通过 HTTP CONNECT 与代理通信的 WebSocket 客户端中看不到任何内容。以 libcurl 的 API 中的 CURLOPT_PROXY 为例。
【解决方案2】:

让我试着解释一下您可能遇到的不同成功率。虽然 HTML5 Web Socket 协议本身不知道代理服务器和防火墙,但它具有与 HTTP 兼容的握手功能,因此 HTTP 服务器可以与 Web Sockets 网关或服务器共享其默认的 HTTP 和 HTTPS 端口(80 和 443)。

Web Socket 协议定义了一个 ws:// 和 wss:// 前缀,分别表示一个 WebSocket 和一个 WebSocket 安全连接。两种方案都使用 HTTP 升级机制来升级到 Web Socket 协议。一些代理服务器是无害的,并且可以与 Web Socket 一起正常工作;其他将阻止 Web Sockets 正常工作,导致连接失败。在某些情况下,可能需要额外的代理服务器配置,并且某些代理服务器可能需要升级以支持 Web Sockets。

如果未加密的 WebSocket 流量在到达 WebSocket 服务器的途中流经显式或透明代理服务器,那么,无论代理服务器是否正常运行,连接几乎肯定会在今天失败(将来,代理服务器可能会支持 Web Socket)。因此,未加密的 WebSocket 连接应仅用于最简单的拓扑。

如果使用加密的 WebSocket 连接,则在 Web Sockets Secure 连接中使用传输层安全性 (TLS) 可确保在将浏览器配置为使用显式代理服务器时发出 HTTP CONNECT 命令。这会在 Web Sockets Secure 客户端和 WebSocket 服务器之间建立一个隧道,通过 HTTP 代理提供低级别的端到端 TCP 通信。在透明代理服务器的情况下,浏览器不知道代理服务器,因此不会发送 HTTP CONNECT。但是,由于有线流量是加密的,中间透明代理服务器可能会简单地允许加密流量通过,因此如果使用 Web Sockets Secure,WebSocket 连接成功的可能性会大得多。使用加密当然不是免费的,但通常可以提供最高的成功率。

查看它的一种方法是下载并安装 Kaazing WebSocket 网关——一个高度优化、代理感知的 WebSocket 网关,它提供原生 WebSocket 支持以及对旧浏览器标准的完整模拟。

【讨论】:

  • 对不起,我误解了你的问题——你是对的,那些客户端不支持代理。
  • 75% 的帖子是从维基百科文章中复制粘贴的。请了解如何使用块引号并引用您的来源。
  • 哎呀!我查看了维基百科文章的版本历史,发现你是贡献这些段落的人。我好尴尬。我很抱歉。 :-( 我正在回滚我的编辑。(我在这里,鞭打你没有引用你自己的工作,哈哈)
  • @PeterLubbers,回复“其他人会阻止 Web Sockets 正常工作,导致连接失败”;但是为什么?
  • @PeterLubbers,回复“今天肯定会失败”,但为什么会失败?
【解决方案3】:

答案是这些客户端根本不支持代理。 -奥卡姆

【讨论】:

  • 嗯,答案是指示了 HTTP CONNECT。一个 HTTP CONNECT 指示的连接看起来像一个到客户端的基本 TCP 连接,所以他在之后发送 Websocket 握手。他为一次 Websocket 握手发送了两个 HTTP 请求。一个用于代理,一个用于 websocket 服务器。
【解决方案4】:

关于 websocket 客户端和透明代理, 我认为 websocket 客户端连接大部分时间都会失败,原因如下(未测试):

  • 如果连接是明确的,由于客户端不知道它正在与http代理服务器通信,它不会发送将http代理变为tcp代理的“CONNECT TO”指令(需要websocket握手后的客户端)。如果代理支持本机 websocket 并且使用 ws 方案而不是 http 处理 URL,则它可以工作。

  • 如果连接是 SSL,透明代理无法知道它应该连接到哪个服务器,因为它已经解密了 https 请求中的主机名。它可以通过动态生成自签名证书(如 SSLStrip)或提供自己的静态证书并解密通信,但如果客户端验证服务器证书,它将失败(请参阅https://serverfault.com/questions/369829/setting-up-a-transparent-ssl-proxy)。

【讨论】:

    【解决方案5】:

    您提到了 Java 代理,作为回应,我想提一下 Java-Websocket 现在支持代理。

    您可以在此处查看相关信息:http://github.com/TooTallNate/Java-WebSocket/issues/88

    【讨论】:

      【解决方案6】:

      websocket-client,一个 Python 包,支持代理,至少在安全方案 wss:// 上,因为在这种情况下代理不需要知道它转发的流量。

      https://github.com/liris/websocket-client/commit/9f4cdb9ec982bfedb9270e883adab2e028bbd8e9

      【讨论】:

        猜你喜欢
        • 2021-03-15
        • 2014-09-30
        • 2015-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多