Example #1
0
 def setUp(self):
     self.channel = DummyChannel()
     request = Request(self.channel, False)
     transport = WebSocketHixieTransport(request)
     handler = TestHandler(transport)
     transport._attachHandler(handler)
     self.decoder = WebSocketHixieFrameDecoder(request.transport, handler)
     self.decoder.MAX_LENGTH = 100
     self.decoder.MAX_BINARY_LENGTH = 1000
Example #2
0
class WebSocketHixie76FrameDecoderTestCase(TestCase):
    """
    Test for the pre-Hybi C{WebSocketFrameDecoder} (hixie-76)
    """

    def setUp(self):
        self.channel = DummyChannel()
        request = Request(self.channel, False)
        transport = WebSocketHixieTransport(request)
        handler = TestHandler(transport)
        transport._attachHandler(handler)
        self.decoder = WebSocketHixieFrameDecoder(request.transport, handler)
        self.decoder.MAX_LENGTH = 100
        self.decoder.MAX_BINARY_LENGTH = 1000


    def assertOneDecodingError(self):
        """
        Assert that exactly one L{DecodingError} has been logged and return
        that error.
        """
        errors = self.flushLoggedErrors(DecodingError)
        self.assertEquals(len(errors), 1)
        return errors[0]


    def test_oneFrame(self):
        """
        We can send one frame handled with one C{dataReceived} call.
        """
        self.decoder.dataReceived("\x00frame\xff")
        self.assertEquals(self.decoder.handler.frames, ["frame"])


    def test_oneFrameSplitted(self):
        """
        A frame can be split into several C{dataReceived} calls, and will be
        combined again when sent to the C{WebSocketHandler}.
        """
        self.decoder.dataReceived("\x00fra")
        self.decoder.dataReceived("me\xff")
        self.assertEquals(self.decoder.handler.frames, ["frame"])


    def test_multipleFrames(self):
        """
        Several frames can be received in a single C{dataReceived} call.
        """
        self.decoder.dataReceived("\x00frame1\xff\x00frame2\xff")
        self.assertEquals(self.decoder.handler.frames, ["frame1", "frame2"])


    def test_missingNull(self):
        """
        If a frame not starting with C{\\x00} is received, the connection is
        dropped.
        """
        self.decoder.dataReceived("frame\xff")
        self.assertOneDecodingError()
        self.assertTrue(self.channel.transport.disconnected)


    def test_missingNullAfterGoodFrame(self):
        """
        If a frame not starting with C{\\x00} is received after a correct
        frame, the connection is dropped.
        """
        self.decoder.dataReceived("\x00frame\xfffoo")
        self.assertOneDecodingError()
        self.assertTrue(self.channel.transport.disconnected)
        self.assertEquals(self.decoder.handler.frames, ["frame"])


    def test_emptyReceive(self):
        """
        Received an empty string doesn't do anything.
        """
        self.decoder.dataReceived("")
        self.assertFalse(self.channel.transport.disconnected)


    def test_maxLength(self):
        """
        If a frame is received which is bigger than C{MAX_LENGTH}, the
        connection is dropped.
        """
        self.decoder.dataReceived("\x00" + "x" * 101)
        self.assertTrue(self.channel.transport.disconnected)


    def test_maxLengthFrameCompleted(self):
        """
        If a too big frame is received in several fragments, the connection is
        dropped.
        """
        self.decoder.dataReceived("\x00" + "x" * 90)
        self.decoder.dataReceived("x" * 11 + "\xff")
        self.assertTrue(self.channel.transport.disconnected)


    def test_frameLengthReset(self):
        """
        The length of frames is reset between frame, thus not creating an error
        when the accumulated length exceeds the maximum frame length.
        """
        for i in range(15):
            self.decoder.dataReceived("\x00" + "x" * 10 + "\xff")
        self.assertFalse(self.channel.transport.disconnected)


    def test_oneBinaryFrame(self):
        """
        A binary frame is parsed and ignored, the following text frame is
        delivered.
        """
        self.decoder.dataReceived("\xff\x0abinarydata\x00text frame\xff")
        self.assertEquals(self.decoder.handler.frames, ["text frame"])


    def test_multipleBinaryFrames(self):
        """
        Text frames intermingled with binary frames are parsed correctly.
        """
        tf1, tf2, tf3 = "\x00frame1\xff", "\x00frame2\xff", "\x00frame3\xff"
        bf1, bf2, bf3 = "\xff\x01X", "\xff\x1a" + "X" * 0x1a, "\xff\x02AB"

        self.decoder.dataReceived(tf1 + bf1 + bf2 + tf2 + tf3 + bf3)
        self.assertEquals(self.decoder.handler.frames,
                          ["frame1", "frame2", "frame3"])


    def test_binaryFrameMultipleLengthBytes(self):
        """
        A binary frame can have its length field spread across multiple bytes.
        """
        bf = "\xff\x81\x48" + "X" * 200
        tf = "\x00frame\xff"
        self.decoder.dataReceived(bf + tf + bf)
        self.assertEquals(self.decoder.handler.frames, ["frame"])


    def test_binaryAndTextSplitted(self):
        """
        Intermingled binary and text frames can be split across several
        C{dataReceived} calls.
        """
        tf1, tf2 = "\x00text\xff", "\x00other text\xff"
        bf1, bf2, bf3 = ("\xff\x01X", "\xff\x81\x48" + "X" * 200,
                         "\xff\x20" + "X" * 32)

        chunks = [bf1[0], bf1[1:], tf1[:2], tf1[2:] + bf2[:2], bf2[2:-2],
                  bf2[-2:-1], bf2[1] + tf2[:-1], tf2[-1], bf3]
        for c in chunks:
            self.decoder.dataReceived(c)

        self.assertEquals(self.decoder.handler.frames, ["text", "other text"])
        self.assertFalse(self.channel.transport.disconnected)


    def test_maxBinaryLength(self):
        """
        If a binary frame's declared length exceeds MAX_BINARY_LENGTH, the
        connection is dropped.
        """
        self.decoder.dataReceived("\xff\xff\xff\xff\xff\x01")
        self.assertTrue(self.channel.transport.disconnected)


    def test_closingHandshake(self):
        """
        After receiving the closing handshake, the server sends its own closing
        handshake and ignores all future data.
        """
        self.decoder.dataReceived("\x00frame\xff\xff\x00random crap")
        self.decoder.dataReceived("more random crap, that's discarded")
        self.assertEquals(self.decoder.handler.frames, ["frame"])
        self.assertTrue(self.decoder.closing)


    def test_invalidFrameType(self):
        """
        Frame types other than 0x00 and 0xff cause the connection to be
        dropped.
        """
        ok = "\x00ok\xff"
        wrong = "\x05foo\xff"

        self.decoder.dataReceived(ok + wrong + ok)
        self.assertEquals(self.decoder.handler.frames, ["ok"])
        error = self.assertOneDecodingError()
        self.assertTrue(self.channel.transport.disconnected)


    def test_emptyFrame(self):
        """
        An empty text frame is correctly parsed.
        """
        self.decoder.dataReceived("\x00\xff")
        self.assertEquals(self.decoder.handler.frames, [""])
        self.assertFalse(self.channel.transport.disconnected)