@ai-ecoverse/slicc-kernel 1.49.0 → 1.50.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/README.md +4 -3
- package/dist/driver-worker.js +2 -1
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js +6 -3
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +174 -65
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +2 -1
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.js +18 -13
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +181 -71
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +18 -12
- package/dist/process-worker.js.map +2 -2
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -715,6 +715,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
715
715
|
reset = false;
|
|
716
716
|
local;
|
|
717
717
|
peer;
|
|
718
|
+
peerCred;
|
|
719
|
+
listenerCred;
|
|
718
720
|
link;
|
|
719
721
|
readShut = false;
|
|
720
722
|
writeShut = false;
|
|
@@ -790,7 +792,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
790
792
|
this.local = this.net.bind(this, addr);
|
|
791
793
|
this.boundAt = this.local;
|
|
792
794
|
}
|
|
793
|
-
listen(backlog) {
|
|
795
|
+
listen(backlog, cred) {
|
|
794
796
|
if (this.state === "connected") throw new KernelError("EISCONN");
|
|
795
797
|
if (this.state !== "open" && this.state !== "listening") throw new KernelError("EINVAL");
|
|
796
798
|
if (!this.local) {
|
|
@@ -799,6 +801,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
799
801
|
}
|
|
800
802
|
this.backlog = Math.min(Math.max(backlog, 1), SOMAXCONN);
|
|
801
803
|
this.state = "listening";
|
|
804
|
+
this.listenerCred ??= cred;
|
|
802
805
|
}
|
|
803
806
|
async accept(signal, nonblock = false) {
|
|
804
807
|
for (; ; ) {
|
|
@@ -815,7 +818,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
815
818
|
this.changes.wake();
|
|
816
819
|
return true;
|
|
817
820
|
}
|
|
818
|
-
connect(addr, viaUplink = true) {
|
|
821
|
+
connect(addr, viaUplink = true, cred) {
|
|
819
822
|
if (this.state === "connected") throw new KernelError("EISCONN");
|
|
820
823
|
if (this.state === "connecting") throw new KernelError("EALREADY");
|
|
821
824
|
if (this.state !== "open") throw new KernelError("EINVAL");
|
|
@@ -833,7 +836,9 @@ var KernelSocket = class _KernelSocket {
|
|
|
833
836
|
const server = new _KernelSocket(this.net, this.domain);
|
|
834
837
|
server.local = addr.family === "inet" ? { ...addr, host: canonicalHost(addr.host) } : addr;
|
|
835
838
|
server.peer = this.local;
|
|
839
|
+
server.peerCred = cred;
|
|
836
840
|
this.peer = server.local;
|
|
841
|
+
this.peerCred = target.listenerCred;
|
|
837
842
|
link(this, server);
|
|
838
843
|
if (!target.offer(server)) {
|
|
839
844
|
this.unlink();
|
|
@@ -952,9 +957,10 @@ var KernelSocket = class _KernelSocket {
|
|
|
952
957
|
this.boundAt = void 0;
|
|
953
958
|
this.changes.wake();
|
|
954
959
|
}
|
|
955
|
-
static pair(net, domain) {
|
|
960
|
+
static pair(net, domain, cred) {
|
|
956
961
|
const a = new _KernelSocket(net, domain);
|
|
957
962
|
const b = new _KernelSocket(net, domain);
|
|
963
|
+
a.peerCred = b.peerCred = cred;
|
|
958
964
|
const name2 = domain === "inet" ? { family: "inet", host: "127.0.0.1", port: 0 } : { family: "unix", path: "" };
|
|
959
965
|
a.local = b.local = a.peer = b.peer = name2;
|
|
960
966
|
link(a, b);
|
|
@@ -1366,9 +1372,10 @@ function fetchTransport(options = {}) {
|
|
|
1366
1372
|
const send = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
1367
1373
|
const Socket = options.webSocket === true ? globalThis.WebSocket : options.webSocket || void 0;
|
|
1368
1374
|
const headers = options.webSocketHeaders === true;
|
|
1375
|
+
const redirect = options.redirect ?? "follow";
|
|
1369
1376
|
return {
|
|
1370
1377
|
traits: {
|
|
1371
|
-
manualRedirects:
|
|
1378
|
+
manualRedirects: redirect === "manual",
|
|
1372
1379
|
encodedBodies: false,
|
|
1373
1380
|
maxRequestBody: options.maxRequestBody ?? MAX_REQUEST_BODY,
|
|
1374
1381
|
crossOrigin: "cors",
|
|
@@ -1383,7 +1390,7 @@ function fetchTransport(options = {}) {
|
|
|
1383
1390
|
headers: joinHeaders(request.headers),
|
|
1384
1391
|
...request.body ? { body: request.body } : {},
|
|
1385
1392
|
signal: request.signal,
|
|
1386
|
-
redirect
|
|
1393
|
+
redirect,
|
|
1387
1394
|
credentials: "omit",
|
|
1388
1395
|
mode: "cors"
|
|
1389
1396
|
});
|
|
@@ -1449,6 +1456,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
1449
1456
|
net: "head",
|
|
1450
1457
|
nid: call.nid,
|
|
1451
1458
|
...response.redirected ? { url: response.url, redirected: true } : {},
|
|
1459
|
+
...response.redirects ? { redirects: response.redirects } : {},
|
|
1452
1460
|
status: response.status,
|
|
1453
1461
|
statusText: response.statusText,
|
|
1454
1462
|
headers: response.headers
|
|
@@ -5712,9 +5720,9 @@ var SAB_I_KILLED = 13;
|
|
|
5712
5720
|
var SAB_I_ASYNC = 14;
|
|
5713
5721
|
var SAB_I_STOP = 15;
|
|
5714
5722
|
var U32 = 2 ** 32;
|
|
5715
|
-
function storeU53(
|
|
5716
|
-
Atomics.store(
|
|
5717
|
-
Atomics.store(
|
|
5723
|
+
function storeU53(header4, lo, hi, value) {
|
|
5724
|
+
Atomics.store(header4, hi, Math.floor(value / U32));
|
|
5725
|
+
Atomics.store(header4, lo, value % U32 | 0);
|
|
5718
5726
|
}
|
|
5719
5727
|
var SAB_STATE_READY = 2;
|
|
5720
5728
|
var SAB_STATUS_BYTES = 1;
|
|
@@ -5757,7 +5765,7 @@ function sabViews(sab) {
|
|
|
5757
5765
|
var PENDING_TTL_MS = SYNC_FS_REQUEST_TIMEOUT_MS + 5e3;
|
|
5758
5766
|
function attachSyncSabResponder(port, sab, token, opts) {
|
|
5759
5767
|
const views = sabViews(sab);
|
|
5760
|
-
const { header:
|
|
5768
|
+
const { header: header4, window } = views;
|
|
5761
5769
|
const pending = /* @__PURE__ */ new Map();
|
|
5762
5770
|
let disposed = false;
|
|
5763
5771
|
const { dispatch: dispatch2 } = opts;
|
|
@@ -5768,20 +5776,20 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
5768
5776
|
pending.delete(id2);
|
|
5769
5777
|
}
|
|
5770
5778
|
function publish(id2, entry, offset) {
|
|
5771
|
-
if (Atomics.load(
|
|
5779
|
+
if (Atomics.load(header4, SAB_I_REQ) !== id2) {
|
|
5772
5780
|
drop(id2);
|
|
5773
5781
|
return;
|
|
5774
5782
|
}
|
|
5775
5783
|
const chunk2 = Math.min(window.byteLength, entry.payload.byteLength - offset);
|
|
5776
5784
|
if (chunk2 > 0) window.set(entry.payload.subarray(offset, offset + chunk2));
|
|
5777
|
-
Atomics.store(
|
|
5778
|
-
storeU53(
|
|
5779
|
-
Atomics.store(
|
|
5780
|
-
storeU53(
|
|
5781
|
-
Atomics.store(
|
|
5782
|
-
Atomics.store(
|
|
5783
|
-
Atomics.add(
|
|
5784
|
-
Atomics.notify(
|
|
5785
|
+
Atomics.store(header4, SAB_I_STATUS, entry.status);
|
|
5786
|
+
storeU53(header4, SAB_I_TOTAL, SAB_I_TOTAL_HI, entry.payload.byteLength);
|
|
5787
|
+
Atomics.store(header4, SAB_I_CHUNK, chunk2);
|
|
5788
|
+
storeU53(header4, SAB_I_OFFSET, SAB_I_OFFSET_HI, offset);
|
|
5789
|
+
Atomics.store(header4, SAB_I_SEQ, id2);
|
|
5790
|
+
Atomics.store(header4, SAB_I_STATE, SAB_STATE_READY);
|
|
5791
|
+
Atomics.add(header4, SAB_I_PUB, 1);
|
|
5792
|
+
Atomics.notify(header4, SAB_I_PUB);
|
|
5785
5793
|
if (offset + chunk2 >= entry.payload.byteLength) drop(id2);
|
|
5786
5794
|
}
|
|
5787
5795
|
function settle(id2, result) {
|
|
@@ -6378,7 +6386,7 @@ var RealmProxy = class {
|
|
|
6378
6386
|
const waiting = new AbortController();
|
|
6379
6387
|
void watchHangup(ctx.socket, abort, waiting.signal);
|
|
6380
6388
|
try {
|
|
6381
|
-
response = await this.upstream(req, url, body, abort.signal);
|
|
6389
|
+
response = await this.upstream(req, url, body, abort.signal, ctx.socket.peerCred?.pid);
|
|
6382
6390
|
} finally {
|
|
6383
6391
|
waiting.abort();
|
|
6384
6392
|
}
|
|
@@ -6404,15 +6412,18 @@ var RealmProxy = class {
|
|
|
6404
6412
|
await conn.write(latin1Bytes("HTTP/1.1 100 Continue\r\n\r\n"), this.stop.signal);
|
|
6405
6413
|
}
|
|
6406
6414
|
}
|
|
6407
|
-
async upstream(req, url, body, signal) {
|
|
6415
|
+
async upstream(req, url, body, signal, owner) {
|
|
6408
6416
|
try {
|
|
6409
|
-
const fetching = this.options.transport.fetch(
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6417
|
+
const fetching = this.options.transport.fetch(
|
|
6418
|
+
{
|
|
6419
|
+
url: toHostLoopback(url),
|
|
6420
|
+
method: req.method.toUpperCase(),
|
|
6421
|
+
headers: forwardRequestHeaders(req.headers),
|
|
6422
|
+
body: req.method === "GET" || req.method === "HEAD" ? void 0 : body,
|
|
6423
|
+
signal
|
|
6424
|
+
},
|
|
6425
|
+
owner
|
|
6426
|
+
);
|
|
6416
6427
|
return await untilAborted(fetching, signal);
|
|
6417
6428
|
} catch (e) {
|
|
6418
6429
|
if (signal.aborted) throw e;
|
|
@@ -6424,13 +6435,13 @@ var RealmProxy = class {
|
|
|
6424
6435
|
}
|
|
6425
6436
|
async relay(conn, method, minor, response, keepAlive) {
|
|
6426
6437
|
const status = response.status;
|
|
6427
|
-
const
|
|
6438
|
+
const bodiless2 = method === "HEAD" || status === 204 || status === 304 || status < 200;
|
|
6428
6439
|
const headers = forwardResponseHeaders(response.headers, {
|
|
6429
6440
|
encodedBodies: this.options.transport.traits.encodedBodies,
|
|
6430
|
-
bodiless
|
|
6441
|
+
bodiless: bodiless2
|
|
6431
6442
|
});
|
|
6432
|
-
const chunked2 = !
|
|
6433
|
-
const keep = keepAlive && (
|
|
6443
|
+
const chunked2 = !bodiless2 && minor >= 1;
|
|
6444
|
+
const keep = keepAlive && (bodiless2 || chunked2);
|
|
6434
6445
|
headers.push(["Connection", keep ? "keep-alive" : "close"]);
|
|
6435
6446
|
if (chunked2) headers.push(["Transfer-Encoding", "chunked"]);
|
|
6436
6447
|
const signal = this.stop.signal;
|
|
@@ -6438,7 +6449,7 @@ var RealmProxy = class {
|
|
|
6438
6449
|
responseHead(status, response.statusText || REASON[status] || "", headers),
|
|
6439
6450
|
signal
|
|
6440
6451
|
);
|
|
6441
|
-
if (
|
|
6452
|
+
if (bodiless2) {
|
|
6442
6453
|
await response.cancel();
|
|
6443
6454
|
return keep;
|
|
6444
6455
|
}
|
|
@@ -7401,8 +7412,10 @@ var HttpHandles = class {
|
|
|
7401
7412
|
open = /* @__PURE__ */ new Map();
|
|
7402
7413
|
nextHandle = 0;
|
|
7403
7414
|
ws;
|
|
7404
|
-
|
|
7415
|
+
owner;
|
|
7416
|
+
constructor(transport, owner) {
|
|
7405
7417
|
this.transport = transport;
|
|
7418
|
+
this.owner = owner;
|
|
7406
7419
|
this.ws = new WsHandles(transport, () => ++this.nextHandle);
|
|
7407
7420
|
}
|
|
7408
7421
|
syscall(req) {
|
|
@@ -7446,13 +7459,16 @@ var HttpHandles = class {
|
|
|
7446
7459
|
}
|
|
7447
7460
|
async respond(handle, req, entry) {
|
|
7448
7461
|
try {
|
|
7449
|
-
const response = await this.transport.fetch(
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7462
|
+
const response = await this.transport.fetch(
|
|
7463
|
+
{
|
|
7464
|
+
url: req.url,
|
|
7465
|
+
method: req.method,
|
|
7466
|
+
headers: req.headers,
|
|
7467
|
+
...req.body ? { body: req.body } : {},
|
|
7468
|
+
signal: entry.abort.signal
|
|
7469
|
+
},
|
|
7470
|
+
this.owner
|
|
7471
|
+
);
|
|
7456
7472
|
entry.body = response.body[Symbol.asyncIterator]();
|
|
7457
7473
|
entry.cancel = () => response.cancel();
|
|
7458
7474
|
if (!this.open.has(handle)) await entry.cancel().catch(() => void 0);
|
|
@@ -8278,7 +8294,7 @@ async function socketSyscall(req, proc) {
|
|
|
8278
8294
|
case "sock-open":
|
|
8279
8295
|
return ok(fds.install(new OpenFile(net.socket(req.domain)), 3));
|
|
8280
8296
|
case "sock-pair": {
|
|
8281
|
-
const [a, b] = KernelSocket.pair(net, req.domain);
|
|
8297
|
+
const [a, b] = KernelSocket.pair(net, req.domain, proc.cred?.());
|
|
8282
8298
|
const first = fds.install(new OpenFile(a), 3);
|
|
8283
8299
|
try {
|
|
8284
8300
|
return ok([first, fds.install(new OpenFile(b), 3)]);
|
|
@@ -8291,12 +8307,12 @@ async function socketSyscall(req, proc) {
|
|
|
8291
8307
|
socketAt(fds, req.fd).bind(req.addr);
|
|
8292
8308
|
return ok();
|
|
8293
8309
|
case "sock-listen":
|
|
8294
|
-
socketAt(fds, req.fd).listen(req.backlog);
|
|
8310
|
+
socketAt(fds, req.fd).listen(req.backlog, proc.cred?.());
|
|
8295
8311
|
return ok();
|
|
8296
8312
|
case "sock-accept":
|
|
8297
8313
|
return ok(await accept(proc, req.fd, req.nonblock));
|
|
8298
8314
|
case "sock-connect": {
|
|
8299
|
-
const dialing = socketAt(fds, req.fd).connect(req.addr);
|
|
8315
|
+
const dialing = socketAt(fds, req.fd).connect(req.addr, true, proc.cred?.());
|
|
8300
8316
|
if (req.nonblock) {
|
|
8301
8317
|
dialing?.catch(() => void 0);
|
|
8302
8318
|
throw new KernelError("EINPROGRESS");
|
|
@@ -9167,6 +9183,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
9167
9183
|
"dl-log",
|
|
9168
9184
|
"dl-closure",
|
|
9169
9185
|
"dl-closure-free",
|
|
9186
|
+
"dl-reserve",
|
|
9170
9187
|
"fd-renumber",
|
|
9171
9188
|
"fd-promote",
|
|
9172
9189
|
"fd-open-tty",
|
|
@@ -9711,7 +9728,8 @@ var WasmProcess = class {
|
|
|
9711
9728
|
fds: this.fds,
|
|
9712
9729
|
net: this.net,
|
|
9713
9730
|
blocking: () => this.blockingSignal(cancelled),
|
|
9714
|
-
resolve: (name2, family, blocking) => resolver.resolve(name2, family, blocking)
|
|
9731
|
+
resolve: (name2, family, blocking) => resolver.resolve(name2, family, blocking),
|
|
9732
|
+
cred: () => ({ pid: this.pid, uid: this.cred.euid, gid: this.cred.egid })
|
|
9715
9733
|
});
|
|
9716
9734
|
}
|
|
9717
9735
|
tty(fd) {
|
|
@@ -9788,6 +9806,8 @@ var WasmProcess = class {
|
|
|
9788
9806
|
case "dl-closure-free":
|
|
9789
9807
|
this.freeClosure(req.index);
|
|
9790
9808
|
return { ok: true, kind: "void" };
|
|
9809
|
+
case "dl-reserve":
|
|
9810
|
+
return { ok: true, kind: "json", json: this.reserveSlots(req.floor, req.size) };
|
|
9791
9811
|
case "sig-mask":
|
|
9792
9812
|
this.caught = req.caught;
|
|
9793
9813
|
this.ignored = req.ignored;
|
|
@@ -9835,6 +9855,12 @@ var WasmProcess = class {
|
|
|
9835
9855
|
freeClosure(index) {
|
|
9836
9856
|
if (!this.closures.live.delete(index)) throw new KernelError("EINVAL");
|
|
9837
9857
|
this.closures.free.push(index);
|
|
9858
|
+
this.dlLog.push({ kind: "closure-free", index });
|
|
9859
|
+
}
|
|
9860
|
+
reserveSlots(floor, size) {
|
|
9861
|
+
const base = Math.max(floor, this.closures.next);
|
|
9862
|
+
this.closures.next = base + size;
|
|
9863
|
+
return base;
|
|
9838
9864
|
}
|
|
9839
9865
|
asyncOps = new AsyncOps(
|
|
9840
9866
|
(req, cancelled) => this.syscall(req, cancelled),
|
|
@@ -9919,12 +9945,12 @@ var Dying = class {
|
|
|
9919
9945
|
timer;
|
|
9920
9946
|
busy = 0;
|
|
9921
9947
|
finish;
|
|
9922
|
-
start(code, sig,
|
|
9948
|
+
start(code, sig, header4, process2, finish) {
|
|
9923
9949
|
if (this.ending) return;
|
|
9924
9950
|
this.ending = { code, sig };
|
|
9925
9951
|
this.finish = finish;
|
|
9926
9952
|
this.arm();
|
|
9927
|
-
Atomics.store(
|
|
9953
|
+
Atomics.store(header4, SAB_I_KILLED, code);
|
|
9928
9954
|
process2.die();
|
|
9929
9955
|
}
|
|
9930
9956
|
async serving(work) {
|
|
@@ -9961,22 +9987,22 @@ function killThread(thread, caught, sig) {
|
|
|
9961
9987
|
function threadCancel(thread) {
|
|
9962
9988
|
return Atomics.load(thread.header, SAB_I_SIGNALS) !== 0 ? AbortSignal.abort() : thread.interrupt.signal;
|
|
9963
9989
|
}
|
|
9964
|
-
function notifiers(
|
|
9990
|
+
function notifiers(header4) {
|
|
9965
9991
|
return {
|
|
9966
9992
|
onPending(sig) {
|
|
9967
|
-
Atomics.or(
|
|
9968
|
-
Atomics.notify(
|
|
9993
|
+
Atomics.or(header4, SAB_I_SIGNALS, sigbit(sig));
|
|
9994
|
+
Atomics.notify(header4, SAB_I_SIGNALS);
|
|
9969
9995
|
},
|
|
9970
9996
|
onAsync() {
|
|
9971
|
-
Atomics.add(
|
|
9972
|
-
Atomics.notify(
|
|
9997
|
+
Atomics.add(header4, SAB_I_ASYNC, 1);
|
|
9998
|
+
Atomics.notify(header4, SAB_I_ASYNC);
|
|
9973
9999
|
}
|
|
9974
10000
|
};
|
|
9975
10001
|
}
|
|
9976
|
-
function publishStops(process2,
|
|
10002
|
+
function publishStops(process2, header4) {
|
|
9977
10003
|
process2.onState((state) => {
|
|
9978
|
-
Atomics.store(
|
|
9979
|
-
Atomics.notify(
|
|
10004
|
+
Atomics.store(header4, SAB_I_STOP, state === "stopped" ? 1 : 0);
|
|
10005
|
+
Atomics.notify(header4, SAB_I_STOP);
|
|
9980
10006
|
});
|
|
9981
10007
|
}
|
|
9982
10008
|
function transferOf(opts, lane) {
|
|
@@ -10044,7 +10070,7 @@ function holdingToken(opts, holds) {
|
|
|
10044
10070
|
renamed: (from, to) => holds.renamed(from, to)
|
|
10045
10071
|
});
|
|
10046
10072
|
}
|
|
10047
|
-
function processOptions(opts,
|
|
10073
|
+
function processOptions(opts, header4, hooks) {
|
|
10048
10074
|
return {
|
|
10049
10075
|
...inherited(opts),
|
|
10050
10076
|
...opts.identity ? { identity: opts.identity } : {},
|
|
@@ -10068,27 +10094,27 @@ function processOptions(opts, header3, hooks) {
|
|
|
10068
10094
|
locks: opts.locks,
|
|
10069
10095
|
onReap: opts.onReap,
|
|
10070
10096
|
resolver: opts.resolver,
|
|
10071
|
-
...notifiers(
|
|
10072
|
-
onTimer: (which) => void Atomics.or(
|
|
10073
|
-
hasPending: () => Atomics.load(
|
|
10097
|
+
...notifiers(header4),
|
|
10098
|
+
onTimer: (which) => void Atomics.or(header4, SAB_I_TIMERS, 1 << which),
|
|
10099
|
+
hasPending: () => Atomics.load(header4, SAB_I_SIGNALS) !== 0 || Atomics.load(header4, SAB_I_TIMERS) !== 0,
|
|
10074
10100
|
raise: hooks.raise,
|
|
10075
10101
|
threadKill: hooks.threadKill,
|
|
10076
|
-
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(
|
|
10102
|
+
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(header4, SAB_I_SIGNALS) } : {}
|
|
10077
10103
|
};
|
|
10078
10104
|
}
|
|
10079
10105
|
function spawnWasmProcess(opts) {
|
|
10080
10106
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
10081
|
-
const
|
|
10107
|
+
const header4 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
10082
10108
|
const threadSignals = /* @__PURE__ */ new Map();
|
|
10083
10109
|
const process2 = new WasmProcess(
|
|
10084
10110
|
opts.pid,
|
|
10085
10111
|
opts.fds,
|
|
10086
|
-
processOptions(opts,
|
|
10112
|
+
processOptions(opts, header4, {
|
|
10087
10113
|
raise: (sig) => signal(sig),
|
|
10088
10114
|
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig)
|
|
10089
10115
|
})
|
|
10090
10116
|
);
|
|
10091
|
-
publishStops(process2,
|
|
10117
|
+
publishStops(process2, header4);
|
|
10092
10118
|
const holds = new HeldPaths();
|
|
10093
10119
|
opts.held?.add(holds);
|
|
10094
10120
|
const token = holdingToken(opts, holds);
|
|
@@ -10200,7 +10226,7 @@ function spawnWasmProcess(opts) {
|
|
|
10200
10226
|
if (process2.signal(sig) !== "terminate") return;
|
|
10201
10227
|
const code = sig === SIG.KILL ? 137 : 128 + sig;
|
|
10202
10228
|
if (opts.program.abi !== "wasi" || done4) finish(code, sig);
|
|
10203
|
-
else dying.start(code, sig,
|
|
10229
|
+
else dying.start(code, sig, header4, process2, () => finish(code, sig));
|
|
10204
10230
|
};
|
|
10205
10231
|
const kill = (code = 137) => finish(code, code > 128 && code < 160 ? code - 128 : void 0);
|
|
10206
10232
|
return {
|
|
@@ -10210,7 +10236,7 @@ function spawnWasmProcess(opts) {
|
|
|
10210
10236
|
signal,
|
|
10211
10237
|
termsig: () => endedBy,
|
|
10212
10238
|
onState: (listener) => process2.onState(listener),
|
|
10213
|
-
memory: () => Atomics.load(
|
|
10239
|
+
memory: () => Atomics.load(header4, SAB_I_MEMORY) * 65536,
|
|
10214
10240
|
ignoredSignals: (fork) => process2.inheritable(fork),
|
|
10215
10241
|
signalMasks: () => process2.signalMasks(),
|
|
10216
10242
|
umask: () => process2.umask,
|
|
@@ -10405,6 +10431,89 @@ var JobTable = class {
|
|
|
10405
10431
|
}
|
|
10406
10432
|
};
|
|
10407
10433
|
|
|
10434
|
+
// src/kernel/net/redirect-hops.ts
|
|
10435
|
+
var HELD_MS = 3e4;
|
|
10436
|
+
var HELD_MAX = 64;
|
|
10437
|
+
var HELD_PER_OWNER = 8;
|
|
10438
|
+
var MATCHED = ["range", "if-none-match", "if-modified-since", "if-range", "accept-encoding"];
|
|
10439
|
+
var KERNEL = -1;
|
|
10440
|
+
function header2(headers, name2) {
|
|
10441
|
+
const values = headers.filter(([n]) => n.toLowerCase() === name2).map(([, v]) => v);
|
|
10442
|
+
return values.length > 0 ? values.join(", ") : void 0;
|
|
10443
|
+
}
|
|
10444
|
+
function fingerprint(headers) {
|
|
10445
|
+
const fields = MATCHED.map((name2) => header2(headers, name2) ?? "");
|
|
10446
|
+
return JSON.stringify([...fields, header2(headers, "authorization") !== void 0]);
|
|
10447
|
+
}
|
|
10448
|
+
function followedWith(status, method) {
|
|
10449
|
+
if (status === 303 && method !== "GET" && method !== "HEAD") return "GET";
|
|
10450
|
+
if ((status === 301 || status === 302) && method === "POST") return "GET";
|
|
10451
|
+
return method;
|
|
10452
|
+
}
|
|
10453
|
+
function bodiless(hop) {
|
|
10454
|
+
return {
|
|
10455
|
+
url: hop.url,
|
|
10456
|
+
status: hop.status,
|
|
10457
|
+
statusText: "",
|
|
10458
|
+
headers: hop.headers,
|
|
10459
|
+
body: (async function* () {
|
|
10460
|
+
})(),
|
|
10461
|
+
cancel: async () => void 0
|
|
10462
|
+
};
|
|
10463
|
+
}
|
|
10464
|
+
function replayingHops(inner, heldMs = HELD_MS) {
|
|
10465
|
+
if (!inner.traits.redirectHops || inner.traits.manualRedirects) return inner;
|
|
10466
|
+
const held = /* @__PURE__ */ new Map();
|
|
10467
|
+
const drop = (key) => {
|
|
10468
|
+
const entry = held.get(key);
|
|
10469
|
+
if (!entry) return;
|
|
10470
|
+
held.delete(key);
|
|
10471
|
+
clearTimeout(entry.timer);
|
|
10472
|
+
void entry.final.cancel().catch(() => void 0);
|
|
10473
|
+
};
|
|
10474
|
+
const keyOf2 = (owner, method, url) => `${owner} ${method} ${url}`;
|
|
10475
|
+
const hold = (key, chain) => {
|
|
10476
|
+
drop(key);
|
|
10477
|
+
const mine = [...held.keys()].filter((k) => held.get(k)?.owner === chain.owner);
|
|
10478
|
+
if (mine.length >= HELD_PER_OWNER) drop(mine[0]);
|
|
10479
|
+
if (held.size >= HELD_MAX) drop(held.keys().next().value);
|
|
10480
|
+
const timer = setTimeout(() => drop(key), heldMs);
|
|
10481
|
+
timer.unref?.();
|
|
10482
|
+
held.set(key, { ...chain, timer });
|
|
10483
|
+
};
|
|
10484
|
+
const replay = (chain) => {
|
|
10485
|
+
const [hop, ...rest2] = chain.hops;
|
|
10486
|
+
const location = hop && header2(hop.headers, "location");
|
|
10487
|
+
if (!hop || location === void 0) return chain.final;
|
|
10488
|
+
const next2 = new URL(location, hop.url).href;
|
|
10489
|
+
const method = followedWith(hop.status, chain.method);
|
|
10490
|
+
hold(keyOf2(chain.owner, method, next2), { ...chain, method, hops: rest2 });
|
|
10491
|
+
return bodiless(hop);
|
|
10492
|
+
};
|
|
10493
|
+
return {
|
|
10494
|
+
traits: { ...inner.traits, manualRedirects: true },
|
|
10495
|
+
...inner.websocket ? { websocket: inner.websocket.bind(inner) } : {},
|
|
10496
|
+
async fetch(request, owner = KERNEL) {
|
|
10497
|
+
const key = keyOf2(owner, request.method, request.url);
|
|
10498
|
+
const waiting = held.get(key);
|
|
10499
|
+
if (waiting && waiting.fingerprint === fingerprint(request.headers)) {
|
|
10500
|
+
held.delete(key);
|
|
10501
|
+
clearTimeout(waiting.timer);
|
|
10502
|
+
return replay(waiting);
|
|
10503
|
+
}
|
|
10504
|
+
const response = await inner.fetch(request);
|
|
10505
|
+
if (!response.redirects?.length) return response;
|
|
10506
|
+
return replay({
|
|
10507
|
+
owner,
|
|
10508
|
+
method: request.method,
|
|
10509
|
+
fingerprint: fingerprint(request.headers),
|
|
10510
|
+
hops: response.redirects,
|
|
10511
|
+
final: response
|
|
10512
|
+
});
|
|
10513
|
+
}
|
|
10514
|
+
};
|
|
10515
|
+
}
|
|
10516
|
+
|
|
10408
10517
|
// src/kernel/settling.ts
|
|
10409
10518
|
var SETUP_OPS = /* @__PURE__ */ new Set([
|
|
10410
10519
|
"proc-list",
|
|
@@ -11830,7 +11939,7 @@ var Launcher = class {
|
|
|
11830
11939
|
this.hostname = hostname;
|
|
11831
11940
|
this.env = { ...networkEnv(hostname), SLICC_CDP_URL: this.cdp.url, ...options.env };
|
|
11832
11941
|
this.ca = kernelCa(options.caStore ?? memoryCaStore());
|
|
11833
|
-
this.transport = options.transport ?? missingTransport();
|
|
11942
|
+
this.transport = replayingHops(options.transport ?? missingTransport());
|
|
11834
11943
|
this.uplink = options.uplink;
|
|
11835
11944
|
this.routes = new Routes(options.uplink?.traits.ipv6 === true);
|
|
11836
11945
|
if (options.uplink?.routes) this.routes.set(options.uplink.routes);
|
|
@@ -12087,7 +12196,7 @@ var Launcher = class {
|
|
|
12087
12196
|
jobs: this.jobs,
|
|
12088
12197
|
ptys: this.ptys,
|
|
12089
12198
|
net: this.net,
|
|
12090
|
-
http: new HttpHandles(this.transport),
|
|
12199
|
+
http: new HttpHandles(this.transport, pid),
|
|
12091
12200
|
locks: this.locks,
|
|
12092
12201
|
resolver: this.resolver,
|
|
12093
12202
|
onReap: (child) => this.reaped(child),
|
|
@@ -12857,7 +12966,7 @@ var RemoteTransport = class {
|
|
|
12857
12966
|
finish();
|
|
12858
12967
|
throw e;
|
|
12859
12968
|
}
|
|
12860
|
-
const { status, statusText, headers, url, redirected } = head;
|
|
12969
|
+
const { status, statusText, headers, url, redirected, redirects } = head;
|
|
12861
12970
|
const read = async () => {
|
|
12862
12971
|
if (finished) return void 0;
|
|
12863
12972
|
const reply = await this.ask({ net: "read", nid }).catch((e) => {
|
|
@@ -12875,6 +12984,7 @@ var RemoteTransport = class {
|
|
|
12875
12984
|
};
|
|
12876
12985
|
return {
|
|
12877
12986
|
...redirected ? { url, redirected } : {},
|
|
12987
|
+
...redirects ? { redirects } : {},
|
|
12878
12988
|
status,
|
|
12879
12989
|
statusText,
|
|
12880
12990
|
headers,
|
|
@@ -13074,7 +13184,7 @@ function parseHead(bytes) {
|
|
|
13074
13184
|
}
|
|
13075
13185
|
return { status: Number(match[1]), statusText: match[2] ?? "", headers };
|
|
13076
13186
|
}
|
|
13077
|
-
function
|
|
13187
|
+
function header3(head, name2) {
|
|
13078
13188
|
return head.headers.find(([key]) => key.toLowerCase() === name2)?.[1];
|
|
13079
13189
|
}
|
|
13080
13190
|
async function* chunked(source) {
|
|
@@ -13103,8 +13213,8 @@ async function* untilClose(source) {
|
|
|
13103
13213
|
}
|
|
13104
13214
|
function bodyOf(source, head, method) {
|
|
13105
13215
|
if (method === "HEAD" || head.status === 204 || head.status === 304) return void 0;
|
|
13106
|
-
if (
|
|
13107
|
-
const length2 =
|
|
13216
|
+
if (header3(head, "transfer-encoding")?.toLowerCase().includes("chunked")) return chunked(source);
|
|
13217
|
+
const length2 = header3(head, "content-length");
|
|
13108
13218
|
if (length2 === void 0) return untilClose(source);
|
|
13109
13219
|
const size = Number(length2);
|
|
13110
13220
|
if (!/^\d+$/.test(length2.trim()) || !Number.isSafeInteger(size)) {
|
|
@@ -13558,7 +13668,7 @@ function hostfsFetchOf(options) {
|
|
|
13558
13668
|
};
|
|
13559
13669
|
}
|
|
13560
13670
|
function nodeTransport() {
|
|
13561
|
-
const transport = fetchTransport({ webSocket: true, webSocketHeaders: true });
|
|
13671
|
+
const transport = fetchTransport({ webSocket: true, webSocketHeaders: true, redirect: "manual" });
|
|
13562
13672
|
return { ...transport, traits: { ...transport.traits, crossOrigin: "any" } };
|
|
13563
13673
|
}
|
|
13564
13674
|
var TERMINATED = "the kernel is terminated";
|