@dutodev/cli 0.4.5 → 0.4.6
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.
|
@@ -373,6 +373,7 @@ async function withFullscreen(stdout, run2) {
|
|
|
373
373
|
const onSignal = () => ac.abort();
|
|
374
374
|
process.on("SIGINT", onSignal);
|
|
375
375
|
process.on("SIGTERM", onSignal);
|
|
376
|
+
process.on("SIGHUP", onSignal);
|
|
376
377
|
process.once("exit", restore);
|
|
377
378
|
stdout.write(ENTER_SCREEN);
|
|
378
379
|
try {
|
|
@@ -380,6 +381,7 @@ async function withFullscreen(stdout, run2) {
|
|
|
380
381
|
} finally {
|
|
381
382
|
process.off("SIGINT", onSignal);
|
|
382
383
|
process.off("SIGTERM", onSignal);
|
|
384
|
+
process.off("SIGHUP", onSignal);
|
|
383
385
|
process.off("exit", restore);
|
|
384
386
|
restore();
|
|
385
387
|
}
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var fail = (msg) => `${paint("err", "\u2716", process.stderr)} ${msg}`;
|
|
|
33
33
|
|
|
34
34
|
// src/index.ts
|
|
35
35
|
import { hostname } from "os";
|
|
36
|
-
import { relative } from "path";
|
|
36
|
+
import { join as join5, relative } from "path";
|
|
37
37
|
import cac from "cac";
|
|
38
38
|
|
|
39
39
|
// src/api.ts
|
|
@@ -538,8 +538,18 @@ function waitForService(res, port, checkMs, pingMs) {
|
|
|
538
538
|
async function startProxy(o) {
|
|
539
539
|
const max = o.maxBody ?? MAX_BODY;
|
|
540
540
|
let nextId = 1;
|
|
541
|
+
const routeWaitMs = o.routeWaitMs ?? 3e3;
|
|
542
|
+
async function routeFor(req) {
|
|
543
|
+
const host = hostOf(req);
|
|
544
|
+
for (let waited = 0; ; waited += 50) {
|
|
545
|
+
const route = o.routes.get(host);
|
|
546
|
+
if (route || waited >= routeWaitMs) return route;
|
|
547
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
548
|
+
}
|
|
549
|
+
}
|
|
541
550
|
const server = createServer(async (req, res) => {
|
|
542
|
-
|
|
551
|
+
req.pause();
|
|
552
|
+
const route = await routeFor(req);
|
|
543
553
|
if (!route) {
|
|
544
554
|
res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
545
555
|
res.end("T\xFAnel n\xE3o encontrado nesta sess\xE3o");
|
|
@@ -619,7 +629,7 @@ async function startProxy(o) {
|
|
|
619
629
|
});
|
|
620
630
|
server.on("upgrade", async (req, client, head) => {
|
|
621
631
|
client.on("error", () => client.destroy());
|
|
622
|
-
const route =
|
|
632
|
+
const route = await routeFor(req);
|
|
623
633
|
if (!route) return void client.end("HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n");
|
|
624
634
|
const id = nextId++;
|
|
625
635
|
const started = Date.now();
|
|
@@ -684,6 +694,74 @@ async function startProxy(o) {
|
|
|
684
694
|
};
|
|
685
695
|
}
|
|
686
696
|
|
|
697
|
+
// src/session/orphans.ts
|
|
698
|
+
import { spawnSync } from "child_process";
|
|
699
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
700
|
+
import { join as join4 } from "path";
|
|
701
|
+
var fileOf = (dir, cfPid) => join4(dir, `cloudflared-${cfPid}.json`);
|
|
702
|
+
function recordCloudflared(dir, cfPid, sessionPid = process.pid) {
|
|
703
|
+
try {
|
|
704
|
+
mkdirSync3(dir, { recursive: true });
|
|
705
|
+
writeFileSync3(fileOf(dir, cfPid), JSON.stringify({ sessionPid, cfPid, at: Date.now() }));
|
|
706
|
+
} catch {
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
function forgetCloudflared(dir, cfPid) {
|
|
710
|
+
rmSync2(fileOf(dir, cfPid), { force: true });
|
|
711
|
+
}
|
|
712
|
+
var realProc = {
|
|
713
|
+
alive(pid) {
|
|
714
|
+
try {
|
|
715
|
+
process.kill(pid, 0);
|
|
716
|
+
return true;
|
|
717
|
+
} catch (err) {
|
|
718
|
+
return err.code === "EPERM";
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
isCloudflared(pid) {
|
|
722
|
+
try {
|
|
723
|
+
if (process.platform === "linux") return readFileSync3(`/proc/${pid}/cmdline`, "utf8").includes("cloudflared");
|
|
724
|
+
if (process.platform === "darwin") return spawnSync("ps", ["-p", String(pid), "-o", "command="], { encoding: "utf8" }).stdout.includes("cloudflared");
|
|
725
|
+
} catch {
|
|
726
|
+
return false;
|
|
727
|
+
}
|
|
728
|
+
return false;
|
|
729
|
+
},
|
|
730
|
+
kill(pid) {
|
|
731
|
+
try {
|
|
732
|
+
process.kill(pid, "SIGTERM");
|
|
733
|
+
} catch {
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
function reapOrphans(dir, proc = realProc) {
|
|
738
|
+
if (!existsSync4(dir)) return 0;
|
|
739
|
+
let killed = 0;
|
|
740
|
+
for (const name of readdirSync(dir)) {
|
|
741
|
+
if (!/^cloudflared-\d+\.json$/.test(name)) continue;
|
|
742
|
+
const path = join4(dir, name);
|
|
743
|
+
let rec;
|
|
744
|
+
try {
|
|
745
|
+
rec = JSON.parse(readFileSync3(path, "utf8"));
|
|
746
|
+
} catch {
|
|
747
|
+
rmSync2(path, { force: true });
|
|
748
|
+
continue;
|
|
749
|
+
}
|
|
750
|
+
const { sessionPid, cfPid } = rec;
|
|
751
|
+
if (typeof sessionPid !== "number" || typeof cfPid !== "number") {
|
|
752
|
+
rmSync2(path, { force: true });
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
if (proc.alive(sessionPid)) continue;
|
|
756
|
+
if (proc.alive(cfPid) && proc.isCloudflared(cfPid)) {
|
|
757
|
+
proc.kill(cfPid);
|
|
758
|
+
killed++;
|
|
759
|
+
}
|
|
760
|
+
rmSync2(path, { force: true });
|
|
761
|
+
}
|
|
762
|
+
return killed;
|
|
763
|
+
}
|
|
764
|
+
|
|
687
765
|
// src/session/records.ts
|
|
688
766
|
var RecordStore = class {
|
|
689
767
|
constructor(max = 500) {
|
|
@@ -765,6 +843,7 @@ var Session = class {
|
|
|
765
843
|
}
|
|
766
844
|
/** Abre os túneis em sequência; falhas ficam no estado e não interrompem os outros. */
|
|
767
845
|
async start(specs) {
|
|
846
|
+
if (this.o.runDir) reapOrphans(this.o.runDir);
|
|
768
847
|
this.proxy = await startProxy({ routes: this.routes, store: this.records });
|
|
769
848
|
this.tunnels = specs.map((s) => this.blank(s, false));
|
|
770
849
|
this.emit();
|
|
@@ -853,6 +932,11 @@ var Session = class {
|
|
|
853
932
|
stdio: ["ignore", "ignore", "pipe"]
|
|
854
933
|
});
|
|
855
934
|
this.child = c;
|
|
935
|
+
const runDir = this.o.runDir;
|
|
936
|
+
if (runDir && c.pid) {
|
|
937
|
+
recordCloudflared(runDir, c.pid);
|
|
938
|
+
c.once("exit", () => forgetCloudflared(runDir, c.pid));
|
|
939
|
+
}
|
|
856
940
|
let buf = "";
|
|
857
941
|
c.stderr?.on("data", (chunk) => {
|
|
858
942
|
if (c !== this.child) return;
|
|
@@ -1010,21 +1094,23 @@ async function runSession(specs, source, flags) {
|
|
|
1010
1094
|
} catch (err) {
|
|
1011
1095
|
fail2(err instanceof Error ? err.message : String(err));
|
|
1012
1096
|
}
|
|
1013
|
-
const session = new Session({ api, deviceId: config.deviceId, deviceName: hostname(), cloudflaredPath, source });
|
|
1097
|
+
const session = new Session({ api, deviceId: config.deviceId, deviceName: hostname(), cloudflaredPath, source, runDir: join5(dutoHome(), "run") });
|
|
1014
1098
|
if (wantsUi(flags)) {
|
|
1015
|
-
const { runFullscreen } = await import("./fullscreen-
|
|
1016
|
-
process.exit(await runFullscreen(session, specs, "0.4.
|
|
1099
|
+
const { runFullscreen } = await import("./fullscreen-EPWB53EP.js");
|
|
1100
|
+
process.exit(await runFullscreen(session, specs, "0.4.6"));
|
|
1017
1101
|
}
|
|
1018
|
-
console.log(`${mark()} ${paint("muted", `${"0.4.
|
|
1102
|
+
console.log(`${mark()} ${paint("muted", `${"0.4.6"} \xB7 ${source} \xB7 Ctrl+C para encerrar`)}`);
|
|
1019
1103
|
const stopLog = runPlain(session, (l) => console.log(l));
|
|
1020
1104
|
const stopped = new Promise((resolve) => {
|
|
1021
1105
|
const onSignal = () => {
|
|
1022
1106
|
process.off("SIGINT", onSignal);
|
|
1023
1107
|
process.off("SIGTERM", onSignal);
|
|
1108
|
+
process.off("SIGHUP", onSignal);
|
|
1024
1109
|
resolve();
|
|
1025
1110
|
};
|
|
1026
1111
|
process.on("SIGINT", onSignal);
|
|
1027
1112
|
process.on("SIGTERM", onSignal);
|
|
1113
|
+
process.on("SIGHUP", onSignal);
|
|
1028
1114
|
});
|
|
1029
1115
|
await Promise.race([session.start(specs), stopped]);
|
|
1030
1116
|
await stopped;
|
|
@@ -1102,7 +1188,7 @@ cli.help(
|
|
|
1102
1188
|
body: s.body.replace(/^\s*For more info, run any command with the `--help` flag:/m, " Mais detalhes de um comando: duto <comando> --help").replace("Display this message", "Mostra esta ajuda").replace("Display version number", "Mostra a vers\xE3o")
|
|
1103
1189
|
}))
|
|
1104
1190
|
);
|
|
1105
|
-
cli.version("0.4.
|
|
1191
|
+
cli.version("0.4.6");
|
|
1106
1192
|
try {
|
|
1107
1193
|
cli.parse(process.argv, { run: false });
|
|
1108
1194
|
await cli.runMatchedCommand();
|