@hotcell/daemon 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-check.d.ts +1 -0
- package/dist/agent-check.js +105 -0
- package/dist/agent-check.js.map +1 -0
- package/dist/api/server.d.ts +64 -0
- package/dist/api/server.js +1368 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/ws.d.ts +14 -0
- package/dist/api/ws.js +214 -0
- package/dist/api/ws.js.map +1 -0
- package/dist/applevz-check.d.ts +1 -0
- package/dist/applevz-check.js +280 -0
- package/dist/applevz-check.js.map +1 -0
- package/dist/backups.d.ts +29 -0
- package/dist/backups.js +76 -0
- package/dist/backups.js.map +1 -0
- package/dist/capacity.d.ts +63 -0
- package/dist/capacity.js +95 -0
- package/dist/capacity.js.map +1 -0
- package/dist/config.d.ts +241 -0
- package/dist/config.js +152 -0
- package/dist/config.js.map +1 -0
- package/dist/cost.d.ts +9 -0
- package/dist/cost.js +19 -0
- package/dist/cost.js.map +1 -0
- package/dist/density-bench.d.ts +1 -0
- package/dist/density-bench.js +97 -0
- package/dist/density-bench.js.map +1 -0
- package/dist/driver/agent-driver.d.ts +67 -0
- package/dist/driver/agent-driver.js +197 -0
- package/dist/driver/agent-driver.js.map +1 -0
- package/dist/driver/agent.d.ts +94 -0
- package/dist/driver/agent.js +319 -0
- package/dist/driver/agent.js.map +1 -0
- package/dist/driver/applevz.d.ts +95 -0
- package/dist/driver/applevz.js +527 -0
- package/dist/driver/applevz.js.map +1 -0
- package/dist/driver/container.d.ts +99 -0
- package/dist/driver/container.js +733 -0
- package/dist/driver/container.js.map +1 -0
- package/dist/driver/fc-api.d.ts +85 -0
- package/dist/driver/fc-api.js +173 -0
- package/dist/driver/fc-api.js.map +1 -0
- package/dist/driver/firecracker.d.ts +126 -0
- package/dist/driver/firecracker.js +560 -0
- package/dist/driver/firecracker.js.map +1 -0
- package/dist/driver/index.d.ts +17 -0
- package/dist/driver/index.js +61 -0
- package/dist/driver/index.js.map +1 -0
- package/dist/driver/router.d.ts +82 -0
- package/dist/driver/router.js +159 -0
- package/dist/driver/router.js.map +1 -0
- package/dist/driver/types.d.ts +234 -0
- package/dist/driver/types.js +2 -0
- package/dist/driver/types.js.map +1 -0
- package/dist/driver/unsupported.d.ts +50 -0
- package/dist/driver/unsupported.js +81 -0
- package/dist/driver/unsupported.js.map +1 -0
- package/dist/driver/vz-image.d.ts +35 -0
- package/dist/driver/vz-image.js +75 -0
- package/dist/driver/vz-image.js.map +1 -0
- package/dist/e2e-harness.d.ts +1 -0
- package/dist/e2e-harness.js +99 -0
- package/dist/e2e-harness.js.map +1 -0
- package/dist/egress-check.d.ts +8 -0
- package/dist/egress-check.js +317 -0
- package/dist/egress-check.js.map +1 -0
- package/dist/fc-check.d.ts +1 -0
- package/dist/fc-check.js +113 -0
- package/dist/fc-check.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +114 -0
- package/dist/index.js.map +1 -0
- package/dist/kernels.d.ts +22 -0
- package/dist/kernels.js +134 -0
- package/dist/kernels.js.map +1 -0
- package/dist/lifecycle.d.ts +49 -0
- package/dist/lifecycle.js +111 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +67 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.d.ts +46 -0
- package/dist/metrics.js +92 -0
- package/dist/metrics.js.map +1 -0
- package/dist/net/firewall.d.ts +4 -0
- package/dist/net/firewall.js +80 -0
- package/dist/net/firewall.js.map +1 -0
- package/dist/pricing.d.ts +36 -0
- package/dist/pricing.js +81 -0
- package/dist/pricing.js.map +1 -0
- package/dist/proxy/allowlist-default.d.ts +23 -0
- package/dist/proxy/allowlist-default.js +53 -0
- package/dist/proxy/allowlist-default.js.map +1 -0
- package/dist/proxy/allowlist.d.ts +43 -0
- package/dist/proxy/allowlist.js +87 -0
- package/dist/proxy/allowlist.js.map +1 -0
- package/dist/proxy/egress.d.ts +49 -0
- package/dist/proxy/egress.js +599 -0
- package/dist/proxy/egress.js.map +1 -0
- package/dist/proxy/ratelimit.d.ts +49 -0
- package/dist/proxy/ratelimit.js +74 -0
- package/dist/proxy/ratelimit.js.map +1 -0
- package/dist/proxy/server.d.ts +26 -0
- package/dist/proxy/server.js +202 -0
- package/dist/proxy/server.js.map +1 -0
- package/dist/router-check.d.ts +1 -0
- package/dist/router-check.js +97 -0
- package/dist/router-check.js.map +1 -0
- package/dist/smoke-fc.d.ts +1 -0
- package/dist/smoke-fc.js +183 -0
- package/dist/smoke-fc.js.map +1 -0
- package/dist/smoke-microvm.d.ts +1 -0
- package/dist/smoke-microvm.js +187 -0
- package/dist/smoke-microvm.js.map +1 -0
- package/dist/smoke-remote.d.ts +20 -0
- package/dist/smoke-remote.js +155 -0
- package/dist/smoke-remote.js.map +1 -0
- package/dist/smoke-vz.d.ts +1 -0
- package/dist/smoke-vz.js +161 -0
- package/dist/smoke-vz.js.map +1 -0
- package/dist/smoke.d.ts +7 -0
- package/dist/smoke.js +962 -0
- package/dist/smoke.js.map +1 -0
- package/dist/store.d.ts +124 -0
- package/dist/store.js +578 -0
- package/dist/store.js.map +1 -0
- package/dist/tracing.d.ts +45 -0
- package/dist/tracing.js +144 -0
- package/dist/tracing.js.map +1 -0
- package/dist/types.d.ts +274 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +27 -0
- package/dist/util.js +63 -0
- package/dist/util.js.map +1 -0
- package/dist/warmpool-check.d.ts +1 -0
- package/dist/warmpool-check.js +83 -0
- package/dist/warmpool-check.js.map +1 -0
- package/dist/web/dashboard.d.ts +1 -0
- package/dist/web/dashboard.js +456 -0
- package/dist/web/dashboard.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"egress.js","sourceRoot":"","sources":["../../src/proxy/egress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory sliding-window rate limiter, keyed by egress token. Tracks two
|
|
3
|
+
* independent budgets per window: provider **calls** and billed **tokens**. The
|
|
4
|
+
* gateway records a call's start before forwarding (calls budget) and its token
|
|
5
|
+
* usage after the response completes (tokens budget), so token accounting lags by
|
|
6
|
+
* at most one in-flight call — standard for a metered gateway.
|
|
7
|
+
*
|
|
8
|
+
* State is per-process and resets on daemon restart; it is intentionally not
|
|
9
|
+
* persisted (a token bucket is ephemeral) and is not cluster-safe — a shared
|
|
10
|
+
* store is the multi-daemon follow-up. Memory is bounded by pruning empty windows
|
|
11
|
+
* lazily on access and dropping a token's state on revoke via `forget`.
|
|
12
|
+
*/
|
|
13
|
+
export interface RateSpec {
|
|
14
|
+
calls?: number;
|
|
15
|
+
tokens?: number;
|
|
16
|
+
windowMs: number;
|
|
17
|
+
}
|
|
18
|
+
export declare class RateLimiter {
|
|
19
|
+
private windows;
|
|
20
|
+
/**
|
|
21
|
+
* Check whether a new call is allowed under the token's call budget, and if so
|
|
22
|
+
* record it. Returns `{ ok: true }` or `{ ok: false, retryAfterMs }`. A spec
|
|
23
|
+
* without a `calls` cap always passes (token-only limits are checked in `note`).
|
|
24
|
+
*/
|
|
25
|
+
allow(token: string, spec: RateSpec, now: number): {
|
|
26
|
+
ok: true;
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
retryAfterMs: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Pre-flight check of the token budget for the *next* call, against usage
|
|
33
|
+
* already recorded in the window. Returns not-ok when the window is already at
|
|
34
|
+
* or over the token cap (the previous call pushed it over). Does not record
|
|
35
|
+
* anything — call `note` after the response to add this call's tokens.
|
|
36
|
+
*/
|
|
37
|
+
checkTokens(token: string, spec: RateSpec, now: number): {
|
|
38
|
+
ok: true;
|
|
39
|
+
} | {
|
|
40
|
+
ok: false;
|
|
41
|
+
retryAfterMs: number;
|
|
42
|
+
};
|
|
43
|
+
/** Record billed tokens for a completed call (feeds the next `checkTokens`). */
|
|
44
|
+
note(token: string, spec: RateSpec, billedTokens: number, now: number): void;
|
|
45
|
+
/** Drop a token's window state (call on revoke/destroy). */
|
|
46
|
+
forget(token: string): void;
|
|
47
|
+
/** Get-or-create the token's window, pruning entries older than `windowMs`. */
|
|
48
|
+
private windowFor;
|
|
49
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory sliding-window rate limiter, keyed by egress token. Tracks two
|
|
3
|
+
* independent budgets per window: provider **calls** and billed **tokens**. The
|
|
4
|
+
* gateway records a call's start before forwarding (calls budget) and its token
|
|
5
|
+
* usage after the response completes (tokens budget), so token accounting lags by
|
|
6
|
+
* at most one in-flight call — standard for a metered gateway.
|
|
7
|
+
*
|
|
8
|
+
* State is per-process and resets on daemon restart; it is intentionally not
|
|
9
|
+
* persisted (a token bucket is ephemeral) and is not cluster-safe — a shared
|
|
10
|
+
* store is the multi-daemon follow-up. Memory is bounded by pruning empty windows
|
|
11
|
+
* lazily on access and dropping a token's state on revoke via `forget`.
|
|
12
|
+
*/
|
|
13
|
+
export class RateLimiter {
|
|
14
|
+
windows = new Map();
|
|
15
|
+
/**
|
|
16
|
+
* Check whether a new call is allowed under the token's call budget, and if so
|
|
17
|
+
* record it. Returns `{ ok: true }` or `{ ok: false, retryAfterMs }`. A spec
|
|
18
|
+
* without a `calls` cap always passes (token-only limits are checked in `note`).
|
|
19
|
+
*/
|
|
20
|
+
allow(token, spec, now) {
|
|
21
|
+
if (spec.calls === undefined)
|
|
22
|
+
return { ok: true };
|
|
23
|
+
const w = this.windowFor(token, spec.windowMs, now);
|
|
24
|
+
if (w.calls.length >= spec.calls) {
|
|
25
|
+
const oldest = w.calls[0];
|
|
26
|
+
return { ok: false, retryAfterMs: Math.max(1, oldest + spec.windowMs - now) };
|
|
27
|
+
}
|
|
28
|
+
w.calls.push(now);
|
|
29
|
+
return { ok: true };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Pre-flight check of the token budget for the *next* call, against usage
|
|
33
|
+
* already recorded in the window. Returns not-ok when the window is already at
|
|
34
|
+
* or over the token cap (the previous call pushed it over). Does not record
|
|
35
|
+
* anything — call `note` after the response to add this call's tokens.
|
|
36
|
+
*/
|
|
37
|
+
checkTokens(token, spec, now) {
|
|
38
|
+
if (spec.tokens === undefined)
|
|
39
|
+
return { ok: true };
|
|
40
|
+
const w = this.windowFor(token, spec.windowMs, now);
|
|
41
|
+
const used = w.tokens.reduce((s, e) => s + e.n, 0);
|
|
42
|
+
if (used >= spec.tokens) {
|
|
43
|
+
const oldest = w.tokens[0]?.at ?? now;
|
|
44
|
+
return { ok: false, retryAfterMs: Math.max(1, oldest + spec.windowMs - now) };
|
|
45
|
+
}
|
|
46
|
+
return { ok: true };
|
|
47
|
+
}
|
|
48
|
+
/** Record billed tokens for a completed call (feeds the next `checkTokens`). */
|
|
49
|
+
note(token, spec, billedTokens, now) {
|
|
50
|
+
if (spec.tokens === undefined || billedTokens <= 0)
|
|
51
|
+
return;
|
|
52
|
+
const w = this.windowFor(token, spec.windowMs, now);
|
|
53
|
+
w.tokens.push({ at: now, n: billedTokens });
|
|
54
|
+
}
|
|
55
|
+
/** Drop a token's window state (call on revoke/destroy). */
|
|
56
|
+
forget(token) {
|
|
57
|
+
this.windows.delete(token);
|
|
58
|
+
}
|
|
59
|
+
/** Get-or-create the token's window, pruning entries older than `windowMs`. */
|
|
60
|
+
windowFor(token, windowMs, now) {
|
|
61
|
+
let w = this.windows.get(token);
|
|
62
|
+
if (!w) {
|
|
63
|
+
w = { calls: [], tokens: [] };
|
|
64
|
+
this.windows.set(token, w);
|
|
65
|
+
}
|
|
66
|
+
const cutoff = now - windowMs;
|
|
67
|
+
while (w.calls.length && w.calls[0] <= cutoff)
|
|
68
|
+
w.calls.shift();
|
|
69
|
+
while (w.tokens.length && w.tokens[0].at <= cutoff)
|
|
70
|
+
w.tokens.shift();
|
|
71
|
+
return w;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=ratelimit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ratelimit.js","sourceRoot":"","sources":["../../src/proxy/ratelimit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Server } from "node:net";
|
|
2
|
+
import type { Config } from "../config.js";
|
|
3
|
+
import type { Driver } from "../driver/types.js";
|
|
4
|
+
import type { SandboxStore } from "../store.js";
|
|
5
|
+
interface Deps {
|
|
6
|
+
config: Config;
|
|
7
|
+
driver: Driver;
|
|
8
|
+
store: SandboxStore;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Preview-URL reverse proxy.
|
|
12
|
+
*
|
|
13
|
+
* A connection-level (L4) splice: we read just the first request's header block
|
|
14
|
+
* to learn the route, then pipe raw bytes between the client socket and a byte
|
|
15
|
+
* bridge into the sandbox. Because the bridge is a hijacked `docker exec`, this
|
|
16
|
+
* works even where container IPs are unreachable from the host (macOS Docker
|
|
17
|
+
* Desktop). Splicing at L4 means HTTP keep-alive, WebSocket upgrades, binary
|
|
18
|
+
* uploads and chunked responses all pass through untouched.
|
|
19
|
+
*
|
|
20
|
+
* Routing (resolved once per connection from the first request):
|
|
21
|
+
* - subdomain: Host: <id>-<port>.localhost[:proxyPort]
|
|
22
|
+
* - path (curl): GET /_hotcell/<id>/<port>/... (prefix rewritten on the first
|
|
23
|
+
* request line; absolute-path assets won't resolve, so subdomain is primary)
|
|
24
|
+
*/
|
|
25
|
+
export declare function createProxyServer({ config, driver, store }: Deps): Server;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { createServer } from "node:net";
|
|
2
|
+
import { resumeSandbox } from "../lifecycle.js";
|
|
3
|
+
import { safeEqual } from "../util.js";
|
|
4
|
+
/**
|
|
5
|
+
* Preview-URL reverse proxy.
|
|
6
|
+
*
|
|
7
|
+
* A connection-level (L4) splice: we read just the first request's header block
|
|
8
|
+
* to learn the route, then pipe raw bytes between the client socket and a byte
|
|
9
|
+
* bridge into the sandbox. Because the bridge is a hijacked `docker exec`, this
|
|
10
|
+
* works even where container IPs are unreachable from the host (macOS Docker
|
|
11
|
+
* Desktop). Splicing at L4 means HTTP keep-alive, WebSocket upgrades, binary
|
|
12
|
+
* uploads and chunked responses all pass through untouched.
|
|
13
|
+
*
|
|
14
|
+
* Routing (resolved once per connection from the first request):
|
|
15
|
+
* - subdomain: Host: <id>-<port>.localhost[:proxyPort]
|
|
16
|
+
* - path (curl): GET /_hotcell/<id>/<port>/... (prefix rewritten on the first
|
|
17
|
+
* request line; absolute-path assets won't resolve, so subdomain is primary)
|
|
18
|
+
*/
|
|
19
|
+
export function createProxyServer({ config, driver, store }) {
|
|
20
|
+
return createServer((socket) => {
|
|
21
|
+
handleConnection(socket, { config, driver, store }).catch(() => {
|
|
22
|
+
socket.destroy();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const MAX_HEADER_BYTES = 64 * 1024;
|
|
27
|
+
async function handleConnection(socket, deps) {
|
|
28
|
+
let buffer = Buffer.alloc(0);
|
|
29
|
+
const onData = (chunk) => {
|
|
30
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
31
|
+
const headerEnd = buffer.indexOf("\r\n\r\n");
|
|
32
|
+
if (headerEnd === -1) {
|
|
33
|
+
if (buffer.length > MAX_HEADER_BYTES) {
|
|
34
|
+
respond(socket, 431, "Request Header Fields Too Large");
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
socket.removeListener("data", onData);
|
|
39
|
+
socket.pause();
|
|
40
|
+
const headerText = buffer.subarray(0, headerEnd).toString("utf8");
|
|
41
|
+
const resolved = resolveRoute(headerText, deps.store);
|
|
42
|
+
if (!resolved) {
|
|
43
|
+
return respond(socket, 404, "No hotcell preview route for this host");
|
|
44
|
+
}
|
|
45
|
+
if (resolved.target.token && !hasToken(headerText, resolved.target.token)) {
|
|
46
|
+
return respond(socket, 403, "Missing or invalid preview token");
|
|
47
|
+
}
|
|
48
|
+
// Apply any first-line rewrite (path-based routing strips the prefix).
|
|
49
|
+
const forwardBuffer = resolved.rewrite && headerEnd >= 0
|
|
50
|
+
? rewriteFirstLine(buffer, resolved.rewrite.from, resolved.rewrite.to)
|
|
51
|
+
: buffer;
|
|
52
|
+
void bridgeAndSplice(socket, forwardBuffer, resolved.target, deps);
|
|
53
|
+
};
|
|
54
|
+
socket.on("data", onData);
|
|
55
|
+
socket.on("error", () => socket.destroy());
|
|
56
|
+
}
|
|
57
|
+
async function bridgeAndSplice(socket, initial, target, { driver, store }) {
|
|
58
|
+
// Inbound preview traffic transparently wakes a paused sandbox — with a
|
|
59
|
+
// memory-snapshot pause the serving process comes back alive, which is what
|
|
60
|
+
// lets the idle reaper hibernate port-exposing sandboxes on snapshot-capable
|
|
61
|
+
// drivers (see lifecycle.reapIdle). A `stopped` sandbox is user intent and
|
|
62
|
+
// stays down.
|
|
63
|
+
const record = store.get(target.sandboxId);
|
|
64
|
+
if (record?.status === "stopped") {
|
|
65
|
+
return respond(socket, 502, "Sandbox is stopped; start it first");
|
|
66
|
+
}
|
|
67
|
+
if (record?.status === "paused") {
|
|
68
|
+
try {
|
|
69
|
+
await resumeSandbox(driver, store, record);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return respond(socket, 502, "Failed to resume the paused sandbox");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Proxied traffic counts as activity so the idle reaper won't pause a sandbox
|
|
76
|
+
// that's actively serving requests.
|
|
77
|
+
store.touch(target.sandboxId);
|
|
78
|
+
let bridge;
|
|
79
|
+
try {
|
|
80
|
+
bridge = await driver.openTcpBridge(target.sandboxId, target.port, "127.0.0.1");
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return respond(socket, 502, "Failed to reach sandbox port");
|
|
84
|
+
}
|
|
85
|
+
const { stream } = bridge;
|
|
86
|
+
stream.write(initial);
|
|
87
|
+
socket.pipe(stream);
|
|
88
|
+
stream.pipe(socket);
|
|
89
|
+
socket.resume();
|
|
90
|
+
// Meter egress: bytes flowing from the sandbox out to the client. Accumulate
|
|
91
|
+
// locally and flush once on close to avoid a DB write per chunk.
|
|
92
|
+
let egress = 0;
|
|
93
|
+
stream.on("data", (chunk) => {
|
|
94
|
+
egress += chunk.length;
|
|
95
|
+
});
|
|
96
|
+
let closed = false;
|
|
97
|
+
const close = () => {
|
|
98
|
+
if (closed)
|
|
99
|
+
return;
|
|
100
|
+
closed = true;
|
|
101
|
+
store.addEgress(target.sandboxId, egress);
|
|
102
|
+
bridge.close();
|
|
103
|
+
socket.destroy();
|
|
104
|
+
};
|
|
105
|
+
socket.on("error", close);
|
|
106
|
+
socket.on("close", close);
|
|
107
|
+
stream.on("error", close);
|
|
108
|
+
stream.on("close", close);
|
|
109
|
+
}
|
|
110
|
+
function resolveRoute(headerText, store) {
|
|
111
|
+
const lines = headerText.split("\r\n");
|
|
112
|
+
const requestLine = lines[0] ?? "";
|
|
113
|
+
const target = requestLine.split(" ")[1] ?? "/";
|
|
114
|
+
// 1) Subdomain routing via the Host header: <id>-<port>.localhost
|
|
115
|
+
const hostLine = lines.find((l) => /^host:/i.test(l));
|
|
116
|
+
if (hostLine) {
|
|
117
|
+
const host = hostLine.slice(hostLine.indexOf(":") + 1).trim();
|
|
118
|
+
const hostname = host.split(":")[0];
|
|
119
|
+
const label = hostname.split(".")[0]; // leftmost label
|
|
120
|
+
const route = store.resolveRoute(label);
|
|
121
|
+
if (route)
|
|
122
|
+
return { target: route };
|
|
123
|
+
}
|
|
124
|
+
// 2) Path-based fallback: /_hotcell/<id>/<port>/... (legacy /_sbx/ accepted).
|
|
125
|
+
const pathMatch = target.match(/^\/(_hotcell|_sbx)\/([^/]+)\/(\d+)(\/.*)?$/);
|
|
126
|
+
if (pathMatch) {
|
|
127
|
+
const exposeId = `${pathMatch[2]}-${pathMatch[3]}`;
|
|
128
|
+
const route = store.resolveRoute(exposeId);
|
|
129
|
+
if (route) {
|
|
130
|
+
const prefix = `/${pathMatch[1]}/${pathMatch[2]}/${pathMatch[3]}`;
|
|
131
|
+
return { target: route, rewrite: { from: prefix, to: "" } };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
/** Strip the `/_hotcell/<id>/<port>` prefix from the first request line's target. */
|
|
137
|
+
function rewriteFirstLine(buffer, from, _to) {
|
|
138
|
+
const lineEnd = buffer.indexOf("\r\n");
|
|
139
|
+
if (lineEnd === -1)
|
|
140
|
+
return buffer;
|
|
141
|
+
// The request line is ASCII; latin1 round-trips bytes safely.
|
|
142
|
+
const firstLine = buffer.subarray(0, lineEnd).toString("latin1");
|
|
143
|
+
const parts = firstLine.split(" ");
|
|
144
|
+
if (parts.length < 3)
|
|
145
|
+
return buffer;
|
|
146
|
+
const [method, target, ...rest] = parts;
|
|
147
|
+
const stripped = target.startsWith(from) ? target.slice(from.length) : target;
|
|
148
|
+
const newTarget = stripped.length === 0 ? "/" : stripped;
|
|
149
|
+
const newLine = `${method} ${newTarget} ${rest.join(" ")}`;
|
|
150
|
+
return Buffer.concat([
|
|
151
|
+
Buffer.from(newLine, "latin1"),
|
|
152
|
+
buffer.subarray(lineEnd),
|
|
153
|
+
]);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Check the per-port preview token, supplied as a `?token=` query param or an
|
|
157
|
+
* `Authorization: Bearer <token>` header. Extracts the actual value and compares
|
|
158
|
+
* it exactly in constant time (the old lowercased-substring match was both
|
|
159
|
+
* case-insensitive and loose).
|
|
160
|
+
*/
|
|
161
|
+
function hasToken(headerText, token) {
|
|
162
|
+
const lines = headerText.split("\r\n");
|
|
163
|
+
// 1) token= query param on the request line.
|
|
164
|
+
const target = (lines[0] ?? "").split(" ")[1] ?? "";
|
|
165
|
+
const q = target.indexOf("?");
|
|
166
|
+
if (q !== -1) {
|
|
167
|
+
const provided = new URLSearchParams(target.slice(q + 1)).get("token");
|
|
168
|
+
if (provided && safeEqual(provided, token))
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
// 2) Authorization: Bearer <token>.
|
|
172
|
+
const authLine = lines.find((l) => /^authorization:/i.test(l));
|
|
173
|
+
if (authLine) {
|
|
174
|
+
const m = /^bearer\s+(.+)$/i.exec(authLine.slice(authLine.indexOf(":") + 1).trim());
|
|
175
|
+
if (m && safeEqual(m[1], token))
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
function respond(socket, status, message) {
|
|
181
|
+
const body = `${message}\n`;
|
|
182
|
+
socket.end(`HTTP/1.1 ${status} ${statusText(status)}\r\n` +
|
|
183
|
+
`Content-Type: text/plain; charset=utf-8\r\n` +
|
|
184
|
+
`Content-Length: ${Buffer.byteLength(body)}\r\n` +
|
|
185
|
+
`Connection: close\r\n\r\n` +
|
|
186
|
+
body);
|
|
187
|
+
}
|
|
188
|
+
function statusText(status) {
|
|
189
|
+
switch (status) {
|
|
190
|
+
case 403:
|
|
191
|
+
return "Forbidden";
|
|
192
|
+
case 404:
|
|
193
|
+
return "Not Found";
|
|
194
|
+
case 431:
|
|
195
|
+
return "Request Header Fields Too Large";
|
|
196
|
+
case 502:
|
|
197
|
+
return "Bad Gateway";
|
|
198
|
+
default:
|
|
199
|
+
return "Error";
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-sandbox driver selection (M7c) end-to-end check. Builds one DriverRouter
|
|
3
|
+
* and runs a **container** sandbox and a **microVM** sandbox side by side under
|
|
4
|
+
* it, proving the daemon routes each sandbox's ops to the driver it was created
|
|
5
|
+
* with. The microVM driver is platform-picked (applevz on macOS, firecracker on
|
|
6
|
+
* Linux; override with SBX_ROUTER_MICROVM). Needs Docker (container driver) +
|
|
7
|
+
* the platform's microVM prerequisites. Run: `npm run check:router`.
|
|
8
|
+
*/
|
|
9
|
+
import assert from "node:assert/strict";
|
|
10
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
11
|
+
import { homedir, tmpdir } from "node:os";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { loadConfig } from "./config.js";
|
|
14
|
+
import { DriverRouter } from "./driver/router.js";
|
|
15
|
+
import { emptyUsage, SandboxStore } from "./store.js";
|
|
16
|
+
function record(id, driver, image) {
|
|
17
|
+
const now = new Date().toISOString();
|
|
18
|
+
return {
|
|
19
|
+
id,
|
|
20
|
+
image,
|
|
21
|
+
status: "running",
|
|
22
|
+
createdAt: now,
|
|
23
|
+
driver,
|
|
24
|
+
labels: {},
|
|
25
|
+
env: {},
|
|
26
|
+
persist: true,
|
|
27
|
+
lastActivityAt: now,
|
|
28
|
+
sleepAfterMs: 0,
|
|
29
|
+
limits: {},
|
|
30
|
+
usage: emptyUsage(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async function main() {
|
|
34
|
+
const stateDir = mkdtempSync(join(tmpdir(), "hotcell-router-"));
|
|
35
|
+
const microvm = process.env.SBX_ROUTER_MICROVM ?? (process.platform === "darwin" ? "applevz" : "firecracker");
|
|
36
|
+
const microImage = process.env.SBX_ROUTER_MICROVM_IMAGE ?? (microvm === "applevz" ? "base" : "alpine:3.20");
|
|
37
|
+
const config = {
|
|
38
|
+
...loadConfig(),
|
|
39
|
+
driver: "container",
|
|
40
|
+
...(microvm === "applevz"
|
|
41
|
+
? { vzStateDir: stateDir, vzImageCacheDir: join(homedir(), ".sbx", "vz", "images") }
|
|
42
|
+
: { fcStateDir: stateDir }),
|
|
43
|
+
};
|
|
44
|
+
const store = new SandboxStore(":memory:");
|
|
45
|
+
const router = new DriverRouter(config, store, "container");
|
|
46
|
+
let passed = 0;
|
|
47
|
+
const ok = (l) => {
|
|
48
|
+
passed++;
|
|
49
|
+
console.log(` ✓ ${l}`);
|
|
50
|
+
};
|
|
51
|
+
const ids = { c: "router-container", v: `router-${microvm}` };
|
|
52
|
+
try {
|
|
53
|
+
// Create both sandboxes through the same router, each naming its driver.
|
|
54
|
+
await router.create({ id: ids.c, image: config.defaultImage, driver: "container", persist: true });
|
|
55
|
+
store.add(record(ids.c, "container", config.defaultImage));
|
|
56
|
+
ok("container sandbox created via the router");
|
|
57
|
+
await router.create({ id: ids.v, image: microImage, driver: microvm, persist: true });
|
|
58
|
+
store.add(record(ids.v, microvm, microImage));
|
|
59
|
+
ok(`${microvm} microVM created via the router`);
|
|
60
|
+
// Exec in each: the router must dispatch to the right driver. The kernel
|
|
61
|
+
// string distinguishes them — a shared Docker host kernel vs the guest's own.
|
|
62
|
+
const uname = async (id) => {
|
|
63
|
+
let out = "";
|
|
64
|
+
const code = await router.exec(id, "uname -sr", {}, (e) => {
|
|
65
|
+
if (e.type === "stdout")
|
|
66
|
+
out += e.data;
|
|
67
|
+
});
|
|
68
|
+
assert.equal(code, 0, `exec exit code for ${id}`);
|
|
69
|
+
return out.trim();
|
|
70
|
+
};
|
|
71
|
+
const cKernel = await uname(ids.c);
|
|
72
|
+
const vKernel = await uname(ids.v);
|
|
73
|
+
assert.match(cKernel, /Linux/, "container exec ran");
|
|
74
|
+
assert.match(vKernel, /Linux/, "microVM exec ran");
|
|
75
|
+
ok(`container exec → ${cKernel}`);
|
|
76
|
+
ok(`${microvm} exec → ${vKernel}`);
|
|
77
|
+
// Prove isolation: a file written in one sandbox is invisible in the other,
|
|
78
|
+
// and each lands on its own driver (different VM/container).
|
|
79
|
+
await router.writeFile(ids.c, { path: "/workspace/who.txt", content: "container" });
|
|
80
|
+
await router.writeFile(ids.v, { path: "/workspace/who.txt", content: microvm });
|
|
81
|
+
assert.equal(await router.readFile(ids.c, { path: "/workspace/who.txt" }), "container");
|
|
82
|
+
assert.equal(await router.readFile(ids.v, { path: "/workspace/who.txt" }), microvm);
|
|
83
|
+
ok("each sandbox's files are isolated on its own driver");
|
|
84
|
+
console.log(`\nrouter-check: ${passed} checks passed (container + ${microvm} under one router)`);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
await router.destroy(ids.c).catch(() => { });
|
|
88
|
+
await router.destroy(ids.v).catch(() => { });
|
|
89
|
+
store.close();
|
|
90
|
+
rmSync(stateDir, { recursive: true, force: true });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
main().then(() => process.exit(0), (err) => {
|
|
94
|
+
console.error("router-check FAILED:", err);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=router-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-check.js","sourceRoot":"","sources":["../src/router-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|