@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.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * autocreated commitinfo by @pushrocks/commitinfo
3
+ */
4
+ export declare const commitinfo: {
5
+ name: string;
6
+ version: string;
7
+ description: string;
8
+ };
@@ -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=
@@ -0,0 +1,3 @@
1
+ export * from './smartproxy.classes.networkproxy.js';
2
+ export * from './smartproxy.portproxy.js';
3
+ export * from './smartproxy.classes.sslredirect.js';
@@ -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 | [![pipeline status](https://gitlab.com/pushrocks/smartproxy/badges/master/pipeline.svg)](https://lossless.cloud)
15
+ GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/pushrocks/smartproxy/badges/master/coverage.svg)](https://lossless.cloud)
16
+ npm | [![npm downloads per month](https://badgen.net/npm/dy/@pushrocks/smartproxy)](https://lossless.cloud)
17
+ Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/pushrocks/smartproxy)](https://lossless.cloud)
18
+ TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud)
19
+ node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
20
+ Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud)
21
+ PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@pushrocks/smartproxy)](https://lossless.cloud)
22
+ PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@pushrocks/smartproxy)](https://lossless.cloud)
23
+ BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@pushrocks/smartproxy)](https://lossless.cloud)
24
+ Platform support | [![Supports Windows 10](https://badgen.net/badge/supports%20Windows%2010/yes/green?icon=windows)](https://lossless.cloud) [![Supports Mac OS X](https://badgen.net/badge/supports%20Mac%20OS%20X/yes/green?icon=apple)](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 | **&copy;** [Lossless GmbH](https://lossless.gmbh)
39
+ | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
40
+
41
+ [![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)
@@ -0,0 +1,8 @@
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
+ }
package/ts/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './smartproxy.classes.networkproxy.js';
2
+ export * from './smartproxy.portproxy.js';
3
+ export * from './smartproxy.classes.sslredirect.js'
@@ -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
+ }