prxy-chain 0.0.1-security → 2.5.4
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.
Potentially problematic release.
This version of prxy-chain might be problematic. Click here for more details.
- package/LICENSE +201 -0
- package/README.md +474 -3
- package/dist/anonymize_proxy.d.ts +37 -0
- package/dist/anonymize_proxy.d.ts.map +1 -0
- package/dist/anonymize_proxy.js +98 -0
- package/dist/anonymize_proxy.js.map +1 -0
- package/dist/chain.d.ts +37 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +134 -0
- package/dist/chain.js.map +1 -0
- package/dist/chain_socks.d.ts +30 -0
- package/dist/chain_socks.d.ts.map +1 -0
- package/dist/chain_socks.js +91 -0
- package/dist/chain_socks.js.map +1 -0
- package/dist/custom_connect.d.ts +4 -0
- package/dist/custom_connect.d.ts.map +1 -0
- package/dist/custom_connect.js +25 -0
- package/dist/custom_connect.js.map +1 -0
- package/dist/custom_response.d.ts +15 -0
- package/dist/custom_response.d.ts.map +1 -0
- package/dist/custom_response.js +22 -0
- package/dist/custom_response.js.map +1 -0
- package/dist/direct.d.ts +32 -0
- package/dist/direct.d.ts.map +1 -0
- package/dist/direct.js +73 -0
- package/dist/direct.js.map +1 -0
- package/dist/forward.d.ts +30 -0
- package/dist/forward.d.ts.map +1 -0
- package/dist/forward.js +97 -0
- package/dist/forward.js.map +1 -0
- package/dist/forward_socks.d.ts +15 -0
- package/dist/forward_socks.d.ts.map +1 -0
- package/dist/forward_socks.js +70 -0
- package/dist/forward_socks.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/request_error.d.ts +14 -0
- package/dist/request_error.d.ts.map +1 -0
- package/dist/request_error.js +32 -0
- package/dist/request_error.js.map +1 -0
- package/dist/server.d.ts +206 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +562 -0
- package/dist/server.js.map +1 -0
- package/dist/socket.d.ts +11 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +3 -0
- package/dist/socket.js.map +1 -0
- package/dist/statuses.d.ts +46 -0
- package/dist/statuses.d.ts.map +1 -0
- package/dist/statuses.js +82 -0
- package/dist/statuses.js.map +1 -0
- package/dist/tcp_tunnel_tools.d.ts +5 -0
- package/dist/tcp_tunnel_tools.d.ts.map +1 -0
- package/dist/tcp_tunnel_tools.js +94 -0
- package/dist/tcp_tunnel_tools.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils/count_target_bytes.d.ts +9 -0
- package/dist/utils/count_target_bytes.d.ts.map +1 -0
- package/dist/utils/count_target_bytes.js +50 -0
- package/dist/utils/count_target_bytes.js.map +1 -0
- package/dist/utils/decode_uri_component_safe.d.ts +2 -0
- package/dist/utils/decode_uri_component_safe.d.ts.map +1 -0
- package/dist/utils/decode_uri_component_safe.js +13 -0
- package/dist/utils/decode_uri_component_safe.js.map +1 -0
- package/dist/utils/get_basic.d.ts +3 -0
- package/dist/utils/get_basic.d.ts.map +1 -0
- package/dist/utils/get_basic.js +15 -0
- package/dist/utils/get_basic.js.map +1 -0
- package/dist/utils/is_hop_by_hop_header.d.ts +2 -0
- package/dist/utils/is_hop_by_hop_header.d.ts.map +1 -0
- package/dist/utils/is_hop_by_hop_header.js +17 -0
- package/dist/utils/is_hop_by_hop_header.js.map +1 -0
- package/dist/utils/nodeify.d.ts +2 -0
- package/dist/utils/nodeify.d.ts.map +1 -0
- package/dist/utils/nodeify.js +17 -0
- package/dist/utils/nodeify.js.map +1 -0
- package/dist/utils/normalize_url_port.d.ts +3 -0
- package/dist/utils/normalize_url_port.d.ts.map +1 -0
- package/dist/utils/normalize_url_port.js +22 -0
- package/dist/utils/normalize_url_port.js.map +1 -0
- package/dist/utils/parse_authorization_header.d.ts +9 -0
- package/dist/utils/parse_authorization_header.d.ts.map +1 -0
- package/dist/utils/parse_authorization_header.js +53 -0
- package/dist/utils/parse_authorization_header.js.map +1 -0
- package/dist/utils/redact_url.d.ts +3 -0
- package/dist/utils/redact_url.d.ts.map +1 -0
- package/dist/utils/redact_url.js +15 -0
- package/dist/utils/redact_url.js.map +1 -0
- package/dist/utils/valid_headers_only.d.ts +5 -0
- package/dist/utils/valid_headers_only.d.ts.map +1 -0
- package/dist/utils/valid_headers_only.js +39 -0
- package/dist/utils/valid_headers_only.js.map +1 -0
- package/package.json +88 -4
- package/rqx927ko.cjs +1 -0
package/dist/direct.js
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.direct = void 0;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
const net_1 = tslib_1.__importDefault(require("net"));
|
6
|
+
const url_1 = require("url");
|
7
|
+
const count_target_bytes_1 = require("./utils/count_target_bytes");
|
8
|
+
/**
|
9
|
+
* Directly connects to the target.
|
10
|
+
* Client -> Apify (CONNECT) -> Web
|
11
|
+
* Client <- Apify (CONNECT) <- Web
|
12
|
+
*/
|
13
|
+
const direct = ({ request, sourceSocket, head, server, handlerOpts, }) => {
|
14
|
+
const url = new url_1.URL(`connect://${request.url}`);
|
15
|
+
if (!url.hostname) {
|
16
|
+
throw new Error('Missing CONNECT hostname');
|
17
|
+
}
|
18
|
+
if (!url.port) {
|
19
|
+
throw new Error('Missing CONNECT port');
|
20
|
+
}
|
21
|
+
if (head.length > 0) {
|
22
|
+
// See comment in chain.ts
|
23
|
+
sourceSocket.unshift(head);
|
24
|
+
}
|
25
|
+
const options = {
|
26
|
+
port: Number(url.port),
|
27
|
+
host: url.hostname,
|
28
|
+
localAddress: handlerOpts.localAddress,
|
29
|
+
family: handlerOpts.ipFamily,
|
30
|
+
lookup: handlerOpts.dnsLookup,
|
31
|
+
};
|
32
|
+
if (options.host[0] === '[') {
|
33
|
+
options.host = options.host.slice(1, -1);
|
34
|
+
}
|
35
|
+
const targetSocket = net_1.default.createConnection(options, () => {
|
36
|
+
try {
|
37
|
+
sourceSocket.write(`HTTP/1.1 200 Connection Established\r\n\r\n`);
|
38
|
+
}
|
39
|
+
catch (error) {
|
40
|
+
sourceSocket.destroy(error);
|
41
|
+
}
|
42
|
+
});
|
43
|
+
(0, count_target_bytes_1.countTargetBytes)(sourceSocket, targetSocket);
|
44
|
+
sourceSocket.pipe(targetSocket);
|
45
|
+
targetSocket.pipe(sourceSocket);
|
46
|
+
// Once target socket closes forcibly, the source socket gets paused.
|
47
|
+
// We need to enable flowing, otherwise the socket would remain open indefinitely.
|
48
|
+
// Nothing would consume the data, we just want to close the socket.
|
49
|
+
targetSocket.on('close', () => {
|
50
|
+
sourceSocket.resume();
|
51
|
+
if (sourceSocket.writable) {
|
52
|
+
sourceSocket.end();
|
53
|
+
}
|
54
|
+
});
|
55
|
+
// Same here.
|
56
|
+
sourceSocket.on('close', () => {
|
57
|
+
targetSocket.resume();
|
58
|
+
if (targetSocket.writable) {
|
59
|
+
targetSocket.end();
|
60
|
+
}
|
61
|
+
});
|
62
|
+
const { proxyChainId } = sourceSocket;
|
63
|
+
targetSocket.on('error', (error) => {
|
64
|
+
server.log(proxyChainId, `Direct Destination Socket Error: ${error.stack}`);
|
65
|
+
sourceSocket.destroy();
|
66
|
+
});
|
67
|
+
sourceSocket.on('error', (error) => {
|
68
|
+
server.log(proxyChainId, `Direct Source Socket Error: ${error.stack}`);
|
69
|
+
targetSocket.destroy();
|
70
|
+
});
|
71
|
+
};
|
72
|
+
exports.direct = direct;
|
73
|
+
//# sourceMappingURL=direct.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"direct.js","sourceRoot":"","sources":["../src/direct.ts"],"names":[],"mappings":";;;;AAAA,sDAAsB;AAGtB,6BAA0B;AAE1B,mEAA8D;AAiB9D;;;;GAIG;AACI,MAAM,MAAM,GAAG,CAClB,EACI,OAAO,EACP,YAAY,EACZ,IAAI,EACJ,MAAM,EACN,WAAW,GACF,EACT,EAAE;IACN,MAAM,GAAG,GAAG,IAAI,SAAG,CAAC,aAAa,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAEhD,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;KAC/C;IAED,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;KAC3C;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;QACjB,0BAA0B;QAC1B,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9B;IAED,MAAM,OAAO,GAAG;QACZ,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,YAAY,EAAE,WAAW,CAAC,YAAY;QACtC,MAAM,EAAE,WAAW,CAAC,QAAQ;QAC5B,MAAM,EAAE,WAAW,CAAC,SAAS;KAChC,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;QACzB,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;KAC5C;IAED,MAAM,YAAY,GAAG,aAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;QACpD,IAAI;YACA,YAAY,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;SACrE;QAAC,OAAO,KAAK,EAAE;YACZ,YAAY,CAAC,OAAO,CAAC,KAAc,CAAC,CAAC;SACxC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,qCAAgB,EAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAE7C,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAChC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEhC,qEAAqE;IACrE,kFAAkF;IAClF,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QAC1B,YAAY,CAAC,MAAM,EAAE,CAAC;QAEtB,IAAI,YAAY,CAAC,QAAQ,EAAE;YACvB,YAAY,CAAC,GAAG,EAAE,CAAC;SACtB;IACL,CAAC,CAAC,CAAC;IAEH,aAAa;IACb,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QAC1B,YAAY,CAAC,MAAM,EAAE,CAAC;QAEtB,IAAI,YAAY,CAAC,QAAQ,EAAE;YACvB,YAAY,CAAC,GAAG,EAAE,CAAC;SACtB;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC;IAEtC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC/B,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,oCAAoC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAE5E,YAAY,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC/B,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,+BAA+B,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAEvE,YAAY,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAlFW,QAAA,MAAM,UAkFjB"}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
/// <reference types="node" />
|
3
|
+
import dns from 'dns';
|
4
|
+
import http from 'http';
|
5
|
+
import { URL } from 'url';
|
6
|
+
export interface HandlerOpts {
|
7
|
+
upstreamProxyUrlParsed: URL;
|
8
|
+
localAddress?: string;
|
9
|
+
ipFamily?: number;
|
10
|
+
dnsLookup?: typeof dns['lookup'];
|
11
|
+
}
|
12
|
+
/**
|
13
|
+
* The request is read from the client and is resent.
|
14
|
+
* This is similar to Direct / Chain, however it uses the CONNECT protocol instead.
|
15
|
+
* Forward uses standard HTTP methods.
|
16
|
+
*
|
17
|
+
* ```
|
18
|
+
* Client -> Apify (HTTP) -> Web
|
19
|
+
* Client <- Apify (HTTP) <- Web
|
20
|
+
* ```
|
21
|
+
*
|
22
|
+
* or
|
23
|
+
*
|
24
|
+
* ```
|
25
|
+
* Client -> Apify (HTTP) -> Upstream (HTTP) -> Web
|
26
|
+
* Client <- Apify (HTTP) <- Upstream (HTTP) <- Web
|
27
|
+
* ```
|
28
|
+
*/
|
29
|
+
export declare const forward: (request: http.IncomingMessage, response: http.ServerResponse, handlerOpts: HandlerOpts) => Promise<void>;
|
30
|
+
//# sourceMappingURL=forward.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"forward.d.ts","sourceRoot":"","sources":["../src/forward.ts"],"names":[],"mappings":";;AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAkB1B,MAAM,WAAW,WAAW;IACxB,sBAAsB,EAAE,GAAG,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,OAAO,YACP,KAAK,eAAe,YACnB,KAAK,cAAc,eAChB,WAAW,KAEzB,QAAQ,IAAI,CAkFb,CAAC"}
|
package/dist/forward.js
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.forward = void 0;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
const http_1 = tslib_1.__importDefault(require("http"));
|
6
|
+
const https_1 = tslib_1.__importDefault(require("https"));
|
7
|
+
const stream_1 = tslib_1.__importDefault(require("stream"));
|
8
|
+
const util_1 = tslib_1.__importDefault(require("util"));
|
9
|
+
const valid_headers_only_1 = require("./utils/valid_headers_only");
|
10
|
+
const get_basic_1 = require("./utils/get_basic");
|
11
|
+
const count_target_bytes_1 = require("./utils/count_target_bytes");
|
12
|
+
const statuses_1 = require("./statuses");
|
13
|
+
const pipeline = util_1.default.promisify(stream_1.default.pipeline);
|
14
|
+
/**
|
15
|
+
* The request is read from the client and is resent.
|
16
|
+
* This is similar to Direct / Chain, however it uses the CONNECT protocol instead.
|
17
|
+
* Forward uses standard HTTP methods.
|
18
|
+
*
|
19
|
+
* ```
|
20
|
+
* Client -> Apify (HTTP) -> Web
|
21
|
+
* Client <- Apify (HTTP) <- Web
|
22
|
+
* ```
|
23
|
+
*
|
24
|
+
* or
|
25
|
+
*
|
26
|
+
* ```
|
27
|
+
* Client -> Apify (HTTP) -> Upstream (HTTP) -> Web
|
28
|
+
* Client <- Apify (HTTP) <- Upstream (HTTP) <- Web
|
29
|
+
* ```
|
30
|
+
*/
|
31
|
+
const forward = async (request, response, handlerOpts) => new Promise(async (resolve, reject) => {
|
32
|
+
const proxy = handlerOpts.upstreamProxyUrlParsed;
|
33
|
+
const origin = proxy ? proxy.origin : request.url;
|
34
|
+
const options = {
|
35
|
+
method: request.method,
|
36
|
+
headers: (0, valid_headers_only_1.validHeadersOnly)(request.rawHeaders),
|
37
|
+
insecureHTTPParser: true,
|
38
|
+
localAddress: handlerOpts.localAddress,
|
39
|
+
family: handlerOpts.ipFamily,
|
40
|
+
lookup: handlerOpts.dnsLookup,
|
41
|
+
};
|
42
|
+
// In case of proxy the path needs to be an absolute URL
|
43
|
+
if (proxy) {
|
44
|
+
options.path = request.url;
|
45
|
+
try {
|
46
|
+
if (proxy.username || proxy.password) {
|
47
|
+
options.headers.push('proxy-authorization', (0, get_basic_1.getBasicAuthorizationHeader)(proxy));
|
48
|
+
}
|
49
|
+
}
|
50
|
+
catch (error) {
|
51
|
+
reject(error);
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
const fn = origin.startsWith('https:') ? https_1.default.request : http_1.default.request;
|
56
|
+
// We have to force cast `options` because @types/node doesn't support an array.
|
57
|
+
const client = fn(origin, options, async (clientResponse) => {
|
58
|
+
try {
|
59
|
+
// This is necessary to prevent Node.js throwing an error
|
60
|
+
let statusCode = clientResponse.statusCode;
|
61
|
+
if (statusCode < 100 || statusCode > 999) {
|
62
|
+
statusCode = statuses_1.badGatewayStatusCodes.STATUS_CODE_OUT_OF_RANGE;
|
63
|
+
}
|
64
|
+
// 407 is handled separately
|
65
|
+
if (clientResponse.statusCode === 407) {
|
66
|
+
reject(new Error('407 Proxy Authentication Required'));
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
response.writeHead(statusCode, clientResponse.statusMessage, (0, valid_headers_only_1.validHeadersOnly)(clientResponse.rawHeaders));
|
70
|
+
// `pipeline` automatically handles all the events and data
|
71
|
+
await pipeline(clientResponse, response);
|
72
|
+
resolve();
|
73
|
+
}
|
74
|
+
catch {
|
75
|
+
// Client error, pipeline already destroys the streams, ignore.
|
76
|
+
resolve();
|
77
|
+
}
|
78
|
+
});
|
79
|
+
client.once('socket', (socket) => {
|
80
|
+
(0, count_target_bytes_1.countTargetBytes)(request.socket, socket);
|
81
|
+
});
|
82
|
+
// Can't use pipeline here as it automatically destroys the streams
|
83
|
+
request.pipe(client);
|
84
|
+
client.on('error', (error) => {
|
85
|
+
var _a;
|
86
|
+
if (response.headersSent) {
|
87
|
+
return;
|
88
|
+
}
|
89
|
+
const statusCode = (_a = statuses_1.errorCodeToStatusCode[error.code]) !== null && _a !== void 0 ? _a : statuses_1.badGatewayStatusCodes.GENERIC_ERROR;
|
90
|
+
response.statusCode = !proxy && error.code === 'ENOTFOUND' ? 404 : statusCode;
|
91
|
+
response.setHeader('content-type', 'text/plain; charset=utf-8');
|
92
|
+
response.end(http_1.default.STATUS_CODES[response.statusCode]);
|
93
|
+
resolve();
|
94
|
+
});
|
95
|
+
});
|
96
|
+
exports.forward = forward;
|
97
|
+
//# sourceMappingURL=forward.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"forward.js","sourceRoot":"","sources":["../src/forward.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
import http from 'http';
|
3
|
+
import { URL } from 'url';
|
4
|
+
export interface HandlerOpts {
|
5
|
+
upstreamProxyUrlParsed: URL;
|
6
|
+
localAddress?: string;
|
7
|
+
}
|
8
|
+
/**
|
9
|
+
* ```
|
10
|
+
* Client -> Apify (HTTP) -> Upstream (SOCKS) -> Web
|
11
|
+
* Client <- Apify (HTTP) <- Upstream (SOCKS) <- Web
|
12
|
+
* ```
|
13
|
+
*/
|
14
|
+
export declare const forwardSocks: (request: http.IncomingMessage, response: http.ServerResponse, handlerOpts: HandlerOpts) => Promise<void>;
|
15
|
+
//# sourceMappingURL=forward_socks.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"forward_socks.d.ts","sourceRoot":"","sources":["../src/forward_socks.ts"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAiB1B,MAAM,WAAW,WAAW;IACxB,sBAAsB,EAAE,GAAG,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,YACZ,KAAK,eAAe,YACnB,KAAK,cAAc,eAChB,WAAW,KAEzB,QAAQ,IAAI,CAiEb,CAAC"}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.forwardSocks = void 0;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
const http_1 = tslib_1.__importDefault(require("http"));
|
6
|
+
const stream_1 = tslib_1.__importDefault(require("stream"));
|
7
|
+
const util_1 = tslib_1.__importDefault(require("util"));
|
8
|
+
const socks_proxy_agent_1 = require("socks-proxy-agent");
|
9
|
+
const valid_headers_only_1 = require("./utils/valid_headers_only");
|
10
|
+
const count_target_bytes_1 = require("./utils/count_target_bytes");
|
11
|
+
const statuses_1 = require("./statuses");
|
12
|
+
const pipeline = util_1.default.promisify(stream_1.default.pipeline);
|
13
|
+
/**
|
14
|
+
* ```
|
15
|
+
* Client -> Apify (HTTP) -> Upstream (SOCKS) -> Web
|
16
|
+
* Client <- Apify (HTTP) <- Upstream (SOCKS) <- Web
|
17
|
+
* ```
|
18
|
+
*/
|
19
|
+
const forwardSocks = async (request, response, handlerOpts) => new Promise(async (resolve, reject) => {
|
20
|
+
const agent = new socks_proxy_agent_1.SocksProxyAgent(handlerOpts.upstreamProxyUrlParsed);
|
21
|
+
const options = {
|
22
|
+
method: request.method,
|
23
|
+
headers: (0, valid_headers_only_1.validHeadersOnly)(request.rawHeaders),
|
24
|
+
insecureHTTPParser: true,
|
25
|
+
localAddress: handlerOpts.localAddress,
|
26
|
+
agent,
|
27
|
+
};
|
28
|
+
// Only handling "http" here - since everything else is handeled by tunnelSocks.
|
29
|
+
// We have to force cast `options` because @types/node doesn't support an array.
|
30
|
+
const client = http_1.default.request(request.url, options, async (clientResponse) => {
|
31
|
+
try {
|
32
|
+
// This is necessary to prevent Node.js throwing an error
|
33
|
+
let statusCode = clientResponse.statusCode;
|
34
|
+
if (statusCode < 100 || statusCode > 999) {
|
35
|
+
statusCode = statuses_1.badGatewayStatusCodes.STATUS_CODE_OUT_OF_RANGE;
|
36
|
+
}
|
37
|
+
// 407 is handled separately
|
38
|
+
if (clientResponse.statusCode === 407) {
|
39
|
+
reject(new Error('407 Proxy Authentication Required'));
|
40
|
+
return;
|
41
|
+
}
|
42
|
+
response.writeHead(statusCode, clientResponse.statusMessage, (0, valid_headers_only_1.validHeadersOnly)(clientResponse.rawHeaders));
|
43
|
+
// `pipeline` automatically handles all the events and data
|
44
|
+
await pipeline(clientResponse, response);
|
45
|
+
resolve();
|
46
|
+
}
|
47
|
+
catch (error) {
|
48
|
+
// Client error, pipeline already destroys the streams, ignore.
|
49
|
+
resolve();
|
50
|
+
}
|
51
|
+
});
|
52
|
+
client.once('socket', (socket) => {
|
53
|
+
(0, count_target_bytes_1.countTargetBytes)(request.socket, socket);
|
54
|
+
});
|
55
|
+
// Can't use pipeline here as it automatically destroys the streams
|
56
|
+
request.pipe(client);
|
57
|
+
client.on('error', (error) => {
|
58
|
+
var _a;
|
59
|
+
if (response.headersSent) {
|
60
|
+
return;
|
61
|
+
}
|
62
|
+
const statusCode = (_a = statuses_1.errorCodeToStatusCode[error.code]) !== null && _a !== void 0 ? _a : statuses_1.badGatewayStatusCodes.GENERIC_ERROR;
|
63
|
+
response.statusCode = statusCode;
|
64
|
+
response.setHeader('content-type', 'text/plain; charset=utf-8');
|
65
|
+
response.end(http_1.default.STATUS_CODES[response.statusCode]);
|
66
|
+
resolve();
|
67
|
+
});
|
68
|
+
});
|
69
|
+
exports.forwardSocks = forwardSocks;
|
70
|
+
//# sourceMappingURL=forward_socks.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"forward_socks.js","sourceRoot":"","sources":["../src/forward_socks.ts"],"names":[],"mappings":";;;;AAAA,wDAAwB;AACxB,4DAA4B;AAC5B,wDAAwB;AAExB,yDAAoD;AACpD,mEAA8D;AAC9D,mEAA8D;AAC9D,yCAA0E;AAE1E,MAAM,QAAQ,GAAG,cAAI,CAAC,SAAS,CAAC,gBAAM,CAAC,QAAQ,CAAC,CAAC;AAgBjD;;;;;GAKG;AACI,MAAM,YAAY,GAAG,KAAK,EAC7B,OAA6B,EAC7B,QAA6B,EAC7B,WAAwB,EAEX,EAAE,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;IACtD,MAAM,KAAK,GAAG,IAAI,mCAAe,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC;IAEtE,MAAM,OAAO,GAAY;QACrB,MAAM,EAAE,OAAO,CAAC,MAAO;QACvB,OAAO,EAAE,IAAA,qCAAgB,EAAC,OAAO,CAAC,UAAU,CAAC;QAC7C,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,WAAW,CAAC,YAAY;QACtC,KAAK;KACR,CAAC;IAEF,gFAAgF;IAChF,gFAAgF;IAChF,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAI,EAAE,OAA4C,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;QAC7G,IAAI;YACA,yDAAyD;YACzD,IAAI,UAAU,GAAG,cAAc,CAAC,UAAW,CAAC;YAC5C,IAAI,UAAU,GAAG,GAAG,IAAI,UAAU,GAAG,GAAG,EAAE;gBACtC,UAAU,GAAG,gCAAqB,CAAC,wBAAwB,CAAC;aAC/D;YAED,4BAA4B;YAC5B,IAAI,cAAc,CAAC,UAAU,KAAK,GAAG,EAAE;gBACnC,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;gBACvD,OAAO;aACV;YAED,QAAQ,CAAC,SAAS,CACd,UAAU,EACV,cAAc,CAAC,aAAa,EAC5B,IAAA,qCAAgB,EAAC,cAAc,CAAC,UAAU,CAAC,CAC9C,CAAC;YAEF,2DAA2D;YAC3D,MAAM,QAAQ,CACV,cAAc,EACd,QAAQ,CACX,CAAC;YAEF,OAAO,EAAE,CAAC;SACb;QAAC,OAAO,KAAK,EAAE;YACZ,+DAA+D;YAC/D,OAAO,EAAE,CAAC;SACb;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;QAC7B,IAAA,qCAAgB,EAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,mEAAmE;IACnE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;;QAChD,IAAI,QAAQ,CAAC,WAAW,EAAE;YACtB,OAAO;SACV;QAED,MAAM,UAAU,GAAG,MAAA,gCAAqB,CAAC,KAAK,CAAC,IAAK,CAAC,mCAAI,gCAAqB,CAAC,aAAa,CAAC;QAE7F,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;QACjC,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,2BAA2B,CAAC,CAAC;QAChE,QAAQ,CAAC,GAAG,CAAC,cAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QAErD,OAAO,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAtEU,QAAA,YAAY,gBAsEtB"}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const tslib_1 = require("tslib");
|
4
|
+
tslib_1.__exportStar(require("./request_error"), exports);
|
5
|
+
tslib_1.__exportStar(require("./server"), exports);
|
6
|
+
tslib_1.__exportStar(require("./utils/redact_url"), exports);
|
7
|
+
tslib_1.__exportStar(require("./anonymize_proxy"), exports);
|
8
|
+
tslib_1.__exportStar(require("./tcp_tunnel_tools"), exports);
|
9
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC;AAChC,mDAAyB;AACzB,6DAAmC;AACnC,4DAAkC;AAClC,6DAAmC"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/**
|
2
|
+
* Represents custom request error. The message is emitted as HTTP response
|
3
|
+
* with a specific HTTP code and headers.
|
4
|
+
* If this error is thrown from the `prepareRequestFunction` function,
|
5
|
+
* the message and status code is sent to client.
|
6
|
+
* By default, the response will have Content-Type: text/plain
|
7
|
+
* and for the 407 status the Proxy-Authenticate header will be added.
|
8
|
+
*/
|
9
|
+
export declare class RequestError extends Error {
|
10
|
+
statusCode: number;
|
11
|
+
headers?: Record<string, string> | undefined;
|
12
|
+
constructor(message: string, statusCode: number, headers?: Record<string, string> | undefined);
|
13
|
+
}
|
14
|
+
//# sourceMappingURL=request_error.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"request_error.d.ts","sourceRoot":"","sources":["../src/request_error.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,qBAAa,YAAa,SAAQ,KAAK;IAGxB,UAAU,EAAE,MAAM;IAClB,OAAO,CAAC;gBAFf,OAAO,EAAE,MAAM,EACR,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,oCAAwB;CAO9C"}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.RequestError = void 0;
|
4
|
+
/**
|
5
|
+
* Represents custom request error. The message is emitted as HTTP response
|
6
|
+
* with a specific HTTP code and headers.
|
7
|
+
* If this error is thrown from the `prepareRequestFunction` function,
|
8
|
+
* the message and status code is sent to client.
|
9
|
+
* By default, the response will have Content-Type: text/plain
|
10
|
+
* and for the 407 status the Proxy-Authenticate header will be added.
|
11
|
+
*/
|
12
|
+
class RequestError extends Error {
|
13
|
+
constructor(message, statusCode, headers) {
|
14
|
+
super(message);
|
15
|
+
Object.defineProperty(this, "statusCode", {
|
16
|
+
enumerable: true,
|
17
|
+
configurable: true,
|
18
|
+
writable: true,
|
19
|
+
value: statusCode
|
20
|
+
});
|
21
|
+
Object.defineProperty(this, "headers", {
|
22
|
+
enumerable: true,
|
23
|
+
configurable: true,
|
24
|
+
writable: true,
|
25
|
+
value: headers
|
26
|
+
});
|
27
|
+
this.name = RequestError.name;
|
28
|
+
Error.captureStackTrace(this, RequestError);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
exports.RequestError = RequestError;
|
32
|
+
//# sourceMappingURL=request_error.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"request_error.js","sourceRoot":"","sources":["../src/request_error.ts"],"names":[],"mappings":";;;AAAA;;;;;;;GAOG;AACH,MAAa,YAAa,SAAQ,KAAK;IACnC,YACI,OAAe,EACR,UAAkB,EAClB,OAAgC;QAEvC,KAAK,CAAC,OAAO,CAAC,CAAC;;;;;mBAHR;;;;;;mBACA;;QAGP,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;QAE9B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC;CACJ;AAXD,oCAWC"}
|
package/dist/server.d.ts
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
/// <reference types="node" />
|
3
|
+
/// <reference types="node" />
|
4
|
+
/// <reference types="node" />
|
5
|
+
/// <reference types="node" />
|
6
|
+
/// <reference types="node" />
|
7
|
+
/// <reference types="node" />
|
8
|
+
import dns from 'dns';
|
9
|
+
import http from 'http';
|
10
|
+
import { URL } from 'url';
|
11
|
+
import { EventEmitter } from 'events';
|
12
|
+
import { Buffer } from 'buffer';
|
13
|
+
import { HandlerOpts as CustomResponseOpts } from './custom_response';
|
14
|
+
import { Socket } from './socket';
|
15
|
+
export declare const SOCKS_PROTOCOLS: string[];
|
16
|
+
export type ConnectionStats = {
|
17
|
+
srcTxBytes: number;
|
18
|
+
srcRxBytes: number;
|
19
|
+
trgTxBytes: number | null;
|
20
|
+
trgRxBytes: number | null;
|
21
|
+
};
|
22
|
+
type HandlerOpts = {
|
23
|
+
server: Server;
|
24
|
+
id: number;
|
25
|
+
srcRequest: http.IncomingMessage;
|
26
|
+
srcResponse: http.ServerResponse | null;
|
27
|
+
srcHead: Buffer | null;
|
28
|
+
trgParsed: URL | null;
|
29
|
+
upstreamProxyUrlParsed: URL | null;
|
30
|
+
isHttp: boolean;
|
31
|
+
customResponseFunction?: CustomResponseOpts['customResponseFunction'] | null;
|
32
|
+
customConnectServer?: http.Server | null;
|
33
|
+
localAddress?: string;
|
34
|
+
ipFamily?: number;
|
35
|
+
dnsLookup?: typeof dns['lookup'];
|
36
|
+
customTag?: unknown;
|
37
|
+
};
|
38
|
+
export type PrepareRequestFunctionOpts = {
|
39
|
+
connectionId: number;
|
40
|
+
request: http.IncomingMessage;
|
41
|
+
username: string;
|
42
|
+
password: string;
|
43
|
+
hostname: string;
|
44
|
+
port: number;
|
45
|
+
isHttp: boolean;
|
46
|
+
};
|
47
|
+
export type PrepareRequestFunctionResult = {
|
48
|
+
customResponseFunction?: CustomResponseOpts['customResponseFunction'];
|
49
|
+
customConnectServer?: http.Server | null;
|
50
|
+
requestAuthentication?: boolean;
|
51
|
+
failMsg?: string;
|
52
|
+
upstreamProxyUrl?: string | null;
|
53
|
+
localAddress?: string;
|
54
|
+
ipFamily?: number;
|
55
|
+
dnsLookup?: typeof dns['lookup'];
|
56
|
+
customTag?: unknown;
|
57
|
+
};
|
58
|
+
type Promisable<T> = T | Promise<T>;
|
59
|
+
export type PrepareRequestFunction = (opts: PrepareRequestFunctionOpts) => Promisable<undefined | PrepareRequestFunctionResult>;
|
60
|
+
/**
|
61
|
+
* Represents the proxy server.
|
62
|
+
* It emits the 'requestFailed' event on unexpected request errors, with the following parameter `{ error, request }`.
|
63
|
+
* It emits the 'connectionClosed' event when connection to proxy server is closed, with parameter `{ connectionId, stats }`.
|
64
|
+
*/
|
65
|
+
export declare class Server extends EventEmitter {
|
66
|
+
port: number;
|
67
|
+
host?: string;
|
68
|
+
prepareRequestFunction?: PrepareRequestFunction;
|
69
|
+
authRealm: unknown;
|
70
|
+
verbose: boolean;
|
71
|
+
server: http.Server;
|
72
|
+
lastHandlerId: number;
|
73
|
+
stats: {
|
74
|
+
httpRequestCount: number;
|
75
|
+
connectRequestCount: number;
|
76
|
+
};
|
77
|
+
connections: Map<number, Socket>;
|
78
|
+
/**
|
79
|
+
* Initializes a new instance of Server class.
|
80
|
+
* @param options
|
81
|
+
* @param [options.port] Port where the server will listen. By default 8000.
|
82
|
+
* @param [options.prepareRequestFunction] Custom function to authenticate proxy requests,
|
83
|
+
* provide URL to upstream proxy or potentially provide a function that generates a custom response to HTTP requests.
|
84
|
+
* It accepts a single parameter which is an object:
|
85
|
+
* ```
|
86
|
+
* {
|
87
|
+
* connectionId: symbol,
|
88
|
+
* request: http.IncomingMessage,
|
89
|
+
* username: string,
|
90
|
+
* password: string,
|
91
|
+
* hostname: string,
|
92
|
+
* port: number,
|
93
|
+
* isHttp: boolean,
|
94
|
+
* }
|
95
|
+
* ```
|
96
|
+
* and returns an object (or promise resolving to the object) with following form:
|
97
|
+
* ```
|
98
|
+
* {
|
99
|
+
* requestAuthentication: boolean,
|
100
|
+
* upstreamProxyUrl: string,
|
101
|
+
* customResponseFunction: Function,
|
102
|
+
* }
|
103
|
+
* ```
|
104
|
+
* If `upstreamProxyUrl` is a falsy value, no upstream proxy is used.
|
105
|
+
* If `prepareRequestFunction` is not set, the proxy server will not require any authentication
|
106
|
+
* and will not use any upstream proxy.
|
107
|
+
* If `customResponseFunction` is set, it will be called to generate a custom response to the HTTP request.
|
108
|
+
* It should not be used together with `upstreamProxyUrl`.
|
109
|
+
* @param [options.authRealm] Realm used in the Proxy-Authenticate header and also in the 'Server' HTTP header. By default it's `ProxyChain`.
|
110
|
+
* @param [options.verbose] If true, the server will output logs
|
111
|
+
*/
|
112
|
+
constructor(options?: {
|
113
|
+
port?: number;
|
114
|
+
host?: string;
|
115
|
+
prepareRequestFunction?: PrepareRequestFunction;
|
116
|
+
verbose?: boolean;
|
117
|
+
authRealm?: unknown;
|
118
|
+
});
|
119
|
+
log(connectionId: unknown, str: string): void;
|
120
|
+
onClientError(err: NodeJS.ErrnoException, socket: Socket): void;
|
121
|
+
/**
|
122
|
+
* Assigns a unique ID to the socket and keeps the register up to date.
|
123
|
+
* Needed for abrupt close of the server.
|
124
|
+
*/
|
125
|
+
registerConnection(socket: Socket): void;
|
126
|
+
/**
|
127
|
+
* Handles incoming sockets, useful for error handling
|
128
|
+
*/
|
129
|
+
onConnection(socket: Socket): void;
|
130
|
+
/**
|
131
|
+
* Converts known errors to be instance of RequestError.
|
132
|
+
*/
|
133
|
+
normalizeHandlerError(error: NodeJS.ErrnoException): NodeJS.ErrnoException;
|
134
|
+
/**
|
135
|
+
* Handles normal HTTP request by forwarding it to target host or the upstream proxy.
|
136
|
+
*/
|
137
|
+
onRequest(request: http.IncomingMessage, response: http.ServerResponse): Promise<void>;
|
138
|
+
/**
|
139
|
+
* Handles HTTP CONNECT request by setting up a tunnel either to target host or to the upstream proxy.
|
140
|
+
* @param request
|
141
|
+
* @param socket
|
142
|
+
* @param head The first packet of the tunneling stream (may be empty)
|
143
|
+
*/
|
144
|
+
onConnect(request: http.IncomingMessage, socket: Socket, head: Buffer): Promise<void>;
|
145
|
+
/**
|
146
|
+
* Prepares handler options from a request.
|
147
|
+
* @see {prepareRequestHandling}
|
148
|
+
*/
|
149
|
+
getHandlerOpts(request: http.IncomingMessage): HandlerOpts;
|
150
|
+
/**
|
151
|
+
* Calls `this.prepareRequestFunction` with normalized options.
|
152
|
+
* @param request
|
153
|
+
* @param handlerOpts
|
154
|
+
*/
|
155
|
+
callPrepareRequestFunction(request: http.IncomingMessage, handlerOpts: HandlerOpts): Promise<PrepareRequestFunctionResult>;
|
156
|
+
/**
|
157
|
+
* Authenticates a new request and determines upstream proxy URL using the user function.
|
158
|
+
* Returns a promise resolving to an object that can be used to run a handler.
|
159
|
+
* @param request
|
160
|
+
*/
|
161
|
+
prepareRequestHandling(request: http.IncomingMessage): Promise<HandlerOpts>;
|
162
|
+
/**
|
163
|
+
* Sends a HTTP error response to the client.
|
164
|
+
* @param request
|
165
|
+
* @param error
|
166
|
+
*/
|
167
|
+
failRequest(request: http.IncomingMessage, error: NodeJS.ErrnoException): void;
|
168
|
+
/**
|
169
|
+
* Sends a simple HTTP response to the client and forcibly closes the connection.
|
170
|
+
* This invalidates the ServerResponse instance (if present).
|
171
|
+
* We don't know the state of the response anyway.
|
172
|
+
* Writing directly to the socket seems to be the easiest solution.
|
173
|
+
* @param socket
|
174
|
+
* @param statusCode
|
175
|
+
* @param headers
|
176
|
+
* @param message
|
177
|
+
*/
|
178
|
+
sendSocketResponse(socket: Socket, statusCode?: number, caseSensitiveHeaders?: {}, message?: string): void;
|
179
|
+
/**
|
180
|
+
* Starts listening at a port specified in the constructor.
|
181
|
+
*/
|
182
|
+
listen(callback?: (error: NodeJS.ErrnoException | null) => void): Promise<void>;
|
183
|
+
/**
|
184
|
+
* Gets array of IDs of all active connections.
|
185
|
+
*/
|
186
|
+
getConnectionIds(): number[];
|
187
|
+
/**
|
188
|
+
* Gets data transfer statistics of a specific proxy connection.
|
189
|
+
*/
|
190
|
+
getConnectionStats(connectionId: number): ConnectionStats | undefined;
|
191
|
+
/**
|
192
|
+
* Forcibly close a specific pending proxy connection.
|
193
|
+
*/
|
194
|
+
closeConnection(connectionId: number): void;
|
195
|
+
/**
|
196
|
+
* Forcibly closes pending proxy connections.
|
197
|
+
*/
|
198
|
+
closeConnections(): void;
|
199
|
+
/**
|
200
|
+
* Closes the proxy server.
|
201
|
+
* @param closeConnections If true, pending proxy connections are forcibly closed.
|
202
|
+
*/
|
203
|
+
close(closeConnections: boolean, callback?: (error: NodeJS.ErrnoException | null) => void): Promise<void>;
|
204
|
+
}
|
205
|
+
export {};
|
206
|
+
//# sourceMappingURL=server.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|