@erfan_bahramali/tping 1.0.0 → 1.1.0
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/README.md +76 -55
- package/dist/crypto/x25519.d.ts +10 -0
- package/dist/crypto/x25519.d.ts.map +1 -0
- package/dist/crypto/x25519.js +51 -0
- package/dist/crypto/x25519.js.map +1 -0
- package/dist/index.js +82 -39
- package/dist/index.js.map +1 -1
- package/dist/lib/attempt.d.ts +31 -0
- package/dist/lib/attempt.d.ts.map +1 -0
- package/dist/lib/attempt.js +94 -0
- package/dist/lib/attempt.js.map +1 -0
- package/dist/lib/checker.d.ts +21 -3
- package/dist/lib/checker.d.ts.map +1 -1
- package/dist/lib/checker.js +133 -49
- package/dist/lib/checker.js.map +1 -1
- package/dist/lib/datacenters.d.ts +15 -0
- package/dist/lib/datacenters.d.ts.map +1 -0
- package/dist/lib/datacenters.js +20 -0
- package/dist/lib/datacenters.js.map +1 -0
- package/dist/lib/parser.d.ts +18 -3
- package/dist/lib/parser.d.ts.map +1 -1
- package/dist/lib/parser.js +174 -78
- package/dist/lib/parser.js.map +1 -1
- package/dist/lib/ping.d.ts +13 -6
- package/dist/lib/ping.d.ts.map +1 -1
- package/dist/lib/ping.js +44 -44
- package/dist/lib/ping.js.map +1 -1
- package/dist/mtproto/exchange.d.ts +10 -0
- package/dist/mtproto/exchange.d.ts.map +1 -0
- package/dist/mtproto/exchange.js +20 -0
- package/dist/mtproto/exchange.js.map +1 -0
- package/dist/mtproto/fake-tls.d.ts +36 -44
- package/dist/mtproto/fake-tls.d.ts.map +1 -1
- package/dist/mtproto/fake-tls.js +174 -148
- package/dist/mtproto/fake-tls.js.map +1 -1
- package/dist/mtproto/messages.d.ts +23 -36
- package/dist/mtproto/messages.d.ts.map +1 -1
- package/dist/mtproto/messages.js +64 -90
- package/dist/mtproto/messages.js.map +1 -1
- package/dist/mtproto/obfuscation.d.ts +23 -20
- package/dist/mtproto/obfuscation.d.ts.map +1 -1
- package/dist/mtproto/obfuscation.js +64 -64
- package/dist/mtproto/obfuscation.js.map +1 -1
- package/dist/mtproto/secret.d.ts +28 -0
- package/dist/mtproto/secret.d.ts.map +1 -0
- package/dist/mtproto/secret.js +68 -0
- package/dist/mtproto/secret.js.map +1 -0
- package/dist/mtproto/transport.d.ts +28 -0
- package/dist/mtproto/transport.d.ts.map +1 -0
- package/dist/mtproto/transport.js +78 -0
- package/dist/mtproto/transport.js.map +1 -0
- package/dist/net/http-client.d.ts +37 -0
- package/dist/net/http-client.d.ts.map +1 -0
- package/dist/net/http-client.js +93 -0
- package/dist/net/http-client.js.map +1 -0
- package/dist/net/http-proxy.d.ts +26 -0
- package/dist/net/http-proxy.d.ts.map +1 -0
- package/dist/net/http-proxy.js +71 -0
- package/dist/net/http-proxy.js.map +1 -0
- package/dist/net/socks5.d.ts +15 -0
- package/dist/net/socks5.d.ts.map +1 -0
- package/dist/net/socks5.js +112 -0
- package/dist/net/socks5.js.map +1 -0
- package/dist/net/stream.d.ts +54 -0
- package/dist/net/stream.d.ts.map +1 -0
- package/dist/net/stream.js +142 -0
- package/dist/net/stream.js.map +1 -0
- package/dist/net/websocket.d.ts +19 -0
- package/dist/net/websocket.d.ts.map +1 -0
- package/dist/net/websocket.js +123 -0
- package/dist/net/websocket.js.map +1 -0
- package/dist/types/index.d.ts +40 -17
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/format.d.ts +7 -14
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +101 -87
- package/dist/utils/format.js.map +1 -1
- package/dist/webproxy/check.d.ts +15 -0
- package/dist/webproxy/check.d.ts.map +1 -0
- package/dist/webproxy/check.js +423 -0
- package/dist/webproxy/check.js.map +1 -0
- package/dist/webproxy/frames.d.ts +30 -0
- package/dist/webproxy/frames.d.ts.map +1 -0
- package/dist/webproxy/frames.js +59 -0
- package/dist/webproxy/frames.js.map +1 -0
- package/dist/webproxy/link.d.ts +27 -0
- package/dist/webproxy/link.d.ts.map +1 -0
- package/dist/webproxy/link.js +107 -0
- package/dist/webproxy/link.js.map +1 -0
- package/package.json +16 -11
- package/dist/mtproto/connection.d.ts +0 -59
- package/dist/mtproto/connection.d.ts.map +0 -1
- package/dist/mtproto/connection.js +0 -198
- package/dist/mtproto/connection.js.map +0 -1
- package/dist/mtproto/socks5.d.ts +0 -36
- package/dist/mtproto/socks5.d.ts.map +0 -1
- package/dist/mtproto/socks5.js +0 -148
- package/dist/mtproto/socks5.js.map +0 -1
package/dist/lib/checker.js
CHANGED
|
@@ -1,72 +1,156 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { AbortedError, Attempt, STAGE_CONNECTING, STAGE_WAITING, describeError } from './attempt.js';
|
|
2
|
+
import { checkWebProxy } from '../webproxy/check.js';
|
|
3
|
+
import { socks5Connect } from '../net/socks5.js';
|
|
4
|
+
import { HttpProxyError, httpConnect, httpTransportRequest } from '../net/http-proxy.js';
|
|
5
|
+
import { parseSecret } from '../mtproto/secret.js';
|
|
6
|
+
import { fakeTlsHandshake } from '../mtproto/fake-tls.js';
|
|
7
|
+
import { createObfuscation, ObfuscatedPipe } from '../mtproto/obfuscation.js';
|
|
8
|
+
import { buildReqPqMulti, parseResPQ } from '../mtproto/messages.js';
|
|
9
|
+
import { exchangeReqPq, InvalidResponseError } from '../mtproto/exchange.js';
|
|
10
|
+
import { DEFAULT_DC, resolveDatacenter } from './datacenters.js';
|
|
3
11
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
12
|
+
* Run `body` on a fresh connection to the proxy and measure the phases.
|
|
13
|
+
* `body` calls `handshakeDone()` when the proxy-level negotiation is finished.
|
|
6
14
|
*/
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
return { proxy, success: false, error: 'Invalid MTProto configuration' };
|
|
10
|
-
}
|
|
15
|
+
const measure = async (proxy, deadline, options, body) => {
|
|
16
|
+
const attempt = new Attempt(deadline, options.signal);
|
|
11
17
|
try {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
const start = Date.now();
|
|
19
|
+
await attempt.stream.connect(proxy.server, proxy.port);
|
|
20
|
+
const connected = Date.now();
|
|
21
|
+
let negotiated = connected;
|
|
22
|
+
await body(attempt, () => {
|
|
23
|
+
negotiated = Date.now();
|
|
24
|
+
});
|
|
25
|
+
const end = Date.now();
|
|
26
|
+
return { timings: { connect: connected - start, handshake: negotiated - connected, rtt: end - negotiated } };
|
|
19
27
|
}
|
|
20
28
|
catch (err) {
|
|
21
|
-
|
|
22
|
-
proxy,
|
|
23
|
-
success: false,
|
|
24
|
-
error: err instanceof Error ? err.message : 'Connection failed',
|
|
25
|
-
};
|
|
29
|
+
throw Object.assign(err instanceof Error ? err : new Error(String(err)), { stage: attempt.stage });
|
|
26
30
|
}
|
|
31
|
+
finally {
|
|
32
|
+
attempt.close();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const checkMTProto = (proxy, dc, deadline, options) => {
|
|
36
|
+
const secret = parseSecret(proxy.secret);
|
|
37
|
+
const mode = secret.kind === 'simple' ? 'intermediate' : 'padded';
|
|
38
|
+
return measure(proxy, deadline, options, async (attempt, handshakeDone) => {
|
|
39
|
+
let pipe = attempt.stream;
|
|
40
|
+
if (secret.kind === 'faketls') {
|
|
41
|
+
attempt.stage = 'fake-TLS handshake';
|
|
42
|
+
pipe = await fakeTlsHandshake(attempt.stream, secret.key, secret.domain ?? '');
|
|
43
|
+
}
|
|
44
|
+
handshakeDone();
|
|
45
|
+
attempt.stage = STAGE_WAITING;
|
|
46
|
+
await exchangeReqPq(new ObfuscatedPipe(pipe, createObfuscation(dc, mode, secret.key)), mode);
|
|
47
|
+
});
|
|
27
48
|
};
|
|
49
|
+
const dcAddress = (dc, transport, options) => options.resolveDc?.(dc, transport) ?? resolveDatacenter(dc, options.ipv6 ?? false, transport);
|
|
28
50
|
/**
|
|
29
|
-
*
|
|
51
|
+
* Direct (unsecured) obfuscated connection to the DC, as used through SOCKS5/HTTP proxies.
|
|
30
52
|
*/
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
53
|
+
const exchangeDirect = (pipe, dc) => exchangeReqPq(new ObfuscatedPipe(pipe, createObfuscation(dc, 'abridged')), 'abridged');
|
|
54
|
+
const checkSocks5 = (proxy, dc, deadline, options) => measure(proxy, deadline, options, async (attempt, handshakeDone) => {
|
|
55
|
+
const target = dcAddress(dc, 'tcp', options);
|
|
56
|
+
await socks5Connect(attempt.stream, target.host, target.port, proxy, (stage) => {
|
|
57
|
+
attempt.stage = stage;
|
|
58
|
+
});
|
|
59
|
+
handshakeDone();
|
|
60
|
+
attempt.stage = STAGE_WAITING;
|
|
61
|
+
await exchangeDirect(attempt.stream, dc);
|
|
62
|
+
});
|
|
63
|
+
const checkHttp = async (proxy, dc, deadline, options) => {
|
|
35
64
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
65
|
+
return await measure(proxy, deadline, options, async (attempt, handshakeDone) => {
|
|
66
|
+
const target = dcAddress(dc, 'tcp', options);
|
|
67
|
+
attempt.stage = 'HTTP CONNECT';
|
|
68
|
+
await httpConnect(attempt.stream, target.host, target.port, proxy);
|
|
69
|
+
handshakeDone();
|
|
70
|
+
attempt.stage = STAGE_WAITING;
|
|
71
|
+
await exchangeDirect(attempt.stream, dc);
|
|
42
72
|
});
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
// Like Telegram Desktop, fall back to the HTTP transport when the proxy refuses CONNECT.
|
|
76
|
+
if (!(err instanceof HttpProxyError) || err.status === undefined || err.status === 407) {
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
const measured = await measure(proxy, deadline, options, async (attempt, handshakeDone) => {
|
|
80
|
+
const target = dcAddress(dc, 'http', options);
|
|
81
|
+
handshakeDone();
|
|
82
|
+
attempt.stage = `${STAGE_WAITING} (HTTP transport)`;
|
|
83
|
+
const { message, nonce } = buildReqPqMulti();
|
|
84
|
+
const reply = parseResPQ(await httpTransportRequest(attempt.stream, target.host, target.port, proxy, message));
|
|
85
|
+
if (!reply || !reply.nonce.equals(nonce)) {
|
|
86
|
+
throw new InvalidResponseError('Invalid reply from Telegram over HTTP transport');
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return { ...measured, via: 'http-transport' };
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const checkDc = async (proxy, dc, options) => {
|
|
93
|
+
const deadline = Date.now() + options.timeout;
|
|
94
|
+
try {
|
|
95
|
+
let measured;
|
|
96
|
+
switch (proxy.type) {
|
|
97
|
+
case 'mtproto':
|
|
98
|
+
measured = await checkMTProto(proxy, dc, deadline, options);
|
|
99
|
+
break;
|
|
100
|
+
case 'socks5':
|
|
101
|
+
measured = await checkSocks5(proxy, dc, deadline, options);
|
|
102
|
+
break;
|
|
103
|
+
case 'http':
|
|
104
|
+
measured = await checkHttp(proxy, dc, deadline, options);
|
|
105
|
+
break;
|
|
106
|
+
default:
|
|
107
|
+
return { dc, success: false, error: 'Unsupported proxy type' };
|
|
49
108
|
}
|
|
50
|
-
|
|
109
|
+
const { connect, handshake, rtt } = measured.timings;
|
|
110
|
+
return { dc, success: true, latency: connect + handshake + rtt, timings: measured.timings, via: measured.via };
|
|
51
111
|
}
|
|
52
112
|
catch (err) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
};
|
|
113
|
+
if (err instanceof AbortedError) {
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
const stage = err.stage ?? STAGE_CONNECTING;
|
|
117
|
+
return { dc, success: false, error: describeError(err, stage) };
|
|
58
118
|
}
|
|
59
119
|
};
|
|
60
120
|
/**
|
|
61
|
-
*
|
|
121
|
+
* Check one proxy the way the official clients use it: open a real connection,
|
|
122
|
+
* do the proxy handshake, and get a resPQ back from each requested Telegram DC.
|
|
62
123
|
*/
|
|
63
|
-
export const checkProxy = async (proxy,
|
|
124
|
+
export const checkProxy = async (proxy, options) => {
|
|
125
|
+
const dcs = options.dcs?.length ? options.dcs : [DEFAULT_DC];
|
|
64
126
|
if (proxy.type === 'mtproto') {
|
|
65
|
-
|
|
127
|
+
try {
|
|
128
|
+
parseSecret(proxy.secret);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
return { proxy, success: false, dcs: [], error: err.message };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
let results;
|
|
135
|
+
try {
|
|
136
|
+
results = proxy.type === 'web'
|
|
137
|
+
? await checkWebProxy(proxy, dcs, options)
|
|
138
|
+
: await Promise.all(dcs.map((dc) => checkDc(proxy, dc, options)));
|
|
66
139
|
}
|
|
67
|
-
|
|
68
|
-
|
|
140
|
+
catch (err) {
|
|
141
|
+
if (err instanceof AbortedError) {
|
|
142
|
+
return { proxy, success: false, dcs: [], error: 'Aborted', aborted: true };
|
|
143
|
+
}
|
|
144
|
+
throw err;
|
|
69
145
|
}
|
|
70
|
-
|
|
146
|
+
const success = results.every((r) => r.success);
|
|
147
|
+
const failed = results.find((r) => !r.success);
|
|
148
|
+
return {
|
|
149
|
+
proxy,
|
|
150
|
+
success,
|
|
151
|
+
latency: success ? Math.max(...results.map((r) => r.latency ?? 0)) : undefined,
|
|
152
|
+
dcs: results,
|
|
153
|
+
error: failed?.error,
|
|
154
|
+
};
|
|
71
155
|
};
|
|
72
156
|
//# sourceMappingURL=checker.js.map
|
package/dist/lib/checker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checker.js","sourceRoot":"","sources":["../../src/lib/checker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checker.js","sourceRoot":"","sources":["../../src/lib/checker.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACrG,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAkB,MAAM,kBAAkB,CAAC;AAoBjF;;;GAGG;AACH,MAAM,OAAO,GAAG,KAAK,EACnB,KAAoB,EACpB,QAAgB,EAChB,OAAqB,EACrB,IAAoE,EACjD,EAAE;IACrB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,UAAU,GAAG,SAAS,CAAC;QAC3B,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,SAAS,GAAG,KAAK,EAAE,SAAS,EAAE,UAAU,GAAG,SAAS,EAAE,GAAG,EAAE,GAAG,GAAG,UAAU,EAAE,EAAE,CAAC;IAC/G,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACrG,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,KAAmB,EAAE,EAAU,EAAE,QAAgB,EAAE,OAAqB,EAAqB,EAAE;IACnH,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAkB,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEjF,OAAO,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE;QACxE,IAAI,IAAI,GAAS,OAAO,CAAC,MAAM,CAAC;QAChC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,GAAG,oBAAoB,CAAC;YACrC,IAAI,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,aAAa,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC;QAC9B,MAAM,aAAa,CAAC,IAAI,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,EAAU,EAAE,SAAyB,EAAE,OAAqB,EAAa,EAAE,CAC5F,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,iBAAiB,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE,SAAS,CAAC,CAAC;AAEhG;;GAEG;AACH,MAAM,cAAc,GAAG,CAAC,IAAU,EAAE,EAAU,EAAiB,EAAE,CAC/D,aAAa,CAAC,IAAI,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AAEzF,MAAM,WAAW,GAAG,CAAC,KAAkB,EAAE,EAAU,EAAE,QAAgB,EAAE,OAAqB,EAAqB,EAAE,CACjH,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE;IACjE,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,MAAM,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;QAC7E,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IACxB,CAAC,CAAC,CAAC;IACH,aAAa,EAAE,CAAC;IAChB,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC;IAC9B,MAAM,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEL,MAAM,SAAS,GAAG,KAAK,EAAE,KAAgB,EAAE,EAAU,EAAE,QAAgB,EAAE,OAAqB,EAAqB,EAAE;IACnH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE;YAC9E,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC7C,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC;YAC/B,MAAM,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACnE,aAAa,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC;YAC9B,MAAM,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,yFAAyF;QACzF,IAAI,CAAC,CAAC,GAAG,YAAY,cAAc,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvF,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE;YACxF,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9C,aAAa,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,GAAG,GAAG,aAAa,mBAAmB,CAAC;YACpD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,eAAe,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/G,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,oBAAoB,CAAC,iDAAiD,CAAC,CAAC;YACpF,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC;IAChD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,KAAK,EAAE,KAAoB,EAAE,EAAU,EAAE,OAAqB,EAAqB,EAAE;IACnG,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAC9C,IAAI,CAAC;QACH,IAAI,QAAkB,CAAC;QACvB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,SAAS;gBACZ,QAAQ,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC5D,MAAM;YACR,KAAK,QAAQ;gBACX,QAAQ,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC3D,MAAM;YACR,KAAK,MAAM;gBACT,QAAQ,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACzD,MAAM;YACR;gBACE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;QACnE,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC;QACrD,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC;IACjH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;YAChC,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,KAAK,GAAI,GAA0B,CAAC,KAAK,IAAI,gBAAgB,CAAC;QACpE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;IAClE,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,KAAoB,EAAE,OAAqB,EAAwB,EAAE;IACpG,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAE7D,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC;QAC3E,CAAC;IACH,CAAC;IACD,IAAI,OAA4B,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK;YAC5B,CAAC,CAAC,MAAM,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC;YAC1C,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;YAChC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7E,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/C,OAAO;QACL,KAAK;QACL,OAAO;QACP,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAC9E,GAAG,EAAE,OAAO;QACZ,KAAK,EAAE,MAAM,EAAE,KAAK;KACrB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production Telegram datacenter addresses (same defaults as the official clients).
|
|
3
|
+
* Only needed for SOCKS5/HTTP proxies; MTProto proxies pick the DC from the DC id.
|
|
4
|
+
*/
|
|
5
|
+
export interface DcAddress {
|
|
6
|
+
readonly host: string;
|
|
7
|
+
readonly port: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const DC_IDS: readonly number[];
|
|
10
|
+
export declare const DEFAULT_DC = 2;
|
|
11
|
+
/**
|
|
12
|
+
* @param transport - 'tcp' uses port 443, 'http' (HTTP transport) uses port 80
|
|
13
|
+
*/
|
|
14
|
+
export declare const resolveDatacenter: (dcId: number, ipv6: boolean, transport: "tcp" | "http") => DcAddress;
|
|
15
|
+
//# sourceMappingURL=datacenters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datacenters.d.ts","sourceRoot":"","sources":["../../src/lib/datacenters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAUD,eAAO,MAAM,MAAM,EAAE,SAAS,MAAM,EAAoB,CAAC;AACzD,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,MAAM,OAAO,EAAE,WAAW,KAAK,GAAG,MAAM,KAAG,SAM1F,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const DATACENTERS = {
|
|
2
|
+
1: { ipv4: '149.154.175.50', ipv6: '2001:b28:f23d:f001::a' },
|
|
3
|
+
2: { ipv4: '149.154.167.51', ipv6: '2001:67c:4e8:f002::a' },
|
|
4
|
+
3: { ipv4: '149.154.175.100', ipv6: '2001:b28:f23d:f003::a' },
|
|
5
|
+
4: { ipv4: '149.154.167.91', ipv6: '2001:67c:4e8:f004::a' },
|
|
6
|
+
5: { ipv4: '149.154.171.5', ipv6: '2001:b28:f23f:f005::a' },
|
|
7
|
+
};
|
|
8
|
+
export const DC_IDS = [1, 2, 3, 4, 5];
|
|
9
|
+
export const DEFAULT_DC = 2;
|
|
10
|
+
/**
|
|
11
|
+
* @param transport - 'tcp' uses port 443, 'http' (HTTP transport) uses port 80
|
|
12
|
+
*/
|
|
13
|
+
export const resolveDatacenter = (dcId, ipv6, transport) => {
|
|
14
|
+
const dc = DATACENTERS[Math.abs(dcId)];
|
|
15
|
+
if (!dc) {
|
|
16
|
+
throw new Error(`Unknown DC ${dcId}`);
|
|
17
|
+
}
|
|
18
|
+
return { host: ipv6 ? dc.ipv6 : dc.ipv4, port: transport === 'http' ? 80 : 443 };
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=datacenters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datacenters.js","sourceRoot":"","sources":["../../src/lib/datacenters.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,GAA+E;IAC9F,CAAC,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,uBAAuB,EAAE;IAC5D,CAAC,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,sBAAsB,EAAE;IAC3D,CAAC,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,uBAAuB,EAAE;IAC7D,CAAC,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,sBAAsB,EAAE;IAC3D,CAAC,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,uBAAuB,EAAE;CAC5D,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAsB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACzD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAE5B;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,IAAa,EAAE,SAAyB,EAAa,EAAE;IACrG,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AACnF,CAAC,CAAC"}
|
package/dist/lib/parser.d.ts
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import type { TelegramProxy } from '../types/index.js';
|
|
2
|
+
export interface ParseIssue {
|
|
3
|
+
readonly input: string;
|
|
4
|
+
readonly reason: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ParseResult {
|
|
7
|
+
readonly proxies: readonly TelegramProxy[];
|
|
8
|
+
readonly issues: readonly ParseIssue[];
|
|
9
|
+
}
|
|
10
|
+
type Outcome = {
|
|
11
|
+
readonly proxy: TelegramProxy;
|
|
12
|
+
} | {
|
|
13
|
+
readonly reason: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const parseProxyString: (token: string) => Outcome;
|
|
2
16
|
/**
|
|
3
|
-
* Parse proxies from
|
|
4
|
-
*
|
|
17
|
+
* Parse proxies from a file path, "-" (stdin), or proxy text.
|
|
18
|
+
* Proxies may be separated by newlines or whitespace; lines starting with "#" are comments.
|
|
5
19
|
*/
|
|
6
|
-
export declare const parseProxies: (input: string) =>
|
|
20
|
+
export declare const parseProxies: (input: string) => ParseResult;
|
|
21
|
+
export {};
|
|
7
22
|
//# sourceMappingURL=parser.d.ts.map
|
package/dist/lib/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAsBvD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CACxC;AAED,KAAK,OAAO,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAsH/E,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,OA2BhD,CAAC;AAgBF;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,WAuB5C,CAAC"}
|
package/dist/lib/parser.js
CHANGED
|
@@ -1,96 +1,192 @@
|
|
|
1
|
-
import { readFileSync,
|
|
1
|
+
import { readFileSync, statSync } from 'fs';
|
|
2
|
+
import { decodeWebSecret, parseWebProxyServer } from '../webproxy/link.js';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
+
* Supported inputs:
|
|
5
|
+
* https://t.me/proxy?server=..&port=..&secret=.. (also telegram.me, telegram.dog, www., http://, no scheme)
|
|
6
|
+
* tg://proxy?server=..&port=..&secret=.. (also tg:proxy)
|
|
7
|
+
* https://t.me/socks?server=..&port=..&user=..&pass=.. / tg://socks?...
|
|
8
|
+
* tg://webproxy?server=host[/path]&secret=.. / https://t.me/webproxy?... (WEB proxy, port 443)
|
|
9
|
+
* socks5://user:pass@host:port (also socks://, socks5h://)
|
|
10
|
+
* http://user:pass@host:port (HTTP proxy, Telegram Desktop)
|
|
4
11
|
*/
|
|
5
|
-
const
|
|
6
|
-
'
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
12
|
+
const TELEGRAM_HOSTS = new Set([
|
|
13
|
+
't.me',
|
|
14
|
+
'telegram.me',
|
|
15
|
+
'telegram.dog',
|
|
16
|
+
'www.t.me',
|
|
17
|
+
'www.telegram.me',
|
|
18
|
+
'www.telegram.dog',
|
|
19
|
+
]);
|
|
20
|
+
const normalize = (token) => {
|
|
21
|
+
// Strip shell-escape backslashes before URL punctuation (e.g. t.me/proxy\?...\&...).
|
|
22
|
+
let value = token.replace(/\\([?=&#])/g, '$1').trim();
|
|
23
|
+
if (/^tg:(?!\/\/)/i.test(value)) {
|
|
24
|
+
value = `tg://${value.slice(3)}`;
|
|
25
|
+
}
|
|
26
|
+
if (/^(www\.)?(t\.me|telegram\.me|telegram\.dog)\//i.test(value)) {
|
|
27
|
+
value = `https://${value}`;
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
};
|
|
31
|
+
const parsePort = (value, fallback) => {
|
|
32
|
+
if (!value) {
|
|
33
|
+
return fallback ?? 'port is missing';
|
|
34
|
+
}
|
|
35
|
+
if (!/^\d+$/.test(value)) {
|
|
36
|
+
return `invalid port "${value}"`;
|
|
37
|
+
}
|
|
38
|
+
const port = Number(value);
|
|
39
|
+
return port >= 1 && port <= 65535 ? port : `port ${port} is out of range`;
|
|
40
|
+
};
|
|
41
|
+
const cleanServer = (value) => (value ?? '').trim().replace(/^\[(.*)\]$/, '$1');
|
|
42
|
+
const decodeUserInfo = (value) => {
|
|
43
|
+
if (!value) {
|
|
44
|
+
return undefined;
|
|
28
45
|
}
|
|
29
46
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
return decodeURIComponent(value);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const fromWebQuery = (params) => {
|
|
54
|
+
const server = (params.get('server') ?? params.get('host') ?? '').trim();
|
|
55
|
+
if (!server) {
|
|
56
|
+
return { reason: 'server is missing' };
|
|
57
|
+
}
|
|
58
|
+
const address = parseWebProxyServer(server);
|
|
59
|
+
if (typeof address === 'string') {
|
|
60
|
+
return { reason: address };
|
|
61
|
+
}
|
|
62
|
+
const secretText = params.get('secret')?.trim();
|
|
63
|
+
if (!secretText) {
|
|
64
|
+
return { reason: 'secret is missing' };
|
|
65
|
+
}
|
|
66
|
+
const secret = decodeWebSecret(secretText, address.basePath !== '');
|
|
67
|
+
if (typeof secret === 'string') {
|
|
68
|
+
return { reason: secret };
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
proxy: { type: 'web', server: address.host, port: 443, basePath: address.basePath, secret: secret.toString('hex') },
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
const fromQuery = (kind, params) => {
|
|
75
|
+
if (kind === 'webproxy') {
|
|
76
|
+
return fromWebQuery(params);
|
|
77
|
+
}
|
|
78
|
+
const server = cleanServer(params.get('server'));
|
|
79
|
+
if (!server) {
|
|
80
|
+
return { reason: 'server is missing' };
|
|
81
|
+
}
|
|
82
|
+
const port = parsePort(params.get('port')?.trim());
|
|
83
|
+
if (typeof port === 'string') {
|
|
84
|
+
return { reason: port };
|
|
85
|
+
}
|
|
86
|
+
if (kind === 'proxy') {
|
|
87
|
+
const secret = params.get('secret')?.trim();
|
|
88
|
+
if (!secret) {
|
|
89
|
+
return { reason: 'secret is missing' };
|
|
44
90
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
91
|
+
return { proxy: { type: 'mtproto', server, port, secret } };
|
|
92
|
+
}
|
|
93
|
+
if (kind === 'socks') {
|
|
94
|
+
return {
|
|
95
|
+
proxy: {
|
|
96
|
+
type: 'socks5',
|
|
97
|
+
server,
|
|
98
|
+
port,
|
|
99
|
+
username: params.get('user') || undefined,
|
|
100
|
+
password: params.get('pass') || undefined,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return { reason: `unknown link type "${kind}"` };
|
|
105
|
+
};
|
|
106
|
+
const fromAuthority = (type, url, defaultPort) => {
|
|
107
|
+
const server = cleanServer(url.hostname);
|
|
108
|
+
if (!server) {
|
|
109
|
+
return { reason: 'server is missing' };
|
|
110
|
+
}
|
|
111
|
+
const port = parsePort(url.port, defaultPort);
|
|
112
|
+
if (typeof port === 'string') {
|
|
113
|
+
return { reason: port };
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
proxy: {
|
|
117
|
+
type,
|
|
118
|
+
server,
|
|
119
|
+
port,
|
|
120
|
+
username: decodeUserInfo(url.username),
|
|
121
|
+
password: decodeUserInfo(url.password),
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
export const parseProxyString = (token) => {
|
|
126
|
+
const value = normalize(token);
|
|
127
|
+
let url;
|
|
128
|
+
try {
|
|
129
|
+
// URLSearchParams turns "+" into a space; keep it for base64 secrets.
|
|
130
|
+
url = new URL(value.replace(/\+/g, '%2B'));
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return { reason: value.includes(':') ? 'not a valid proxy link' : 'not a proxy link, and no such file' };
|
|
134
|
+
}
|
|
135
|
+
const protocol = url.protocol.toLowerCase();
|
|
136
|
+
const host = url.hostname.toLowerCase();
|
|
137
|
+
if (protocol === 'tg:') {
|
|
138
|
+
return fromQuery(host, url.searchParams);
|
|
139
|
+
}
|
|
140
|
+
if ((protocol === 'https:' || protocol === 'http:') && TELEGRAM_HOSTS.has(host)) {
|
|
141
|
+
return fromQuery(url.pathname.replace(/^\/+|\/+$/g, '').toLowerCase(), url.searchParams);
|
|
142
|
+
}
|
|
143
|
+
if (protocol === 'socks5:' || protocol === 'socks5h:' || protocol === 'socks:') {
|
|
144
|
+
return fromAuthority('socks5', url, 1080);
|
|
145
|
+
}
|
|
146
|
+
if (protocol === 'http:') {
|
|
147
|
+
return fromAuthority('http', url, 80);
|
|
148
|
+
}
|
|
149
|
+
return { reason: 'unsupported link (expected t.me/proxy, t.me/socks, tg://..., socks5:// or http://)' };
|
|
150
|
+
};
|
|
151
|
+
const readInput = (input) => {
|
|
152
|
+
if (input === '-') {
|
|
153
|
+
return readFileSync(0, 'utf-8');
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
if (statSync(input).isFile()) {
|
|
157
|
+
return readFileSync(input, 'utf-8');
|
|
60
158
|
}
|
|
61
159
|
}
|
|
62
160
|
catch {
|
|
63
|
-
|
|
161
|
+
// Not a file: treat as proxy text.
|
|
64
162
|
}
|
|
65
|
-
return
|
|
163
|
+
return input;
|
|
66
164
|
};
|
|
67
165
|
/**
|
|
68
|
-
* Parse proxies from
|
|
69
|
-
*
|
|
166
|
+
* Parse proxies from a file path, "-" (stdin), or proxy text.
|
|
167
|
+
* Proxies may be separated by newlines or whitespace; lines starting with "#" are comments.
|
|
70
168
|
*/
|
|
71
169
|
export const parseProxies = (input) => {
|
|
72
|
-
let content;
|
|
73
|
-
// Check if input is a file path
|
|
74
|
-
if (existsSync(input)) {
|
|
75
|
-
try {
|
|
76
|
-
content = readFileSync(input, 'utf-8');
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
content = input;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
content = input;
|
|
84
|
-
}
|
|
85
|
-
// Parse each line
|
|
86
170
|
const proxies = [];
|
|
87
|
-
const
|
|
88
|
-
for (const
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
|
|
171
|
+
const issues = [];
|
|
172
|
+
for (const rawLine of readInput(input).split(/\r?\n/)) {
|
|
173
|
+
const line = rawLine.trim();
|
|
174
|
+
if (!line || line.startsWith('#')) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
for (const token of line.split(/\s+/)) {
|
|
178
|
+
if (token.startsWith('#')) {
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
const outcome = parseProxyString(token);
|
|
182
|
+
if ('proxy' in outcome) {
|
|
183
|
+
proxies.push(outcome.proxy);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
issues.push({ input: token, reason: outcome.reason });
|
|
187
|
+
}
|
|
92
188
|
}
|
|
93
189
|
}
|
|
94
|
-
return proxies;
|
|
190
|
+
return { proxies, issues };
|
|
95
191
|
};
|
|
96
192
|
//# sourceMappingURL=parser.js.map
|
package/dist/lib/parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"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"}
|