mirror of
https://github.com/curl/curl.git
synced 2026-08-25 15:23:38 +03:00
websocket: pause writing and meta data fix
When writing a decoded chunk of websocket data, always flush the writer chain so that buffered data gets delivered before the ws meta data gets updated. Add client writer flags CURL_CW_FLAG_BLOWUP for writer types that may significantly enlarge write sizes. This flag causes the pause writer to be added and shrinks the write chunk sizes. We do not want that for content decoders like WS that do not change the size. Add test_20_13 to check that large frames are paused/unpaused correctly with the matching meta data. Fixes #22413 Reported-by: Hendrik Hübner Closes #22416
This commit is contained in:
parent
53565fbfd6
commit
3974491c97
11 changed files with 64 additions and 23 deletions
|
|
@ -325,12 +325,22 @@ class TestWebsockets:
|
|||
rss2 = r.profile.stats['rss'] / (1024 * 1024)
|
||||
assert (rss1 * 1.1) >= rss2, 'bad memory increase'
|
||||
|
||||
# test frame delivery when pausing
|
||||
def test_20_12_pause_frames(self, env: Env, ws_4frames):
|
||||
# test small frames delivery when pausing
|
||||
def test_20_12_pause_frames_small(self, env: Env, ws_4frames):
|
||||
payload = 127 * "x"
|
||||
client = LocalClient(env=env, name='cli_ws_pause')
|
||||
if not client.exists():
|
||||
pytest.skip(f'example client not built: {client.name}')
|
||||
url = f'ws://localhost:{ws_4frames.port}/'
|
||||
url = f'ws://localhost:{ws_4frames.port}/small'
|
||||
r = client.run(args=[url, payload])
|
||||
r.check_exit_code(0)
|
||||
|
||||
# test small frames delivery when pausing
|
||||
def test_20_13_pause_frames_large(self, env: Env, ws_4frames):
|
||||
payload = 127 * "x"
|
||||
client = LocalClient(env=env, name='cli_ws_pause')
|
||||
if not client.exists():
|
||||
pytest.skip(f'example client not built: {client.name}')
|
||||
url = f'ws://localhost:{ws_4frames.port}/large'
|
||||
r = client.run(args=[url, payload])
|
||||
r.check_exit_code(0)
|
||||
|
|
|
|||
|
|
@ -29,21 +29,30 @@ import logging
|
|||
|
||||
import websockets
|
||||
|
||||
MESSAGES = [
|
||||
MESSAGES_SMALL = [
|
||||
"Hello 1",
|
||||
"Hello 2",
|
||||
"Hello 3",
|
||||
"Hello 4",
|
||||
]
|
||||
|
||||
MESSAGES_LARGE = [
|
||||
b"x" * 65536,
|
||||
b"x" * 65536,
|
||||
b"x" * 65536,
|
||||
b"x" * 65536,
|
||||
]
|
||||
|
||||
|
||||
async def handler(websocket):
|
||||
peer = websocket.remote_address
|
||||
print(f"client from {peer[0]}:{peer[1]}", flush=True)
|
||||
print("handshake complete", flush=True)
|
||||
|
||||
msgs = MESSAGES_LARGE if websocket.request.path == '/large' else MESSAGES_SMALL
|
||||
|
||||
await asyncio.sleep(0.1)
|
||||
for index, payload in enumerate(MESSAGES, start=1):
|
||||
for index, payload in enumerate(msgs, start=1):
|
||||
await websocket.send(payload)
|
||||
print(f"sent frame {index}: {payload!r}", flush=True)
|
||||
# await asyncio.sleep(0.2)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue