From 1d25512cf4d4ce01d720951232c88fe0d3d5741b Mon Sep 17 00:00:00 2001 From: "Michiel, Jeroen" Date: Fri, 19 Jan 2018 15:02:08 +0100 Subject: [PATCH 1/3] fix for issue #230 --- ws4py/framing.py | 2 +- ws4py/streaming.py | 12 +++++++-- ws4py/websocket.py | 64 +++++++++++++++++++++++++--------------------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/ws4py/framing.py b/ws4py/framing.py index 5046167..691b3a3 100644 --- a/ws4py/framing.py +++ b/ws4py/framing.py @@ -252,7 +252,7 @@ def _parsing(self): some_bytes = buf[:self.payload_length] self.body = some_bytes - yield + yield len(some_bytes)-len(buf) def mask(self, data): """ diff --git a/ws4py/streaming.py b/ws4py/streaming.py index 4420ba1..945378f 100644 --- a/ws4py/streaming.py +++ b/ws4py/streaming.py @@ -177,12 +177,20 @@ def receiver(self): utf8validator = Utf8Validator() running = True frame = None + remaining = 0 while running: frame = Frame() while 1: try: - some_bytes = (yield next(frame.parser)) - frame.parser.send(some_bytes) + if remaining<0: + #another message left in the pipeline + some_bytes = (yield remaining) + else: + some_bytes = (yield next(frame.parser)) + remaining = frame.parser.send(some_bytes) + if remaining < 0: + #another message is waiting, but we can finish this one + next(frame.parser) except GeneratorExit: running = False break diff --git a/ws4py/websocket.py b/ws4py/websocket.py index 511921e..f6a1593 100644 --- a/ws4py/websocket.py +++ b/ws4py/websocket.py @@ -455,39 +455,45 @@ def process(self, bytes): if not bytes and self.reading_buffer_size > 0: return False - self.reading_buffer_size = s.parser.send(bytes) or DEFAULT_READING_SIZE + while bytes: + self.reading_buffer_size = s.parser.send(bytes) or DEFAULT_READING_SIZE - if s.closing is not None: - logger.debug("Closing message received (%d) '%s'" % (s.closing.code, s.closing.reason)) - if not self.server_terminated: - self.close(s.closing.code, s.closing.reason) + if self.reading_buffer_size < 0: + bytes = bytes[self.reading_buffer_size:] else: - self.client_terminated = True - return False + bytes = b'' + + if s.closing is not None: + logger.debug("Closing message received (%d) '%s'" % (s.closing.code, s.closing.reason)) + if not self.server_terminated: + self.close(s.closing.code, s.closing.reason) + else: + self.client_terminated = True + return False - if s.errors: - for error in s.errors: - logger.debug("Error message received (%d) '%s'" % (error.code, error.reason)) - self.close(error.code, error.reason) - s.errors = [] - return False + if s.errors: + for error in s.errors: + logger.debug("Error message received (%d) '%s'" % (error.code, error.reason)) + self.close(error.code, error.reason) + s.errors = [] + return False - if s.has_message: - self.received_message(s.message) - if s.message is not None: - s.message.data = None - s.message = None - return True - - if s.pings: - for ping in s.pings: - self._write(s.pong(ping.data)) - s.pings = [] - - if s.pongs: - for pong in s.pongs: - self.ponged(pong) - s.pongs = [] + if s.has_message: + self.received_message(s.message) + if s.message is not None: + s.message.data = None + s.message = None + continue + + if s.pings: + for ping in s.pings: + self._write(s.pong(ping.data)) + s.pings = [] + + if s.pongs: + for pong in s.pongs: + self.ponged(pong) + s.pongs = [] return True From 358b62eb056d7856fc9e7a40c8eb1c39a8fe6f6d Mon Sep 17 00:00:00 2001 From: "Michiel, Jeroen" Date: Fri, 19 Jan 2018 15:14:55 +0100 Subject: [PATCH 2/3] fix unittest --- test/test_websocket.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_websocket.py b/test/test_websocket.py index 96fb384..cc736e8 100644 --- a/test/test_websocket.py +++ b/test/test_websocket.py @@ -165,6 +165,7 @@ def test_closing_message_received(self): ws = WebSocket(sock=m) with patch.multiple(ws, close=c): ws.stream = s + s.parser.send = lambda p:1 ws.stream.closing = CloseControlMessage(code=1000, reason='test closing') ws.process(b'unused for this test') c.assert_called_once_with(1000, b'test closing') From c038986ba3d344af92d4d6a7f8a7eb31d9811f47 Mon Sep 17 00:00:00 2001 From: "Michiel, Jeroen" Date: Fri, 19 Jan 2018 16:38:53 +0100 Subject: [PATCH 3/3] extra safety --- ws4py/framing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ws4py/framing.py b/ws4py/framing.py index 691b3a3..f6ab740 100644 --- a/ws4py/framing.py +++ b/ws4py/framing.py @@ -252,7 +252,7 @@ def _parsing(self): some_bytes = buf[:self.payload_length] self.body = some_bytes - yield len(some_bytes)-len(buf) + yield min(0,len(some_bytes)-len(buf)) def mask(self, data): """