@push.rocks/smartproxy 3.0.58
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/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +4 -0
- package/dist_ts/smartproxy.classes.networkproxy.d.ts +30 -0
- package/dist_ts/smartproxy.classes.networkproxy.js +327 -0
- package/dist_ts/smartproxy.classes.router.d.ts +14 -0
- package/dist_ts/smartproxy.classes.router.js +24 -0
- package/dist_ts/smartproxy.classes.sslredirect.d.ts +9 -0
- package/dist_ts/smartproxy.classes.sslredirect.js +28 -0
- package/dist_ts/smartproxy.plugins.d.ts +16 -0
- package/dist_ts/smartproxy.plugins.js +21 -0
- package/dist_ts/smartproxy.portproxy.d.ts +10 -0
- package/dist_ts/smartproxy.portproxy.js +64 -0
- package/license +19 -0
- package/npmextra.json +18 -0
- package/package.json +49 -0
- package/readme.md +41 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/index.ts +3 -0
- package/ts/smartproxy.classes.networkproxy.ts +372 -0
- package/ts/smartproxy.classes.router.ts +24 -0
- package/ts/smartproxy.classes.sslredirect.ts +32 -0
- package/ts/smartproxy.plugins.ts +27 -0
- package/ts/smartproxy.portproxy.ts +70 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* autocreated commitinfo by @pushrocks/commitinfo
|
|
3
|
+
*/
|
|
4
|
+
export const commitinfo = {
|
|
5
|
+
name: '@pushrocks/smartproxy',
|
|
6
|
+
version: '3.0.58',
|
|
7
|
+
description: 'a proxy for handling high workloads of proxying'
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx1QkFBdUI7SUFDN0IsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLGlEQUFpRDtDQUMvRCxDQUFBIn0=
|
package/dist_ts/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './smartproxy.classes.networkproxy.js';
|
|
2
|
+
export * from './smartproxy.portproxy.js';
|
|
3
|
+
export * from './smartproxy.classes.sslredirect.js';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHNDQUFzQyxDQUFDO0FBQ3JELGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYyxxQ0FBcUMsQ0FBQSJ9
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
4
|
+
import { ProxyRouter } from './smartproxy.classes.router.js';
|
|
5
|
+
export interface INetworkProxyOptions {
|
|
6
|
+
port: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class NetworkProxy {
|
|
9
|
+
options: INetworkProxyOptions;
|
|
10
|
+
proxyConfigs: plugins.tsclass.network.IReverseProxyConfig[];
|
|
11
|
+
httpsServer: plugins.https.Server;
|
|
12
|
+
router: ProxyRouter;
|
|
13
|
+
socketMap: plugins.lik.ObjectMap<plugins.net.Socket>;
|
|
14
|
+
defaultHeaders: {
|
|
15
|
+
[key: string]: string;
|
|
16
|
+
};
|
|
17
|
+
alreadyAddedReverseConfigs: {
|
|
18
|
+
[hostName: string]: plugins.tsclass.network.IReverseProxyConfig;
|
|
19
|
+
};
|
|
20
|
+
constructor(optionsArg: INetworkProxyOptions);
|
|
21
|
+
/**
|
|
22
|
+
* starts the proxyInstance
|
|
23
|
+
*/
|
|
24
|
+
start(): Promise<void>;
|
|
25
|
+
updateProxyConfigs(proxyConfigsArg: plugins.tsclass.network.IReverseProxyConfig[]): Promise<void>;
|
|
26
|
+
addDefaultHeaders(headersArg: {
|
|
27
|
+
[key: string]: string;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
stop(): Promise<void>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
2
|
+
import { ProxyRouter } from './smartproxy.classes.router.js';
|
|
3
|
+
export class NetworkProxy {
|
|
4
|
+
constructor(optionsArg) {
|
|
5
|
+
this.proxyConfigs = [];
|
|
6
|
+
this.router = new ProxyRouter();
|
|
7
|
+
this.socketMap = new plugins.lik.ObjectMap();
|
|
8
|
+
this.defaultHeaders = {};
|
|
9
|
+
this.alreadyAddedReverseConfigs = {};
|
|
10
|
+
this.options = optionsArg;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* starts the proxyInstance
|
|
14
|
+
*/
|
|
15
|
+
async start() {
|
|
16
|
+
this.httpsServer = plugins.https.createServer(
|
|
17
|
+
// ================
|
|
18
|
+
// Spotted this keypair in the code?
|
|
19
|
+
// Don't get exited:
|
|
20
|
+
// It is an invalid default keypair.
|
|
21
|
+
// For proper requests custom domain level keypairs are used that are provided in the reverse config
|
|
22
|
+
// ================
|
|
23
|
+
{
|
|
24
|
+
key: `-----BEGIN PRIVATE KEY-----
|
|
25
|
+
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
|
|
74
|
+
2TkK01XDDJURK5Lhuvc7WrK2rSJ/fK+0GA==
|
|
75
|
+
-----END PRIVATE KEY-----
|
|
76
|
+
`,
|
|
77
|
+
cert: `-----BEGIN CERTIFICATE-----
|
|
78
|
+
MIIEljCCAn4CCQDY+ZbC9FASVjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJE
|
|
79
|
+
RTAeFw0xOTA5MjAxNjAxNDRaFw0yMDA5MTkxNjAxNDRaMA0xCzAJBgNVBAYTAkRF
|
|
80
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4thf9JEK/epoXt8hFr8t
|
|
81
|
+
pkRzmaEkgbSKoOga3uGXDLvdNf3BzSIxZ8pzRhZfUnutcmW1thdz3wre/pEJR7oN
|
|
82
|
+
QsfixbLL8/oS5QeXKiUGX0Ssfdg4W0TsoLcRva+1AZsf38MfiUPhzh1/UW/rMywW
|
|
83
|
+
asazQwRZdkkXb4nKJ2IFZx22qnAD4/5Sug+sfeKoFBF/rzI2yK7rognt7kW2LHv6
|
|
84
|
+
rswHnZ1Z2P/gbhlZ/EhG9hFVRZwRLDscWKcuWcxkePDt2J1pDNqD6SYa6ZjGC3AE
|
|
85
|
+
TJw5iEA1bLQ9YvjDNpVYcf6ZvcSilIFjSQu5cs9sUbHGeKTrS5HzfeJXh1PfJyL8
|
|
86
|
+
X0Hu7UBSjfSudso3baE9FGiBFBW2cnXZKDZGtV8eq/qxPetOOgS09pVbNP6508WV
|
|
87
|
+
BR+rz98/VDZLZqcbZ2UpOuz4+kAKmbYE9GplxKQZZO7wWEox7Mid/uUdcqEo4QKn
|
|
88
|
+
no6ujOuzQzn5a2oOS0k5Hk3uHapNJWlW9YI3LHtfADpYH+6cOR+/c3JWBzQJ6AD7
|
|
89
|
+
muvNzA9mWXeHqLxMMP4pkmb7otzZYrEkodUqJgAQxcYhGh6XsCPfJ/D9RN734OJc
|
|
90
|
+
gleVXFI8Kz455HxCW19XNfz16k7T6kqhZ/6SOBbkxEuqg7oEthAP109ZZzgx4oDo
|
|
91
|
+
hQsw24TjLkI4SPIc7nr60UUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAu0+zrg0C
|
|
92
|
+
mlSv4Yi24OwB7TBvx+WHesl1IilCUdTiiUMo3NumvsU9Dr3Jkd0jGqYI0eyH4gIt
|
|
93
|
+
KrhAveXfEw7tAOEHiYicmAdIFtyzh++ZWb8mgbBeqij1MP/76Jv+cc0lUqpfRo/A
|
|
94
|
+
qytAsPAILuyL1o1jh28JHcq+v+WYn/FEhjUlH6emhGKGlsAjhUPjzK8MEshNolhj
|
|
95
|
+
t2UXw9WB5B2xWvrqlNMy0F3NAZBkZ/+k21HZo6FmVi+q6OEGcOo7wJt6wrH/lko9
|
|
96
|
+
LxX96GC1JoN1Pfr2FoTKy1WHzrSfyGmDIUCrbaYQ58UuMOR+5eIPPdkf/030u5eX
|
|
97
|
+
xXhF2fBujD57E2zQGh/l2MrOjamcSo0+wYhOqlX3WNdaKNAzPqloBnF6w7eqLYde
|
|
98
|
+
h9He39ySmxjENwv3miOjEP1sBeMBSRfL/ckEonfK5uJgYA5nVMQ3ojUeDMZzLfFE
|
|
99
|
+
Ue2WHt+uPyYk7mMZfOrK2uHzI2/Coqj7lbfRodFwj+fCArYBck2NZannDPKA6X8V
|
|
100
|
+
TzJTbTCteOUUJTrcfZ0gGhGkF4nYLmX5OI+TPqrDJf0fZ+mzAEHzDDVXcBYpYRDr
|
|
101
|
+
r8d9QwrK+WaqVi2ofbMfMByVF72jgeJNa4nxwT9bVbu/Q1T2Lt+YPb4pQ7yCoUgS
|
|
102
|
+
JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
103
|
+
-----END CERTIFICATE-----
|
|
104
|
+
`,
|
|
105
|
+
}, async (originRequest, originResponse) => {
|
|
106
|
+
/**
|
|
107
|
+
* endRequest function
|
|
108
|
+
* can be used to prematurely end a request
|
|
109
|
+
*/
|
|
110
|
+
const endOriginReqRes = (statusArg = 404, messageArg = 'This route is not available on this server.', headers = {}) => {
|
|
111
|
+
originResponse.writeHead(statusArg, messageArg);
|
|
112
|
+
originResponse.end(messageArg);
|
|
113
|
+
if (originRequest.socket !== originResponse.socket) {
|
|
114
|
+
console.log('hey, something is strange.');
|
|
115
|
+
}
|
|
116
|
+
originResponse.destroy();
|
|
117
|
+
};
|
|
118
|
+
console.log(`got request: ${originRequest.headers.host}${plugins.url.parse(originRequest.url).path}`);
|
|
119
|
+
const destinationConfig = this.router.routeReq(originRequest);
|
|
120
|
+
if (!destinationConfig) {
|
|
121
|
+
console.log(`${originRequest.headers.host} can't be routed properly. Terminating request.`);
|
|
122
|
+
endOriginReqRes();
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// authentication
|
|
126
|
+
if (destinationConfig.authentication) {
|
|
127
|
+
const authInfo = destinationConfig.authentication;
|
|
128
|
+
switch (authInfo.type) {
|
|
129
|
+
case 'Basic':
|
|
130
|
+
const authHeader = originRequest.headers.authorization;
|
|
131
|
+
if (authHeader) {
|
|
132
|
+
if (!authHeader.includes('Basic ')) {
|
|
133
|
+
return endOriginReqRes(401, 'Authentication required', {
|
|
134
|
+
'WWW-Authenticate': 'Basic realm="Access to the staging site", charset="UTF-8"',
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const authStringBase64 = originRequest.headers.authorization.replace('Basic ', '');
|
|
138
|
+
const authString = plugins.smartstring.base64.decode(authStringBase64);
|
|
139
|
+
const userPassArray = authString.split(':');
|
|
140
|
+
const user = userPassArray[0];
|
|
141
|
+
const pass = userPassArray[1];
|
|
142
|
+
if (user === authInfo.user && pass === authInfo.pass) {
|
|
143
|
+
console.log('request successfully authenticated');
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
return endOriginReqRes(403, 'Forbidden: Wrong credentials');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
break;
|
|
150
|
+
default:
|
|
151
|
+
return endOriginReqRes(403, 'Forbidden: unsupported authentication method configured. Please report to the admin.');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
let destinationUrl;
|
|
155
|
+
if (destinationConfig) {
|
|
156
|
+
destinationUrl = `http://${destinationConfig.destinationIp}:${destinationConfig.destinationPort}${originRequest.url}`;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
return endOriginReqRes();
|
|
160
|
+
}
|
|
161
|
+
console.log(destinationUrl);
|
|
162
|
+
const proxyResponse = await plugins.smartrequest.request(destinationUrl, {
|
|
163
|
+
method: originRequest.method,
|
|
164
|
+
headers: {
|
|
165
|
+
...originRequest.headers,
|
|
166
|
+
'X-Forwarded-Host': originRequest.headers.host,
|
|
167
|
+
'X-Forwarded-Proto': 'https'
|
|
168
|
+
},
|
|
169
|
+
keepAlive: true,
|
|
170
|
+
}, true, // lets make this streaming
|
|
171
|
+
(proxyRequest) => {
|
|
172
|
+
originRequest.on('data', (data) => {
|
|
173
|
+
proxyRequest.write(data);
|
|
174
|
+
});
|
|
175
|
+
originRequest.on('end', (data) => {
|
|
176
|
+
proxyRequest.end();
|
|
177
|
+
});
|
|
178
|
+
originRequest.on('error', () => {
|
|
179
|
+
proxyRequest.end();
|
|
180
|
+
});
|
|
181
|
+
originRequest.on('close', () => {
|
|
182
|
+
proxyRequest.end();
|
|
183
|
+
});
|
|
184
|
+
originRequest.on('timeout', () => {
|
|
185
|
+
proxyRequest.end();
|
|
186
|
+
originRequest.destroy();
|
|
187
|
+
});
|
|
188
|
+
proxyRequest.on('error', () => {
|
|
189
|
+
endOriginReqRes();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
originResponse.statusCode = proxyResponse.statusCode;
|
|
193
|
+
console.log(proxyResponse.statusCode);
|
|
194
|
+
for (const defaultHeader of Object.keys(this.defaultHeaders)) {
|
|
195
|
+
originResponse.setHeader(defaultHeader, this.defaultHeaders[defaultHeader]);
|
|
196
|
+
}
|
|
197
|
+
for (const header of Object.keys(proxyResponse.headers)) {
|
|
198
|
+
originResponse.setHeader(header, proxyResponse.headers[header]);
|
|
199
|
+
}
|
|
200
|
+
proxyResponse.on('data', (data) => {
|
|
201
|
+
originResponse.write(data);
|
|
202
|
+
});
|
|
203
|
+
proxyResponse.on('end', () => {
|
|
204
|
+
originResponse.end();
|
|
205
|
+
});
|
|
206
|
+
proxyResponse.on('error', () => {
|
|
207
|
+
originResponse.destroy();
|
|
208
|
+
});
|
|
209
|
+
proxyResponse.on('close', () => {
|
|
210
|
+
originResponse.end();
|
|
211
|
+
});
|
|
212
|
+
proxyResponse.on('timeout', () => {
|
|
213
|
+
originResponse.end();
|
|
214
|
+
originResponse.destroy();
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
// Enable websockets
|
|
218
|
+
const wsServer = new plugins.ws.WebSocketServer({ server: this.httpsServer });
|
|
219
|
+
wsServer.on('connection', async (wsIncoming, reqArg) => {
|
|
220
|
+
console.log(`wss proxy: got connection for wsc for https://${reqArg.headers.host}${reqArg.url}`);
|
|
221
|
+
let wsOutgoing;
|
|
222
|
+
const outGoingDeferred = plugins.smartpromise.defer();
|
|
223
|
+
try {
|
|
224
|
+
wsOutgoing = new plugins.wsDefault(`ws://${this.router.routeReq(reqArg).destinationIp}:${this.router.routeReq(reqArg).destinationPort}${reqArg.url}`);
|
|
225
|
+
console.log('wss proxy: initiated outgoing proxy');
|
|
226
|
+
wsOutgoing.on('open', async () => {
|
|
227
|
+
outGoingDeferred.resolve();
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
console.log(err);
|
|
232
|
+
wsIncoming.terminate();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
wsIncoming.on("message", async (message, isBinary) => {
|
|
236
|
+
await outGoingDeferred.promise;
|
|
237
|
+
// console.log("client to upstream", message);
|
|
238
|
+
wsOutgoing.send(message, { binary: isBinary });
|
|
239
|
+
});
|
|
240
|
+
wsOutgoing.on("message", async (message, isBinary) => {
|
|
241
|
+
// console.log("upstream to client", message);
|
|
242
|
+
wsIncoming.send(message, { binary: isBinary });
|
|
243
|
+
});
|
|
244
|
+
const terminateWsOutgoing = () => {
|
|
245
|
+
wsOutgoing.terminate();
|
|
246
|
+
console.log('terminated outgoing ws.');
|
|
247
|
+
};
|
|
248
|
+
wsIncoming.on("error", () => terminateWsOutgoing());
|
|
249
|
+
wsIncoming.on("close", () => terminateWsOutgoing());
|
|
250
|
+
const terminateWsIncoming = () => {
|
|
251
|
+
wsIncoming.terminate();
|
|
252
|
+
console.log('terminated incoming ws.');
|
|
253
|
+
};
|
|
254
|
+
wsOutgoing.on("error", () => terminateWsIncoming());
|
|
255
|
+
wsOutgoing.on("close", () => terminateWsIncoming());
|
|
256
|
+
});
|
|
257
|
+
this.httpsServer.keepAliveTimeout = 600 * 1000;
|
|
258
|
+
this.httpsServer.headersTimeout = 600 * 1000;
|
|
259
|
+
this.httpsServer.on('connection', (connection) => {
|
|
260
|
+
this.socketMap.add(connection);
|
|
261
|
+
console.log(`added connection. now ${this.socketMap.getArray().length} sockets connected.`);
|
|
262
|
+
const cleanupConnection = () => {
|
|
263
|
+
if (this.socketMap.checkForObject(connection)) {
|
|
264
|
+
this.socketMap.remove(connection);
|
|
265
|
+
console.log(`removed connection. ${this.socketMap.getArray().length} sockets remaining.`);
|
|
266
|
+
connection.destroy();
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
connection.on('close', () => {
|
|
270
|
+
cleanupConnection();
|
|
271
|
+
});
|
|
272
|
+
connection.on('error', () => {
|
|
273
|
+
cleanupConnection();
|
|
274
|
+
});
|
|
275
|
+
connection.on('end', () => {
|
|
276
|
+
cleanupConnection();
|
|
277
|
+
});
|
|
278
|
+
connection.on('timeout', () => {
|
|
279
|
+
cleanupConnection();
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
this.httpsServer.listen(this.options.port);
|
|
283
|
+
console.log(`NetworkProxy -> OK: now listening for new connections on port ${this.options.port}`);
|
|
284
|
+
}
|
|
285
|
+
async updateProxyConfigs(proxyConfigsArg) {
|
|
286
|
+
console.log(`got new proxy configs`);
|
|
287
|
+
this.proxyConfigs = proxyConfigsArg;
|
|
288
|
+
this.router.setNewProxyConfigs(proxyConfigsArg);
|
|
289
|
+
for (const hostCandidate of this.proxyConfigs) {
|
|
290
|
+
// console.log(hostCandidate);
|
|
291
|
+
const existingHostNameConfig = this.alreadyAddedReverseConfigs[hostCandidate.hostName];
|
|
292
|
+
if (!existingHostNameConfig) {
|
|
293
|
+
this.alreadyAddedReverseConfigs[hostCandidate.hostName] = hostCandidate;
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
if (existingHostNameConfig.publicKey === hostCandidate.publicKey &&
|
|
297
|
+
existingHostNameConfig.privateKey === hostCandidate.privateKey) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
this.alreadyAddedReverseConfigs[hostCandidate.hostName] = hostCandidate;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
this.httpsServer.addContext(hostCandidate.hostName, {
|
|
305
|
+
cert: hostCandidate.publicKey,
|
|
306
|
+
key: hostCandidate.privateKey,
|
|
307
|
+
});
|
|
308
|
+
this.httpsServer;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
async addDefaultHeaders(headersArg) {
|
|
312
|
+
for (const headerKey of Object.keys(headersArg)) {
|
|
313
|
+
this.defaultHeaders[headerKey] = headersArg[headerKey];
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
async stop() {
|
|
317
|
+
const done = plugins.smartpromise.defer();
|
|
318
|
+
this.httpsServer.close(() => {
|
|
319
|
+
done.resolve();
|
|
320
|
+
});
|
|
321
|
+
await this.socketMap.forEach(async (socket) => {
|
|
322
|
+
socket.destroy();
|
|
323
|
+
});
|
|
324
|
+
await done.promise;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRwcm94eS5jbGFzc2VzLm5ldHdvcmtwcm94eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0cHJveHkuY2xhc3Nlcy5uZXR3b3JrcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSx5QkFBeUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFNN0QsTUFBTSxPQUFPLFlBQVk7SUFhdkIsWUFBWSxVQUFnQztRQVZyQyxpQkFBWSxHQUFrRCxFQUFFLENBQUM7UUFFakUsV0FBTSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFDM0IsY0FBUyxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQXNCLENBQUM7UUFDNUQsbUJBQWMsR0FBOEIsRUFBRSxDQUFDO1FBRS9DLCtCQUEwQixHQUU3QixFQUFFLENBQUM7UUFHTCxJQUFJLENBQUMsT0FBTyxHQUFHLFVBQVUsQ0FBQztJQUM1QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsS0FBSztRQUNoQixJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsWUFBWTtRQUMzQyxtQkFBbUI7UUFDbkIsb0NBQW9DO1FBQ3BDLG9CQUFvQjtRQUNwQixvQ0FBb0M7UUFDcEMsb0dBQW9HO1FBQ3BHLG1CQUFtQjtRQUNuQjtZQUNFLEdBQUcsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQW9EUjtZQUNHLElBQUksRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0tBMkJUO1NBQ0UsRUFDRCxLQUFLLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxFQUFFO1lBQ3RDOzs7ZUFHRztZQUNILE1BQU0sZUFBZSxHQUFHLENBQ3RCLFlBQW9CLEdBQUcsRUFDdkIsYUFBcUIsNkNBQTZDLEVBQ2xFLFVB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
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
3
|
+
export declare class ProxyRouter {
|
|
4
|
+
reverseProxyConfigs: plugins.tsclass.network.IReverseProxyConfig[];
|
|
5
|
+
/**
|
|
6
|
+
* sets a new set of reverse configs to be routed to
|
|
7
|
+
* @param reverseCandidatesArg
|
|
8
|
+
*/
|
|
9
|
+
setNewProxyConfigs(reverseCandidatesArg: plugins.tsclass.network.IReverseProxyConfig[]): void;
|
|
10
|
+
/**
|
|
11
|
+
* routes a request
|
|
12
|
+
*/
|
|
13
|
+
routeReq(req: plugins.http.IncomingMessage): plugins.tsclass.network.IReverseProxyConfig;
|
|
14
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import './smartproxy.plugins.js';
|
|
2
|
+
export class ProxyRouter {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.reverseProxyConfigs = [];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* sets a new set of reverse configs to be routed to
|
|
8
|
+
* @param reverseCandidatesArg
|
|
9
|
+
*/
|
|
10
|
+
setNewProxyConfigs(reverseCandidatesArg) {
|
|
11
|
+
this.reverseProxyConfigs = reverseCandidatesArg;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* routes a request
|
|
15
|
+
*/
|
|
16
|
+
routeReq(req) {
|
|
17
|
+
const originalHost = req.headers.host;
|
|
18
|
+
const correspodingReverseProxyConfig = this.reverseProxyConfigs.find((reverseConfig) => {
|
|
19
|
+
return reverseConfig.hostName === originalHost;
|
|
20
|
+
});
|
|
21
|
+
return correspodingReverseProxyConfig;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRwcm94eS5jbGFzc2VzLnJvdXRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0cHJveHkuY2xhc3Nlcy5yb3V0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBeUIseUJBQXlCLENBQUM7QUFFbkQsTUFBTSxPQUFPLFdBQVc7SUFBeEI7UUFDUyx3QkFBbUIsR0FBa0QsRUFBRSxDQUFDO0lBb0JqRixDQUFDO0lBbEJDOzs7T0FHRztJQUNJLGtCQUFrQixDQUFDLG9CQUFtRTtRQUMzRixJQUFJLENBQUMsbUJBQW1CLEdBQUcsb0JBQW9CLENBQUM7SUFDbEQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksUUFBUSxDQUFDLEdBQWlDO1FBQy9DLE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQ3RDLE1BQU0sOEJBQThCLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDLGFBQWEsRUFBRSxFQUFFO1lBQ3JGLE9BQU8sYUFBYSxDQUFDLFFBQVEsS0FBSyxZQUFZLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLDhCQUE4QixDQUFDO0lBQ3hDLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
3
|
+
export declare class SslRedirect {
|
|
4
|
+
httpServer: plugins.http.Server;
|
|
5
|
+
port: number;
|
|
6
|
+
constructor(portArg: number);
|
|
7
|
+
start(): Promise<void>;
|
|
8
|
+
stop(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
2
|
+
export class SslRedirect {
|
|
3
|
+
constructor(portArg) {
|
|
4
|
+
this.port = portArg;
|
|
5
|
+
}
|
|
6
|
+
async start() {
|
|
7
|
+
this.httpServer = plugins.http.createServer((request, response) => {
|
|
8
|
+
const requestUrl = new URL(request.url, `http://${request.headers.host}`);
|
|
9
|
+
const completeUrlWithoutProtocol = `${requestUrl.host}${requestUrl.pathname}${requestUrl.search}`;
|
|
10
|
+
const redirectUrl = `https://${completeUrlWithoutProtocol}`;
|
|
11
|
+
console.log(`Got http request for http://${completeUrlWithoutProtocol}`);
|
|
12
|
+
console.log(`Redirecting to ${redirectUrl}`);
|
|
13
|
+
response.writeHead(302, {
|
|
14
|
+
Location: redirectUrl,
|
|
15
|
+
});
|
|
16
|
+
response.end();
|
|
17
|
+
});
|
|
18
|
+
this.httpServer.listen(this.port);
|
|
19
|
+
}
|
|
20
|
+
async stop() {
|
|
21
|
+
const done = plugins.smartpromise.defer();
|
|
22
|
+
this.httpServer.close(() => {
|
|
23
|
+
done.resolve();
|
|
24
|
+
});
|
|
25
|
+
await done.promise;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRwcm94eS5jbGFzc2VzLnNzbHJlZGlyZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRwcm94eS5jbGFzc2VzLnNzbHJlZGlyZWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0seUJBQXlCLENBQUM7QUFFbkQsTUFBTSxPQUFPLFdBQVc7SUFHdEIsWUFBWSxPQUFlO1FBQ3pCLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDO0lBQ3RCLENBQUM7SUFFTSxLQUFLLENBQUMsS0FBSztRQUNoQixJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQ2hFLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsVUFBVSxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDMUUsTUFBTSwwQkFBMEIsR0FBRyxHQUFHLFVBQVUsQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbEcsTUFBTSxXQUFXLEdBQUcsV0FBVywwQkFBMEIsRUFBRSxDQUFDO1lBQzVELE9BQU8sQ0FBQyxHQUFHLENBQUMsK0JBQStCLDBCQUEwQixFQUFFLENBQUMsQ0FBQztZQUN6RSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQzdDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUN0QixRQUFRLEVBQUUsV0FBVzthQUN0QixDQUFDLENBQUM7WUFDSCxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDakIsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJO1FBQ2YsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMxQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDekIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3JCLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as http from 'http';
|
|
2
|
+
import * as https from 'https';
|
|
3
|
+
import * as net from 'net';
|
|
4
|
+
import * as url from 'url';
|
|
5
|
+
export { http, https, net, url };
|
|
6
|
+
import * as tsclass from '@tsclass/tsclass';
|
|
7
|
+
export { tsclass };
|
|
8
|
+
import * as lik from '@pushrocks/lik';
|
|
9
|
+
import * as smartdelay from '@pushrocks/smartdelay';
|
|
10
|
+
import * as smartpromise from '@pushrocks/smartpromise';
|
|
11
|
+
import * as smartrequest from '@pushrocks/smartrequest';
|
|
12
|
+
import * as smartstring from '@pushrocks/smartstring';
|
|
13
|
+
export { lik, smartdelay, smartrequest, smartpromise, smartstring };
|
|
14
|
+
import * as ws from 'ws';
|
|
15
|
+
import wsDefault from 'ws';
|
|
16
|
+
export { wsDefault, ws };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// node native scope
|
|
2
|
+
import * as http from 'http';
|
|
3
|
+
import * as https from 'https';
|
|
4
|
+
import * as net from 'net';
|
|
5
|
+
import * as url from 'url';
|
|
6
|
+
export { http, https, net, url };
|
|
7
|
+
// tsclass scope
|
|
8
|
+
import * as tsclass from '@tsclass/tsclass';
|
|
9
|
+
export { tsclass };
|
|
10
|
+
// pushrocks scope
|
|
11
|
+
import * as lik from '@pushrocks/lik';
|
|
12
|
+
import * as smartdelay from '@pushrocks/smartdelay';
|
|
13
|
+
import * as smartpromise from '@pushrocks/smartpromise';
|
|
14
|
+
import * as smartrequest from '@pushrocks/smartrequest';
|
|
15
|
+
import * as smartstring from '@pushrocks/smartstring';
|
|
16
|
+
export { lik, smartdelay, smartrequest, smartpromise, smartstring };
|
|
17
|
+
// third party scope
|
|
18
|
+
import * as ws from 'ws';
|
|
19
|
+
import wsDefault from 'ws';
|
|
20
|
+
export { wsDefault, ws };
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRwcm94eS5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRwcm94eS5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9CQUFvQjtBQUNwQixPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMvQixPQUFPLEtBQUssR0FBRyxNQUFNLEtBQUssQ0FBQztBQUMzQixPQUFPLEtBQUssR0FBRyxNQUFNLEtBQUssQ0FBQztBQUUzQixPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFFakMsZ0JBQWdCO0FBQ2hCLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFFNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDO0FBRW5CLGtCQUFrQjtBQUNsQixPQUFPLEtBQUssR0FBRyxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sS0FBSyxVQUFVLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxLQUFLLFlBQVksTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssWUFBWSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sS0FBSyxXQUFXLE1BQU0sd0JBQXdCLENBQUM7QUFFdEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsQ0FBQztBQUVwRSxvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxTQUFTLE1BQU0sSUFBSSxDQUFDO0FBRTNCLE9BQU8sRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMifQ==
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
3
|
+
export declare class PortProxy {
|
|
4
|
+
netServer: plugins.net.Server;
|
|
5
|
+
fromPort: number;
|
|
6
|
+
toPort: number;
|
|
7
|
+
constructor(fromPortArg: number, toPortArg: number);
|
|
8
|
+
start(): Promise<void>;
|
|
9
|
+
stop(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
2
|
+
import * as net from 'net';
|
|
3
|
+
export class PortProxy {
|
|
4
|
+
constructor(fromPortArg, toPortArg) {
|
|
5
|
+
this.fromPort = fromPortArg;
|
|
6
|
+
this.toPort = toPortArg;
|
|
7
|
+
}
|
|
8
|
+
async start() {
|
|
9
|
+
const cleanUpSockets = (from, to) => {
|
|
10
|
+
from.end();
|
|
11
|
+
to.end();
|
|
12
|
+
from.removeAllListeners();
|
|
13
|
+
to.removeAllListeners();
|
|
14
|
+
from.unpipe();
|
|
15
|
+
to.unpipe();
|
|
16
|
+
from.destroy();
|
|
17
|
+
to.destroy();
|
|
18
|
+
};
|
|
19
|
+
this.netServer = net
|
|
20
|
+
.createServer((from) => {
|
|
21
|
+
const to = net.createConnection({
|
|
22
|
+
host: 'localhost',
|
|
23
|
+
port: this.toPort,
|
|
24
|
+
});
|
|
25
|
+
from.setTimeout(120000);
|
|
26
|
+
from.pipe(to);
|
|
27
|
+
to.pipe(from);
|
|
28
|
+
from.on('error', () => {
|
|
29
|
+
cleanUpSockets(from, to);
|
|
30
|
+
});
|
|
31
|
+
to.on('error', () => {
|
|
32
|
+
cleanUpSockets(from, to);
|
|
33
|
+
});
|
|
34
|
+
from.on('close', () => {
|
|
35
|
+
cleanUpSockets(from, to);
|
|
36
|
+
});
|
|
37
|
+
to.on('close', () => {
|
|
38
|
+
cleanUpSockets(from, to);
|
|
39
|
+
});
|
|
40
|
+
from.on('timeout', () => {
|
|
41
|
+
cleanUpSockets(from, to);
|
|
42
|
+
});
|
|
43
|
+
to.on('timeout', () => {
|
|
44
|
+
cleanUpSockets(from, to);
|
|
45
|
+
});
|
|
46
|
+
from.on('end', () => {
|
|
47
|
+
cleanUpSockets(from, to);
|
|
48
|
+
});
|
|
49
|
+
to.on('end', () => {
|
|
50
|
+
cleanUpSockets(from, to);
|
|
51
|
+
});
|
|
52
|
+
})
|
|
53
|
+
.listen(this.fromPort);
|
|
54
|
+
console.log(`PortProxy -> OK: Now listening on port ${this.fromPort}`);
|
|
55
|
+
}
|
|
56
|
+
async stop() {
|
|
57
|
+
const done = plugins.smartpromise.defer();
|
|
58
|
+
this.netServer.close(() => {
|
|
59
|
+
done.resolve();
|
|
60
|
+
});
|
|
61
|
+
await done.promise;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRwcm94eS5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHByb3h5LnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sS0FBSyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBRTNCLE1BQU0sT0FBTyxTQUFTO0lBS3BCLFlBQVksV0FBbUIsRUFBRSxTQUFpQjtRQUNoRCxJQUFJLENBQUMsUUFBUSxHQUFHLFdBQVcsQ0FBQztRQUM1QixJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUMxQixDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQUs7UUFDaEIsTUFBTSxjQUFjLEdBQUcsQ0FBQyxJQUF3QixFQUFFLEVBQXNCLEVBQUUsRUFBRTtZQUMxRSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDWCxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUMxQixFQUFFLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixDQUFDLENBQUM7UUFDRixJQUFJLENBQUMsU0FBUyxHQUFHLEdBQUc7YUFDakIsWUFBWSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDckIsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixDQUFDO2dCQUM5QixJQUFJLEVBQUUsV0FBVztnQkFDakIsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNO2FBQ2xCLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNkLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDZCxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ3BCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ2xCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ3BCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ2xCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7Z0JBQ3RCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7Z0JBQ3BCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7Z0JBQ2xCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7Z0JBQ2hCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7YUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsMENBQTBDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSTtRQUNmLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDMUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFO1lBQ3hCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUNyQixDQUFDO0NBQ0YifQ==
|
package/license
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2019 Lossless GmbH (hello@lossless.com)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/npmextra.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"gitzone": {
|
|
3
|
+
"projectType": "npm",
|
|
4
|
+
"module": {
|
|
5
|
+
"githost": "gitlab.com",
|
|
6
|
+
"gitscope": "pushrocks",
|
|
7
|
+
"gitrepo": "smartproxy",
|
|
8
|
+
"description": "a proxy for handling high workloads of proxying",
|
|
9
|
+
"npmPackagename": "@pushrocks/smartproxy",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"projectDomain": "push.rocks"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"npmci": {
|
|
15
|
+
"npmGlobalTools": [],
|
|
16
|
+
"npmAccessLevel": "public"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@push.rocks/smartproxy",
|
|
3
|
+
"version": "3.0.58",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "a proxy for handling high workloads of proxying",
|
|
6
|
+
"main": "dist_ts/index.js",
|
|
7
|
+
"typings": "dist_ts/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"author": "Lossless GmbH",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "(tstest test/)",
|
|
13
|
+
"build": "(tsbuild --web --allowimplicitany)",
|
|
14
|
+
"format": "(gitzone format)",
|
|
15
|
+
"buildDocs": "tsdoc"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@gitzone/tsbuild": "^2.1.65",
|
|
19
|
+
"@gitzone/tsrun": "^1.2.39",
|
|
20
|
+
"@gitzone/tstest": "^1.0.73",
|
|
21
|
+
"@pushrocks/tapbundle": "^5.0.4",
|
|
22
|
+
"@types/node": "^18.7.8"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@pushrocks/lik": "^6.0.0",
|
|
26
|
+
"@pushrocks/smartdelay": "^2.0.13",
|
|
27
|
+
"@pushrocks/smartpromise": "^3.1.7",
|
|
28
|
+
"@pushrocks/smartrequest": "^2.0.10",
|
|
29
|
+
"@pushrocks/smartstring": "^4.0.2",
|
|
30
|
+
"@tsclass/tsclass": "^4.0.19",
|
|
31
|
+
"@types/ws": "^8.5.3",
|
|
32
|
+
"ws": "^8.8.1"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"ts/**/*",
|
|
36
|
+
"ts_web/**/*",
|
|
37
|
+
"dist/**/*",
|
|
38
|
+
"dist_*/**/*",
|
|
39
|
+
"dist_ts/**/*",
|
|
40
|
+
"dist_ts_web/**/*",
|
|
41
|
+
"assets/**/*",
|
|
42
|
+
"cli.js",
|
|
43
|
+
"npmextra.json",
|
|
44
|
+
"readme.md"
|
|
45
|
+
],
|
|
46
|
+
"browserslist": [
|
|
47
|
+
"last 1 chrome versions"
|
|
48
|
+
]
|
|
49
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# @pushrocks/smartproxy
|
|
2
|
+
a proxy for handling high workloads of proxying
|
|
3
|
+
|
|
4
|
+
## Availabililty and Links
|
|
5
|
+
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartproxy)
|
|
6
|
+
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartproxy)
|
|
7
|
+
* [github.com (source mirror)](https://github.com/pushrocks/smartproxy)
|
|
8
|
+
* [docs (typedoc)](https://pushrocks.gitlab.io/smartproxy/)
|
|
9
|
+
|
|
10
|
+
## Status for master
|
|
11
|
+
|
|
12
|
+
Status Category | Status Badge
|
|
13
|
+
-- | --
|
|
14
|
+
GitLab Pipelines | [](https://lossless.cloud)
|
|
15
|
+
GitLab Pipline Test Coverage | [](https://lossless.cloud)
|
|
16
|
+
npm | [](https://lossless.cloud)
|
|
17
|
+
Snyk | [](https://lossless.cloud)
|
|
18
|
+
TypeScript Support | [](https://lossless.cloud)
|
|
19
|
+
node Support | [](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
|
20
|
+
Code Style | [](https://lossless.cloud)
|
|
21
|
+
PackagePhobia (total standalone install weight) | [](https://lossless.cloud)
|
|
22
|
+
PackagePhobia (package size on registry) | [](https://lossless.cloud)
|
|
23
|
+
BundlePhobia (total size when bundled) | [](https://lossless.cloud)
|
|
24
|
+
Platform support | [](https://lossless.cloud) [](https://lossless.cloud)
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
## Contribution
|
|
29
|
+
|
|
30
|
+
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
|
31
|
+
|
|
32
|
+
## Contribution
|
|
33
|
+
|
|
34
|
+
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
|
35
|
+
|
|
36
|
+
For further information read the linked docs at the top of this readme.
|
|
37
|
+
|
|
38
|
+
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
|
39
|
+
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
|
|
40
|
+
|
|
41
|
+
[](https://maintainedby.lossless.com)
|
package/ts/index.ts
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
2
|
+
import { ProxyRouter } from './smartproxy.classes.router.js';
|
|
3
|
+
|
|
4
|
+
export interface INetworkProxyOptions {
|
|
5
|
+
port: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class NetworkProxy {
|
|
9
|
+
// INSTANCE
|
|
10
|
+
public options: INetworkProxyOptions;
|
|
11
|
+
public proxyConfigs: plugins.tsclass.network.IReverseProxyConfig[] = [];
|
|
12
|
+
public httpsServer: plugins.https.Server;
|
|
13
|
+
public router = new ProxyRouter();
|
|
14
|
+
public socketMap = new plugins.lik.ObjectMap<plugins.net.Socket>();
|
|
15
|
+
public defaultHeaders: { [key: string]: string } = {};
|
|
16
|
+
|
|
17
|
+
public alreadyAddedReverseConfigs: {
|
|
18
|
+
[hostName: string]: plugins.tsclass.network.IReverseProxyConfig;
|
|
19
|
+
} = {};
|
|
20
|
+
|
|
21
|
+
constructor(optionsArg: INetworkProxyOptions) {
|
|
22
|
+
this.options = optionsArg;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* starts the proxyInstance
|
|
27
|
+
*/
|
|
28
|
+
public async start() {
|
|
29
|
+
this.httpsServer = plugins.https.createServer(
|
|
30
|
+
// ================
|
|
31
|
+
// Spotted this keypair in the code?
|
|
32
|
+
// Don't get exited:
|
|
33
|
+
// It is an invalid default keypair.
|
|
34
|
+
// For proper requests custom domain level keypairs are used that are provided in the reverse config
|
|
35
|
+
// ================
|
|
36
|
+
{
|
|
37
|
+
key: `-----BEGIN PRIVATE KEY-----
|
|
38
|
+
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
|
|
87
|
+
2TkK01XDDJURK5Lhuvc7WrK2rSJ/fK+0GA==
|
|
88
|
+
-----END PRIVATE KEY-----
|
|
89
|
+
`,
|
|
90
|
+
cert: `-----BEGIN CERTIFICATE-----
|
|
91
|
+
MIIEljCCAn4CCQDY+ZbC9FASVjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJE
|
|
92
|
+
RTAeFw0xOTA5MjAxNjAxNDRaFw0yMDA5MTkxNjAxNDRaMA0xCzAJBgNVBAYTAkRF
|
|
93
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4thf9JEK/epoXt8hFr8t
|
|
94
|
+
pkRzmaEkgbSKoOga3uGXDLvdNf3BzSIxZ8pzRhZfUnutcmW1thdz3wre/pEJR7oN
|
|
95
|
+
QsfixbLL8/oS5QeXKiUGX0Ssfdg4W0TsoLcRva+1AZsf38MfiUPhzh1/UW/rMywW
|
|
96
|
+
asazQwRZdkkXb4nKJ2IFZx22qnAD4/5Sug+sfeKoFBF/rzI2yK7rognt7kW2LHv6
|
|
97
|
+
rswHnZ1Z2P/gbhlZ/EhG9hFVRZwRLDscWKcuWcxkePDt2J1pDNqD6SYa6ZjGC3AE
|
|
98
|
+
TJw5iEA1bLQ9YvjDNpVYcf6ZvcSilIFjSQu5cs9sUbHGeKTrS5HzfeJXh1PfJyL8
|
|
99
|
+
X0Hu7UBSjfSudso3baE9FGiBFBW2cnXZKDZGtV8eq/qxPetOOgS09pVbNP6508WV
|
|
100
|
+
BR+rz98/VDZLZqcbZ2UpOuz4+kAKmbYE9GplxKQZZO7wWEox7Mid/uUdcqEo4QKn
|
|
101
|
+
no6ujOuzQzn5a2oOS0k5Hk3uHapNJWlW9YI3LHtfADpYH+6cOR+/c3JWBzQJ6AD7
|
|
102
|
+
muvNzA9mWXeHqLxMMP4pkmb7otzZYrEkodUqJgAQxcYhGh6XsCPfJ/D9RN734OJc
|
|
103
|
+
gleVXFI8Kz455HxCW19XNfz16k7T6kqhZ/6SOBbkxEuqg7oEthAP109ZZzgx4oDo
|
|
104
|
+
hQsw24TjLkI4SPIc7nr60UUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAu0+zrg0C
|
|
105
|
+
mlSv4Yi24OwB7TBvx+WHesl1IilCUdTiiUMo3NumvsU9Dr3Jkd0jGqYI0eyH4gIt
|
|
106
|
+
KrhAveXfEw7tAOEHiYicmAdIFtyzh++ZWb8mgbBeqij1MP/76Jv+cc0lUqpfRo/A
|
|
107
|
+
qytAsPAILuyL1o1jh28JHcq+v+WYn/FEhjUlH6emhGKGlsAjhUPjzK8MEshNolhj
|
|
108
|
+
t2UXw9WB5B2xWvrqlNMy0F3NAZBkZ/+k21HZo6FmVi+q6OEGcOo7wJt6wrH/lko9
|
|
109
|
+
LxX96GC1JoN1Pfr2FoTKy1WHzrSfyGmDIUCrbaYQ58UuMOR+5eIPPdkf/030u5eX
|
|
110
|
+
xXhF2fBujD57E2zQGh/l2MrOjamcSo0+wYhOqlX3WNdaKNAzPqloBnF6w7eqLYde
|
|
111
|
+
h9He39ySmxjENwv3miOjEP1sBeMBSRfL/ckEonfK5uJgYA5nVMQ3ojUeDMZzLfFE
|
|
112
|
+
Ue2WHt+uPyYk7mMZfOrK2uHzI2/Coqj7lbfRodFwj+fCArYBck2NZannDPKA6X8V
|
|
113
|
+
TzJTbTCteOUUJTrcfZ0gGhGkF4nYLmX5OI+TPqrDJf0fZ+mzAEHzDDVXcBYpYRDr
|
|
114
|
+
r8d9QwrK+WaqVi2ofbMfMByVF72jgeJNa4nxwT9bVbu/Q1T2Lt+YPb4pQ7yCoUgS
|
|
115
|
+
JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
116
|
+
-----END CERTIFICATE-----
|
|
117
|
+
`,
|
|
118
|
+
},
|
|
119
|
+
async (originRequest, originResponse) => {
|
|
120
|
+
/**
|
|
121
|
+
* endRequest function
|
|
122
|
+
* can be used to prematurely end a request
|
|
123
|
+
*/
|
|
124
|
+
const endOriginReqRes = (
|
|
125
|
+
statusArg: number = 404,
|
|
126
|
+
messageArg: string = 'This route is not available on this server.',
|
|
127
|
+
headers: plugins.http.OutgoingHttpHeaders = {}
|
|
128
|
+
) => {
|
|
129
|
+
originResponse.writeHead(statusArg, messageArg);
|
|
130
|
+
originResponse.end(messageArg);
|
|
131
|
+
if (originRequest.socket !== originResponse.socket) {
|
|
132
|
+
console.log('hey, something is strange.')
|
|
133
|
+
}
|
|
134
|
+
originResponse.destroy();
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
console.log(`got request: ${originRequest.headers.host}${plugins.url.parse(originRequest.url).path}`);
|
|
138
|
+
const destinationConfig = this.router.routeReq(originRequest);
|
|
139
|
+
|
|
140
|
+
if (!destinationConfig) {
|
|
141
|
+
console.log(`${originRequest.headers.host} can't be routed properly. Terminating request.`);
|
|
142
|
+
endOriginReqRes();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// authentication
|
|
147
|
+
if (destinationConfig.authentication) {
|
|
148
|
+
const authInfo = destinationConfig.authentication;
|
|
149
|
+
switch (authInfo.type) {
|
|
150
|
+
case 'Basic':
|
|
151
|
+
const authHeader = originRequest.headers.authorization;
|
|
152
|
+
if (authHeader) {
|
|
153
|
+
if (!authHeader.includes('Basic ')) {
|
|
154
|
+
return endOriginReqRes(401, 'Authentication required', {
|
|
155
|
+
'WWW-Authenticate': 'Basic realm="Access to the staging site", charset="UTF-8"',
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const authStringBase64 = originRequest.headers.authorization.replace('Basic ', '');
|
|
159
|
+
const authString: string = plugins.smartstring.base64.decode(authStringBase64);
|
|
160
|
+
const userPassArray = authString.split(':');
|
|
161
|
+
const user = userPassArray[0];
|
|
162
|
+
const pass = userPassArray[1];
|
|
163
|
+
if (user === authInfo.user && pass === authInfo.pass) {
|
|
164
|
+
console.log('request successfully authenticated');
|
|
165
|
+
} else {
|
|
166
|
+
return endOriginReqRes(403, 'Forbidden: Wrong credentials');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
break;
|
|
170
|
+
default:
|
|
171
|
+
return endOriginReqRes(
|
|
172
|
+
403,
|
|
173
|
+
'Forbidden: unsupported authentication method configured. Please report to the admin.'
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
let destinationUrl: string;
|
|
179
|
+
if (destinationConfig) {
|
|
180
|
+
destinationUrl = `http://${destinationConfig.destinationIp}:${destinationConfig.destinationPort}${originRequest.url}`;
|
|
181
|
+
} else {
|
|
182
|
+
return endOriginReqRes();
|
|
183
|
+
}
|
|
184
|
+
console.log(destinationUrl);
|
|
185
|
+
const proxyResponse = await plugins.smartrequest.request(
|
|
186
|
+
destinationUrl,
|
|
187
|
+
{
|
|
188
|
+
method: originRequest.method,
|
|
189
|
+
headers: {
|
|
190
|
+
...originRequest.headers,
|
|
191
|
+
'X-Forwarded-Host': originRequest.headers.host,
|
|
192
|
+
'X-Forwarded-Proto': 'https'
|
|
193
|
+
},
|
|
194
|
+
keepAlive: true,
|
|
195
|
+
},
|
|
196
|
+
true, // lets make this streaming
|
|
197
|
+
(proxyRequest) => {
|
|
198
|
+
originRequest.on('data', (data) => {
|
|
199
|
+
proxyRequest.write(data);
|
|
200
|
+
});
|
|
201
|
+
originRequest.on('end', (data) => {
|
|
202
|
+
proxyRequest.end();
|
|
203
|
+
});
|
|
204
|
+
originRequest.on('error', () => {
|
|
205
|
+
proxyRequest.end();
|
|
206
|
+
});
|
|
207
|
+
originRequest.on('close', () => {
|
|
208
|
+
proxyRequest.end();
|
|
209
|
+
});
|
|
210
|
+
originRequest.on('timeout', () => {
|
|
211
|
+
proxyRequest.end();
|
|
212
|
+
originRequest.destroy();
|
|
213
|
+
});
|
|
214
|
+
proxyRequest.on('error', () => {
|
|
215
|
+
endOriginReqRes();
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
originResponse.statusCode = proxyResponse.statusCode;
|
|
220
|
+
console.log(proxyResponse.statusCode);
|
|
221
|
+
for (const defaultHeader of Object.keys(this.defaultHeaders)) {
|
|
222
|
+
originResponse.setHeader(defaultHeader, this.defaultHeaders[defaultHeader]);
|
|
223
|
+
}
|
|
224
|
+
for (const header of Object.keys(proxyResponse.headers)) {
|
|
225
|
+
originResponse.setHeader(header, proxyResponse.headers[header]);
|
|
226
|
+
}
|
|
227
|
+
proxyResponse.on('data', (data) => {
|
|
228
|
+
originResponse.write(data);
|
|
229
|
+
});
|
|
230
|
+
proxyResponse.on('end', () => {
|
|
231
|
+
originResponse.end();
|
|
232
|
+
});
|
|
233
|
+
proxyResponse.on('error', () => {
|
|
234
|
+
originResponse.destroy();
|
|
235
|
+
});
|
|
236
|
+
proxyResponse.on('close', () => {
|
|
237
|
+
originResponse.end();
|
|
238
|
+
});
|
|
239
|
+
proxyResponse.on('timeout', () => {
|
|
240
|
+
originResponse.end();
|
|
241
|
+
originResponse.destroy()
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
// Enable websockets
|
|
248
|
+
const wsServer = new plugins.ws.WebSocketServer({ server: this.httpsServer });
|
|
249
|
+
wsServer.on('connection', async (wsIncoming: plugins.wsDefault, reqArg: plugins.http.IncomingMessage) => {
|
|
250
|
+
console.log(`wss proxy: got connection for wsc for https://${reqArg.headers.host}${reqArg.url}`);
|
|
251
|
+
|
|
252
|
+
let wsOutgoing: plugins.wsDefault;
|
|
253
|
+
|
|
254
|
+
const outGoingDeferred = plugins.smartpromise.defer();
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
wsOutgoing = new plugins.wsDefault(`ws://${this.router.routeReq(reqArg).destinationIp}:${this.router.routeReq(reqArg).destinationPort}${reqArg.url}`);
|
|
258
|
+
console.log('wss proxy: initiated outgoing proxy');
|
|
259
|
+
wsOutgoing.on('open', async () => {
|
|
260
|
+
outGoingDeferred.resolve();
|
|
261
|
+
})
|
|
262
|
+
} catch (err) {
|
|
263
|
+
console.log(err);
|
|
264
|
+
wsIncoming.terminate();
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
wsIncoming.on("message", async (message, isBinary) => {
|
|
269
|
+
await outGoingDeferred.promise;
|
|
270
|
+
// console.log("client to upstream", message);
|
|
271
|
+
wsOutgoing.send(message, { binary: isBinary });
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
wsOutgoing.on("message", async (message, isBinary) => {
|
|
275
|
+
// console.log("upstream to client", message);
|
|
276
|
+
wsIncoming.send(message, { binary: isBinary });
|
|
277
|
+
});
|
|
278
|
+
const terminateWsOutgoing = () => {
|
|
279
|
+
wsOutgoing.terminate();
|
|
280
|
+
console.log('terminated outgoing ws.');
|
|
281
|
+
}
|
|
282
|
+
wsIncoming.on("error", () => terminateWsOutgoing());
|
|
283
|
+
wsIncoming.on("close", () => terminateWsOutgoing());
|
|
284
|
+
|
|
285
|
+
const terminateWsIncoming = () => {
|
|
286
|
+
wsIncoming.terminate();
|
|
287
|
+
console.log('terminated incoming ws.');
|
|
288
|
+
}
|
|
289
|
+
wsOutgoing.on("error", () => terminateWsIncoming());
|
|
290
|
+
wsOutgoing.on("close", () => terminateWsIncoming());
|
|
291
|
+
|
|
292
|
+
});
|
|
293
|
+
this.httpsServer.keepAliveTimeout = 600 * 1000;
|
|
294
|
+
this.httpsServer.headersTimeout = 600 * 1000;
|
|
295
|
+
|
|
296
|
+
this.httpsServer.on('connection', (connection: plugins.net.Socket) => {
|
|
297
|
+
this.socketMap.add(connection);
|
|
298
|
+
console.log(`added connection. now ${this.socketMap.getArray().length} sockets connected.`);
|
|
299
|
+
const cleanupConnection = () => {
|
|
300
|
+
if (this.socketMap.checkForObject(connection)) {
|
|
301
|
+
this.socketMap.remove(connection);
|
|
302
|
+
console.log(`removed connection. ${this.socketMap.getArray().length} sockets remaining.`);
|
|
303
|
+
connection.destroy();
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
connection.on('close', () => {
|
|
307
|
+
cleanupConnection();
|
|
308
|
+
});
|
|
309
|
+
connection.on('error', () => {
|
|
310
|
+
cleanupConnection();
|
|
311
|
+
});
|
|
312
|
+
connection.on('end', () => {
|
|
313
|
+
cleanupConnection();
|
|
314
|
+
});
|
|
315
|
+
connection.on('timeout', () => {
|
|
316
|
+
cleanupConnection();
|
|
317
|
+
})
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
this.httpsServer.listen(this.options.port);
|
|
321
|
+
console.log(
|
|
322
|
+
`NetworkProxy -> OK: now listening for new connections on port ${this.options.port}`
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
public async updateProxyConfigs(proxyConfigsArg: plugins.tsclass.network.IReverseProxyConfig[]) {
|
|
327
|
+
console.log(`got new proxy configs`);
|
|
328
|
+
this.proxyConfigs = proxyConfigsArg;
|
|
329
|
+
this.router.setNewProxyConfigs(proxyConfigsArg);
|
|
330
|
+
for (const hostCandidate of this.proxyConfigs) {
|
|
331
|
+
// console.log(hostCandidate);
|
|
332
|
+
|
|
333
|
+
const existingHostNameConfig = this.alreadyAddedReverseConfigs[hostCandidate.hostName];
|
|
334
|
+
|
|
335
|
+
if (!existingHostNameConfig) {
|
|
336
|
+
this.alreadyAddedReverseConfigs[hostCandidate.hostName] = hostCandidate;
|
|
337
|
+
} else {
|
|
338
|
+
if (
|
|
339
|
+
existingHostNameConfig.publicKey === hostCandidate.publicKey &&
|
|
340
|
+
existingHostNameConfig.privateKey === hostCandidate.privateKey
|
|
341
|
+
) {
|
|
342
|
+
continue;
|
|
343
|
+
} else {
|
|
344
|
+
this.alreadyAddedReverseConfigs[hostCandidate.hostName] = hostCandidate;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
this.httpsServer.addContext(hostCandidate.hostName, {
|
|
349
|
+
cert: hostCandidate.publicKey,
|
|
350
|
+
key: hostCandidate.privateKey,
|
|
351
|
+
});
|
|
352
|
+
this.httpsServer;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
public async addDefaultHeaders(headersArg: { [key: string]: string }) {
|
|
357
|
+
for (const headerKey of Object.keys(headersArg)) {
|
|
358
|
+
this.defaultHeaders[headerKey] = headersArg[headerKey];
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
public async stop() {
|
|
363
|
+
const done = plugins.smartpromise.defer();
|
|
364
|
+
this.httpsServer.close(() => {
|
|
365
|
+
done.resolve();
|
|
366
|
+
});
|
|
367
|
+
await this.socketMap.forEach(async (socket) => {
|
|
368
|
+
socket.destroy();
|
|
369
|
+
});
|
|
370
|
+
await done.promise;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
2
|
+
|
|
3
|
+
export class ProxyRouter {
|
|
4
|
+
public reverseProxyConfigs: plugins.tsclass.network.IReverseProxyConfig[] = [];
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* sets a new set of reverse configs to be routed to
|
|
8
|
+
* @param reverseCandidatesArg
|
|
9
|
+
*/
|
|
10
|
+
public setNewProxyConfigs(reverseCandidatesArg: plugins.tsclass.network.IReverseProxyConfig[]) {
|
|
11
|
+
this.reverseProxyConfigs = reverseCandidatesArg;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* routes a request
|
|
16
|
+
*/
|
|
17
|
+
public routeReq(req: plugins.http.IncomingMessage): plugins.tsclass.network.IReverseProxyConfig {
|
|
18
|
+
const originalHost = req.headers.host;
|
|
19
|
+
const correspodingReverseProxyConfig = this.reverseProxyConfigs.find((reverseConfig) => {
|
|
20
|
+
return reverseConfig.hostName === originalHost;
|
|
21
|
+
});
|
|
22
|
+
return correspodingReverseProxyConfig;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
2
|
+
|
|
3
|
+
export class SslRedirect {
|
|
4
|
+
httpServer: plugins.http.Server;
|
|
5
|
+
port: number;
|
|
6
|
+
constructor(portArg: number) {
|
|
7
|
+
this.port = portArg;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public async start() {
|
|
11
|
+
this.httpServer = plugins.http.createServer((request, response) => {
|
|
12
|
+
const requestUrl = new URL(request.url, `http://${request.headers.host}`);
|
|
13
|
+
const completeUrlWithoutProtocol = `${requestUrl.host}${requestUrl.pathname}${requestUrl.search}`;
|
|
14
|
+
const redirectUrl = `https://${completeUrlWithoutProtocol}`;
|
|
15
|
+
console.log(`Got http request for http://${completeUrlWithoutProtocol}`);
|
|
16
|
+
console.log(`Redirecting to ${redirectUrl}`);
|
|
17
|
+
response.writeHead(302, {
|
|
18
|
+
Location: redirectUrl,
|
|
19
|
+
});
|
|
20
|
+
response.end();
|
|
21
|
+
});
|
|
22
|
+
this.httpServer.listen(this.port);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public async stop() {
|
|
26
|
+
const done = plugins.smartpromise.defer();
|
|
27
|
+
this.httpServer.close(() => {
|
|
28
|
+
done.resolve();
|
|
29
|
+
});
|
|
30
|
+
await done.promise;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// node native scope
|
|
2
|
+
import * as http from 'http';
|
|
3
|
+
import * as https from 'https';
|
|
4
|
+
import * as net from 'net';
|
|
5
|
+
import * as url from 'url';
|
|
6
|
+
|
|
7
|
+
export { http, https, net, url };
|
|
8
|
+
|
|
9
|
+
// tsclass scope
|
|
10
|
+
import * as tsclass from '@tsclass/tsclass';
|
|
11
|
+
|
|
12
|
+
export { tsclass };
|
|
13
|
+
|
|
14
|
+
// pushrocks scope
|
|
15
|
+
import * as lik from '@pushrocks/lik';
|
|
16
|
+
import * as smartdelay from '@pushrocks/smartdelay';
|
|
17
|
+
import * as smartpromise from '@pushrocks/smartpromise';
|
|
18
|
+
import * as smartrequest from '@pushrocks/smartrequest';
|
|
19
|
+
import * as smartstring from '@pushrocks/smartstring';
|
|
20
|
+
|
|
21
|
+
export { lik, smartdelay, smartrequest, smartpromise, smartstring };
|
|
22
|
+
|
|
23
|
+
// third party scope
|
|
24
|
+
import * as ws from 'ws';
|
|
25
|
+
import wsDefault from 'ws';
|
|
26
|
+
|
|
27
|
+
export { wsDefault, ws };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as plugins from './smartproxy.plugins.js';
|
|
2
|
+
import * as net from 'net';
|
|
3
|
+
|
|
4
|
+
export class PortProxy {
|
|
5
|
+
netServer: plugins.net.Server;
|
|
6
|
+
fromPort: number;
|
|
7
|
+
toPort: number;
|
|
8
|
+
|
|
9
|
+
constructor(fromPortArg: number, toPortArg: number) {
|
|
10
|
+
this.fromPort = fromPortArg;
|
|
11
|
+
this.toPort = toPortArg;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public async start() {
|
|
15
|
+
const cleanUpSockets = (from: plugins.net.Socket, to: plugins.net.Socket) => {
|
|
16
|
+
from.end();
|
|
17
|
+
to.end();
|
|
18
|
+
from.removeAllListeners();
|
|
19
|
+
to.removeAllListeners();
|
|
20
|
+
from.unpipe();
|
|
21
|
+
to.unpipe();
|
|
22
|
+
from.destroy();
|
|
23
|
+
to.destroy();
|
|
24
|
+
};
|
|
25
|
+
this.netServer = net
|
|
26
|
+
.createServer((from) => {
|
|
27
|
+
const to = net.createConnection({
|
|
28
|
+
host: 'localhost',
|
|
29
|
+
port: this.toPort,
|
|
30
|
+
});
|
|
31
|
+
from.setTimeout(120000);
|
|
32
|
+
from.pipe(to);
|
|
33
|
+
to.pipe(from);
|
|
34
|
+
from.on('error', () => {
|
|
35
|
+
cleanUpSockets(from, to);
|
|
36
|
+
});
|
|
37
|
+
to.on('error', () => {
|
|
38
|
+
cleanUpSockets(from, to);
|
|
39
|
+
});
|
|
40
|
+
from.on('close', () => {
|
|
41
|
+
cleanUpSockets(from, to);
|
|
42
|
+
});
|
|
43
|
+
to.on('close', () => {
|
|
44
|
+
cleanUpSockets(from, to);
|
|
45
|
+
});
|
|
46
|
+
from.on('timeout', () => {
|
|
47
|
+
cleanUpSockets(from, to);
|
|
48
|
+
});
|
|
49
|
+
to.on('timeout', () => {
|
|
50
|
+
cleanUpSockets(from, to);
|
|
51
|
+
});
|
|
52
|
+
from.on('end', () => {
|
|
53
|
+
cleanUpSockets(from, to);
|
|
54
|
+
});
|
|
55
|
+
to.on('end', () => {
|
|
56
|
+
cleanUpSockets(from, to);
|
|
57
|
+
});
|
|
58
|
+
})
|
|
59
|
+
.listen(this.fromPort);
|
|
60
|
+
console.log(`PortProxy -> OK: Now listening on port ${this.fromPort}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public async stop() {
|
|
64
|
+
const done = plugins.smartpromise.defer();
|
|
65
|
+
this.netServer.close(() => {
|
|
66
|
+
done.resolve();
|
|
67
|
+
});
|
|
68
|
+
await done.promise;
|
|
69
|
+
}
|
|
70
|
+
}
|