我正在尝试使用Nginx proxy_pass
制作一个Websocket,但是却收到“ 502 Bad Gateway”,而我的Golang后端响应:“ websocket:客户端未使用websocket协议:'upgrade'令牌在“连接”标题中找不到”。
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_params:
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有选择地传递信息?
我应该从这里继续吗?
答案 0 :(得分:1)
在搜寻网并弄短后,我通过反复试验解决了这个问题。因此,这可能不是最专业的解决方案。无论如何,看起来我们不能像这样在Nginx中使用节节进行正则表达式:
location ~* /chatclientws/[\w\-]+ {
...
proxy_pass "http://localhost:8000/chatclientws/$1";
}
}
相反,请执行以下操作:
# Name your regex variable.
location ~* /chatclientws/(?<Your_Variable_Name>[\w\-]+) {
...
# Then reference it in your proxy_pass.
proxy_pass "http://localhost:8000/chatclientws/$Your_Variable_Name";
}
本质上,将您的正则表达式放入命名变量中。我想。