Skip to content

Commit 005051c

Browse files
committed
feat: Node 运行环境支持 SOCKS5 代理
1 parent 61078b1 commit 005051c

3 files changed

Lines changed: 74 additions & 8 deletions

File tree

backend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sub-store",
3-
"version": "2.19.79",
3+
"version": "2.19.81",
44
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
55
"main": "src/main.js",
66
"scripts": {
@@ -32,6 +32,7 @@
3232
"dns-packet": "^5.6.1",
3333
"dotenv": "^16.4.7",
3434
"express": "^4.17.1",
35+
"fetch-socks": "^1.3.2",
3536
"http-proxy-middleware": "^3.0.3",
3637
"ip-address": "^9.0.5",
3738
"js-base64": "^3.7.2",

backend/pnpm-lock.yaml

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/src/vendor/open-api.js

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,26 @@ function isPlainObject(obj) {
1818
);
1919
}
2020

21+
function parseSocks5Uri(uri) {
22+
// eslint-disable-next-line no-unused-vars
23+
let [__, username, password, server, port, query, name] = uri.match(
24+
/^socks5:\/\/(?:(.*?):(.*?)@)?(.*?)(?::(\d+?))?(\?.*?)?(?:#(.*?))?$/,
25+
);
26+
if (port) {
27+
port = parseInt(port, 10);
28+
} else {
29+
$.error(`port is not present in line: ${uri}`);
30+
throw new Error(`port is not present in line: ${uri}`);
31+
}
32+
return {
33+
type: 5,
34+
host: server,
35+
port,
36+
37+
userId: username != null ? decodeURIComponent(username) : undefined,
38+
password: password != null ? decodeURIComponent(password) : undefined,
39+
};
40+
}
2141
export class OpenAPI {
2242
constructor(name = 'untitled', debug = false) {
2343
this.name = name;
@@ -393,6 +413,7 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
393413
}
394414
if (isNode) {
395415
const undici = eval("require('undici')");
416+
const { socksDispatcher } = eval("require('fetch-socks')");
396417
const {
397418
ProxyAgent,
398419
EnvHttpProxyAgent,
@@ -422,16 +443,34 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
422443
).toString('base64')}`,
423444
};
424445
}
446+
let dispatcher;
447+
if (!opts.proxy) {
448+
const allProxy =
449+
eval('process.env.all_proxy') ||
450+
eval('process.env.ALL_PROXY');
451+
if (allProxy && /^socks5:\/\//.test(allProxy)) {
452+
opts.proxy = allProxy;
453+
}
454+
}
455+
if (opts.proxy) {
456+
if (/^socks5:\/\//.test(opts.proxy)) {
457+
dispatcher = socksDispatcher(
458+
parseSocks5Uri(opts.proxy),
459+
agentOpts,
460+
);
461+
} else {
462+
dispatcher = new ProxyAgent({
463+
...agentOpts,
464+
uri: opts.proxy,
465+
});
466+
}
467+
} else {
468+
dispatcher = new EnvHttpProxyAgent(agentOpts);
469+
}
425470
const response = await request(opts.url, {
426471
...opts,
427472
method: method.toUpperCase(),
428-
dispatcher: (opts.proxy
429-
? new ProxyAgent({
430-
...agentOpts,
431-
uri: opts.proxy,
432-
})
433-
: new EnvHttpProxyAgent(agentOpts)
434-
).compose(
473+
dispatcher: dispatcher.compose(
435474
interceptors.redirect({
436475
maxRedirections: 3,
437476
throwOnMaxRedirects: true,

0 commit comments

Comments
 (0)