summaryrefslogtreecommitdiff
path: root/tests/extmod/websocket_basic.py
diff options
context:
space:
mode:
authorJeff Epler <jepler@gmail.com>2025-08-04 10:05:28 -0500
committerDamien George <damien@micropython.org>2025-10-05 15:41:54 +1100
commitb94162b5dfe19ae1083a0bdf0611e07262fe8fe8 (patch)
tree438422297ee322155ee7363bcb8f46eb1afc30f7 /tests/extmod/websocket_basic.py
parentd921dd6d61be29866e62b923d3e37859829188bd (diff)
extmod/modwebsocket: Enable split frames and test them.
This fixes several assertion errors that were found in fuzz testing, for unimplemented portions of the websocket spec. The assertions were either turned into Python exceptions, or the missing functionality was implemented. Split frames are now enabled and work, enabling reception of frames up to 64kB (assuming they are encoded with a 16-bit size field). Frames with a 64-bit size fields remain unsupported but no longer result in an assertion error. Instead, Initial reception of such a frame will result in OSError(EIO) and subsequent operations on the same websocket will fail because framing has been lost. Transmitting frames larger than 64kB is unsupported. Attempting to transmit such a frame will result in OSError(ENOBUFS). Subsequent operations on the websocket are possible. Signed-off-by: Jeff Epler <jepler@gmail.com>
Diffstat (limited to 'tests/extmod/websocket_basic.py')
-rw-r--r--tests/extmod/websocket_basic.py27
1 files changed, 22 insertions, 5 deletions
diff --git a/tests/extmod/websocket_basic.py b/tests/extmod/websocket_basic.py
index 133457784..6ebd65d65 100644
--- a/tests/extmod/websocket_basic.py
+++ b/tests/extmod/websocket_basic.py
@@ -13,6 +13,13 @@ def ws_read(msg, sz):
return ws.read(sz)
+# put raw data in the stream and do a series of websocket read
+def ws_readn(msg, *args):
+ ws = websocket.websocket(io.BytesIO(msg))
+ for sz in args:
+ yield ws.read(sz)
+
+
# do a websocket write and then return the raw data from the stream
def ws_write(msg, sz):
s = io.BytesIO()
@@ -24,18 +31,28 @@ def ws_write(msg, sz):
# basic frame
print(ws_read(b"\x81\x04ping", 4))
-print(ws_read(b"\x80\x04ping", 4)) # FRAME_CONT
print(ws_write(b"pong", 6))
-# split frames are not supported
-# print(ws_read(b"\x01\x04ping", 4))
+# split frames and irregular size reads
+for s in ws_readn(b"\x01\x04ping\x00\x04Ping\x80\x04PING", 6, 4, 2, 2):
+ print(s)
# extended payloads
print(ws_read(b"\x81~\x00\x80" + b"ping" * 32, 128))
print(ws_write(b"pong" * 32, 132))
-# mask (returned data will be 'mask' ^ 'mask')
-print(ws_read(b"\x81\x84maskmask", 4))
+# 64-bit payload size, unsupported by MicroPython implementation. Framing is lost.
+msg = b"\x81\x7f\x00\x00\x00\x00\x00\x00\x00\x80" + b"ping" * 32
+ws = websocket.websocket(io.BytesIO(msg))
+try:
+ print(ws.read(1))
+except OSError as e:
+ print("ioctl: EIO:", e.errno == errno.EIO)
+
+# mask (returned data will be 'maskmask' ^ 'maskMASK')
+print(ws_read(b"\x81\x88maskmaskMASK", 8))
+# mask w/2-byte payload len (returned data will be 'maskmask' ^ 'maskMASK')
+print(ws_read(b"\x81\xfe\x00\x08maskmaskMASK", 8))
# close control frame
s = io.BytesIO(b"\x88\x00") # FRAME_CLOSE