25

nginx 现在支持代理 websockets,但是如果没有单独的location块适用于使用 websockets 的 URI,我无法找到有关如何执行此操作的任何信息。

我见过一些人推荐这种方法的一些变体:

location / {
    proxy_http_version 1.1;

    proxy_set_header    Upgrade     $http_upgrade;
    proxy_set_header    Connection  "upgrade";

    proxy_pass  http://host:port;
}

这会是代理标准 HTTP 和 websockets 的正确方法吗?

我不希望Upgrade标题或Connection设置为,upgrade除非这是浏览器发送的内容,但这些proxy_set_header行是 websocket 工作所必需的。

为什么 nginx 不只是转发原始的 Upgrade/Connection 标头?

我已经对此进行了试验,发现 nginx 不会代理Upgrade标头并将标头更改Connectionclosefromupgrade如果在没有这两proxy_set_header行的情况下运行。与它们一起,Connection用于upgrade非 websocket 请求,这也很糟糕。

4

1 回答 1

25

为什么 nginx 不只是转发原始的 Upgrade/Connection 标头?

来自官方文档由于“升级”是逐跳标头,因此它不会从客户端传递到代理服务器

请参阅RFC 2616


我不希望将 Upgrade 标头或 Connection 设置为“升级”,除非这是浏览器发送的内容,

还有一个例子:

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

对于非 websocket 请求,连接是“升级”,这也很糟糕。

你真的知道Connection标题是什么意思吗?只是来自 RFC 的引用:对于此字段中的每个连接令牌,请从消息中删除与连接令牌同名的任何标头字段。

怎么可能不好?

于 2013-03-04T09:46:36.693 回答