Browse Source

Sync with websockify.

Pull in websockify 4725aa7.

- Update to c0855c6cae of web-socket-js

- Update both the submodule and the swf build. The submodule now
  contains the unobfuscated source for swfobject.js which should make
  websockify more DFSG compliant.

- Remove Hixie support. iOS 6 now includes HyBi support which means
  there is no remaining platform that needs Hixie.
Joel Martin 12 years ago
parent
commit
c3c51ed32b
3 changed files with 29 additions and 124 deletions
  1. 1 1
      include/web-socket-js-project
  2. BIN
      include/web-socket-js/WebSocketMain.swf
  3. 28 123
      utils/websocket.py

+ 1 - 1
include/web-socket-js-project

@@ -1 +1 @@
-Subproject commit 7677e7a954561cc44dac7659219bef768c904b62
+Subproject commit c0855c6caec589c33acc22b6ee5e562287e65f3d

BIN
include/web-socket-js/WebSocketMain.swf


+ 28 - 123
utils/websocket.py

@@ -6,9 +6,9 @@ Copyright 2011 Joel Martin
 Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
 
 Supports following protocol versions:
-    - http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75
-    - http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
+    - http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07
     - http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10
+    - http://tools.ietf.org/html/rfc6455
 
 You can make a cert/key with openssl using:
 openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
@@ -37,8 +37,8 @@ try:    from http.server import SimpleHTTPRequestHandler
 except: from SimpleHTTPServer import SimpleHTTPRequestHandler
 
 # python 2.6 differences
-try:    from hashlib import md5, sha1
-except: from md5 import md5; from sha import sha as sha1
+try:    from hashlib import sha1
+except: from sha import sha as sha1
 
 # python 2.5 differences
 try:
@@ -50,15 +50,15 @@ except:
         return struct.unpack(fmt, slice)
 
 # Degraded functionality if these imports are missing
-for mod, sup in [('numpy', 'HyBi protocol'), ('ssl', 'TLS/SSL/wss'),
-        ('multiprocessing', 'Multi-Processing'),
-        ('resource', 'daemonizing')]:
+for mod, msg in [('numpy', 'HyBi protocol will be slower'),
+                 ('ssl', 'TLS/SSL/wss is disabled'),
+                 ('multiprocessing', 'Multi-Processing is disabled'),
+                 ('resource', 'daemonizing is disabled')]:
     try:
         globals()[mod] = __import__(mod)
     except ImportError:
         globals()[mod] = None
-        print("WARNING: no '%s' module, %s is slower or disabled" % (
-            mod, sup))
+        print("WARNING: no '%s' module, %s" % (mod, msg))
 if multiprocessing and sys.platform == 'win32':
     # make sockets pickle-able/inheritable
     import multiprocessing.reduction
@@ -72,14 +72,6 @@ class WebSocketServer(object):
 
     buffer_size = 65536
 
-
-    server_handshake_hixie = """HTTP/1.1 101 Web Socket Protocol Handshake\r
-Upgrade: WebSocket\r
-Connection: Upgrade\r
-%sWebSocket-Origin: %s\r
-%sWebSocket-Location: %s://%s%s\r
-"""
-
     server_handshake_hybi = """HTTP/1.1 101 Switching Protocols\r
 Upgrade: websocket\r
 Connection: Upgrade\r
@@ -381,33 +373,6 @@ Sec-WebSocket-Accept: %s\r
 
         return f
 
-    @staticmethod
-    def encode_hixie(buf):
-        return s2b("\x00" + b2s(b64encode(buf)) + "\xff"), 1, 1
-
-    @staticmethod
-    def decode_hixie(buf):
-        end = buf.find(s2b('\xff'))
-        return {'payload': b64decode(buf[1:end]),
-                'hlen': 1,
-                'masked': False,
-                'length': end - 1,
-                'left': len(buf) - (end + 1)}
-
-
-    @staticmethod
-    def gen_md5(keys):
-        """ Generate hash value for WebSockets hixie-76. """
-        key1 = keys['Sec-WebSocket-Key1']
-        key2 = keys['Sec-WebSocket-Key2']
-        key3 = keys['key3']
-        spaces1 = key1.count(" ")
-        spaces2 = key2.count(" ")
-        num1 = int("".join([c for c in key1 if c.isdigit()])) / spaces1
-        num2 = int("".join([c for c in key2 if c.isdigit()])) / spaces2
-
-        return b2s(md5(pack('>II8s',
-            int(num1), int(num2), key3)).digest())
 
     #
     # WebSocketServer logging/output functions
@@ -444,16 +409,10 @@ Sec-WebSocket-Accept: %s\r
 
         if bufs:
             for buf in bufs:
-                if self.version.startswith("hybi"):
-                    if self.base64:
-                        encbuf, lenhead, lentail = self.encode_hybi(
-                                buf, opcode=1, base64=True)
-                    else:
-                        encbuf, lenhead, lentail = self.encode_hybi(
-                                buf, opcode=2, base64=False)
-
+                if self.base64:
+                    encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=1, base64=True)
                 else:
-                    encbuf, lenhead, lentail = self.encode_hixie(buf)
+                    encbuf, lenhead, lentail = self.encode_hybi(buf, opcode=2, base64=False)
 
                 if self.rec:
                     self.rec.write("%s,\n" %
@@ -498,41 +457,21 @@ Sec-WebSocket-Accept: %s\r
             self.recv_part = None
 
         while buf:
-            if self.version.startswith("hybi"):
-
-                frame = self.decode_hybi(buf, base64=self.base64)
-                #print("Received buf: %s, frame: %s" % (repr(buf), frame))
-
-                if frame['payload'] == None:
-                    # Incomplete/partial frame
-                    self.traffic("}.")
-                    if frame['left'] > 0:
-                        self.recv_part = buf[-frame['left']:]
-                    break
-                else:
-                    if frame['opcode'] == 0x8: # connection close
-                        closed = {'code': frame['close_code'],
-                                  'reason': frame['close_reason']}
-                        break
-
+            frame = self.decode_hybi(buf, base64=self.base64)
+            #print("Received buf: %s, frame: %s" % (repr(buf), frame))
+
+            if frame['payload'] == None:
+                # Incomplete/partial frame
+                self.traffic("}.")
+                if frame['left'] > 0:
+                    self.recv_part = buf[-frame['left']:]
+                break
             else:
-                if buf[0:2] == s2b('\xff\x00'):
-                    closed = {'code': 1000,
-                              'reason': "Client sent orderly close frame"}
-                    break
-
-                elif buf[0:2] == s2b('\x00\xff'):
-                    buf = buf[2:]
-                    continue # No-op
-
-                elif buf.count(s2b('\xff')) == 0:
-                    # Partial frame
-                    self.traffic("}.")
-                    self.recv_part = buf
+                if frame['opcode'] == 0x8: # connection close
+                    closed = {'code': frame['close_code'],
+                              'reason': frame['close_reason']}
                     break
 
-                frame = self.decode_hixie(buf)
-
             self.traffic("}")
 
             if self.rec:
@@ -560,17 +499,9 @@ Sec-WebSocket-Accept: %s\r
     def send_close(self, code=1000, reason=''):
         """ Send a WebSocket orderly close frame. """
 
-        if self.version.startswith("hybi"):
-            msg = pack(">H%ds" % len(reason), code, reason)
-
-            buf, h, t = self.encode_hybi(msg, opcode=0x08, base64=False)
-            self.client.send(buf)
-
-        elif self.version == "hixie-76":
-            buf = s2b('\xff\x00')
-            self.client.send(buf)
-
-        # No orderly close for 75
+        msg = pack(">H%ds" % len(reason), code, reason)
+        buf, h, t = self.encode_hybi(msg, opcode=0x08, base64=False)
+        self.client.send(buf)
 
     def do_websocket_handshake(self, headers, path):
         h = self.headers = headers
@@ -612,28 +543,7 @@ Sec-WebSocket-Accept: %s\r
             response += "\r\n"
 
         else:
-            # Hixie version of the protocol (75 or 76)
-
-            if h.get('key3'):
-                trailer = self.gen_md5(h)
-                pre = "Sec-"
-                self.version = "hixie-76"
-            else:
-                trailer = ""
-                pre = ""
-                self.version = "hixie-75"
-
-            # We only support base64 in Hixie era
-            self.base64 = True
-
-            response = self.server_handshake_hixie % (pre,
-                    h['Origin'], pre, self.scheme, h['Host'], path)
-
-            if 'base64' in protocols:
-                response += "%sWebSocket-Protocol: base64\r\n" % pre
-            else:
-                self.msg("Warning: client does not report 'base64' protocol support")
-            response += "\r\n" + trailer
+            raise self.EClose("Missing Sec-WebSocket-Version header. Hixie protocols not supported.")
 
         return response
 
@@ -957,11 +867,6 @@ class WSRequestHandler(SimpleHTTPRequestHandler):
         if (self.headers.get('upgrade') and
                 self.headers.get('upgrade').lower() == 'websocket'):
 
-            if (self.headers.get('sec-websocket-key1') or
-                    self.headers.get('websocket-key1')):
-                # For Hixie-76 read out the key hash
-                self.headers.__setitem__('key3', self.rfile.read(8))
-
             # Just indicate that an WebSocket upgrade is needed
             self.last_code = 101
             self.last_message = "101 Switching Protocols"