mirror of
https://github.com/morluto/rea.git
synced 2026-10-31 20:06:14 +00:00
fix(mcp): leave the live session alone when the new client left during the initialize probe
A complete initialize still parses after its client disconnects, so the takeover closed the working transport for a client that would never receive the new session. The takeover now also requires that the request's signal has not aborted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
baff9d359e
commit
d15d817e92
2 files changed
+27
-1
No files matched your search
@@ -519,6 +519,30 @@ it("requires exact Accept media ranges before a sessionless POST may replace the
|
||||
await client.close();
|
||||
});
|
||||
|
||||
it("keeps the live session when the new client left before its initialize was probed", async () => {
|
||||
const slot = new McpSessionSlot(
|
||||
createEchoServer(() => undefined),
|
||||
undefined,
|
||||
);
|
||||
const close = vi.spyOn(
|
||||
WebStandardStreamableHTTPServerTransport.prototype,
|
||||
"close",
|
||||
);
|
||||
try {
|
||||
expect((await slot.handle(initializeRequest())).status).toBe(200);
|
||||
const left = new AbortController();
|
||||
left.abort();
|
||||
const abandoned = new Request(initializeRequest(), { signal: left.signal });
|
||||
expect((await slot.handle(abandoned)).status).toBe(400);
|
||||
expect(close).not.toHaveBeenCalled();
|
||||
expect((await slot.handle(initializeRequest())).status).toBe(200);
|
||||
expect(close).toHaveBeenCalledTimes(1);
|
||||
} finally {
|
||||
close.mockRestore();
|
||||
await slot.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps a session whose transport shutdown failed so the next close retries it", async () => {
|
||||
let shutdowns = 0;
|
||||
const slot = new McpSessionSlot(
|
||||
|
||||
@@ -232,7 +232,9 @@ export class McpSessionSlot {
|
||||
const open = this.#live;
|
||||
if (
|
||||
open?.transport.sessionId !== undefined &&
|
||||
(await isInitializePost(request))
|
||||
(await isInitializePost(request)) &&
|
||||
// A client that left while its initialize was probed would evict the session for nobody.
|
||||
!request.signal.aborted
|
||||
) {
|
||||
if (this.#closed) return SHUTTING_DOWN();
|
||||
this.logger?.info("MCP HTTP session replaced by a new client");
|
||||
|
||||
Reference in new issue
Block a user