Reverse proxy to websocket always fails

1. The problem I’m having:

I’m trying to establish a websocket connection, but it keeps failing.
In the client I have:
const socket = new WebSocket('wss://doekewartena.nl/wss59fps');

In the node js server I have:
const wss = new WebSocket.Server({ server, path: '/wss59fps' });

My Caddyfile:

doekewartena.nl {

        log {
                output file /var/log/caddy/frustration.log
        }

        reverse_proxy /wss59fps localhost:9090

        redir https://www.{host}{uri}
}

www.doekewartena.nl {
        root * /home/doekewartena_nl/sftp/www
     
        #
        # main
        #

        handle_path /* {
                rewrite * /main{uri}
                file_server
        }

        #
        # 59 fps
        #

        redir /59fps    /59fps/

        handle_path /59fps/* {
                rewrite * /59fps/client{uri}
                file_server
        }
}

I get a 302 status which will be listed below in #2.
At this point I’m just lost of what to do. And since most topics are locked it’s hard to ask questions of why someone did what.

The thing that makes the most sense to me is in this topic:

@websockets {
	header Connection *Upgrade*
	header Upgrade websocket
}
reverse_proxy @websockets localhost:6001

I don’t understand how to intergrate this in my Caddyfile tho.
Like how do I combine the above snippet with the wss59fps path?

2. Error messages and/or full log output:

sudo cat /var/log/caddy/frustration.log
{"level":"info","ts":1725298657.6525447,"logger":"http.log.access.log1","msg":"handled request","request":{"remote_ip":"192.168.1.254","remote_port":"54087","client_ip":"192.168.1.254","proto":"HTTP/1.1","method":"GET","host":"doekewartena.nl","uri":"/wss59fps","headers":{"Sec-Websocket-Version":["13"],"Sec-Fetch-Dest":["empty"],"Sec-Fetch-Site":["same-site"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Origin":["https://www.doekewartena.nl"],"Sec-Websocket-Key":["uChH+3RCdjMcJdTlC1spFg=="],"Pragma":["no-cache"],"Accept":["*/*"],"Sec-Websocket-Extensions":["permessage-deflate"],"Sec-Fetch-Mode":["websocket"],"Upgrade":["websocket"],"Accept-Language":["en-GB,en;q=0.5"],"Connection":["keep-alive, Upgrade"],"Cache-Control":["no-cache"]},"tls":{"resumed":true,"version":772,"cipher_suite":4865,"proto":"http/1.1","server_name":"doekewartena.nl"}},"bytes_read":0,"user_id":"","duration":0.000183488,"size":0,"status":302,"resp_headers":{"Server":["Caddy"],"Alt-Svc":["h3=\":443\"; ma=2592000"],"Location":["https://www.doekewartena.nl/wss59fps"],"Content-Type":[]}}
{"level":"info","ts":1725298868.9810967,"logger":"http.log.access.log1","msg":"handled request","request":{"remote_ip":"192.168.1.254","remote_port":"64115","client_ip":"192.168.1.254","proto":"HTTP/1.1","method":"GET","host":"doekewartena.nl","uri":"/wss59fps","headers":{"Accept-Language":["en-US,en;q=0.5"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Sec-Websocket-Extensions":["permessage-deflate"],"Sec-Fetch-Dest":["empty"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:129.0) Gecko/20100101 Firefox/129.0"],"Sec-Websocket-Key":["FHT83gbTIoOaqaDFTq1QYg=="],"Sec-Fetch-Site":["same-site"],"Pragma":["no-cache"],"Upgrade":["websocket"],"Connection":["keep-alive, Upgrade"],"Accept":["*/*"],"Sec-Websocket-Version":["13"],"Origin":["https://www.doekewartena.nl"],"Sec-Fetch-Mode":["websocket"],"Cache-Control":["no-cache"]},"tls":{"resumed":true,"version":772,"cipher_suite":4865,"proto":"http/1.1","server_name":"doekewartena.nl"}},"bytes_read":0,"user_id":"","duration":0.000144191,"size":0,"status":302,"resp_headers":{"Server":["Caddy"],"Alt-Svc":["h3=\":443\"; ma=2592000"],"Location":["https://www.doekewartena.nl/wss59fps"],"Content-Type":[]}}

3. Caddy version:

v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

4. How I installed and ran Caddy:

a. System environment:

Mac Mini running Ubuntu

b. Command:

caddy reload after makking changes to my Caddyfile

d. My complete Caddy config:

See above

This is not required. Websocket proxying works out of the box, that @websockets is only used to separate websocket requests to a different upstream from non-websocket requests.

From your access logs we see:

"host": "doekewartena.nl",

"status": 302,

and

"Location": [ "https://www.doekewartena.nl/wss59fps" ],

Which tells a story: someone connected to doekewartena.nl and was redirected to www.doekewartena.nl, essentially.

This is because you have configured Caddy to redirect all requests:

All you’ll need to do is not configure Caddy to redirect the requests you want to proxy.

1 Like