Nginx向Golang后端发送“连接:关闭”而不是“连接:升级”

时间:2019-06-20 20:14:23

标签: go nginx

我正在尝试使用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有选择地传递信息?

我应该从这里继续吗?

1 个答案:

答案 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";
}

本质上,将您的正则表达式放入命名变量中。我想。