Spaces:
Paused
Paused
icebear0828 Claude Opus 4.6 commited on
Commit ·
e7285df
1
Parent(s): d85b21d
feat: auto-detect local proxy (mihomo/clash/v2ray)
Browse filesOn startup, probe common local proxy ports (7890, 7897, 10809, 1080,
10808) and automatically use the first one found. No config needed —
just have a proxy running and it works.
Priority: config proxy_url > HTTPS_PROXY env > auto-detect.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- src/index.ts +4 -0
- src/tls/curl-binary.ts +62 -5
src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import modelsApp from "./routes/models.js";
|
|
| 15 |
import { createWebRoutes } from "./routes/web.js";
|
| 16 |
import { CookieJar } from "./proxy/cookie-jar.js";
|
| 17 |
import { startUpdateChecker, stopUpdateChecker } from "./update-checker.js";
|
|
|
|
| 18 |
|
| 19 |
async function main() {
|
| 20 |
// Load configuration
|
|
@@ -30,6 +31,9 @@ async function main() {
|
|
| 30 |
process.exit(1);
|
| 31 |
}
|
| 32 |
|
|
|
|
|
|
|
|
|
|
| 33 |
// Initialize managers
|
| 34 |
const accountPool = new AccountPool();
|
| 35 |
const refreshScheduler = new RefreshScheduler(accountPool);
|
|
|
|
| 15 |
import { createWebRoutes } from "./routes/web.js";
|
| 16 |
import { CookieJar } from "./proxy/cookie-jar.js";
|
| 17 |
import { startUpdateChecker, stopUpdateChecker } from "./update-checker.js";
|
| 18 |
+
import { initProxy } from "./tls/curl-binary.js";
|
| 19 |
|
| 20 |
async function main() {
|
| 21 |
// Load configuration
|
|
|
|
| 31 |
process.exit(1);
|
| 32 |
}
|
| 33 |
|
| 34 |
+
// Detect proxy (config > env > auto-detect local ports)
|
| 35 |
+
await initProxy();
|
| 36 |
+
|
| 37 |
// Initialize managers
|
| 38 |
const accountPool = new AccountPool();
|
| 39 |
const refreshScheduler = new RefreshScheduler(accountPool);
|
src/tls/curl-binary.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
| 12 |
|
| 13 |
import { existsSync } from "fs";
|
| 14 |
import { execFileSync } from "child_process";
|
|
|
|
| 15 |
import { resolve } from "path";
|
| 16 |
import { getConfig } from "../config.js";
|
| 17 |
|
|
@@ -141,15 +142,71 @@ export function getChromeTlsArgs(): string[] {
|
|
| 141 |
return [..._tlsArgs];
|
| 142 |
}
|
| 143 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
/**
|
| 145 |
* Get proxy args to prepend to curl commands.
|
| 146 |
-
*
|
| 147 |
-
* Returns empty array when no proxy is configured.
|
| 148 |
*/
|
| 149 |
export function getProxyArgs(): string[] {
|
| 150 |
-
|
| 151 |
-
const url = config.tls.proxy_url;
|
| 152 |
-
if (url) return ["-x", url];
|
| 153 |
return [];
|
| 154 |
}
|
| 155 |
|
|
|
|
| 12 |
|
| 13 |
import { existsSync } from "fs";
|
| 14 |
import { execFileSync } from "child_process";
|
| 15 |
+
import { createConnection } from "net";
|
| 16 |
import { resolve } from "path";
|
| 17 |
import { getConfig } from "../config.js";
|
| 18 |
|
|
|
|
| 142 |
return [..._tlsArgs];
|
| 143 |
}
|
| 144 |
|
| 145 |
+
/**
|
| 146 |
+
* Common local proxy ports to auto-detect.
|
| 147 |
+
* Checked in order: mihomo/clash, v2ray, SOCKS5 common.
|
| 148 |
+
*/
|
| 149 |
+
const PROXY_PORTS = [
|
| 150 |
+
{ port: 7890, proto: "http" }, // mihomo / clash
|
| 151 |
+
{ port: 7897, proto: "http" }, // clash-verge
|
| 152 |
+
{ port: 10809, proto: "http" }, // v2ray HTTP
|
| 153 |
+
{ port: 1080, proto: "socks5" }, // SOCKS5 common
|
| 154 |
+
{ port: 10808, proto: "socks5" },// v2ray SOCKS5
|
| 155 |
+
];
|
| 156 |
+
|
| 157 |
+
let _proxyUrl: string | null | undefined; // undefined = not yet detected
|
| 158 |
+
|
| 159 |
+
/** Probe a TCP port on localhost. Resolves true if a server is listening. */
|
| 160 |
+
function probePort(port: number, timeoutMs = 500): Promise<boolean> {
|
| 161 |
+
return new Promise((resolve) => {
|
| 162 |
+
const sock = createConnection({ host: "127.0.0.1", port }, () => {
|
| 163 |
+
sock.destroy();
|
| 164 |
+
resolve(true);
|
| 165 |
+
});
|
| 166 |
+
sock.setTimeout(timeoutMs);
|
| 167 |
+
sock.on("timeout", () => { sock.destroy(); resolve(false); });
|
| 168 |
+
sock.on("error", () => { resolve(false); });
|
| 169 |
+
});
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
/**
|
| 173 |
+
* Detect a local proxy by probing common ports.
|
| 174 |
+
* Called once at startup, result is cached.
|
| 175 |
+
*/
|
| 176 |
+
async function detectLocalProxy(): Promise<string | null> {
|
| 177 |
+
for (const { port, proto } of PROXY_PORTS) {
|
| 178 |
+
if (await probePort(port)) {
|
| 179 |
+
const url = `${proto}://127.0.0.1:${port}`;
|
| 180 |
+
console.log(`[Proxy] Auto-detected local proxy: ${url}`);
|
| 181 |
+
return url;
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
return null;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
/**
|
| 188 |
+
* Initialize proxy detection. Called once at startup from index.ts.
|
| 189 |
+
* Priority: config proxy_url > HTTPS_PROXY env > auto-detect local ports.
|
| 190 |
+
*/
|
| 191 |
+
export async function initProxy(): Promise<void> {
|
| 192 |
+
const config = getConfig();
|
| 193 |
+
if (config.tls.proxy_url) {
|
| 194 |
+
_proxyUrl = config.tls.proxy_url;
|
| 195 |
+
console.log(`[Proxy] Using configured proxy: ${_proxyUrl}`);
|
| 196 |
+
return;
|
| 197 |
+
}
|
| 198 |
+
_proxyUrl = await detectLocalProxy();
|
| 199 |
+
if (!_proxyUrl) {
|
| 200 |
+
console.log("[Proxy] No local proxy detected — direct connection");
|
| 201 |
+
}
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
/**
|
| 205 |
* Get proxy args to prepend to curl commands.
|
| 206 |
+
* Uses cached result from initProxy().
|
|
|
|
| 207 |
*/
|
| 208 |
export function getProxyArgs(): string[] {
|
| 209 |
+
if (_proxyUrl) return ["-x", _proxyUrl];
|
|
|
|
|
|
|
| 210 |
return [];
|
| 211 |
}
|
| 212 |
|