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



我有一个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 *;
}
}

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

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";

第一行看起来像是将请求传递的"Upgrade"标头设置为$http_Upgrade。我假设,如果请求中没有传递此标头,那么"Upgrade"将被设置为null(或等效值(,这将无效。这是正确的吗?

我发现它在实践中也很好用,尽管至少有一个用户对此有问题

此行:

proxy_set_header Upgrade $http_upgrade;

实际上是在做你想做的事情,因为$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;
}
}

什么都没发生。很好。我使用相同的nginx块来代理一个graphqlhttp端点和一个ws端点。

最新更新