【发布时间】:2019-06-21 23:45:21
【问题描述】:
我正在尝试使用 Nginx proxy_pass 一个 websocket,但我得到“502 Bad Gateway”,我的 Golang 后端响应:“websocket:客户端未使用 websocket 协议:找不到‘升级’令牌在“连接”标题中”。
Nginx 配置:
server {
listen 80;
server_name eg.example.com;
location / {
include proxy_params;
proxy_pass http://localhost:8000/;
}
location ~* /chatclientws/[\w\-]+ {
include proxy_params;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# Added a dummy header to see if Nginx is passing the request properly.
proxy_set_header Dummy "Test";
proxy_pass "http://localhost:8000/chatclientws/$1/";
}
}
代理参数:
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
Golang 函数中的httputil.DumpRequest() 用于路由产生:
GET /chatclientws/13c21679-45b0-424a-872f-aa012a9ee7a0 HTTP/1.0
Host: eg.example.com
# Connection says close.
Connection: close
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,en-GB;q=0.8
Cache-Control: no-cache
# Connection says close again.
Connection: close
Cookie: clientroom=13c21679-45b0-424a-872f-aa012a9ee7a0
Origin: eg.example.com
Pragma: no-cache
# But websocket request does come through.
Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits
Sec-Websocket-Key: ykQiDfJ2Tr2Z88WtnBQkAw==
Sec-Websocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
X-Forwarded-For: 92.54.215.31
X-Forwarded-Proto: http
X-Nginx-Proxy: true
X-Real-Ip: 92.54.215.31
不知何故,Nginx 正在传递除了正确的 Connection 标头之外的所有必要信息。
或者看起来是这样。如上所示,我添加了一个虚拟标头proxy_set_header Dummy "Test";,以查看 Nginx 是否真的将标头向下传递。虚拟标头永远无法通过。
在另一个具有相同 Nginx 配置但没有动态生成的路径名的页面上,虚拟标头和 websocket 连接运行良好。而且,如果我硬编码路径名而不是使用正则表达式,就像这样:
location /chatclientws/1a904868-608d-42b2-9e02-4d7d4f8cef19 {
...
proxy_pass "http://localhost:8000/chatclientws/1a904868-608d-42b2-9e02-4d7d4f8cef19";
}
有效。
所以,我相信我在这里错误地使用了正则表达式。但是我在网上看到的所有例子似乎都说我的使用是可以的。
我很困惑以及 websocket 升级请求是如何通过的。为什么 Nginx 会选择性地传递信息?
我应该如何从这里开始?
【问题讨论】: