Browse Source

Added some comments + input checking + template for multiplex extension

Taddeus Kroes 12 năm trước cách đây
mục cha
commit
6efb88078d
2 tập tin đã thay đổi với 63 bổ sung12 xóa
  1. 1 1
      __init__.py
  2. 62 11
      extension.py

+ 1 - 1
__init__.py

@@ -8,4 +8,4 @@ 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, DeflateFrame, Multiplex

+ 62 - 11
extension.py

@@ -15,7 +15,7 @@ class Extension(object):
 
         for param, value in kwargs.items():
             if param not in self.parameters:
-                raise HandshakeError('invalid parameter "%s"' % param)
+                raise HandshakeError('unrecognized parameter "%s"' % param)
 
             if value is None:
                 value = True
@@ -42,42 +42,93 @@ class Extension(object):
 
 
 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
     parameters = ['max_window_bits', 'no_context_takeover']
 
+    # FIXME: is this correct?
+    default_max_window_bits = 32768
+
     def __init__(self, **kwargs):
         super(DeflateFrame, self).__init__(**kwargs)
 
         if self.max_window_bits is None:
-            # FIXME: is this correct? None may actually be a better value
-            self.max_window_bits = 0
+            self.max_window_bits = self.default_max_window_bits
+        elif not isinstance(self.max_window_bits, int):
+            raise HandshakeError('"max_window_bits" must be an integer')
+        elif self.max_window_bits > 32768:
+            raise HandshakeError('"max_window_bits" may not be larger than '
+                                 '32768')
+
+        if self.no_context_takeover is None:
+            self.no_context_takeover = False
+        elif self.no_context_takeover is not True:
+            raise HandshakeError('"no_context_takeover" must have no value')
 
     def hook_send(self, frame):
-        # FIXME: original `frame` is modified, maybe it should be copied?
-
         if not frame.rsv1:
             frame.rsv1 = True
-            frame.payload = self.encode(frame.payload)
+            frame.payload = self.deflate(frame.payload)
 
         return frame
 
     def hook_recv(self, frame):
-        # FIXME: original `frame` is modified, maybe it should be copied?
-
         if frame.rsv1:
             frame.rsv1 = False
-            frame.payload = self.decode(frame.payload)
+            frame.payload = self.inflate(frame.payload)
 
         return frame
 
     def header_params(self):
         raise NotImplementedError  # TODO
 
-    def encode(self, data):
+    def deflate(self, data):
+        raise NotImplementedError  # TODO
+
+    def inflate(self, data):
+        raise NotImplementedError  # TODO
+
+
+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
+    parameters = ['quota']
+
+    def __init__(self, **kwargs):
+        super(Multiplex, self).__init__(**kwargs)
+
+        # TODO: check "quota" value
+
+    def hook_send(self, frame):
+        raise NotImplementedError  # TODO
+
+    def hook_recv(self, frame):
         raise NotImplementedError  # TODO
 
-    def decode(self, data):
+    def header_params(self):
         raise NotImplementedError  # TODO