forked from hwcwy/silu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.ts
109 lines (97 loc) · 3.07 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { Command, configure, EnumType, handler, Logger } from "./lib/mod.ts";
const authType = new EnumType(["none", "basic"]);
const cmd = new Command()
.name("Silu")
.version("0.1.3")
.description("A simple http/https tunnel && proxy server of Deno")
.usage("[option...]")
.type("authType", authType)
.option(
"--timeout, -t <milliseconds:number>",
"Timeout for each TCP connection.",
{
default: 1000,
},
)
.option("--bind, -b <hostname:string>", "Bind address", {
default: "0.0.0.0",
})
.option("--config, -c <file:string>", "Config file", {
standalone: true,
})
.group("HTTP")
.option("--http.port <port:number>", "Http port")
.group("HTTPS")
.option("--https.port <port:number>", "Https port", {
depends: ["https.crt", "https.key"],
})
.option("--https.crt <file:string>", "Certificate file", {
depends: ["https.port", "https.key"],
})
.option("--https.key <file:string>", "Certificate key", {
depends: ["https.port", "https.crt"],
})
.group("Auth")
.option("--auth.username, --au <username:string>", "auth username")
.option("--auth.password, --ap <password:string>", "auth password")
.option("--auth.type, --at <type:authType>", "auth type", {
default: "none" as const,
})
.group("Log")
.option(
"--log.mode, --lm <mode:logMode>",
"Enable log with mode",
{ default: "both" as const },
)
.option("--log.level, --ll <type:logLevel>", "Log level", {
default: "warn" as const,
})
.option("--log.dir, --ld <dir:string>", "Log dir", {
default: "./log",
}).option("--log.rotate, --lr <rotate:boolean>", "Cut by day", {
default: false,
}).option(
"--log.max_bytes, --lmb <maxBytes:number>",
"The max bytes for a single log file",
{ depends: ["log.max_backup_count"] },
).option(
"--log.max_backup_count, --lmc <maxBackupCount:number>",
"The max number of log files to keep",
{ depends: ["log.max_bytes"] },
);
async function main() {
let command = await cmd.parse(Deno.args);
const { config } = command.options;
if (config) {
const c = readAsConfig(config);
command = await cmd.parse(c);
}
if (!(command.options?.http || command.options?.https)) {
cmd.showHelp();
// Deno.exit();
}
const { http, https, timeout, log, auth, bind } = command.options;
const listener = await configure(http, https, bind);
for await (const conn of listener) {
handler(conn, auth, timeout, logger).catch((e) => {});
}
}
main().catch((e) => {});
function readAsConfig(file: string) {
const configRaw = Deno.readTextFileSync(file);
const configLines = configRaw.split("\n");
const config = [];
for (const line of configLines.values()) {
if (!line.trim() || line.trimStart().startsWith("#")) continue;
const l = line.split("#")[0];
const split = l.split("=");
const option = `--${split[0].trim()}`;
let value = split[1].trim();
if (value.startsWith("eval(") && value.endsWith(")")) {
const expression = value.slice(5, -1);
value = eval(expression);
}
config.push(option, value);
}
return config;
}