fix(websocket): byte-based caps for pending buffer + inbound WS sizes (WS-05, WS-06)

This commit is contained in:
2026-08-29 12:00:04 +00:00
parent 5024d99862
commit 92cc11a74f
5 changed files with 264 additions and 23 deletions
+28 -1
View File
@@ -11,7 +11,8 @@ use alkcall::registry::registration::{
};
use alkcall::registry::spec::{AccessControl, OperationSpec, OperationType, Visibility};
use alkhttp::websocket::{
frame_channel0_chunk, ChunkAssembler, FrameAssembler, WsClient, WS_MESSAGE_CAP,
frame_channel0_chunk, ChunkAssembler, FrameAssembler, WsClient, INBOUND_WS_MESSAGE_CAP,
WS_MESSAGE_CAP,
};
use std::collections::HashMap;
use std::sync::Arc;
@@ -579,3 +580,29 @@ async fn services_list_over_channel0_is_access_control_filtered() {
assert!(!names.contains(&"admin/secret"), "got: {names:?}");
ws.close().await;
}
#[tokio::test]
async fn inbound_message_over_cap_fails_the_connection() {
let addr = spawn_ws_server(
echo_registry(),
provider_with(vec![("tok-1", identity("alice", &[]))]),
)
.await;
let mut ws = WsClient::connect_authorized(&format!("{addr}/alk/channels"), "tok-1")
.await
.unwrap();
// One WS binary message larger than INBOUND_WS_MESSAGE_CAP: the
// server's explicit max_message_size (WS-06) must fail the
// connection instead of accepting it (the byte-adapter boundary is
// the chunk header, so the adapter never dissects messages; the WS
// library cap is the enforcement point).
let oversized = vec![b'x'; INBOUND_WS_MESSAGE_CAP + 1];
ws.send_binary_piece(&oversized).await;
let close = ws
.next_close(std::time::Duration::from_secs(5))
.await
.expect("server must fail the oversized-inbound connection (WS-06)");
assert!(close.is_some(), "expected a close or stream end, got {close:?}");
}