Browse Source

Split extension.py into base file and extension implementation files

Also, moved WebkitDeflateFrame to library source instead of tests
Taddeus Kroes 12 năm trước cách đây
mục cha
commit
7c99e4fe3a
5 tập tin đã thay đổi với 123 bổ sung121 xóa
  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})