micropython-lib icon indicating copy to clipboard operation
micropython-lib copied to clipboard

aiohttp: ws: frame not fully received/read if large

Open mirko opened this issue 5 months ago • 3 comments

I noticed how large payload are cut-off when using the high-level receive-functions provided by the websocket implementation of aiohttp.

The following debug statements show the observed truncation:

diff --git a/python-ecosys/aiohttp/aiohttp/aiohttp_ws.py b/python-ecosys/aiohttp/aiohttp/aiohttp_ws.py
index 6e0818c..34c7b08 100644
--- a/python-ecosys/aiohttp/aiohttp/aiohttp_ws.py
+++ b/python-ecosys/aiohttp/aiohttp/aiohttp_ws.py
@@ -203,7 +203,9 @@ class WebSocketClient:
 
         if has_mask:  # pragma: no cover
             mask = await self.reader.read(4)
+        print("READING BYTES:", length)
         payload = await self.reader.read(length)
+        print("READ BYTES:", len(payload))
         if has_mask:  # pragma: no cover
             payload = bytes(x ^ mask[i % 4] for i, x in enumerate(payload))
         return opcode, payload

Output from test run supposed to receive a >1.5KiB payload:

READING BYTES: 1594
READ BYTES: 1436

mirko avatar Jul 31 '25 16:07 mirko

The issue probably lies in that read(n) does not guarantee to actually read n bytes (all at once). Normally I'd iterate over reading until result is null/None or read and count received bytes in a loop until everything is received as expected. Neither approach appears to work in this scenario, though.

mirko avatar Jul 31 '25 16:07 mirko

Attempted fix: https://github.com/micropython/micropython-lib/pull/1038

mirko avatar Jul 31 '25 16:07 mirko

Should be fixed by #1034 (which is merged).

dpgeorge avatar Aug 01 '25 00:08 dpgeorge