Commits

Arkaitz Jimenez  committed ddce9d8

Send to modern Firefox and Chrome works

  • Participants
  • Parent commits 99e782e
  • Branches default

Comments (0)

Files changed (2)

File geventwebsocket/handler.py

-import re
+import re,sys
 import struct
 from hashlib import md5
 from socket import error
         # TODO: refactor to run under run_application
         # In case the client doesn't want to initialize a WebSocket connection
         # we will proceed with the default PyWSGI functionality.
-        if self.environ.get("HTTP_CONNECTION").endswith("Upgrade") or \
+        print "Connection is [%s]"%(self.environ.get("HTTP_CONNECTION"))
+        if not self.environ.get("HTTP_CONNECTION").endswith("Upgrade") or \
            self.environ.get("HTTP_UPGRADE").lower() != "websocket" or \
            not self.environ.get("HTTP_SEC_WEBSOCKET_ORIGIN") or \
            not self.accept_upgrade():
 
         # Detect the Websocket protocol
         if "HTTP_SEC_WEBSOCKET_KEY1" in self.environ:
+            version = 75
+        else:
             version = 76
-        else:
-            version = 75
+
 
         if version == 75:
+            challenge = self._get_challenge()
             headers.extend([
                 ("WebSocket-Origin", self.websocket.origin),
                 ("WebSocket-Protocol", self.websocket.protocol),
                 ("WebSocket-Location", "ws://" + self.environ.get('HTTP_HOST') + self.websocket.path),
             ])
             self.start_response("101 Web Socket Protocol Handshake", headers)
+            self.write(challenge)
         elif version == 76:
-            challenge = self._get_challenge()
             headers.extend([
                 ("Sec-WebSocket-Origin", self.websocket.origin),
                 ("Sec-WebSocket-Protocol", self.websocket.protocol),
                 ("Sec-WebSocket-Location", "ws://" + self.environ.get('HTTP_HOST') + self.websocket.path),
+                ("Sec-WebSocket-Accept", self.get_accept_response()),
             ])
-
             self.start_response("101 Web Socket Protocol Handshake", headers)
-            self.write(challenge)
         else:
             raise Exception("WebSocket version not supported")
 
         return self.run_application()
 
+    def get_accept_response(self):
+        import base64, hashlib
+        key = self.environ.get('HTTP_SEC_WEBSOCKET_KEY')
+        completebytes = hashlib.sha1(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").hexdigest().decode('hex')
+        return base64.b64encode(completebytes)
+    
+
     def accept_upgrade(self):
         """
         Returns True if request is allowed to be upgraded.
                 towrite.append("%s: %s\r\n" % header)
 
             towrite.append("\r\n")
-            self.socket.sendall(str(towrite))
+            self.socket.sendall("".join(towrite))
             self.headers_sent = True
         else:
             super(WebSocketHandler, self).start_response(status, headers, exc_info)

File geventwebsocket/websocket.py

 from gevent.coros import Semaphore
-
-# This class implements the Websocket protocol draft version as of May 23, 2010
-# The version as of August 6, 2010 will be implementend once Firefox or
-# Webkit-trunk support this version.
+import struct
 
 class WebSocket(object):
     def __init__(self, sock, rfile, environ):
         self._writelock = Semaphore(1)
 
     def send(self, message):
+
         if isinstance(message, unicode):
             message = message.encode('utf-8')
         elif isinstance(message, str):
         else:
             raise Exception("Invalid message encoding")
 
+        msglen = len(message)
+        frameheader = 0x81
+        maskbit = 0
+        if msglen <= 125: masklen = chr(maskbit | msglen)
+        elif msglen < (1 << 16): masklen = chr(maskbit | 126) + struct.pack('!H', msglen)
+        elif msglen < (1 << 63): masklen = chr(maskbit | 127) + struct.pack('!Q', msglen)
+
+        framebytes = chr(frameheader) + masklen + message
         with self._writelock:
-            self.socket.sendall("\x00" + message + "\xFF")
+            self.socket.sendall(framebytes)
 
     def detach(self):
         self.socket = None