We all know we could use curl anytime with HTTP requests but what about WebSockets? I was debugging a WebSocket the other day which was basically a Docker service sitting behind an Nginx reverse proxy so I figured I’d write it down.
But, first of all, a bit of basics.
http vs websockets
HTTP is request and response. Stateless. You ask for something, the server responds, and that’s it.
WebSockets are stateful. They create a persistent, two-way connection between your browser and the server on. Think of it like UDP but running on top of TCP and as part of the application layer lol.
The tricky part? When you’re using Nginx as a reverse proxy, the initial WebSockets connection actually starts as a regular HTTP request that gets “upgraded” to a WebSockets connection. This is where things can get confusing during debugging.
curl
Before we can test anything with curl, we need a WebSockets key. This is basically a security handshake that proves both the client and server actually understand the WebSockets protocol.
So, generate one first:
openssl rand -base64 16
or even:
head -c 16 /dev/urandom | base64
Either way, you’ll get something like: XrBxDCiSL/2Bxptca15PEw==
Then:
curl -i -N \
-H "Connection: Upgrade" \
-H "Upgrade: WebSocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: <your_generated_base64_encoded_websockets_key_here>" \
http://localhost/ws
Quick notes:
- Don’t forget to replace
http://localhost/wswith your actual WebSockets endpoint. - If you get the “101 Switching Protocols” response, WebSocket is working.
- The
-iflag shows response headers, and-Ndisables buffering (important for real-time data).
nginx
You’ll need to modify two files to get WebSockets Nginx proxy working properly.
First, add this to your /etc/nginx/nginx.conf:
http {
#... some config ...
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
#... rest of config ...
}
Then in your site config e.g. /etc/nginx/conf.d/default.conf:
server {
# ... some config ...
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
Quick notes:
- Don’t forget to update
proxy_pass http://backendto point to wherever your WebSocket service is actually running. - HTTP/1.1 is important here. Websockets don’t really “use” HTTP/1.1 ongoing. They just borrow it for the handshake, then switch to their ownx protocol.
- Technically you could run WebSockets on HTTP/2 however its not really popular choice. Doable, but not practically viable at all.
bottom line
And there’s that. With these Nginx configs and the curl command, you’ve got everything you need to test and verify WebSocket connections… to a certain extend.
Still monitoring your infra manually? Maybe, just maybe give justanotheruptime.com a look ;)