websocket + 代理请求失败,返回400

场景

业务服务提供了 websocket 服务,基于 websocket 来实现报表数据的推送,客户在浏览器上查看报表,经过 http 代理将请求传递给后端服务。

问题

客户在浏览器上查看报表数据时,报表功能异常,浏览器开发工具查看到 websocket 握手在服务端拒绝掉,返回 400 bad request。

分析

400 一般是由于客户端,所以应该是客户端请求参数或者路出现问题。通过对比正常和异常的websocket 请求报文,得到,异常的报文缺少了 Upgrade:websocket 的 http 头部。
Upgrade 属于 hop-to-hop 类型的 http cache ,与 end-to-end 不同,后者在两个客户端请求至最终后端服务时都不会变,如 User-Agent,而前者则会在经过代理时被处理掉,需要 proxy 的能力再将这类 hop-to-hop header 处理下。

解决方案

nginx 有如下解决方案,在 http 请求头里把 Upgrade 补上去,前提是在代理到后端之前的报文有 Upgrade。

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

参考

关于Nginx+websocket 400问题 https://www.jianshu.com/p/d5b136a27bdf
End-to-end and Hop-by-hop Headers https://tools.ietf.org/html/rfc2616#section-13.5.1

原文地址:https://www.cnblogs.com/haoqingchuan/p/9567082.html