-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.ts
More file actions
57 lines (48 loc) · 1.95 KB
/
server.ts
File metadata and controls
57 lines (48 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import http from "node:http";
import { createServerAdapter } from "@whatwg-node/server";
import { acceptFetcherCapabilityFromNodeSocket } from "captun/node";
import { WebSocketServer } from "ws";
let egressTunnel: ReturnType<typeof acceptFetcherCapabilityFromNodeSocket> | undefined;
const egressFetch: typeof fetch = async (input, init) => {
if (egressTunnel) return egressTunnel.fetch(new Request(input, init));
return fetch(input, init);
};
const webSockets = new WebSocketServer({ noServer: true });
const server = http.createServer(createServerAdapter(serverFetch));
async function serverFetch(request: Request): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/weather") {
const city = url.searchParams.get("city") || "";
const weatherResponse = await egressFetch(`https://wttr.in/${city}?format=j1`);
const weather = (await weatherResponse.json()) as {
current_condition: [{ temp_C: string }];
};
return new Response(
`The temperature in ${city} is ${weather.current_condition[0].temp_C} celsius`,
);
}
return new Response("Not found\n", { status: 404 });
}
server.on("upgrade", (request, socket, head) => {
const url = new URL(request.url || "/", `http://${request.headers.host || "127.0.0.1"}`);
if (url.pathname !== "/__intercept-egress-traffic") {
socket.destroy();
return;
}
webSockets.handleUpgrade(request, socket, head, (webSocket) => {
const tunnel = acceptFetcherCapabilityFromNodeSocket(webSocket, {
onDisconnect: () => {
if (egressTunnel === tunnel) egressTunnel = undefined;
},
});
egressTunnel?.[Symbol.dispose]();
egressTunnel = tunnel;
queueMicrotask(() => void tunnel.ready({ url: `${url.protocol}//${url.host}` }));
});
});
server.listen(Number(process.env.PORT), "127.0.0.1");
process.on("SIGINT", () => {
webSockets.close();
server.close(() => process.exit(0));
setTimeout(() => process.exit(1), 5_000).unref();
});