nginx now supports proxying websockets, but I was unable to find any information on how to do this without having a separate location block that applies to URIs on which websockets are used.
I've seen some folks recommending some variations of this approach:
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://host:port;
}
Would that be the correct way to proxy standard HTTP as well as websockets?
I don't want the Upgrade
header or Connection
being set to upgrade
unless that's what the browser sent, but these proxy_set_header
lines are required for websockets to work.
Why doesn't nginx just forward the original Upgrade/Connection headers?
I've experimented with this and found that nginx does not proxy the Upgrade
header and changes the Connection
header to close
from upgrade
if running without the two proxy_set_header
lines. With them, Connection
is upgrade
for non-websocket requests, which is also bad.
From the official documentation: since the “Upgrade” is a hop-by-hop header, it is not passed from a client to proxied server
See RFC 2616.
There is also an example:
Do you actually know what the
Connection
header means? Just a quote from RFC: for each connection-token in this field, remove any header field(s) from the message with the same name as the connection-token.How it can be bad?