From 3143c723399e8d1aa65566912718dac9d5c65b76 Mon Sep 17 00:00:00 2001 From: Alexander Peyser Date: Thu, 29 Aug 2024 17:37:51 +0200 Subject: [PATCH] Read full json message from socket in i3ipc.aio.connection (#1) Python socket.recv takes a _maximum_length -- but may return a shorter message depending on detail of the socket state. Replaced with a socket.recv_into loop that read the entire json message. --- i3ipc/aio/connection.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/i3ipc/aio/connection.py b/i3ipc/aio/connection.py index 4755853..f29a290 100644 --- a/i3ipc/aio/connection.py +++ b/i3ipc/aio/connection.py @@ -300,12 +300,22 @@ def _message_reader(self): except Exception as e: self.main_quit(_error=e) - def _read_message(self): + def _recv(self, size): + buf = bytearray(size) + mem = memoryview(buf) + sock = self._sub_socket + while len(mem): + if not (rsize := sock.recv_into(mem)): + return b'' + mem = mem[rsize:] + mem.release() + return buf + def _read_message(self): error = None buf = b'' try: - buf = self._sub_socket.recv(_struct_header_size) + buf = self._recv(_struct_header_size) except ConnectionError as e: error = e @@ -325,7 +335,7 @@ def _read_message(self): magic, message_length, event_type = _unpack_header(buf) assert magic == _MAGIC - raw_message = self._sub_socket.recv(message_length) + raw_message = self._recv(message_length) message = json.loads(raw_message) # events have the highest bit set