@ai-ecoverse/slicc-kernel 1.170.4 → 1.171.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 +2 -1
- package/dist/driver-worker.js +32 -10
- package/dist/driver-worker.js.map +3 -3
- package/dist/index.js +49 -19
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +284 -254
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +36 -14
- package/dist/node-driver-worker.js.map +3 -3
- package/dist/node-process-worker.cjs +1 -1
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +383 -296
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/kernel/net/remote-transport.d.ts +4 -1
- package/dist/types/kernel/net/transport.d.ts +4 -0
- package/dist/types/node/follow.d.ts +4 -0
- package/dist/types/node.d.ts +1 -0
- package/dist/types/transport.d.ts +2 -2
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -7310,6 +7310,19 @@ function uploadsFor(peer) {
|
|
|
7310
7310
|
});
|
|
7311
7311
|
return { of, answer: (call) => pulls.get(call.nid)?.(call) };
|
|
7312
7312
|
}
|
|
7313
|
+
function headOf(nid, response) {
|
|
7314
|
+
return {
|
|
7315
|
+
net: "head",
|
|
7316
|
+
nid,
|
|
7317
|
+
...response.url !== void 0 ? { url: response.url } : {},
|
|
7318
|
+
...response.redirected !== void 0 ? { redirected: response.redirected } : {},
|
|
7319
|
+
...response.redirects ? { redirects: response.redirects } : {},
|
|
7320
|
+
...response.opaqueRedirect ? { opaqueRedirect: true } : {},
|
|
7321
|
+
status: response.status,
|
|
7322
|
+
statusText: response.statusText,
|
|
7323
|
+
headers: response.headers
|
|
7324
|
+
};
|
|
7325
|
+
}
|
|
7313
7326
|
function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS2 } = {}) {
|
|
7314
7327
|
const open2 = /* @__PURE__ */ new Map();
|
|
7315
7328
|
const fail2 = (nid, e) => {
|
|
@@ -7335,6 +7348,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS2 } = {})
|
|
|
7335
7348
|
method: call.method,
|
|
7336
7349
|
headers: call.headers,
|
|
7337
7350
|
...call.streamed ? { bodyStream: uploads.of(call.nid, abort.signal) } : call.body ? { body: call.body } : {},
|
|
7351
|
+
...call.redirect !== void 0 ? { redirect: call.redirect } : {},
|
|
7338
7352
|
signal: abort.signal
|
|
7339
7353
|
});
|
|
7340
7354
|
if (!open2.has(call.nid)) {
|
|
@@ -7342,15 +7356,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS2 } = {})
|
|
|
7342
7356
|
return;
|
|
7343
7357
|
}
|
|
7344
7358
|
open2.set(call.nid, { abort, body: response.body[Symbol.asyncIterator](), response });
|
|
7345
|
-
peer.postMessage(
|
|
7346
|
-
net: "head",
|
|
7347
|
-
nid: call.nid,
|
|
7348
|
-
...response.redirected ? { url: response.url, redirected: true } : {},
|
|
7349
|
-
...response.redirects ? { redirects: response.redirects } : {},
|
|
7350
|
-
status: response.status,
|
|
7351
|
-
statusText: response.statusText,
|
|
7352
|
-
headers: response.headers
|
|
7353
|
-
});
|
|
7359
|
+
peer.postMessage(headOf(call.nid, response));
|
|
7354
7360
|
} catch (e) {
|
|
7355
7361
|
fail2(call.nid, e);
|
|
7356
7362
|
}
|
|
@@ -8206,9 +8212,9 @@ function serveClient(port, host) {
|
|
|
8206
8212
|
ended.resolve();
|
|
8207
8213
|
}
|
|
8208
8214
|
async function hello(message3) {
|
|
8209
|
-
const
|
|
8210
|
-
if (
|
|
8211
|
-
send2({ hello: { protocol: PROTOCOL, error:
|
|
8215
|
+
const refused4 = versionError(message3.protocol) ?? await hosts.requests.accept(host, message3);
|
|
8216
|
+
if (refused4) {
|
|
8217
|
+
send2({ hello: { protocol: PROTOCOL, error: refused4 } });
|
|
8212
8218
|
detach();
|
|
8213
8219
|
return;
|
|
8214
8220
|
}
|
|
@@ -8498,7 +8504,7 @@ function satisfies(version, range2) {
|
|
|
8498
8504
|
}
|
|
8499
8505
|
|
|
8500
8506
|
// src/version.ts
|
|
8501
|
-
var KERNEL_VERSION = true ? "1.
|
|
8507
|
+
var KERNEL_VERSION = true ? "1.171.0" : "0.0.0-dev";
|
|
8502
8508
|
var OS_RELEASE = "6.0.0-slicc";
|
|
8503
8509
|
function procVersion() {
|
|
8504
8510
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -8790,10 +8796,10 @@ async function tierPackages(fs, physical, roots, bins, kernel, global) {
|
|
|
8790
8796
|
const own = commandsOf(pkg, manifest);
|
|
8791
8797
|
const named = new Set(own.map((command) => command.name));
|
|
8792
8798
|
const extra = bins ? await binCommandsOf(physical, pkg, manifest, named) : [];
|
|
8793
|
-
const
|
|
8799
|
+
const refused4 = engineRefusal(manifest, kernel);
|
|
8794
8800
|
const name2 = pkg.slice(root.length + 1);
|
|
8795
8801
|
const dependency = direct?.has(name2) === false;
|
|
8796
|
-
const marks = { ...
|
|
8802
|
+
const marks = { ...refused4 ? { refused: refused4 } : {}, ...dependency ? { dependency } : {} };
|
|
8797
8803
|
out.push({
|
|
8798
8804
|
name: name2,
|
|
8799
8805
|
pkg,
|
|
@@ -8825,7 +8831,7 @@ function winners(tier) {
|
|
|
8825
8831
|
}
|
|
8826
8832
|
return out;
|
|
8827
8833
|
}
|
|
8828
|
-
async function scanCommands(fs, modules, binsFrom = Number.POSITIVE_INFINITY, kernel = KERNEL_VERSION,
|
|
8834
|
+
async function scanCommands(fs, modules, binsFrom = Number.POSITIVE_INFINITY, kernel = KERNEL_VERSION, refused4, global = /* @__PURE__ */ new Set()) {
|
|
8829
8835
|
const found = /* @__PURE__ */ new Map();
|
|
8830
8836
|
const physical = physicalResolver(fs);
|
|
8831
8837
|
const tiers = (typeof modules === "string" ? [modules] : modules).map(
|
|
@@ -8839,7 +8845,7 @@ async function scanCommands(fs, modules, binsFrom = Number.POSITIVE_INFINITY, ke
|
|
|
8839
8845
|
const dependencies = [];
|
|
8840
8846
|
for (const [index, roots] of tiers.entries()) {
|
|
8841
8847
|
const tier = await tierPackages(fs, physical, roots, index >= binsFrom, kernel, global);
|
|
8842
|
-
if (
|
|
8848
|
+
if (refused4) refused4.push(...tier.flatMap((entry) => entry.commands.filter((c) => c.refused)));
|
|
8843
8849
|
await take(tier.filter((entry) => !entry.dependency));
|
|
8844
8850
|
dependencies.push(tier.filter((entry) => entry.dependency));
|
|
8845
8851
|
}
|
|
@@ -10912,8 +10918,8 @@ var RealmProxy = class {
|
|
|
10912
10918
|
}
|
|
10913
10919
|
async connect(conn, incoming, req, idle2) {
|
|
10914
10920
|
const target = tunnelTarget(req);
|
|
10915
|
-
const
|
|
10916
|
-
if (
|
|
10921
|
+
const refused4 = target.port === 443 ? await this.tunnelReady(target) : void 0;
|
|
10922
|
+
if (refused4) throw refused4;
|
|
10917
10923
|
await conn.write(latin1Bytes("HTTP/1.1 200 Connection Established\r\n\r\n"), this.stop.signal);
|
|
10918
10924
|
try {
|
|
10919
10925
|
const first = await incoming.peek(this.stop.signal);
|
|
@@ -13418,8 +13424,8 @@ var DriverConnection = class _DriverConnection {
|
|
|
13418
13424
|
} finally {
|
|
13419
13425
|
clearTimeout(timer);
|
|
13420
13426
|
}
|
|
13421
|
-
const
|
|
13422
|
-
if (
|
|
13427
|
+
const refused4 = driverVersionError(hello.protocol);
|
|
13428
|
+
if (refused4) throw errnoError("EPROTO", refused4);
|
|
13423
13429
|
if (hello.error) throw errnoError(hello.errno ?? "EIO", hello.error);
|
|
13424
13430
|
return new _DriverConnection(port, hello.capabilities ?? {}, waiting, timeoutMs, options);
|
|
13425
13431
|
}
|
|
@@ -15443,8 +15449,8 @@ async function guarded(entry, path, req) {
|
|
|
15443
15449
|
return { paths };
|
|
15444
15450
|
} catch (err) {
|
|
15445
15451
|
const refusal2 = err.code === "EACCES";
|
|
15446
|
-
const
|
|
15447
|
-
return { refused:
|
|
15452
|
+
const refused4 = req.op === "exists" && refusal2 ? json2(false) : toErrno(err);
|
|
15453
|
+
return { refused: refused4 };
|
|
15448
15454
|
}
|
|
15449
15455
|
}
|
|
15450
15456
|
async function copyOp(entry, path, req) {
|
|
@@ -15640,13 +15646,13 @@ async function created2(entry, req) {
|
|
|
15640
15646
|
return seen === void 0 ? looked : json2({ ...looked.json, seen });
|
|
15641
15647
|
}
|
|
15642
15648
|
var DENIED = /* @__PURE__ */ new Set(["EACCES", "EPERM"]);
|
|
15643
|
-
async function rmPermitted(entry, path, req,
|
|
15649
|
+
async function rmPermitted(entry, path, req, refused4) {
|
|
15644
15650
|
const st = await entry.fs.lstat(path).catch(() => void 0);
|
|
15645
|
-
if (!st?.isDirectory) return
|
|
15651
|
+
if (!st?.isDirectory) return refused4;
|
|
15646
15652
|
const unlisted = await guarded(entry, path, { ...req, op: "readdir" });
|
|
15647
15653
|
if ("refused" in unlisted) return unlisted.refused;
|
|
15648
15654
|
const names2 = await entry.fs.readdir(path).catch(() => void 0);
|
|
15649
|
-
if (!names2) return
|
|
15655
|
+
if (!names2) return refused4;
|
|
15650
15656
|
let first;
|
|
15651
15657
|
for (const name2 of names2) {
|
|
15652
15658
|
const child = await dispatchOne(entry, {
|
|
@@ -15697,14 +15703,14 @@ async function newDevName(entry, path, req) {
|
|
|
15697
15703
|
const named = NAMING.has(req.op);
|
|
15698
15704
|
if (!named && !CREATIONS.has(req.op)) return void 0;
|
|
15699
15705
|
const target = named ? entry.fs.resolvePath(entry.cwd, req.arg2 ?? "") : path;
|
|
15700
|
-
const
|
|
15701
|
-
if (!
|
|
15706
|
+
const refused4 = devCreation(target, entry.cred?.());
|
|
15707
|
+
if (!refused4) return void 0;
|
|
15702
15708
|
const there = await entry.fs.lstat(target).then(
|
|
15703
15709
|
() => true,
|
|
15704
15710
|
() => false
|
|
15705
15711
|
);
|
|
15706
15712
|
if (there) return void 0;
|
|
15707
|
-
return { ok: false, errno:
|
|
15713
|
+
return { ok: false, errno: refused4, message: `${target}: no new names in /dev or /proc` };
|
|
15708
15714
|
}
|
|
15709
15715
|
var MISS_OPS = /* @__PURE__ */ new Set(["stat", "lstat"]);
|
|
15710
15716
|
async function linkFree(fs, path) {
|
|
@@ -17807,8 +17813,8 @@ var KernelLoopback = class {
|
|
|
17807
17813
|
);
|
|
17808
17814
|
} catch (err) {
|
|
17809
17815
|
socket.close();
|
|
17810
|
-
const
|
|
17811
|
-
throw
|
|
17816
|
+
const refused4 = err instanceof KernelError && err.code === "ECONNREFUSED";
|
|
17817
|
+
throw refused4 ? errno2("ECONNREFUSED", `nothing listens on the kernel's port ${port}`) : err;
|
|
17812
17818
|
}
|
|
17813
17819
|
signal.addEventListener("abort", () => socket.close(), { once: true });
|
|
17814
17820
|
return socket;
|
|
@@ -29035,6 +29041,234 @@ function enableDnsStub(net, stub) {
|
|
|
29035
29041
|
});
|
|
29036
29042
|
}
|
|
29037
29043
|
|
|
29044
|
+
// src/kernel/net/remote-transport.ts
|
|
29045
|
+
var TransportError = class extends Error {
|
|
29046
|
+
status;
|
|
29047
|
+
code;
|
|
29048
|
+
detail;
|
|
29049
|
+
constructor(message3, status, code, detail) {
|
|
29050
|
+
super(message3);
|
|
29051
|
+
this.status = status;
|
|
29052
|
+
this.code = code;
|
|
29053
|
+
this.detail = detail === "transport" ? detail : void 0;
|
|
29054
|
+
}
|
|
29055
|
+
};
|
|
29056
|
+
function unfollowed2(redirect) {
|
|
29057
|
+
return redirect !== void 0 && redirect !== "follow";
|
|
29058
|
+
}
|
|
29059
|
+
function honors(traits, redirect) {
|
|
29060
|
+
if (traits.redirectPolicy === true) return true;
|
|
29061
|
+
const hops = traits.redirectHops;
|
|
29062
|
+
const raw2 = traits.manualRedirects === true && (hops === void 0 || hops === false);
|
|
29063
|
+
return redirect === "manual" && raw2;
|
|
29064
|
+
}
|
|
29065
|
+
function refused3(message3) {
|
|
29066
|
+
return new TransportError(message3, 502, void 0, "transport");
|
|
29067
|
+
}
|
|
29068
|
+
var RemoteTransport = class {
|
|
29069
|
+
traits;
|
|
29070
|
+
port;
|
|
29071
|
+
waiting = /* @__PURE__ */ new Map();
|
|
29072
|
+
nextId = 0;
|
|
29073
|
+
sockets = /* @__PURE__ */ new Map();
|
|
29074
|
+
uploads = /* @__PURE__ */ new Map();
|
|
29075
|
+
failure;
|
|
29076
|
+
constructor(port, traits) {
|
|
29077
|
+
this.port = port;
|
|
29078
|
+
this.traits = traits;
|
|
29079
|
+
}
|
|
29080
|
+
receive(reply) {
|
|
29081
|
+
if (reply.net === "body-pull") {
|
|
29082
|
+
void this.pull(reply.nid);
|
|
29083
|
+
return;
|
|
29084
|
+
}
|
|
29085
|
+
const socket = this.sockets.get(reply.nid);
|
|
29086
|
+
if (socket && this.toSocket(reply, socket)) return;
|
|
29087
|
+
const waiter = this.waiting.get(reply.nid);
|
|
29088
|
+
if (!waiter) return;
|
|
29089
|
+
this.waiting.delete(reply.nid);
|
|
29090
|
+
if (reply.net === "error") {
|
|
29091
|
+
waiter.reject(new TransportError(reply.message, reply.status, reply.code, reply.detail));
|
|
29092
|
+
} else waiter.resolve(reply);
|
|
29093
|
+
}
|
|
29094
|
+
toSocket(reply, socket) {
|
|
29095
|
+
if (reply.net === "ws-message") socket.queue.push(reply.data);
|
|
29096
|
+
else if (reply.net === "ws-acked") socket.acked(reply.n);
|
|
29097
|
+
else if (reply.net === "ws-closed") {
|
|
29098
|
+
this.sockets.delete(reply.nid);
|
|
29099
|
+
socket.queue.end({ code: reply.code, reason: reply.reason });
|
|
29100
|
+
} else return false;
|
|
29101
|
+
return true;
|
|
29102
|
+
}
|
|
29103
|
+
async pull(nid) {
|
|
29104
|
+
const upload = this.uploads.get(nid);
|
|
29105
|
+
if (!upload) {
|
|
29106
|
+
this.port.postMessage({ net: "body-error", nid, message: "the request body is gone" });
|
|
29107
|
+
return;
|
|
29108
|
+
}
|
|
29109
|
+
try {
|
|
29110
|
+
const next3 = await upload.next();
|
|
29111
|
+
if (next3.done) {
|
|
29112
|
+
this.uploads.delete(nid);
|
|
29113
|
+
this.port.postMessage({ net: "body-end", nid });
|
|
29114
|
+
} else this.port.postMessage({ net: "body-chunk", nid, bytes: next3.value });
|
|
29115
|
+
} catch (e) {
|
|
29116
|
+
this.uploads.delete(nid);
|
|
29117
|
+
this.port.postMessage({
|
|
29118
|
+
net: "body-error",
|
|
29119
|
+
nid,
|
|
29120
|
+
message: e instanceof Error ? e.message : String(e)
|
|
29121
|
+
});
|
|
29122
|
+
}
|
|
29123
|
+
}
|
|
29124
|
+
dropUpload(nid) {
|
|
29125
|
+
const upload = this.uploads.get(nid);
|
|
29126
|
+
this.uploads.delete(nid);
|
|
29127
|
+
void upload?.return?.().catch(() => void 0);
|
|
29128
|
+
}
|
|
29129
|
+
fail(error) {
|
|
29130
|
+
this.failure = error;
|
|
29131
|
+
for (const nid of [...this.uploads.keys()]) this.dropUpload(nid);
|
|
29132
|
+
for (const waiter of this.waiting.values()) waiter.reject(error);
|
|
29133
|
+
this.waiting.clear();
|
|
29134
|
+
for (const socket of this.sockets.values())
|
|
29135
|
+
socket.queue.end({ code: 1011, reason: error.message });
|
|
29136
|
+
this.sockets.clear();
|
|
29137
|
+
}
|
|
29138
|
+
ask(call) {
|
|
29139
|
+
if (this.failure) return Promise.reject(this.failure);
|
|
29140
|
+
return new Promise((resolve2, reject) => {
|
|
29141
|
+
this.waiting.set(call.nid, { resolve: resolve2, reject });
|
|
29142
|
+
this.port.postMessage(call);
|
|
29143
|
+
});
|
|
29144
|
+
}
|
|
29145
|
+
cancel(nid) {
|
|
29146
|
+
const waiter = this.waiting.get(nid);
|
|
29147
|
+
this.waiting.delete(nid);
|
|
29148
|
+
waiter?.reject(new TransportError("the request was cancelled"));
|
|
29149
|
+
this.port.postMessage({ net: "cancel", nid });
|
|
29150
|
+
}
|
|
29151
|
+
async fetch(request3) {
|
|
29152
|
+
const nid = ++this.nextId;
|
|
29153
|
+
const { signal, redirect } = request3;
|
|
29154
|
+
signal.throwIfAborted();
|
|
29155
|
+
if (unfollowed2(redirect) && !honors(this.traits, redirect)) {
|
|
29156
|
+
throw refused3(`this transport cannot honor redirect: ${redirect}`);
|
|
29157
|
+
}
|
|
29158
|
+
let finished = false;
|
|
29159
|
+
const abort = () => {
|
|
29160
|
+
finished = true;
|
|
29161
|
+
this.dropUpload(nid);
|
|
29162
|
+
this.cancel(nid);
|
|
29163
|
+
};
|
|
29164
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
29165
|
+
const finish = () => {
|
|
29166
|
+
this.dropUpload(nid);
|
|
29167
|
+
if (finished) return;
|
|
29168
|
+
finished = true;
|
|
29169
|
+
signal.removeEventListener("abort", abort);
|
|
29170
|
+
};
|
|
29171
|
+
if (request3.bodyStream) this.uploads.set(nid, request3.bodyStream[Symbol.asyncIterator]());
|
|
29172
|
+
let head;
|
|
29173
|
+
try {
|
|
29174
|
+
head = await this.ask({
|
|
29175
|
+
net: "fetch",
|
|
29176
|
+
nid,
|
|
29177
|
+
url: request3.url,
|
|
29178
|
+
method: request3.method,
|
|
29179
|
+
headers: request3.headers,
|
|
29180
|
+
...request3.bodyStream ? { streamed: true } : request3.body ? { body: request3.body } : {},
|
|
29181
|
+
...redirect !== void 0 ? { redirect } : {}
|
|
29182
|
+
});
|
|
29183
|
+
} catch (e) {
|
|
29184
|
+
finish();
|
|
29185
|
+
throw e;
|
|
29186
|
+
}
|
|
29187
|
+
const { status, statusText, headers, url, redirected: redirected2, redirects, opaqueRedirect } = head;
|
|
29188
|
+
const read = async () => {
|
|
29189
|
+
if (finished) return void 0;
|
|
29190
|
+
const reply = await this.ask({ net: "read", nid }).catch((e) => {
|
|
29191
|
+
finish();
|
|
29192
|
+
throw e;
|
|
29193
|
+
});
|
|
29194
|
+
if (reply.net === "chunk") return reply.bytes;
|
|
29195
|
+
finish();
|
|
29196
|
+
return void 0;
|
|
29197
|
+
};
|
|
29198
|
+
const cancel = async () => {
|
|
29199
|
+
if (finished) return;
|
|
29200
|
+
finish();
|
|
29201
|
+
this.cancel(nid);
|
|
29202
|
+
};
|
|
29203
|
+
if (unfollowed2(redirect) && (redirected2 || redirects?.length)) {
|
|
29204
|
+
await cancel();
|
|
29205
|
+
throw refused3(`this transport followed a redirect despite redirect: ${redirect}`);
|
|
29206
|
+
}
|
|
29207
|
+
return {
|
|
29208
|
+
...url !== void 0 ? { url } : {},
|
|
29209
|
+
...redirected2 !== void 0 ? { redirected: redirected2 } : {},
|
|
29210
|
+
...redirects ? { redirects } : {},
|
|
29211
|
+
...opaqueRedirect ? { opaqueRedirect } : {},
|
|
29212
|
+
status,
|
|
29213
|
+
statusText,
|
|
29214
|
+
headers,
|
|
29215
|
+
cancel,
|
|
29216
|
+
body: {
|
|
29217
|
+
[Symbol.asyncIterator]: () => ({
|
|
29218
|
+
next: async () => {
|
|
29219
|
+
const bytes = await read();
|
|
29220
|
+
return bytes ? { value: bytes, done: false } : { value: void 0, done: true };
|
|
29221
|
+
},
|
|
29222
|
+
return: async () => {
|
|
29223
|
+
await cancel();
|
|
29224
|
+
return { value: void 0, done: true };
|
|
29225
|
+
}
|
|
29226
|
+
})
|
|
29227
|
+
}
|
|
29228
|
+
};
|
|
29229
|
+
}
|
|
29230
|
+
async websocket(request3) {
|
|
29231
|
+
const nid = ++this.nextId;
|
|
29232
|
+
const { signal } = request3;
|
|
29233
|
+
signal.throwIfAborted();
|
|
29234
|
+
const abort = () => this.cancel(nid);
|
|
29235
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
29236
|
+
let opened2;
|
|
29237
|
+
try {
|
|
29238
|
+
opened2 = await this.ask({
|
|
29239
|
+
net: "ws-open",
|
|
29240
|
+
nid,
|
|
29241
|
+
url: request3.url,
|
|
29242
|
+
protocols: request3.protocols,
|
|
29243
|
+
headers: request3.headers
|
|
29244
|
+
});
|
|
29245
|
+
} finally {
|
|
29246
|
+
signal.removeEventListener("abort", abort);
|
|
29247
|
+
}
|
|
29248
|
+
const close = (code, reason) => this.port.postMessage({ net: "ws-close", nid, code, reason });
|
|
29249
|
+
const queue = new MessageQueue(
|
|
29250
|
+
() => close(1e3, "a message is too big"),
|
|
29251
|
+
Number.POSITIVE_INFINITY,
|
|
29252
|
+
(n) => this.port.postMessage({ net: "ws-consumed", nid, n })
|
|
29253
|
+
);
|
|
29254
|
+
let unacked = 0;
|
|
29255
|
+
this.sockets.set(nid, { queue, acked: (n) => void (unacked -= n) });
|
|
29256
|
+
return {
|
|
29257
|
+
protocol: opened2.protocol,
|
|
29258
|
+
get buffered() {
|
|
29259
|
+
return unacked;
|
|
29260
|
+
},
|
|
29261
|
+
send: (data) => {
|
|
29262
|
+
unacked += payloadSize(data);
|
|
29263
|
+
this.port.postMessage({ net: "ws-send", nid, data });
|
|
29264
|
+
},
|
|
29265
|
+
messages: queue,
|
|
29266
|
+
close,
|
|
29267
|
+
closed: queue.closed
|
|
29268
|
+
};
|
|
29269
|
+
}
|
|
29270
|
+
};
|
|
29271
|
+
|
|
29038
29272
|
// src/kernel/net/redirect-hops.ts
|
|
29039
29273
|
var HELD_MS = 3e4;
|
|
29040
29274
|
var HELD_MAX2 = 64;
|
|
@@ -29110,7 +29344,9 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
29110
29344
|
return { ...inner.traits, manualRedirects: true };
|
|
29111
29345
|
},
|
|
29112
29346
|
...inner.websocket ? { websocket: inner.websocket.bind(inner) } : {},
|
|
29113
|
-
async fetch(request3,
|
|
29347
|
+
async fetch(request3, ...rest2) {
|
|
29348
|
+
if (unfollowed2(request3.redirect)) return inner.fetch(request3, ...rest2);
|
|
29349
|
+
const [caller] = rest2;
|
|
29114
29350
|
const owner = caller ?? KERNEL;
|
|
29115
29351
|
const key = keyOf3(owner, request3.method, request3.url);
|
|
29116
29352
|
const waiting = held.get(key);
|
|
@@ -29120,7 +29356,7 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
29120
29356
|
return replay(waiting);
|
|
29121
29357
|
}
|
|
29122
29358
|
if (waiting) drop(key);
|
|
29123
|
-
const response = await inner.fetch(request3,
|
|
29359
|
+
const response = await inner.fetch(request3, ...rest2);
|
|
29124
29360
|
if (!response.redirects?.length) return response;
|
|
29125
29361
|
return replay({
|
|
29126
29362
|
owner,
|
|
@@ -29559,9 +29795,9 @@ function serveFilesystem(port, handlers, capabilities = {}, options = {}) {
|
|
|
29559
29795
|
let open2 = false;
|
|
29560
29796
|
const reply = (message3, transfer = []) => port.postMessage(message3, transfer);
|
|
29561
29797
|
async function hello(message3) {
|
|
29562
|
-
const
|
|
29563
|
-
if (
|
|
29564
|
-
reply({ hello: { protocol: DRIVER_PROTOCOL, error:
|
|
29798
|
+
const refused4 = driverVersionError(message3.protocol);
|
|
29799
|
+
if (refused4) {
|
|
29800
|
+
reply({ hello: { protocol: DRIVER_PROTOCOL, error: refused4, errno: "EPROTO" } });
|
|
29565
29801
|
return;
|
|
29566
29802
|
}
|
|
29567
29803
|
try {
|
|
@@ -32118,16 +32354,16 @@ var Launcher = class {
|
|
|
32118
32354
|
if (!found) {
|
|
32119
32355
|
found = this.swaps.settled().then(() => this.trustedAppended()).then(async (appended2) => {
|
|
32120
32356
|
const tiers = await this.tiers(scope, appended2);
|
|
32121
|
-
const
|
|
32357
|
+
const refused4 = [];
|
|
32122
32358
|
const commands = await scanCommands(
|
|
32123
32359
|
this.scanned,
|
|
32124
32360
|
tiers,
|
|
32125
32361
|
tiers.length - appended2.length,
|
|
32126
32362
|
void 0,
|
|
32127
|
-
|
|
32363
|
+
refused4,
|
|
32128
32364
|
await this.globalRoots(scope)
|
|
32129
32365
|
);
|
|
32130
|
-
this.refusedOf.set(commands,
|
|
32366
|
+
this.refusedOf.set(commands, refused4.map(refusing));
|
|
32131
32367
|
return commands;
|
|
32132
32368
|
}).then(
|
|
32133
32369
|
(commands) => this.refusals(commands).set(SUDO_COMMAND.name, SUDO_COMMAND).set(CRONTAB_COMMAND.name, CRONTAB_COMMAND)
|
|
@@ -32333,14 +32569,14 @@ var Launcher = class {
|
|
|
32333
32569
|
return await this.commandAt(path, scope) ?? await this.refusedAt(path, name2, scope);
|
|
32334
32570
|
}
|
|
32335
32571
|
async refusedAt(path, name2, scope) {
|
|
32336
|
-
const
|
|
32337
|
-
if (
|
|
32572
|
+
const refused4 = this.refusedOf.get(await this.commands(scope)) ?? [];
|
|
32573
|
+
if (refused4.length === 0) return void 0;
|
|
32338
32574
|
const st = await this.base.stat(path).catch(() => void 0);
|
|
32339
32575
|
if (!st?.isFile) return void 0;
|
|
32340
32576
|
const real = await physicalPathAsync(this.base, path).catch(() => path);
|
|
32341
32577
|
const same3 = async (own) => own === path || await physicalPathAsync(this.base, own).catch(() => own) === real;
|
|
32342
32578
|
const owners = [];
|
|
32343
|
-
for (const c of
|
|
32579
|
+
for (const c of refused4) {
|
|
32344
32580
|
const origin = c.origin;
|
|
32345
32581
|
for (const own of [origin.glue, origin.wasm, ...origin.variants ?? []]) {
|
|
32346
32582
|
if (!await same3(own)) continue;
|
|
@@ -32350,11 +32586,11 @@ var Launcher = class {
|
|
|
32350
32586
|
}
|
|
32351
32587
|
const stem = name2.replace(/\.wasm$/, "");
|
|
32352
32588
|
const named = owners.find((c) => c.name === name2) ?? owners.find((c) => c.name === stem);
|
|
32353
|
-
return named ?? owners[0] ?? await this.refusedCopy(real, name2,
|
|
32589
|
+
return named ?? owners[0] ?? await this.refusedCopy(real, name2, refused4);
|
|
32354
32590
|
}
|
|
32355
|
-
async refusedCopy(real, name2,
|
|
32591
|
+
async refusedCopy(real, name2, refused4) {
|
|
32356
32592
|
const dir = real.slice(0, real.lastIndexOf("/"));
|
|
32357
|
-
for (const c of
|
|
32593
|
+
for (const c of refused4) {
|
|
32358
32594
|
const origin = c.origin;
|
|
32359
32595
|
if (origin.abi !== "emscripten" || origin.script || c.name !== name2) continue;
|
|
32360
32596
|
const own = await physicalPathAsync(this.base, origin.glue).catch(() => origin.glue);
|
|
@@ -32562,12 +32798,12 @@ var Launcher = class {
|
|
|
32562
32798
|
return void 0;
|
|
32563
32799
|
}
|
|
32564
32800
|
async planOne(req, { ppid, cred, scope }, catalogOnly = false) {
|
|
32565
|
-
const
|
|
32801
|
+
const refused4 = (err) => {
|
|
32566
32802
|
throw codeOf8(err) === "EACCES" ? new SpawnError("EACCES") : err;
|
|
32567
32803
|
};
|
|
32568
|
-
const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(
|
|
32804
|
+
const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(refused4);
|
|
32569
32805
|
const planned = await this.plan(file, req.argv, req.cwd, scope, req.argv0, catalogOnly);
|
|
32570
|
-
await this.mayExec(cred, { ...req, file, pid: ppid }, planned).catch(
|
|
32806
|
+
await this.mayExec(cred, { ...req, file, pid: ppid }, planned).catch(refused4);
|
|
32571
32807
|
if (planned) return planned;
|
|
32572
32808
|
throw new SpawnError(catalogOnly ? "ENOENT" : await this.unrunnable(file, req.cwd, scope));
|
|
32573
32809
|
}
|
|
@@ -34547,212 +34783,6 @@ function integrityAsker(port) {
|
|
|
34547
34783
|
return { lookup: lookup2, answer: answer2 };
|
|
34548
34784
|
}
|
|
34549
34785
|
|
|
34550
|
-
// src/kernel/net/remote-transport.ts
|
|
34551
|
-
var TransportError = class extends Error {
|
|
34552
|
-
status;
|
|
34553
|
-
code;
|
|
34554
|
-
detail;
|
|
34555
|
-
constructor(message3, status, code, detail) {
|
|
34556
|
-
super(message3);
|
|
34557
|
-
this.status = status;
|
|
34558
|
-
this.code = code;
|
|
34559
|
-
this.detail = detail === "transport" ? detail : void 0;
|
|
34560
|
-
}
|
|
34561
|
-
};
|
|
34562
|
-
var RemoteTransport = class {
|
|
34563
|
-
traits;
|
|
34564
|
-
port;
|
|
34565
|
-
waiting = /* @__PURE__ */ new Map();
|
|
34566
|
-
nextId = 0;
|
|
34567
|
-
sockets = /* @__PURE__ */ new Map();
|
|
34568
|
-
uploads = /* @__PURE__ */ new Map();
|
|
34569
|
-
failure;
|
|
34570
|
-
constructor(port, traits) {
|
|
34571
|
-
this.port = port;
|
|
34572
|
-
this.traits = traits;
|
|
34573
|
-
}
|
|
34574
|
-
receive(reply) {
|
|
34575
|
-
if (reply.net === "body-pull") {
|
|
34576
|
-
void this.pull(reply.nid);
|
|
34577
|
-
return;
|
|
34578
|
-
}
|
|
34579
|
-
const socket = this.sockets.get(reply.nid);
|
|
34580
|
-
if (socket && this.toSocket(reply, socket)) return;
|
|
34581
|
-
const waiter = this.waiting.get(reply.nid);
|
|
34582
|
-
if (!waiter) return;
|
|
34583
|
-
this.waiting.delete(reply.nid);
|
|
34584
|
-
if (reply.net === "error") {
|
|
34585
|
-
waiter.reject(new TransportError(reply.message, reply.status, reply.code, reply.detail));
|
|
34586
|
-
} else waiter.resolve(reply);
|
|
34587
|
-
}
|
|
34588
|
-
toSocket(reply, socket) {
|
|
34589
|
-
if (reply.net === "ws-message") socket.queue.push(reply.data);
|
|
34590
|
-
else if (reply.net === "ws-acked") socket.acked(reply.n);
|
|
34591
|
-
else if (reply.net === "ws-closed") {
|
|
34592
|
-
this.sockets.delete(reply.nid);
|
|
34593
|
-
socket.queue.end({ code: reply.code, reason: reply.reason });
|
|
34594
|
-
} else return false;
|
|
34595
|
-
return true;
|
|
34596
|
-
}
|
|
34597
|
-
async pull(nid) {
|
|
34598
|
-
const upload = this.uploads.get(nid);
|
|
34599
|
-
if (!upload) {
|
|
34600
|
-
this.port.postMessage({ net: "body-error", nid, message: "the request body is gone" });
|
|
34601
|
-
return;
|
|
34602
|
-
}
|
|
34603
|
-
try {
|
|
34604
|
-
const next3 = await upload.next();
|
|
34605
|
-
if (next3.done) {
|
|
34606
|
-
this.uploads.delete(nid);
|
|
34607
|
-
this.port.postMessage({ net: "body-end", nid });
|
|
34608
|
-
} else this.port.postMessage({ net: "body-chunk", nid, bytes: next3.value });
|
|
34609
|
-
} catch (e) {
|
|
34610
|
-
this.uploads.delete(nid);
|
|
34611
|
-
this.port.postMessage({
|
|
34612
|
-
net: "body-error",
|
|
34613
|
-
nid,
|
|
34614
|
-
message: e instanceof Error ? e.message : String(e)
|
|
34615
|
-
});
|
|
34616
|
-
}
|
|
34617
|
-
}
|
|
34618
|
-
dropUpload(nid) {
|
|
34619
|
-
const upload = this.uploads.get(nid);
|
|
34620
|
-
this.uploads.delete(nid);
|
|
34621
|
-
void upload?.return?.().catch(() => void 0);
|
|
34622
|
-
}
|
|
34623
|
-
fail(error) {
|
|
34624
|
-
this.failure = error;
|
|
34625
|
-
for (const nid of [...this.uploads.keys()]) this.dropUpload(nid);
|
|
34626
|
-
for (const waiter of this.waiting.values()) waiter.reject(error);
|
|
34627
|
-
this.waiting.clear();
|
|
34628
|
-
for (const socket of this.sockets.values())
|
|
34629
|
-
socket.queue.end({ code: 1011, reason: error.message });
|
|
34630
|
-
this.sockets.clear();
|
|
34631
|
-
}
|
|
34632
|
-
ask(call) {
|
|
34633
|
-
if (this.failure) return Promise.reject(this.failure);
|
|
34634
|
-
return new Promise((resolve2, reject) => {
|
|
34635
|
-
this.waiting.set(call.nid, { resolve: resolve2, reject });
|
|
34636
|
-
this.port.postMessage(call);
|
|
34637
|
-
});
|
|
34638
|
-
}
|
|
34639
|
-
cancel(nid) {
|
|
34640
|
-
const waiter = this.waiting.get(nid);
|
|
34641
|
-
this.waiting.delete(nid);
|
|
34642
|
-
waiter?.reject(new TransportError("the request was cancelled"));
|
|
34643
|
-
this.port.postMessage({ net: "cancel", nid });
|
|
34644
|
-
}
|
|
34645
|
-
async fetch(request3) {
|
|
34646
|
-
const nid = ++this.nextId;
|
|
34647
|
-
const { signal } = request3;
|
|
34648
|
-
signal.throwIfAborted();
|
|
34649
|
-
let finished = false;
|
|
34650
|
-
const abort = () => {
|
|
34651
|
-
finished = true;
|
|
34652
|
-
this.dropUpload(nid);
|
|
34653
|
-
this.cancel(nid);
|
|
34654
|
-
};
|
|
34655
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
34656
|
-
const finish = () => {
|
|
34657
|
-
this.dropUpload(nid);
|
|
34658
|
-
if (finished) return;
|
|
34659
|
-
finished = true;
|
|
34660
|
-
signal.removeEventListener("abort", abort);
|
|
34661
|
-
};
|
|
34662
|
-
if (request3.bodyStream) this.uploads.set(nid, request3.bodyStream[Symbol.asyncIterator]());
|
|
34663
|
-
let head;
|
|
34664
|
-
try {
|
|
34665
|
-
head = await this.ask({
|
|
34666
|
-
net: "fetch",
|
|
34667
|
-
nid,
|
|
34668
|
-
url: request3.url,
|
|
34669
|
-
method: request3.method,
|
|
34670
|
-
headers: request3.headers,
|
|
34671
|
-
...request3.bodyStream ? { streamed: true } : request3.body ? { body: request3.body } : {}
|
|
34672
|
-
});
|
|
34673
|
-
} catch (e) {
|
|
34674
|
-
finish();
|
|
34675
|
-
throw e;
|
|
34676
|
-
}
|
|
34677
|
-
const { status, statusText, headers, url, redirected: redirected2, redirects } = head;
|
|
34678
|
-
const read = async () => {
|
|
34679
|
-
if (finished) return void 0;
|
|
34680
|
-
const reply = await this.ask({ net: "read", nid }).catch((e) => {
|
|
34681
|
-
finish();
|
|
34682
|
-
throw e;
|
|
34683
|
-
});
|
|
34684
|
-
if (reply.net === "chunk") return reply.bytes;
|
|
34685
|
-
finish();
|
|
34686
|
-
return void 0;
|
|
34687
|
-
};
|
|
34688
|
-
const cancel = async () => {
|
|
34689
|
-
if (finished) return;
|
|
34690
|
-
finish();
|
|
34691
|
-
this.cancel(nid);
|
|
34692
|
-
};
|
|
34693
|
-
return {
|
|
34694
|
-
...redirected2 ? { url, redirected: redirected2 } : {},
|
|
34695
|
-
...redirects ? { redirects } : {},
|
|
34696
|
-
status,
|
|
34697
|
-
statusText,
|
|
34698
|
-
headers,
|
|
34699
|
-
cancel,
|
|
34700
|
-
body: {
|
|
34701
|
-
[Symbol.asyncIterator]: () => ({
|
|
34702
|
-
next: async () => {
|
|
34703
|
-
const bytes = await read();
|
|
34704
|
-
return bytes ? { value: bytes, done: false } : { value: void 0, done: true };
|
|
34705
|
-
},
|
|
34706
|
-
return: async () => {
|
|
34707
|
-
await cancel();
|
|
34708
|
-
return { value: void 0, done: true };
|
|
34709
|
-
}
|
|
34710
|
-
})
|
|
34711
|
-
}
|
|
34712
|
-
};
|
|
34713
|
-
}
|
|
34714
|
-
async websocket(request3) {
|
|
34715
|
-
const nid = ++this.nextId;
|
|
34716
|
-
const { signal } = request3;
|
|
34717
|
-
signal.throwIfAborted();
|
|
34718
|
-
const abort = () => this.cancel(nid);
|
|
34719
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
34720
|
-
let opened2;
|
|
34721
|
-
try {
|
|
34722
|
-
opened2 = await this.ask({
|
|
34723
|
-
net: "ws-open",
|
|
34724
|
-
nid,
|
|
34725
|
-
url: request3.url,
|
|
34726
|
-
protocols: request3.protocols,
|
|
34727
|
-
headers: request3.headers
|
|
34728
|
-
});
|
|
34729
|
-
} finally {
|
|
34730
|
-
signal.removeEventListener("abort", abort);
|
|
34731
|
-
}
|
|
34732
|
-
const close = (code, reason) => this.port.postMessage({ net: "ws-close", nid, code, reason });
|
|
34733
|
-
const queue = new MessageQueue(
|
|
34734
|
-
() => close(1e3, "a message is too big"),
|
|
34735
|
-
Number.POSITIVE_INFINITY,
|
|
34736
|
-
(n) => this.port.postMessage({ net: "ws-consumed", nid, n })
|
|
34737
|
-
);
|
|
34738
|
-
let unacked = 0;
|
|
34739
|
-
this.sockets.set(nid, { queue, acked: (n) => void (unacked -= n) });
|
|
34740
|
-
return {
|
|
34741
|
-
protocol: opened2.protocol,
|
|
34742
|
-
get buffered() {
|
|
34743
|
-
return unacked;
|
|
34744
|
-
},
|
|
34745
|
-
send: (data) => {
|
|
34746
|
-
unacked += payloadSize(data);
|
|
34747
|
-
this.port.postMessage({ net: "ws-send", nid, data });
|
|
34748
|
-
},
|
|
34749
|
-
messages: queue,
|
|
34750
|
-
close,
|
|
34751
|
-
closed: queue.closed
|
|
34752
|
-
};
|
|
34753
|
-
}
|
|
34754
|
-
};
|
|
34755
|
-
|
|
34756
34786
|
// src/sealed-relay.ts
|
|
34757
34787
|
function sealedAsker(port) {
|
|
34758
34788
|
const asks = /* @__PURE__ */ new Map();
|