websocket - 实现对 HTTP/2 代理的 websocket 支持

标签 websocket proxy http2

我正在开发一个 https http/2 代理服务器,如下所述: https://chromium.googlesource.com/chromium/src/+/HEAD/net/docs/proxy.md#HTTPS-proxy-scheme 那里提到

HTTPS proxies using HTTP/2 can offer better performance in Chrome than a regular HTTP proxy due to higher connection limits (HTTP/1.1 proxies in Chrome are limited to 32 simultaneous connections across all domains).

但是,当用户尝试通过原始 http 连接使用 websocket 浏览网站时,响应包含“升级”http header ,该 header 禁止在 http/2 中使用,因为 HTTP/2 没有 websocket。 https://daniel.haxx.se/blog/2016/06/15/no-websockets-over-http2/#:~:text=There%20is%20no%20websockets%20for%20HTTP%2F2.&text=That%20spec%20details%20how%20a,connection%20into%20a%20websockets%20connection. 问题在于,当 http1.1 流量通过实现 http/2 的 https 代理时, header 必须从 http1.1 传输到 http/2。当然,当网页使用 TLS 时,就不存在这样的问题,因为所有流量都通过 http“CONNECT”方法建立的连接。当网站不使用 TLS 时会出现此问题。 如果这个问题没有解决方案,就意味着HTTPS代理不应该实现HTTP/2协议(protocol)。

最佳答案

As there is no websockets for HTTP/2

您发布的链接是旧的,从那时起,通过 HTTP/2 的 WebSocket 已由 RFC 8441 指定。 .

HTTP/2 代理的行为在RFC 7540, section 8.3 中指定。 .

当客户端使用安全 HTTP/2 与代理通信时,每个 HTTP/2 流都是通往服务器的“隧道”。

客户端和代理使用安全的 HTTP/2 进行通信,并且“隧道”的发生是因为每个 HTTP/2 流都成为具有“无限”响应的“无限”请求,即 HTTP/2 的“无限”系列 携带不透明字节数组有效负载的双向数据帧。

代理的工作是解开客户端收到的DATA帧,并将字节数组有效负载转发到服务器,也许将其重新包装成HTTP/2 DATA 框架,如果代理和服务器之间的通信也是 HTTP/2(可能可以优化解包和重新包装,但这可能很棘手 - 例如流编号可能不同)。 p>

当客户端尝试通过 HTTP/2 执行 WebSocket 时,浏览器将按照 RFC 8441 的指定执行操作,并且代理将收到带有 :protocolCONNECT 请求> 伪 header ,代理必须知道在这种情况下要做什么,具体取决于它使用什么协议(protocol)与服务器通信。

上面描述了当与客户端的通信是 HTTP/2 时,您的代理需要支持什么。

如果您的代理需要支持使用 HTTP/1.1 的客户端,那么您需要实现代理支持 HTTP/1.1 和 WebSocket 代理所需的功能,这通常并不困难:第一个只是 HTTP/1.1 转发或 HTTP CONNECT“隧道”,第二个是 WebSocket HTTP 升级请求转发,然后是“隧道”连接,甚至是成熟的 WebSocket 代理。

免责声明,我已在 Jetty Project 中实现了上述所有内容。 您可以使用 Jetty 10 或更高版本来实现 HTTP/1.1、HTTP/2 或 WebSocket、客户端和服务器(因此也是代理)。还支持基于 HTTP/2 的 WebSocket。

最后,为了回答你的最后一个问题,即使存在 WebSocket,安全代理也完全有可能支持 HTTP/2。

例如,与服务器的明文 WebSocket 连接以 HTTP 升级请求开始;该请求将被加密发送到代理,代理将解密并将其转发到服务器(使用服务器支持的任何协议(protocol)——甚至可以是基于安全 HTTP/2 的 WebSocket);服务器将回复 101 并将连接升级到 WebSocket;代理将从服务器接收 101 并升级到“隧道”或 WebSocket 代理;代理加密101响应并将其转发给客户端;客户端对其进行解密并将连接升级到 WebSocket。 此时,客户端正在通过与代理的安全连接与服务器进行明文 WebSocket 通信(代理看到明文 WebSocket 通信)。

反之亦然,与服务器的安全 WebSocket 连接首先通过代理与服务器建立 HTTP CONNECT 隧道;然后客户端将与服务器建立安全通信;然后它将把 HTTP 升级到 WebSocket 发送到服务器(通过代理隧道)。 此时,客户端正在通过与代理的安全连接与服务器进行安全的 WebSocket 通信(代理无法看到 WebSocket 通信)。

HTTP/2 变体是类似的,只是考虑到 HTTP/2 的“隧道”和传输 WebSocket 的特定方式。

关于websocket - 实现对 HTTP/2 代理的 websocket 支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65129151/

相关文章:

windows - 适用于 Windows 的最佳白名单功能 http 代理?

apache - 在 EV SSL 上使用 3 个域进行错误的重定向

ios - iOS 10 中的 HTTP/2 服务器推送

javascript - 扩展如何监听 WebSocket? (如果 WebSocket 在 iframe 中怎么办?)

symfony2 在 Amazon ELB : always trust proxy data? 后面

linux - 通过代理ssh错误使用Docker

google-chrome - 我们应该在 HTTP/2 中复用多少并发请求

html - websocket 消息可以乱序到达吗?

asp.net-core - 多个 SignalR(websocket)连接与具有多个集线器的单个连接

android - 由于空指针异常导致 Firebase 崩溃