Apparently, to support operating behind an haproxy you can't wait for the nonce string. see the gist: https://gist.github.com/729332
I'm not 100% sure about how this works but reading references in other servers: Worlize/Socket.IO-node@b9bef2b
It appears the nonce e.g. the request body is optional? From my gist it's clear that it's not included when proxied behind HAProxy... I'm just getting setup with em-* so will take a shot at a patch but thought it'd be helpful to get some more eyes on this...
I'm using the following to manage haproxy locally for testing: https://gist.github.com/729335
I've messed around with changing the websock from mode http and mode tcp - believe with the changes in the other mentioned servers mode http would/can work... i've also tested running on the same or different ports.
more information - after hacking a little it appears you can wait for the third key (e.g. nonce) when receiving the 101 header
"HTTP/1.1 101 WebSocket Protocol Handshake\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Location: ws://127.0.0.1:8888/\r\nSec-WebSocket-Origin: http://127.0.0.1:9000\r\n\r\n\x1E\xDC\xEB\xC2aRe\xBD\xAD\xE0]\x1C\xDE\e'\x8D"]]
Hmm, that's a gotcha. I've been running an older version of em-websocket behind haproxy, so haven't run into this. Having said that, I'm pretty sure pusherapp is running on latest version -- kinda surprised Martyn haven't run into this already?
You're running into the issue that the third key data is not HTTP compliant, and HAProxy is doing the correct thing by not sending it when operating in layer 7 mode. Unfortunately those bytes are required as part of the handshake process in draft 76. This has been subject to more discussion than you want to imagine on the hybi list. Suffice to say that the protocol will change to remove this issue. Willy Tarreau (creator of HAProxy) is very active in protocol discussions, so eventually I'm certain that HAProxy will have good support for WebSockets.
As Illya says, we use HAProxy for pusherapp, but we use it in layer 4 mode (set mode tcp) for exactly this reason. This works fine for us, since we have dedicated hosts serving websocket traffic, but it would be an issue if you wanted to serve HTTP and WebSocket traffic on the same port. I don't have a solution for that I'm afraid.
Thank you for the very detailed explanation - I'm on vacation for the next few days. When I get back I plan to try using the alternate port in mode tcp, my goal to have a workable configuration that could be used as reference.
Sorry to 'revive' an old ticket, I would like to know if steps has been taken to support this situation.
I'm using Haproxy 1.5-dev11/em-websocket and so far I'm getting 502 all the way in http mode due to HandshakeError, "Connection and Upgrade headers required".
HandshakeError, "Connection and Upgrade headers required"
Switching to tcp mode works of course, but I'm curious if anyone has progress info to share about this specific issue.
AFAIK there's no option in haproxy to handle a situation like this, yet.
I haven't investigated this issue in recent memory I'm afraid. @jcoglan am I right in think that you've got this working?
Yep, including for draft-76 with HAProxy in http mode, which is really annoying. Here's the commit, can't remember if it's the complete picture but it's relevant.
Sorry I'm a bit confused, is that something I should fix on my app rather than directly in em-websocket?
It's something that (IMO) should be handled by a WebSocket library. Part of this is a historical problem with how draft-76 does handshakes, which ought to be covered up by a library API.
Thanks James. I've reopened this issue since it's clear that a workaround is possible, and probably desirable.
I'm unlikely to get around to this one but I'm very happy to accept a pull request if anyone wants to take it on.
Is this still a known issue in 2015? We are trying to load balance using HAproxy and we're seeing odd behaviour.