Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions __tests__/pending-handshake.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Type } from 'typebox';
import { createMockTransportNetwork } from '../testUtil';
import { waitFor } from '../testUtil/fixtures/cleanup';
import { createPromiseWithResolvers } from '../transport/promises';
import { SessionState } from '../transport';

test('a validating handshake cannot connect after the server closes', async () => {
// Risk: a client connects to a dead server and its calls hang.
Expand Down Expand Up @@ -36,3 +37,43 @@ test('a validating handshake cannot connect after the server closes', async () =
await network.cleanup();
}
});

test('a rejecting handshake cannot crash or connect after the server closes', async () => {
// Risk: a validation failure during shutdown must not crash the server process.
const network = createMockTransportNetwork();
const validation = createPromiseWithResolvers<object>();
let validating = false;
const server = network.getServerTransport('SERVER', {
schema: Type.Object({}),
validate: () => {
validating = true;

return validation.promise;
},
});
const client = network.getClientTransport('client', {
schema: Type.Object({}),
construct: async () => ({}),
});
let connected = false;
server.addEventListener('sessionTransition', ({ state }) => {
if (state === SessionState.Connected) {
connected = true;
}
});
try {
client.connect('SERVER');
await waitFor(() => expect(validating).toBe(true));
server.close();
validation.reject(new Error('validation failed'));
await vi.advanceTimersByTimeAsync(0);
expect(connected).toBe(false);
expect(server.sessions.size).toBe(0);
expect(server.pendingSessions.size).toBe(0);
expect(server.getStatus()).toBe('closed');
} finally {
client.close();
server.close();
await network.cleanup();
}
});
4 changes: 4 additions & 0 deletions transport/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,10 @@ export abstract class ServerTransport<
session.conn.extras,
);
} catch (err) {
if (session._isConsumed) {
return;
}

this.rejectHandshakeRequest(
session,
msg.from,
Expand Down
Loading