@ai-ecoverse/slicc-kernel 1.49.1 → 1.51.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 +3 -2
- 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 +165 -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 +493 -266
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +172 -71
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +543 -316
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
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");
|
|
@@ -9712,7 +9728,8 @@ var WasmProcess = class {
|
|
|
9712
9728
|
fds: this.fds,
|
|
9713
9729
|
net: this.net,
|
|
9714
9730
|
blocking: () => this.blockingSignal(cancelled),
|
|
9715
|
-
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 })
|
|
9716
9733
|
});
|
|
9717
9734
|
}
|
|
9718
9735
|
tty(fd) {
|
|
@@ -9928,12 +9945,12 @@ var Dying = class {
|
|
|
9928
9945
|
timer;
|
|
9929
9946
|
busy = 0;
|
|
9930
9947
|
finish;
|
|
9931
|
-
start(code, sig,
|
|
9948
|
+
start(code, sig, header4, process2, finish) {
|
|
9932
9949
|
if (this.ending) return;
|
|
9933
9950
|
this.ending = { code, sig };
|
|
9934
9951
|
this.finish = finish;
|
|
9935
9952
|
this.arm();
|
|
9936
|
-
Atomics.store(
|
|
9953
|
+
Atomics.store(header4, SAB_I_KILLED, code);
|
|
9937
9954
|
process2.die();
|
|
9938
9955
|
}
|
|
9939
9956
|
async serving(work) {
|
|
@@ -9970,22 +9987,22 @@ function killThread(thread, caught, sig) {
|
|
|
9970
9987
|
function threadCancel(thread) {
|
|
9971
9988
|
return Atomics.load(thread.header, SAB_I_SIGNALS) !== 0 ? AbortSignal.abort() : thread.interrupt.signal;
|
|
9972
9989
|
}
|
|
9973
|
-
function notifiers(
|
|
9990
|
+
function notifiers(header4) {
|
|
9974
9991
|
return {
|
|
9975
9992
|
onPending(sig) {
|
|
9976
|
-
Atomics.or(
|
|
9977
|
-
Atomics.notify(
|
|
9993
|
+
Atomics.or(header4, SAB_I_SIGNALS, sigbit(sig));
|
|
9994
|
+
Atomics.notify(header4, SAB_I_SIGNALS);
|
|
9978
9995
|
},
|
|
9979
9996
|
onAsync() {
|
|
9980
|
-
Atomics.add(
|
|
9981
|
-
Atomics.notify(
|
|
9997
|
+
Atomics.add(header4, SAB_I_ASYNC, 1);
|
|
9998
|
+
Atomics.notify(header4, SAB_I_ASYNC);
|
|
9982
9999
|
}
|
|
9983
10000
|
};
|
|
9984
10001
|
}
|
|
9985
|
-
function publishStops(process2,
|
|
10002
|
+
function publishStops(process2, header4) {
|
|
9986
10003
|
process2.onState((state) => {
|
|
9987
|
-
Atomics.store(
|
|
9988
|
-
Atomics.notify(
|
|
10004
|
+
Atomics.store(header4, SAB_I_STOP, state === "stopped" ? 1 : 0);
|
|
10005
|
+
Atomics.notify(header4, SAB_I_STOP);
|
|
9989
10006
|
});
|
|
9990
10007
|
}
|
|
9991
10008
|
function transferOf(opts, lane) {
|
|
@@ -10053,7 +10070,7 @@ function holdingToken(opts, holds) {
|
|
|
10053
10070
|
renamed: (from, to) => holds.renamed(from, to)
|
|
10054
10071
|
});
|
|
10055
10072
|
}
|
|
10056
|
-
function processOptions(opts,
|
|
10073
|
+
function processOptions(opts, header4, hooks) {
|
|
10057
10074
|
return {
|
|
10058
10075
|
...inherited(opts),
|
|
10059
10076
|
...opts.identity ? { identity: opts.identity } : {},
|
|
@@ -10077,27 +10094,27 @@ function processOptions(opts, header3, hooks) {
|
|
|
10077
10094
|
locks: opts.locks,
|
|
10078
10095
|
onReap: opts.onReap,
|
|
10079
10096
|
resolver: opts.resolver,
|
|
10080
|
-
...notifiers(
|
|
10081
|
-
onTimer: (which) => void Atomics.or(
|
|
10082
|
-
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,
|
|
10083
10100
|
raise: hooks.raise,
|
|
10084
10101
|
threadKill: hooks.threadKill,
|
|
10085
|
-
...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) } : {}
|
|
10086
10103
|
};
|
|
10087
10104
|
}
|
|
10088
10105
|
function spawnWasmProcess(opts) {
|
|
10089
10106
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
10090
|
-
const
|
|
10107
|
+
const header4 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
10091
10108
|
const threadSignals = /* @__PURE__ */ new Map();
|
|
10092
10109
|
const process2 = new WasmProcess(
|
|
10093
10110
|
opts.pid,
|
|
10094
10111
|
opts.fds,
|
|
10095
|
-
processOptions(opts,
|
|
10112
|
+
processOptions(opts, header4, {
|
|
10096
10113
|
raise: (sig) => signal(sig),
|
|
10097
10114
|
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig)
|
|
10098
10115
|
})
|
|
10099
10116
|
);
|
|
10100
|
-
publishStops(process2,
|
|
10117
|
+
publishStops(process2, header4);
|
|
10101
10118
|
const holds = new HeldPaths();
|
|
10102
10119
|
opts.held?.add(holds);
|
|
10103
10120
|
const token = holdingToken(opts, holds);
|
|
@@ -10209,7 +10226,7 @@ function spawnWasmProcess(opts) {
|
|
|
10209
10226
|
if (process2.signal(sig) !== "terminate") return;
|
|
10210
10227
|
const code = sig === SIG.KILL ? 137 : 128 + sig;
|
|
10211
10228
|
if (opts.program.abi !== "wasi" || done4) finish(code, sig);
|
|
10212
|
-
else dying.start(code, sig,
|
|
10229
|
+
else dying.start(code, sig, header4, process2, () => finish(code, sig));
|
|
10213
10230
|
};
|
|
10214
10231
|
const kill = (code = 137) => finish(code, code > 128 && code < 160 ? code - 128 : void 0);
|
|
10215
10232
|
return {
|
|
@@ -10219,7 +10236,7 @@ function spawnWasmProcess(opts) {
|
|
|
10219
10236
|
signal,
|
|
10220
10237
|
termsig: () => endedBy,
|
|
10221
10238
|
onState: (listener) => process2.onState(listener),
|
|
10222
|
-
memory: () => Atomics.load(
|
|
10239
|
+
memory: () => Atomics.load(header4, SAB_I_MEMORY) * 65536,
|
|
10223
10240
|
ignoredSignals: (fork) => process2.inheritable(fork),
|
|
10224
10241
|
signalMasks: () => process2.signalMasks(),
|
|
10225
10242
|
umask: () => process2.umask,
|
|
@@ -10414,6 +10431,89 @@ var JobTable = class {
|
|
|
10414
10431
|
}
|
|
10415
10432
|
};
|
|
10416
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
|
+
|
|
10417
10517
|
// src/kernel/settling.ts
|
|
10418
10518
|
var SETUP_OPS = /* @__PURE__ */ new Set([
|
|
10419
10519
|
"proc-list",
|
|
@@ -11839,7 +11939,7 @@ var Launcher = class {
|
|
|
11839
11939
|
this.hostname = hostname;
|
|
11840
11940
|
this.env = { ...networkEnv(hostname), SLICC_CDP_URL: this.cdp.url, ...options.env };
|
|
11841
11941
|
this.ca = kernelCa(options.caStore ?? memoryCaStore());
|
|
11842
|
-
this.transport = options.transport ?? missingTransport();
|
|
11942
|
+
this.transport = replayingHops(options.transport ?? missingTransport());
|
|
11843
11943
|
this.uplink = options.uplink;
|
|
11844
11944
|
this.routes = new Routes(options.uplink?.traits.ipv6 === true);
|
|
11845
11945
|
if (options.uplink?.routes) this.routes.set(options.uplink.routes);
|
|
@@ -12096,7 +12196,7 @@ var Launcher = class {
|
|
|
12096
12196
|
jobs: this.jobs,
|
|
12097
12197
|
ptys: this.ptys,
|
|
12098
12198
|
net: this.net,
|
|
12099
|
-
http: new HttpHandles(this.transport),
|
|
12199
|
+
http: new HttpHandles(this.transport, pid),
|
|
12100
12200
|
locks: this.locks,
|
|
12101
12201
|
resolver: this.resolver,
|
|
12102
12202
|
onReap: (child) => this.reaped(child),
|
|
@@ -12866,7 +12966,7 @@ var RemoteTransport = class {
|
|
|
12866
12966
|
finish();
|
|
12867
12967
|
throw e;
|
|
12868
12968
|
}
|
|
12869
|
-
const { status, statusText, headers, url, redirected } = head;
|
|
12969
|
+
const { status, statusText, headers, url, redirected, redirects } = head;
|
|
12870
12970
|
const read = async () => {
|
|
12871
12971
|
if (finished) return void 0;
|
|
12872
12972
|
const reply = await this.ask({ net: "read", nid }).catch((e) => {
|
|
@@ -12884,6 +12984,7 @@ var RemoteTransport = class {
|
|
|
12884
12984
|
};
|
|
12885
12985
|
return {
|
|
12886
12986
|
...redirected ? { url, redirected } : {},
|
|
12987
|
+
...redirects ? { redirects } : {},
|
|
12887
12988
|
status,
|
|
12888
12989
|
statusText,
|
|
12889
12990
|
headers,
|
|
@@ -13083,7 +13184,7 @@ function parseHead(bytes) {
|
|
|
13083
13184
|
}
|
|
13084
13185
|
return { status: Number(match[1]), statusText: match[2] ?? "", headers };
|
|
13085
13186
|
}
|
|
13086
|
-
function
|
|
13187
|
+
function header3(head, name2) {
|
|
13087
13188
|
return head.headers.find(([key]) => key.toLowerCase() === name2)?.[1];
|
|
13088
13189
|
}
|
|
13089
13190
|
async function* chunked(source) {
|
|
@@ -13112,8 +13213,8 @@ async function* untilClose(source) {
|
|
|
13112
13213
|
}
|
|
13113
13214
|
function bodyOf(source, head, method) {
|
|
13114
13215
|
if (method === "HEAD" || head.status === 204 || head.status === 304) return void 0;
|
|
13115
|
-
if (
|
|
13116
|
-
const length2 =
|
|
13216
|
+
if (header3(head, "transfer-encoding")?.toLowerCase().includes("chunked")) return chunked(source);
|
|
13217
|
+
const length2 = header3(head, "content-length");
|
|
13117
13218
|
if (length2 === void 0) return untilClose(source);
|
|
13118
13219
|
const size = Number(length2);
|
|
13119
13220
|
if (!/^\d+$/.test(length2.trim()) || !Number.isSafeInteger(size)) {
|
|
@@ -13567,7 +13668,7 @@ function hostfsFetchOf(options) {
|
|
|
13567
13668
|
};
|
|
13568
13669
|
}
|
|
13569
13670
|
function nodeTransport() {
|
|
13570
|
-
const transport = fetchTransport({ webSocket: true, webSocketHeaders: true });
|
|
13671
|
+
const transport = fetchTransport({ webSocket: true, webSocketHeaders: true, redirect: "manual" });
|
|
13571
13672
|
return { ...transport, traits: { ...transport.traits, crossOrigin: "any" } };
|
|
13572
13673
|
}
|
|
13573
13674
|
var TERMINATED = "the kernel is terminated";
|