ddan-js 2.6.23 → 2.6.25
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.
- package/bin/ddan-js.esm.js +1 -1
- package/bin/ddan-js.js +1 -1
- package/bin/lib/modules/convert/index.js +13 -1
- package/bin/lib/modules/node/child.js +18 -0
- package/bin/lib/modules/node/index.js +3 -1
- package/bin/lib/modules/node/proxy.js +93 -0
- package/bin/lib/modules/node/socks5.js +39 -22
- package/bin/types/index.d.ts +13 -0
- package/bin/types/modules/convert/index.d.ts +1 -0
- package/bin/types/modules/node/child.d.ts +4 -0
- package/bin/types/modules/node/index.d.ts +13 -3
- package/bin/types/modules/node/proxy.d.ts +12 -0
- package/bin/types/modules/node/socks5.d.ts +5 -10
- package/package.json +1 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const child_1 = require("./child");
|
|
4
|
+
const convert_1 = require("../convert");
|
|
5
|
+
const getSystemProxy = () => {
|
|
6
|
+
try {
|
|
7
|
+
if (process.platform === 'win32') {
|
|
8
|
+
return getWindowsSystemProxy();
|
|
9
|
+
}
|
|
10
|
+
else if (process.platform === 'darwin') {
|
|
11
|
+
return getMacOSSystemProxy();
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const getWindowsSystemProxy = async () => {
|
|
22
|
+
do {
|
|
23
|
+
let err, text;
|
|
24
|
+
[err, text] = await child_1.default.child_exec(`reg query "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"`);
|
|
25
|
+
if (err)
|
|
26
|
+
break;
|
|
27
|
+
const proxyEnabledLine = text.split('\n').find((line) => line.includes('ProxyEnable'));
|
|
28
|
+
const ProxyEnable = proxyEnabledLine && proxyEnabledLine.trim().endsWith('1');
|
|
29
|
+
if (!ProxyEnable)
|
|
30
|
+
break;
|
|
31
|
+
const proxyServerLine = text.split('\n').find((line) => line.includes('ProxyServer'));
|
|
32
|
+
const proxyServer = proxyServerLine ? proxyServerLine.split(' ').filter(Boolean).pop() : '';
|
|
33
|
+
if (!proxyServer)
|
|
34
|
+
break;
|
|
35
|
+
// 解析 IP 和端口
|
|
36
|
+
const proxyParts = proxyServer.split(':');
|
|
37
|
+
if (proxyParts.length <= 1)
|
|
38
|
+
break;
|
|
39
|
+
const ipaddress = proxyParts[0];
|
|
40
|
+
const port = +(proxyParts[1] || '');
|
|
41
|
+
if (!ipaddress || !port)
|
|
42
|
+
break;
|
|
43
|
+
return { ipaddress, port };
|
|
44
|
+
} while (false);
|
|
45
|
+
return undefined;
|
|
46
|
+
};
|
|
47
|
+
const getMacOSSystemProxy = async () => {
|
|
48
|
+
do {
|
|
49
|
+
let err, text;
|
|
50
|
+
[err, text] = await child_1.default.child_exec(`networksetup -getwebproxy "Wi-Fi"`);
|
|
51
|
+
if (err)
|
|
52
|
+
break;
|
|
53
|
+
const outputLines = text.split('\n');
|
|
54
|
+
const proxyEnabledLine = outputLines.find((line) => line.includes('Enabled'));
|
|
55
|
+
const isEnabled = proxyEnabledLine && proxyEnabledLine.includes('Yes');
|
|
56
|
+
if (!isEnabled)
|
|
57
|
+
break;
|
|
58
|
+
const proxyServerLine = outputLines.find((line) => line.includes('Server'));
|
|
59
|
+
const proxyPortLine = outputLines.find((line) => line.includes('Port'));
|
|
60
|
+
const ipaddress = proxyServerLine ? proxyServerLine.split(':')[1]?.trim() : null;
|
|
61
|
+
const proxyPort = proxyPortLine ? proxyPortLine.split(':')[1]?.trim() : null;
|
|
62
|
+
const port = +(proxyPort || '');
|
|
63
|
+
if (!ipaddress || !port)
|
|
64
|
+
break;
|
|
65
|
+
return { ipaddress, port };
|
|
66
|
+
} while (false);
|
|
67
|
+
return undefined;
|
|
68
|
+
};
|
|
69
|
+
// if (host === 'singapore-upgrade.geelark.com') {
|
|
70
|
+
// return 'SOCKS5 127.0.0.1:${port}';
|
|
71
|
+
// }
|
|
72
|
+
// { proxy = 'DIRECT'; default = 'DIRECT', rules: string[]
|
|
73
|
+
const getPacDataUrl = ({ proxy = 'DIRECT', defProxy = 'DIRECT', rules = ['*'] }) => {
|
|
74
|
+
const _proxy = proxy || defProxy || "DIRECT";
|
|
75
|
+
const content = `
|
|
76
|
+
function FindProxyForURL(url, host) {
|
|
77
|
+
if (isInNet(host, "127.0.0.1", "255.255.255.255") ||
|
|
78
|
+
shExpMatch(host, "localhost") ||
|
|
79
|
+
shExpMatch(host, "<local>")) {
|
|
80
|
+
return "DIRECT";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for (let rule of ${rules}) {
|
|
84
|
+
if (rule && shExpMatch(host, rule)) {
|
|
85
|
+
return "${_proxy}";
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return "${defProxy}";
|
|
89
|
+
}
|
|
90
|
+
`;
|
|
91
|
+
return convert_1.default.toDataUrl(content);
|
|
92
|
+
};
|
|
93
|
+
exports.default = { getSystemProxy, getPacDataUrl };
|
|
@@ -67,17 +67,11 @@ class Socks5 {
|
|
|
67
67
|
this.upstreamProxy = upstreamProxy;
|
|
68
68
|
return true;
|
|
69
69
|
}
|
|
70
|
-
setSystemProxy(config) {
|
|
71
|
-
|
|
72
|
-
if (
|
|
73
|
-
this.
|
|
74
|
-
return true;
|
|
70
|
+
setSystemProxy(use, config) {
|
|
71
|
+
this.useSystemProxy = use;
|
|
72
|
+
if (use && config && config.ipaddress && config.port) {
|
|
73
|
+
this.systemProxy = config;
|
|
75
74
|
}
|
|
76
|
-
if (!addr || !port)
|
|
77
|
-
return false;
|
|
78
|
-
this.systemProxy = { addr, port };
|
|
79
|
-
this.useSystemProxy = true;
|
|
80
|
-
return true;
|
|
81
75
|
}
|
|
82
76
|
setAllowedDomains(allowedDomains = []) {
|
|
83
77
|
this.allowedDomains = new Set(allowedDomains);
|
|
@@ -124,11 +118,8 @@ class Socks5 {
|
|
|
124
118
|
else if (this.useSystemProxy && this.systemProxy) {
|
|
125
119
|
this.__debug && console.log(`[socks] handle connection system`, destination.addr);
|
|
126
120
|
// 走系统代理
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
port: this.systemProxy.port,
|
|
130
|
-
});
|
|
131
|
-
this.setupDataForwarding(clientSocket, localSocket);
|
|
121
|
+
const systemSocket = await this.connectToSystemProxy(destination);
|
|
122
|
+
this.setupDataForwarding(clientSocket, systemSocket);
|
|
132
123
|
}
|
|
133
124
|
else {
|
|
134
125
|
this.__debug && console.log(`[socks] handle connection local`, destination.addr);
|
|
@@ -179,6 +170,15 @@ class Socks5 {
|
|
|
179
170
|
});
|
|
180
171
|
});
|
|
181
172
|
}
|
|
173
|
+
getPoolConnection(key) {
|
|
174
|
+
if (!key)
|
|
175
|
+
return undefined;
|
|
176
|
+
// 如果已有连接在池中,复用
|
|
177
|
+
if (this.connectionPool[key] && !this.connectionPool[key].destroyed) {
|
|
178
|
+
return this.connectionPool[key];
|
|
179
|
+
}
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
182
|
// 上游代理连接
|
|
183
183
|
async connectToUpstreamProxy(destination) {
|
|
184
184
|
const destKey = `${destination.addr}:${destination.port}`;
|
|
@@ -205,14 +205,31 @@ class Socks5 {
|
|
|
205
205
|
throw new Error('Failed to connect to upstream proxy: ' + err);
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (
|
|
213
|
-
return
|
|
208
|
+
// 上游代理连接
|
|
209
|
+
async connectToSystemProxy(destination) {
|
|
210
|
+
const destKey = `${destination.addr}:${destination.port}`;
|
|
211
|
+
const cacheConnection = this.getPoolConnection(destKey);
|
|
212
|
+
if (cacheConnection)
|
|
213
|
+
return cacheConnection;
|
|
214
|
+
const options = {
|
|
215
|
+
proxy: { ...this.systemProxy, type: 5 },
|
|
216
|
+
command: 'connect',
|
|
217
|
+
destination: {
|
|
218
|
+
host: destination.addr,
|
|
219
|
+
port: destination.port,
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
try {
|
|
223
|
+
const { socket: upstreamSocket } = await socks_1.SocksClient.createConnection(options);
|
|
224
|
+
this.connectionPool[destKey] = upstreamSocket;
|
|
225
|
+
upstreamSocket.on('close', () => {
|
|
226
|
+
delete this.connectionPool[destKey];
|
|
227
|
+
});
|
|
228
|
+
return upstreamSocket;
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
throw new Error('Failed to connect to upstream proxy: ' + err);
|
|
214
232
|
}
|
|
215
|
-
return undefined;
|
|
216
233
|
}
|
|
217
234
|
// 本地连接
|
|
218
235
|
async connectToLocal(destination) {
|
package/bin/types/index.d.ts
CHANGED
|
@@ -79,6 +79,7 @@ declare const dUtil: {
|
|
|
79
79
|
getRandomBytes: (length: number) => Uint8Array;
|
|
80
80
|
textEncode: (text: string) => Uint8Array;
|
|
81
81
|
textDecode: (buf: ArrayBuffer) => string;
|
|
82
|
+
toDataUrl: (textOrBuf: string | ArrayBuffer, contentType?: string) => string;
|
|
82
83
|
toBase64: (input?: string) => string;
|
|
83
84
|
fromBase64: (input?: string) => string;
|
|
84
85
|
bytesToBase64: (bytes: Uint8Array) => string;
|
|
@@ -247,6 +248,7 @@ declare const dHook: {
|
|
|
247
248
|
getRandomBytes: (length: number) => Uint8Array;
|
|
248
249
|
textEncode: (text: string) => Uint8Array;
|
|
249
250
|
textDecode: (buf: ArrayBuffer) => string;
|
|
251
|
+
toDataUrl: (textOrBuf: string | ArrayBuffer, contentType?: string) => string;
|
|
250
252
|
toBase64: (input?: string) => string;
|
|
251
253
|
fromBase64: (input?: string) => string;
|
|
252
254
|
bytesToBase64: (bytes: Uint8Array) => string;
|
|
@@ -502,6 +504,16 @@ declare const dNode: {
|
|
|
502
504
|
Ecdh: typeof import("./modules/node/ecdh").default;
|
|
503
505
|
EcdhSpki: typeof import("./modules/node/ecdh-spki").default;
|
|
504
506
|
Socks5: typeof import("./modules/node/socks5").Socks5;
|
|
507
|
+
getSystemProxy: () => Promise<{
|
|
508
|
+
ipaddress: string;
|
|
509
|
+
port: number;
|
|
510
|
+
} | undefined> | undefined;
|
|
511
|
+
getPacDataUrl: ({ proxy, defProxy, rules }: {
|
|
512
|
+
proxy?: string | undefined;
|
|
513
|
+
defProxy?: string | undefined;
|
|
514
|
+
rules?: string[] | undefined;
|
|
515
|
+
}) => string;
|
|
516
|
+
child_exec: (cmd: string) => Promise<[any, string]>;
|
|
505
517
|
brotliCompress: typeof import("./modules/node/brotli").brotliCompress;
|
|
506
518
|
brotliDecompress: typeof import("./modules/node/brotli").brotliDecompress;
|
|
507
519
|
};
|
|
@@ -829,6 +841,7 @@ declare const _default: {
|
|
|
829
841
|
getRandomBytes: (length: number) => Uint8Array;
|
|
830
842
|
textEncode: (text: string) => Uint8Array;
|
|
831
843
|
textDecode: (buf: ArrayBuffer) => string;
|
|
844
|
+
toDataUrl: (textOrBuf: string | ArrayBuffer, contentType?: string) => string;
|
|
832
845
|
toBase64: (input?: string) => string;
|
|
833
846
|
fromBase64: (input?: string) => string;
|
|
834
847
|
bytesToBase64: (bytes: Uint8Array) => string;
|
|
@@ -10,6 +10,7 @@ declare const _default: {
|
|
|
10
10
|
getRandomBytes: (length: number) => Uint8Array;
|
|
11
11
|
textEncode: (text: string) => Uint8Array;
|
|
12
12
|
textDecode: (buf: ArrayBuffer) => string;
|
|
13
|
+
toDataUrl: (textOrBuf: string | ArrayBuffer, contentType?: string) => string;
|
|
13
14
|
toBase64: (input?: string) => string;
|
|
14
15
|
fromBase64: (input?: string) => string;
|
|
15
16
|
bytesToBase64: (bytes: Uint8Array) => string;
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
import Ecdh from
|
|
2
|
-
import EcdhSpki from
|
|
3
|
-
import { Socks5 } from
|
|
1
|
+
import Ecdh from './ecdh';
|
|
2
|
+
import EcdhSpki from './ecdh-spki';
|
|
3
|
+
import { Socks5 } from './socks5';
|
|
4
4
|
declare const _default: {
|
|
5
5
|
Ecdh: typeof Ecdh;
|
|
6
6
|
EcdhSpki: typeof EcdhSpki;
|
|
7
7
|
Socks5: typeof Socks5;
|
|
8
|
+
getSystemProxy: () => Promise<{
|
|
9
|
+
ipaddress: string;
|
|
10
|
+
port: number;
|
|
11
|
+
} | undefined> | undefined;
|
|
12
|
+
getPacDataUrl: ({ proxy, defProxy, rules }: {
|
|
13
|
+
proxy?: string | undefined;
|
|
14
|
+
defProxy?: string | undefined;
|
|
15
|
+
rules?: string[] | undefined;
|
|
16
|
+
}) => string;
|
|
17
|
+
child_exec: (cmd: string) => Promise<[any, string]>;
|
|
8
18
|
brotliCompress: typeof import("./brotli").brotliCompress;
|
|
9
19
|
brotliDecompress: typeof import("./brotli").brotliDecompress;
|
|
10
20
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
getSystemProxy: () => Promise<{
|
|
3
|
+
ipaddress: string;
|
|
4
|
+
port: number;
|
|
5
|
+
} | undefined> | undefined;
|
|
6
|
+
getPacDataUrl: ({ proxy, defProxy, rules }: {
|
|
7
|
+
proxy?: string | undefined;
|
|
8
|
+
defProxy?: string | undefined;
|
|
9
|
+
rules?: string[] | undefined;
|
|
10
|
+
}) => string;
|
|
11
|
+
};
|
|
12
|
+
export default _default;
|
|
@@ -2,12 +2,8 @@ interface IProxyConfig {
|
|
|
2
2
|
ipaddress: string;
|
|
3
3
|
port: number;
|
|
4
4
|
type?: 5;
|
|
5
|
-
userId
|
|
6
|
-
password
|
|
7
|
-
}
|
|
8
|
-
interface IDestination {
|
|
9
|
-
addr: string;
|
|
10
|
-
port: number;
|
|
5
|
+
userId?: string;
|
|
6
|
+
password?: string;
|
|
11
7
|
}
|
|
12
8
|
export declare class Socks5 {
|
|
13
9
|
private upstreamProxy;
|
|
@@ -24,16 +20,15 @@ export declare class Socks5 {
|
|
|
24
20
|
validateProxyConfig(proxyConfig?: IProxyConfig): "" | "无效的上游代理 IP 地址" | "无效的上游代理端口" | "无效的上游代理用户名" | "无效的上游代理密码";
|
|
25
21
|
start(startPort?: number): Promise<number>;
|
|
26
22
|
setUpstreamProxy(upstreamProxy: IProxyConfig): boolean;
|
|
27
|
-
setSystemProxy(
|
|
28
|
-
use: boolean;
|
|
29
|
-
}): boolean;
|
|
23
|
+
setSystemProxy(use: boolean, config?: IProxyConfig): void;
|
|
30
24
|
setAllowedDomains(allowedDomains?: string[]): void;
|
|
31
25
|
private findAvailablePort;
|
|
32
26
|
private handleSocksConnection;
|
|
33
27
|
private performHandshake;
|
|
34
28
|
private parseClientRequest;
|
|
35
|
-
private connectToUpstreamProxy;
|
|
36
29
|
private getPoolConnection;
|
|
30
|
+
private connectToUpstreamProxy;
|
|
31
|
+
private connectToSystemProxy;
|
|
37
32
|
private connectToLocal;
|
|
38
33
|
private setupDataForwarding;
|
|
39
34
|
private isAllowedDomain;
|