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
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)