diff --git a/src/galaxy/api/jsonrpc.py b/src/galaxy/api/jsonrpc.py index 62a36b4..e491c3f 100644 --- a/src/galaxy/api/jsonrpc.py +++ b/src/galaxy/api/jsonrpc.py @@ -74,6 +74,7 @@ class Server(): self._notifications = {} self._eof_listeners = [] self._input_buffer = bytes() + self._input_buffer_it = 0 def register_method(self, name, callback, internal, sensitive_params=False): """ @@ -120,15 +121,17 @@ class Server(): """Like StreamReader.readline but without limit""" while True: chunk = await self._reader.read(1024) - if not chunk: - return chunk - previous_size = len(self._input_buffer) self._input_buffer += chunk - it = self._input_buffer.find(b"\n", previous_size) + it = self._input_buffer.find(b"\n", self._input_buffer_it) if it < 0: - continue + if not chunk: + return bytes() # EOF + else: + self._input_buffer_it = len(self._input_buffer) + continue line = self._input_buffer[:it] self._input_buffer = self._input_buffer[it+1:] + self._input_buffer_it = 0 return line def stop(self): diff --git a/tests/test_chunk_messages.py b/tests/test_chunk_messages.py index 3e09adb..68a4b52 100644 --- a/tests/test_chunk_messages.py +++ b/tests/test_chunk_messages.py @@ -12,6 +12,43 @@ def test_chunked_messages(plugin, read): message = json.dumps(request).encode() + b"\n" read.side_effect = [message[:5], message[5:], b""] - plugin.get_owned_games.return_value = None asyncio.run(plugin.run()) plugin.install_game.assert_called_with(game_id="3") + +def test_joined_messages(plugin, read): + requests = [ + { + "jsonrpc": "2.0", + "method": "install_game", + "params": { + "game_id": "3" + } + }, + { + "jsonrpc": "2.0", + "method": "launch_game", + "params": { + "game_id": "3" + } + } + ] + data = b"".join([json.dumps(request).encode() + b"\n" for request in requests]) + + read.side_effect = [data, b""] + asyncio.run(plugin.run()) + plugin.install_game.assert_called_with(game_id="3") + plugin.launch_game.assert_called_with(game_id="3") + +def test_not_finished(plugin, read): + request = { + "jsonrpc": "2.0", + "method": "install_game", + "params": { + "game_id": "3" + } + } + + message = json.dumps(request).encode() # no new line + read.side_effect = [message, b""] + asyncio.run(plugin.run()) + plugin.install_game.assert_not_called()