From 47a58d354d3c289ce8fcd56f817976a43029887f Mon Sep 17 00:00:00 2001 From: Rapptz Date: Sat, 14 Oct 2017 21:17:27 -0400 Subject: Reimplement zlib streaming. This time with less bugs. It turned out that the crash was due to a synchronisation issue between the pending reads and the actual shard polling mechanism. Essentially the pending reads would be cancelled via a simple bool but there would still be a pass left and thus we would have a single pending read left before or after running the polling mechanism and this would cause a race condition. Now the pending read mechanism is properly waited for before returning control back to the caller. --- discord/gateway.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'discord/gateway.py') diff --git a/discord/gateway.py b/discord/gateway.py index 0ab02760..547d3401 100644 --- a/discord/gateway.py +++ b/discord/gateway.py @@ -186,6 +186,8 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol): # ws related stuff self.session_id = None self.sequence = None + self._zlib = zlib.decompressobj() + self._buffer = bytearray() @classmethod @asyncio.coroutine @@ -312,8 +314,17 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol): self._dispatch('socket_raw_receive', msg) if isinstance(msg, bytes): - msg = zlib.decompress(msg, 15, 10490000) # This is 10 MiB - msg = msg.decode('utf-8') + self._buffer.extend(msg) + + if len(msg) >= 4: + if msg[-4:] == b'\x00\x00\xff\xff': + msg = self._zlib.decompress(self._buffer) + msg = msg.decode('utf-8') + self._buffer = bytearray() + else: + return + else: + return msg = json.loads(msg) -- cgit v1.2.3