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
浙公網安備 33010602011771號