瀏覽代碼

Split extension.py into base file and extension implementation files

Also, moved WebkitDeflateFrame to library source instead of tests
Taddeus Kroes 12 年之前
父節點
當前提交
7c99e4fe3a
共有 5 個文件被更改,包括 123 次插入121 次删除
  1. 3 1
      __init__.py
  2. 90 0
      deflate_frame.py
  3. 0 115
      extension.py
  4. 29 0
      multiplex.py
  5. 1 5
      test/server.py

+ 3 - 1
__init__.py

@@ -8,4 +8,6 @@ from frame import Frame, ControlFrame, OPCODE_CONTINUATION, OPCODE_TEXT, \
 from connection import Connection
 from message import Message, TextMessage, BinaryMessage
 from errors import SocketClosed, HandshakeError, PingError, SSLError
-from extension import Extension, DeflateFrame
+from extension import Extension
+from deflate_frame import DeflateFrame, WebkitDeflateFrame
+#from multiplex import Multiplex

+ 90 - 0
deflate_frame.py

@@ -0,0 +1,90 @@
+import zlib
+
+from frame import ControlFrame
+from errors import SocketClosed
+from extension import Extension
+
+
+class DeflateFrame(Extension):
+    """
+    This is an implementation of the "deflate-frame" extension, as defined by
+    http://tools.ietf.org/html/draft-tyoshino-hybi-websocket-perframe-deflate-06.
+
+    Supported parameters are:
+    - max_window_size: maximum size for the LZ77 sliding window.
+    - no_context_takeover: disallows usage of LZ77 sliding window from
+                           previously built frames for the current frame.
+
+    Note that the deflate and inflate hooks modify the RSV1 bit and payload of
+    existing `Frame` objects.
+    """
+
+    name = 'deflate-frame'
+    rsv1 = True
+    # FIXME: is 32768 (below) correct?
+    defaults = {'max_window_bits': 15, 'no_context_takeover': False}
+
+    def __init__(self, defaults={}, request={}):
+        Extension.__init__(self, defaults, request)
+
+        mwb = self.defaults['max_window_bits']
+        cto = self.defaults['no_context_takeover']
+
+        if not isinstance(mwb, int):
+            raise ValueError('"max_window_bits" must be an integer')
+        elif mwb > 32768:
+            raise ValueError('"max_window_bits" may not be larger than 32768')
+
+        if cto is not False and cto is not True:
+            raise ValueError('"no_context_takeover" must have no value')
+
+    class Hook(Extension.Hook):
+        def __init__(self, extension, **kwargs):
+            Extension.Hook.__init__(self, extension, **kwargs)
+
+            if not self.no_context_takeover:
+                self.defl = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
+                                            zlib.DEFLATED,
+                                            -self.max_window_bits)
+
+            other_wbits = self.extension.request.get('max_window_bits', 15)
+            self.dec = zlib.decompressobj(-other_wbits)
+
+        def send(self, frame):
+            if not frame.rsv1 and not isinstance(frame, ControlFrame):
+                frame.rsv1 = True
+                frame.payload = self.deflate(frame.payload)
+
+            return frame
+
+        def recv(self, frame):
+            if frame.rsv1:
+                if isinstance(frame, ControlFrame):
+                    raise SocketClosed('received compressed control frame')
+
+                frame.rsv1 = False
+                frame.payload = self.inflate(frame.payload)
+
+            return frame
+
+        def deflate(self, data):
+            if self.no_context_takeover:
+                defl = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
+                                        zlib.DEFLATED, -self.max_window_bits)
+                # FIXME: why the '\x00' below? This was borrowed from
+                # https://github.com/fancycode/tornado/blob/bc317b6dcf63608ff004ff1f57073be0504b6550/tornado/websocket.py#L91
+                return defl.compress(data) + defl.flush(zlib.Z_FINISH) + '\x00'
+
+            compressed = self.defl.compress(data)
+            compressed += self.defl.flush(zlib.Z_SYNC_FLUSH)
+            assert compressed[-4:] == '\x00\x00\xff\xff'
+            return compressed[:-4]
+
+        def inflate(self, data):
+            data = self.dec.decompress(str(data + '\x00\x00\xff\xff'))
+            assert not self.dec.unused_data
+            return data
+
+
+class WebkitDeflateFrame(DeflateFrame):
+    name = 'x-webkit-deflate-frame'

+ 0 - 115
extension.py

@@ -1,9 +1,3 @@
-import zlib
-
-from frame import ControlFrame
-from errors import SocketClosed
-
-
 class Extension(object):
     name = ''
     rsv1 = False
@@ -49,115 +43,6 @@ class Extension(object):
             return frame
 
 
-class DeflateFrame(Extension):
-    """
-    This is an implementation of the "deflate-frame" extension, as defined by
-    http://tools.ietf.org/html/draft-tyoshino-hybi-websocket-perframe-deflate-06.
-
-    Supported parameters are:
-    - max_window_size: maximum size for the LZ77 sliding window.
-    - no_context_takeover: disallows usage of LZ77 sliding window from
-                           previously built frames for the current frame.
-
-    Note that the deflate and inflate hooks modify the RSV1 bit and payload of
-    existing `Frame` objects.
-    """
-
-    name = 'deflate-frame'
-    rsv1 = True
-    # FIXME: is 32768 (below) correct?
-    defaults = {'max_window_bits': 15, 'no_context_takeover': False}
-
-    def __init__(self, defaults={}, request={}):
-        Extension.__init__(self, defaults, request)
-
-        mwb = self.defaults['max_window_bits']
-        cto = self.defaults['no_context_takeover']
-
-        if not isinstance(mwb, int):
-            raise ValueError('"max_window_bits" must be an integer')
-        elif mwb > 32768:
-            raise ValueError('"max_window_bits" may not be larger than 32768')
-
-        if cto is not False and cto is not True:
-            raise ValueError('"no_context_takeover" must have no value')
-
-    class Hook(Extension.Hook):
-        def __init__(self, extension, **kwargs):
-            Extension.Hook.__init__(self, extension, **kwargs)
-
-            if not self.no_context_takeover:
-                self.defl = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
-                                            zlib.DEFLATED,
-                                            -self.max_window_bits)
-
-            other_wbits = self.extension.request.get('max_window_bits', 15)
-            self.dec = zlib.decompressobj(-other_wbits)
-
-        def send(self, frame):
-            if not frame.rsv1 and not isinstance(frame, ControlFrame):
-                frame.rsv1 = True
-                frame.payload = self.deflate(frame.payload)
-
-            return frame
-
-        def recv(self, frame):
-            if frame.rsv1:
-                if isinstance(frame, ControlFrame):
-                    raise SocketClosed('received compressed control frame')
-
-                frame.rsv1 = False
-                frame.payload = self.inflate(frame.payload)
-
-            return frame
-
-        def deflate(self, data):
-            if self.no_context_takeover:
-                defl = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
-                                        zlib.DEFLATED, -self.max_window_bits)
-                # FIXME: why the '\x00' below? This was borrowed from
-                # https://github.com/fancycode/tornado/blob/bc317b6dcf63608ff004ff1f57073be0504b6550/tornado/websocket.py#L91
-                return defl.compress(data) + defl.flush(zlib.Z_FINISH) + '\x00'
-
-            compressed = self.defl.compress(data)
-            compressed += self.defl.flush(zlib.Z_SYNC_FLUSH)
-            assert compressed[-4:] == '\x00\x00\xff\xff'
-            return compressed[:-4]
-
-        def inflate(self, data):
-            data = self.dec.decompress(str(data + '\x00\x00\xff\xff'))
-            assert not self.dec.unused_data
-            return data
-
-
-class Multiplex(Extension):
-    """
-    This is an implementation of the "mux" extension, as defined by
-    http://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-11.
-
-    Supported parameters are:
-    - quota: TODO
-    """
-
-    name = 'mux'
-    rsv1 = True  # FIXME
-    rsv2 = True  # FIXME
-    rsv3 = True  # FIXME
-    defaults = {'quota': None}
-
-    def __init__(self, defaults={}, request={}):
-        Extension.__init__(self, defaults, request)
-
-        # TODO: check "quota" value
-
-    class Hook(Extension.Hook):
-        def send(self, frame):
-            raise NotImplementedError  # TODO
-
-        def recv(self, frame):
-            raise NotImplementedError  # TODO
-
-
 def filter_extensions(extensions):
     """
     Remove extensions that use conflicting rsv bits and/or opcodes, with the

+ 29 - 0
multiplex.py

@@ -0,0 +1,29 @@
+from extension import Extension
+
+
+class Multiplex(Extension):
+    """
+    This is an implementation of the "mux" extension, as defined by
+    http://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-11.
+
+    Supported parameters are:
+    - quota: TODO
+    """
+
+    name = 'mux'
+    rsv1 = True  # FIXME
+    rsv2 = True  # FIXME
+    rsv3 = True  # FIXME
+    defaults = {'quota': None}
+
+    def __init__(self, defaults={}, request={}):
+        Extension.__init__(self, defaults, request)
+
+        # TODO: check "quota" value
+
+    class Hook(Extension.Hook):
+        def send(self, frame):
+            raise NotImplementedError  # TODO
+
+        def recv(self, frame):
+            raise NotImplementedError  # TODO

+ 1 - 5
test/server.py

@@ -7,7 +7,7 @@ basepath = abspath(dirname(abspath(__file__)) + '/..')
 sys.path.insert(0, basepath)
 
 from server import Server
-from extension import DeflateFrame
+from deflate_frame import WebkitDeflateFrame
 
 
 class EchoServer(Server):
@@ -16,10 +16,6 @@ class EchoServer(Server):
         client.send(message)
 
 
-class WebkitDeflateFrame(DeflateFrame):
-    name = 'x-webkit-deflate-frame'
-
-
 if __name__ == '__main__':
     deflate = WebkitDeflateFrame()
     #deflate = WebkitDeflateFrame(defaults={'no_context_takeover': True})