0

I have WebSockets enabled using an Undertow server. When I run the Undertow server directly, WebSockets work well. I serve my pages using HTTPS and I test the endpoint using "wss:" in javascript: it works.

But now, I try to use Apache as a reverse proxy and I want it to let WebSocket connections reach the Undertow server. This is my current Virtual Host:

<VirtualHost *:80 *:443>
    ServerName test.example.org

    SSLEngine on 
    SSLCertificateFile /etc/letsencrypt/live/example.org/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/example.org/chain.pem

    ProxyPass / http://test.example.org:44444/
    ProxyPassReverse / http://test.example.org:44444/

</VirtualHost>

Here, Undertow is started as a HTTP server (not HTTPS) on port 44444 and the SSL security is done by Apache.

All the HTML pages work well, but when I try to start a WebSocket connection, I get this error (Chrome) :

WebSocket connection to 'wss://test.example.org/websockets/echo' failed: Error during WebSocket handshake: 'Upgrade' header is missing

And, when I look at the Network tab, I see that indeed two headers are missing in the response from the server, when the "wss://" call is made: "Connection: Upgrade" and "Upgrade: WebSocket". Those headers are present when I connect to Undertow directly, without Apache.

The "Sec-WebSocket-Accept" and "Sec-WebSocket-Location" headers are there but, and I guess this is a second issue, "Sec-WebSocket-Location" is 'ws://test.example.org/websockets/echo' not 'wss://test.example.org/websockets/echo' since Undertow runs on HTTP, not HTTPS.

Last thing, the mod_proxy_wstunnel documentation says "The connection is automatically upgraded to a websocket connection". What does this mean? Apache is upgrading the HTTP connection to a WebSocket connection by itself? This is not what I want! I want to handle the initial HTTP request and the upgrading processes by myself, using Undertow. I use informations from the initial HTTP connection to validate if the user can be connected to the requested endpoint and, if so, I programmatically call Undertow's WebSocketProtocolHandshakeHandler#handleRequest(exchange) to upgrade to a WebSocket connection. I just want Apache to let everything pass without interfering.

Any help on how to run WebSockets using Undertow behind an Apache reverse-proxy?

electrotype
  • 8,342
  • 11
  • 59
  • 96

1 Answers1

1

I got tired and decided to try Nginx.

Within 3 hours, not only did I get WebSockets working, but all my sites on a server were moved to it. Super easy.

The magical lines for WebSockets, in nginx.conf, are:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

I understand that "Upgrade" is a special "hop-by-hop" header which has to be explicitly configured to be kept.

I hope there is a similar solution for Apache, but man, there is so few documentation about this!

electrotype
  • 8,342
  • 11
  • 59
  • 96