From ce02250ed3579706f800cfc5e622da834d79f933 Mon Sep 17 00:00:00 2001 From: cbecker333 Date: Tue, 12 Oct 2010 21:21:35 -0700 Subject: [PATCH] Accomodate websocket draft 76 over HAProxy http mode. Changed the order of header writing and nonce reading to allow HAProxy to fully establish the connection when in http mode. For more background read here: http://www.mail-archive.com/haproxy@formilux.org/msg03067.html --- tornado/websocket.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/tornado/websocket.py b/tornado/websocket.py index b760fef6b..3ec2f6bde 100644 --- a/tornado/websocket.py +++ b/tornado/websocket.py @@ -81,6 +81,26 @@ class WebSocketHandler(tornado.web.RequestHandler): logging.debug("Malformed WebSocket request received") self._abort() return + self.stream.write( + "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" + "Upgrade: WebSocket\r\n" + "Connection: Upgrade\r\n" + "Server: TornadoServer/%(version)s\r\n" + "Sec-WebSocket-Origin: %(origin)s\r\n" + "Sec-WebSocket-Location: ws://%(host)s%(path)s\r\n\r\n" % (dict( + version=tornado.version, + origin=self.request.headers["Origin"], + host=self.request.host, + path=self.request.path)), + self._do_handle_challenge) + + def _do_handle_challenge(self): + """ + This is called after we write the first part of the header, but + before we write the challenge response. + Allows an intermediary like HAProxy to use standard http by + writing the 101 response before acquiring the nonce for challenge. + """ self.stream.read_bytes(8, self._handle_challenge) def _handle_challenge(self, challenge): @@ -93,19 +113,7 @@ class WebSocketHandler(tornado.web.RequestHandler): self._write_response(challenge_response) def _write_response(self, challenge): - self.stream.write( - "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" - "Upgrade: WebSocket\r\n" - "Connection: Upgrade\r\n" - "Server: TornadoServer/%(version)s\r\n" - "Sec-WebSocket-Origin: %(origin)s\r\n" - "Sec-WebSocket-Location: ws://%(host)s%(path)s\r\n" - "\r\n%(challenge)s" % (dict( - version=tornado.version, - origin=self.request.headers["Origin"], - host=self.request.host, - path=self.request.path, - challenge=challenge))) + self.stream.write("%s" % challenge) self.async_callback(self.open)(*self.open_args, **self.open_kwargs) self._receive_message() -- 2.47.2