3

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.

1 Answer 1

4

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.

1
  • You've brought an end to many hours of frustration for me. Thanks for this explanation and code. Commented Jul 15 at 22:24

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.