Three pre-existing Streamable HTTP transport items surfaced during the #2547 review that are independent of the keep-alive and delivery work there. Collecting them here so they don't get lost; each is small enough to fix individually.
-
Protocol-version gate accepts unvalidated strings on initialize. The priming/resumability gate compares protocolVersion >= '2025-11-25' lexicographically, and for initialize requests the string comes verbatim from the request body without being checked against SUPPORTED_PROTOCOL_VERSIONS (non-initialize requests are header-validated). Unsupported strings that sort above the threshold (draft, 2026-01-01) enable priming events and the polling callbacks for the initialize stream even though the negotiated version in the response may be lower. Gate on the negotiated version instead.
-
Concurrent DELETE requests can fire onsessionclosed twice. While the first DELETE is parked on the callback await, _closed is still false, so a second DELETE passes the guards and fires the callback again for the same session. A flag set before invoking the callback closes the window.
-
The EventStore contract has no session scoping for the standalone stream. Every transport stores standalone server-initiated messages under the fixed id _GET_stream, so a store instance shared across sessions (module-level store in ssePollingExample, or any multi-node shared store) mixes sessions on standalone resume: one session's resume can replay another session's notifications. The contract needs a session dimension, or documented single-session store usage.
Applies to both main and v1.x.
Three pre-existing Streamable HTTP transport items surfaced during the #2547 review that are independent of the keep-alive and delivery work there. Collecting them here so they don't get lost; each is small enough to fix individually.
Protocol-version gate accepts unvalidated strings on initialize. The priming/resumability gate compares
protocolVersion >= '2025-11-25'lexicographically, and for initialize requests the string comes verbatim from the request body without being checked againstSUPPORTED_PROTOCOL_VERSIONS(non-initialize requests are header-validated). Unsupported strings that sort above the threshold (draft,2026-01-01) enable priming events and the polling callbacks for the initialize stream even though the negotiated version in the response may be lower. Gate on the negotiated version instead.Concurrent DELETE requests can fire
onsessionclosedtwice. While the first DELETE is parked on the callback await,_closedis still false, so a second DELETE passes the guards and fires the callback again for the same session. A flag set before invoking the callback closes the window.The
EventStorecontract has no session scoping for the standalone stream. Every transport stores standalone server-initiated messages under the fixed id_GET_stream, so a store instance shared across sessions (module-level store inssePollingExample, or any multi-node shared store) mixes sessions on standalone resume: one session's resume can replay another session's notifications. The contract needs a session dimension, or documented single-session store usage.Applies to both main and v1.x.