1

I have several services I'm placing behind an NGINX reverse proxy, which was simple enough to setup, but I've run into a problem with websockets. A single endpoint is simple enough to specify with a location that includes

   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "upgrade";

The problem is that there are many endpoints with websockets. And we keep finding new things that don't work because there's yet another websocket endpoint we didn't know about.

Is there a way to only set the Upgrade and Connection header if the client passes it? If I include those two lines for the whole service it attempts to upgrade every connection, not just the websockets.

directedition
  • 287
  • 3
  • 10

1 Answers1

1

Just had the same problem, and was battling if statements in nginx configuration and realized these directives:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Don't do anything unless the client set an Upgrade header.

So instead of adding specific Location directive for each websocket endpoint, you can just make a global one:

server {
  listen          443 ssl;
  server_name     my-server.example
  location / {
    proxy_pass http://local-service.example/;
    proxy_http_version 1.1;
    proxy_read_timeout 86400s;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

  }
}

This proxy's any HTTP request and also makes websockets work for the entire namespace. The reason it works is because $http_upgrade is empty for non-websocket requests.

Evert
  • 129
  • 2
  • 7