使铬使用 CONNECT 进行 websockets

Posted

技术标签:

【中文标题】使铬使用 CONNECT 进行 websockets【英文标题】:make chromium use CONNECT for websockets 【发布时间】:2015-08-11 07:20:18 【问题描述】:

在工作中,IT 引入了一种基于 squid 的新代理解决方案。 It should support websockets if the client uses connect:

Squid 本身不支持 WebSockets。但是,如果客户端 软件正确使用 CONNECT 应该可以 鱿鱼-3.4.5。

使用 chomiums DevTools(在 SO 上),我可以看到从 HTTPS 连接升级到 wss 连接的握手过程。这不起作用(见下图)。问题似乎是铬使用GET 而不是CONNECT

我还看到服务器响应有Connection: keep-alive 而不是Upgrade,这是我所期望的。因此页面底部的错误。

问题:如何配置 chromium 以使用 CONNECT 而不是 GET

旁注:这与this post on meta.se 有关。 FF 弹出一大堆代理身份验证请求,但仍然失败。

【问题讨论】:

【参考方案1】:

正如您在RFC6455 文档中看到的那样,请求应该是一个 GET 请求:

打开握手旨在与基于 HTTP 的服务器端软件和中介兼容,以便 HTTP 客户端与该服务器通信和 WebSocket 客户端与该服务器通信都可以使用单个端口。为此,WebSocket 客户端的握手是一个 HTTP 升级请求:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

... GET 方法的“Request-URI” [RFC2616] 用于标识 WebSocket 连接的端点,既允许从一个 IP 地址提供多个域,也允许多个 WebSocket 端点由单个服务器提供服务。

在different section 中声明:

客户端的打开握手由以下部分组成。如果服务器在读取握手时发现客户端没有发送符合以下描述的握手(请注意,根据 [RFC2616],标头字段的顺序并不重要),包括但不限于任何违规行为根据为握手组件指定的 ABNF 语法,服务器必须停止处理客户端的握手并返回带有适当错误代码(例如 400 Bad Request)的 HTTP 响应。

    HTTP/1.1 或更高版本的GET 请求,包括“Request-URI” [RFC2616] 应该被解释为 /resource name/ 在第 3 节中定义(或绝对 HTTP/HTTPS URI 包含 /资源名称/)。

所以...嗯....使用 CONNECT 请求实际上是问题,而不是解决方案...

我会努力推动 squid 正确评估 Websocket 请求或猴子修补 squid 的解决方法,而不是尝试强制 chomiums 使用可能被其他 Websocket 服务器拒绝的非标准请求。

【讨论】:

好的,所以根本问题很可能是服务器响应不包含Connection: UpgradeUpgrade: websocket...在我的情况下很可能是因为代理...【参考方案2】:

正如 Myst 所说,WebSockets 使用 GET。

尝试使用 WSS://,您可能会得到它的工作,因为代理不能干扰安全连接。

http://www.infoq.com/articles/Web-Sockets-Proxy-Servers

【讨论】:

请求已经使用了 wss://,但是我们的代理做了 MITM,我不确定它不会触及数据...

以上是关于使铬使用 CONNECT 进行 websockets的主要内容,如果未能解决你的问题,请参考以下文章

Spring Websocket ChannelInterceptor 未触发 CONNECT 事件

在 websocket 服务器中处理 CONNECT 请求

Django Channels - 握手和连接,但未执行 websocket.connect 函数

无法使用 Vue 插件连接到 WebSocket

AWS WebSocket API 网关必须对 $connect、$disconnect 和 $default 具有相同的集成?

python ssl wrap_socket connect faied到一个安全的websocket服务