MCPcopy Create free account
hub / github.com/cloudflare/computer / handleConnect

Function handleConnect

packages/computerd/src/cli/computerd.ts:335–404  ·  view source on GitHub ↗
(
  request: IncomingMessage,
  response: ServerResponse,
  rpc: ReturnType<typeof createWorkspaceServer>,
  upstreamSlot: { ws: WebSocket | undefined },
)

Source from the content-addressed store, hash-verified

333}
334
335async function handleConnect(
336 request: IncomingMessage,
337 response: ServerResponse,
338 rpc: ReturnType<typeof createWorkspaceServer>,
339 upstreamSlot: { ws: WebSocket | undefined },
340): Promise<void> {
341 let body: ConnectBody;
342 try {
343 body = await readJson<ConnectBody>(request);
344 } catch (error) {
345 send(response, 400, `invalid JSON body: ${(error as Error).message}\n`, {
346 "content-type": "text/plain; charset=utf-8",
347 });
348 return;
349 }
350
351 if (typeof body.url !== "string" || body.url.length === 0) {
352 send(response, 400, "missing 'url' in body\n", {
353 "content-type": "text/plain; charset=utf-8",
354 });
355 return;
356 }
357 const baseUrl = body.url.replace(/\/+$/, "");
358 const healthTimeoutMs =
359 typeof body.healthTimeoutMs === "number" && body.healthTimeoutMs > 0
360 ? body.healthTimeoutMs
361 : 30_000;
362
363 try {
364 await waitForHealth(baseUrl, healthTimeoutMs);
365 } catch (error) {
366 send(response, 502, `upstream /health unreachable: ${(error as Error).message}\n`, {
367 "content-type": "text/plain; charset=utf-8",
368 });
369 return;
370 }
371
372 // Close any prior outbound session before opening a new one. A DO
373 // restart / hibernate hands the new incarnation a fresh /connect;
374 // without this, the previous WebSocket leaks for the life of the
375 // container.
376 const previous = upstreamSlot.ws;
377 if (previous !== undefined) {
378 upstreamSlot.ws = undefined;
379 try {
380 previous.close(1000, "replaced by new /connect");
381 } catch {
382 // already closed; idempotent
383 }
384 }
385
386 const wsUrl = `${toWebSocketUrl(baseUrl)}/ws`;
387 const ws = new WebSocket(wsUrl);
388 upstreamSlot.ws = ws;
389 ws.once("open", () => {
390 console.log(`/connect: attached RPC session to ${wsUrl}`);
391 acceptWebSocketSession(ws, rpc);
392 });

Callers 1

createHTTPServerFunction · 0.85

Calls 8

acceptWebSocketSessionFunction · 0.90
sendFunction · 0.85
waitForHealthFunction · 0.70
toWebSocketUrlFunction · 0.70
replaceMethod · 0.65
closeMethod · 0.65
logMethod · 0.65
errorMethod · 0.65

Tested by

no test coverage detected