capsite/toybox: a grant is an object in env, not the vat's global fetch

A vat's globalOutbound is now always null. A granted host arrives as
env.egress, an Egress the app can hand to whichever of its parts should
have it; as globalOutbound it was ambient to every module in the vat.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dckcandClaude Opus 5.5 committed 2026-10-13 21:44:29 -05:00
1 parent 7bf6eb44c7
commit 2820c015ee
4 files changed
+20 -13

No files matched your search

+5 -3
View File
@@ -1,13 +1,15 @@
import { DurableObject } from "cloudflare:workers";
/** `?url=<target>` fetches it; with `&ws=1`, opens a WebSocket there and reports the echo of "hello". */
/** `?url=<target>` fetches it through `env.egress`; with `&ws=1`, opens a WebSocket there and reports the echo of "hello". */
export class App extends DurableObject {
async fetch(request) {
const params = new URL(request.url).searchParams;
const target = params.get("url");
const { egress } = this.env;
if (!egress) return new Response("no egress granted\n");
try {
if (!params.has("ws")) return new Response(`got: ${await (await fetch(target)).text()}\n`);
const resp = await fetch(target, { headers: { Upgrade: "websocket" } });
if (!params.has("ws")) return new Response(`got: ${await (await egress.fetch(target)).text()}\n`);
const resp = await egress.fetch(target, { headers: { Upgrade: "websocket" } });
const ws = resp.webSocket;
if (!ws) return new Response(`no websocket: ${resp.status} ${await resp.text()}`);
ws.accept();