如果我在不打算升级到 websocket 连接的 HTTP 请求中包含“Upgrade”和“Connection”标头,会发生什么情况?

Zac*_*ith 7 nginx websocket

我有一个 Nginx 服务器块,用于代理对 node.js 服务器的请求。该服务器同时提供 HTTP 内容和 WS (websocket) 内容。是否可以在不应升级到 Websocket 连接的请求上添加升级标头?

即使用 Nginx 代理到服务 HTTP 和 WS 的 Node.js 服务器,使用单独的服务器块是一个好习惯吗?

这是我目前的 Nginx 服务器块:

server {

  listen 443 ssl;
  listen [::]:443;
  server_name api.mysite.com;

  ssl_certificate ...;
  ssl_certificate_key ...;
  ssl_dhparam ...;
  ssl_protocols ...;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ...;

  location / {

    proxy_pass http://localhost:5000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $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-Host $server_name;
    proxy_set_header Access-Control-Allow-Origin *;
  }
}
Run Code Online (Sandbox Code Playgroud)

看起来我总是向代理到 Node.js 服务器的请求Upgrade添加Connection标头,即使我不想升级:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
Run Code Online (Sandbox Code Playgroud)

第一行看起来像是将“Upgrade”标头设置为从请求传递的 $http_upgrade。我假设如果请求中未传递此标头,则“Upgrade”将设置为null(或等效值),这将不起作用。那是对的吗?

pau*_*aul 8

我发现它在实践中也运行良好,尽管至少有一个用户遇到了问题。

这行:

proxy_set_header Upgrade $http_upgrade;
Run Code Online (Sandbox Code Playgroud)

实际上是在做你想做的事情,因为$http_upgrade来自客户端发送的标头。因此,如果客户端不请求升级,则不会被传递。

由于某种原因,似乎没有等效的$http_connection变量,但您可以使用 创建一个map,这是官方解决方案

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    ...

    location /chat/ {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}
Run Code Online (Sandbox Code Playgroud)