From 70ffb446ed40fcddd57f887ef355b1e0000b9291 Mon Sep 17 00:00:00 2001 From: oxy-star Date: Thu, 9 Jul 2026 08:49:25 +0300 Subject: [PATCH] Fix client getting stuck on server EOF --- aiomcache/client.py | 5 +++++ tests/commands_test.py | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/aiomcache/client.py b/aiomcache/client.py index 78896f4..be8df0d 100644 --- a/aiomcache/client.py +++ b/aiomcache/client.py @@ -107,6 +107,11 @@ async def _execute_simple_command(self, conn: Connection, raw_command: bytes) -> while not line.endswith(b'\r\n'): line = await conn.reader.readline() + if not line: + # readline() returns an empty string at EOF. + raise ClientException( + 'Connection closed by the server before receiving a full response', + ) response.extend(line) return response[:-2] diff --git a/tests/commands_test.py b/tests/commands_test.py index ae5768e..2ae9048 100644 --- a/tests/commands_test.py +++ b/tests/commands_test.py @@ -362,6 +362,26 @@ async def test_close(mcache: Client) -> None: assert mcache._pool.size() == 0 +async def test_simple_command_server_dies_mid_response() -> None: + async def handler(reader: asyncio.StreamReader, + writer: asyncio.StreamWriter) -> None: + await reader.readline() + writer.write(b"VERSION 1.6.0") # incomplete line, no \r\n + await writer.drain() + writer.close() + + server = await asyncio.start_server(handler, "127.0.0.1", 0) + port = server.sockets[0].getsockname()[1] + client = Client("127.0.0.1", port) + try: + with pytest.raises(ClientException, match="closed by the server"): + await asyncio.wait_for(client.version(), timeout=5) + finally: + await client.close() + server.close() + await server.wait_closed() + + @pytest.mark.parametrize( "value", [