icebear0828 Claude Opus 4.6 commited on
Commit
e7285df
·
1 Parent(s): d85b21d

feat: auto-detect local proxy (mihomo/clash/v2ray)

Browse files

On 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>

Files changed (2) hide show
  1. src/index.ts +4 -0
  2. 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
- * Reads from config tls.proxy_url (which also picks up HTTPS_PROXY env var).
147
- * Returns empty array when no proxy is configured.
148
  */
149
  export function getProxyArgs(): string[] {
150
- const config = getConfig();
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