【问题标题】:Nginx sending "Connection: close" instead of "Connection: upgrade" to Golang back endNginx 向 Golang 后端发送“连接:关闭”而不是“连接:升级”
【发布时间】: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 会选择性地传递信息?

我应该如何从这里开始?

【问题讨论】:

    标签: go nginx


    【解决方案1】:

    在网上搜索并出现不足后,我通过反复试验解决了这个问题。所以,这可能不是最专业的解决方案。无论如何,看起来我们不能像这样在 Nginx 中使用 location 节进行正则表达式:

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

    本质上,将您的正则表达式转换为命名变量。我猜。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多