@daisy/ace-axe-runner-electron 1.2.3-beta.2 → 1.2.6-alpha.1
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/lib/cli.js +22 -1
- package/lib/init.js +525 -250
- package/lib/selfsigned.js +31 -31
- package/package.json +5 -7
- package/src/cli.js +22 -1
- package/src/init.js +441 -157
- package/src/selfsigned.js +30 -30
package/src/init.js
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// TOO LATE FOR JEST RUNNER DUE TO AFTER ELECTRON APP.READY!
|
|
4
|
+
// (see package.json patcher script "patchElectronJestRunner3")
|
|
5
|
+
// // NO_HTTP_ADD
|
|
6
|
+
// const electron = require('electron');
|
|
7
|
+
// const protocol = electron.protocol;
|
|
8
|
+
// const ACE_ELECTRON_HTTP_PROTOCOL = "acehttps";
|
|
9
|
+
// // app.commandLine.appendSwitch("autoplay-policy", "no-user-gesture-required");
|
|
10
|
+
// protocol.registerSchemesAsPrivileged([{
|
|
11
|
+
// privileges: {
|
|
12
|
+
// allowServiceWorkers: false,
|
|
13
|
+
// bypassCSP: false,
|
|
14
|
+
// corsEnabled: true,
|
|
15
|
+
// secure: true,
|
|
16
|
+
// standard: true,
|
|
17
|
+
// stream: true,
|
|
18
|
+
// supportFetchAPI: true,
|
|
19
|
+
// },
|
|
20
|
+
// scheme: ACE_ELECTRON_HTTP_PROTOCOL,
|
|
21
|
+
// }]);
|
|
22
|
+
|
|
23
|
+
const mime = require('mime-types');
|
|
24
|
+
|
|
25
|
+
const nodeStream = require('stream');
|
|
26
|
+
|
|
3
27
|
const path = require('path');
|
|
4
28
|
const fs = require('fs');
|
|
5
|
-
const url = require('url');
|
|
6
29
|
|
|
7
30
|
const electron = require('electron');
|
|
8
31
|
const app = electron.app;
|
|
@@ -13,13 +36,6 @@ const BrowserWindow = electron.BrowserWindow;
|
|
|
13
36
|
|
|
14
37
|
const fsOriginal = require('original-fs');
|
|
15
38
|
|
|
16
|
-
const express = require('express');
|
|
17
|
-
const portfinder = require('portfinder');
|
|
18
|
-
// const http = require('http');
|
|
19
|
-
const https = require('https');
|
|
20
|
-
|
|
21
|
-
const generateSelfSignedData = require('./selfsigned').generateSelfSignedData;
|
|
22
|
-
|
|
23
39
|
const isDev = process && process.env && (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true');
|
|
24
40
|
const showWindow = false;
|
|
25
41
|
|
|
@@ -32,16 +48,28 @@ const SESSION_PARTITION = "persist:axe";
|
|
|
32
48
|
|
|
33
49
|
const HTTP_QUERY_PARAM = "AXE_RUNNER";
|
|
34
50
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
const ACE_ELECTRON_HTTP_PROTOCOL = "acehttps";
|
|
52
|
+
|
|
53
|
+
// NO_HTTP_REMOVE
|
|
54
|
+
// const express = require('express');
|
|
55
|
+
// const portfinder = require('portfinder');
|
|
56
|
+
// // const http = require('http');
|
|
57
|
+
// const https = require('https');
|
|
58
|
+
// const generateSelfSignedData = require('./selfsigned').generateSelfSignedData;
|
|
59
|
+
// let expressApp;
|
|
60
|
+
// let httpServer;
|
|
61
|
+
// let port;
|
|
62
|
+
// let ip;
|
|
63
|
+
// let proto;
|
|
64
|
+
// let rootUrl;
|
|
42
65
|
let httpServerStartWasRequested = false;
|
|
43
66
|
let httpServerStarted = false;
|
|
44
67
|
|
|
68
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner ELECTRON MODULE INSTANCE`);
|
|
69
|
+
|
|
70
|
+
// NO_HTTP_ADD
|
|
71
|
+
const rootUrl = `${ACE_ELECTRON_HTTP_PROTOCOL}://0.0.0.0`;
|
|
72
|
+
|
|
45
73
|
let browserWindows = undefined;
|
|
46
74
|
|
|
47
75
|
const jsCache = {};
|
|
@@ -50,6 +78,126 @@ let _firstTimeInit = true;
|
|
|
50
78
|
|
|
51
79
|
let iHttpReq = 0;
|
|
52
80
|
|
|
81
|
+
// NO_HTTP_ADD
|
|
82
|
+
class BufferReadableStream extends nodeStream.Readable {
|
|
83
|
+
constructor(buffer) {
|
|
84
|
+
super();
|
|
85
|
+
this.buffer = buffer;
|
|
86
|
+
this.alreadyRead = 0;
|
|
87
|
+
}
|
|
88
|
+
_read(size) {
|
|
89
|
+
if (this.alreadyRead >= this.buffer.length) {
|
|
90
|
+
this.push(null);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let chunk = this.alreadyRead ?
|
|
95
|
+
this.buffer.slice(this.alreadyRead) :
|
|
96
|
+
this.buffer;
|
|
97
|
+
|
|
98
|
+
if (size) {
|
|
99
|
+
let l = size;
|
|
100
|
+
if (size > chunk.length) {
|
|
101
|
+
l = chunk.length;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
chunk = chunk.slice(0, l);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
this.alreadyRead += chunk.length;
|
|
108
|
+
this.push(chunk);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function bufferToStream(buffer) {
|
|
112
|
+
return new BufferReadableStream(buffer);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let _streamProtocolHandler = undefined;
|
|
116
|
+
const streamProtocolHandler = async (
|
|
117
|
+
req,
|
|
118
|
+
callback) => {
|
|
119
|
+
|
|
120
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} streamProtocolHandler req.url: ${req.url}`);
|
|
121
|
+
const u = new URL(req.url);
|
|
122
|
+
|
|
123
|
+
if (LOG_DEBUG) {
|
|
124
|
+
Object.keys(req.headers).forEach((header) => {
|
|
125
|
+
const val = req.headers[header];
|
|
126
|
+
|
|
127
|
+
console.log(`${ACE_LOG_PREFIX} streamProtocolHandler req.header: ${header} => ${val}`);
|
|
128
|
+
|
|
129
|
+
// if (val) {
|
|
130
|
+
// headers[header] = val;
|
|
131
|
+
// }
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let ref = u.origin;
|
|
136
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} streamProtocolHandler u.origin: ${ref}`);
|
|
137
|
+
if (req.referrer && req.referrer.trim()) {
|
|
138
|
+
ref = req.referrer;
|
|
139
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} streamProtocolHandler req.referrer: ${ref}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const headers = {};
|
|
143
|
+
|
|
144
|
+
if (ref && ref !== "null" && !/^https?:\/\/localhost.+/.test(ref) && !/^https?:\/\/127\.0\.0\.1.+/.test(ref)) {
|
|
145
|
+
headers.referer = ref;
|
|
146
|
+
} else {
|
|
147
|
+
headers.referer = `${ACE_ELECTRON_HTTP_PROTOCOL}://0.0.0.0/`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// CORS everything!
|
|
151
|
+
headers["Access-Control-Allow-Origin"] = "*";
|
|
152
|
+
headers["Access-Control-Allow-Methods"] = "GET, HEAD, OPTIONS"; // POST, DELETE, PUT, PATCH
|
|
153
|
+
// tslint:disable-next-line:max-line-length
|
|
154
|
+
headers["Access-Control-Allow-Headers"] = "Content-Type, Content-Length, Accept-Ranges, Content-Range, Range, Link, Transfer-Encoding, X-Requested-With, Authorization, Accept, Origin, User-Agent, DNT, Cache-Control, Keep-Alive, If-Modified-Since";
|
|
155
|
+
// tslint:disable-next-line:max-line-length
|
|
156
|
+
headers["Access-Control-Expose-Headers"] = "Content-Type, Content-Length, Accept-Ranges, Content-Range, Range, Link, Transfer-Encoding, X-Requested-With, Authorization, Accept, Origin, User-Agent, DNT, Cache-Control, Keep-Alive, If-Modified-Since";
|
|
157
|
+
|
|
158
|
+
if (!_streamProtocolHandler) {
|
|
159
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} !? _streamProtocolHandler`);
|
|
160
|
+
|
|
161
|
+
const buff = Buffer.from("<html><body><p>Internal Server Error</p><p>!_streamProtocolHandler</p></body></html>");
|
|
162
|
+
headers["Content-Length"] = buff.length.toString();
|
|
163
|
+
callback({
|
|
164
|
+
data: bufferToStream(buff),
|
|
165
|
+
headers,
|
|
166
|
+
statusCode: 500,
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} BEFORE _streamProtocolHandler ${req.url}`);
|
|
171
|
+
await _streamProtocolHandler(req, callback, headers);
|
|
172
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} AFTER _streamProtocolHandler ${req.url}`);
|
|
173
|
+
};
|
|
174
|
+
app.whenReady().then(async () => {
|
|
175
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} Electron app ready`);
|
|
176
|
+
|
|
177
|
+
// try {
|
|
178
|
+
// await clearSessions();
|
|
179
|
+
// } catch (err) {
|
|
180
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} clearSessions fail?`);
|
|
181
|
+
// }
|
|
182
|
+
|
|
183
|
+
// if (session.defaultSession) {
|
|
184
|
+
// session.defaultSession.protocol.registerStreamProtocol(
|
|
185
|
+
// ACE_ELECTRON_HTTP_PROTOCOL,
|
|
186
|
+
// streamProtocolHandler);
|
|
187
|
+
// }
|
|
188
|
+
const sess = session.fromPartition(SESSION_PARTITION, { cache: true });
|
|
189
|
+
if (sess) {
|
|
190
|
+
sess.protocol.registerStreamProtocol(
|
|
191
|
+
ACE_ELECTRON_HTTP_PROTOCOL,
|
|
192
|
+
streamProtocolHandler);
|
|
193
|
+
|
|
194
|
+
sess.setPermissionRequestHandler((wc, permission, callback) => {
|
|
195
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} setPermissionRequestHandler ${wc.getURL()} => ${permission}`);
|
|
196
|
+
callback(true);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
53
201
|
function loadUrl(browserWindow) {
|
|
54
202
|
browserWindow.ace__loadUrlPending = undefined;
|
|
55
203
|
|
|
@@ -151,6 +299,8 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
151
299
|
}
|
|
152
300
|
axeRunnerInit.todo = false;
|
|
153
301
|
|
|
302
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunnerInit TODO ...`);
|
|
303
|
+
|
|
154
304
|
const firstTimeInit = _firstTimeInit;
|
|
155
305
|
_firstTimeInit = false;
|
|
156
306
|
|
|
@@ -171,7 +321,8 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
171
321
|
webSecurity: true,
|
|
172
322
|
webviewTag: false,
|
|
173
323
|
enableRemoteModule: false,
|
|
174
|
-
partition: SESSION_PARTITION
|
|
324
|
+
partition: SESSION_PARTITION,
|
|
325
|
+
nativeWindowOpen: false, // The default of nativeWindowOpen is deprecated and will be changing from false to true in Electron 15. See https://github.com/electron/electron/issues/28511
|
|
175
326
|
},
|
|
176
327
|
});
|
|
177
328
|
|
|
@@ -226,15 +377,18 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
226
377
|
return;
|
|
227
378
|
}
|
|
228
379
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
380
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunnerInit firstTimeInit ...`);
|
|
381
|
+
|
|
382
|
+
// NO_HTTP_REMOVE
|
|
383
|
+
// app.on("certificate-error", (event, webContents, u, error, certificate, callback) => {
|
|
384
|
+
// if (u.indexOf(`${rootUrl}/`) === 0) {
|
|
385
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error OKAY ${u}`);
|
|
386
|
+
// callback(true);
|
|
387
|
+
// return;
|
|
388
|
+
// }
|
|
389
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error FAIL ${u}`);
|
|
390
|
+
// callback(false);
|
|
391
|
+
// });
|
|
238
392
|
|
|
239
393
|
// const filter = { urls: ["*", "*://*/*"] };
|
|
240
394
|
|
|
@@ -259,25 +413,23 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
259
413
|
// }
|
|
260
414
|
// };
|
|
261
415
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
sess.setCertificateVerifyProc(setCertificateVerifyProcCB);
|
|
280
|
-
}
|
|
416
|
+
// NO_HTTP_REMOVE
|
|
417
|
+
// const setCertificateVerifyProcCB = (request, callback) => {
|
|
418
|
+
// if (request.hostname === ip) {
|
|
419
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify OKAY ${request.hostname}`);
|
|
420
|
+
// callback(0); // OK
|
|
421
|
+
// return;
|
|
422
|
+
// }
|
|
423
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify FALLBACK ${request.hostname}`);
|
|
424
|
+
// callback(-3); // Chromium
|
|
425
|
+
// // callback(-2); // Fail
|
|
426
|
+
// };
|
|
427
|
+
// const sess = session.fromPartition(SESSION_PARTITION, { cache: true }); // || session.defaultSession;
|
|
428
|
+
// if (sess) {
|
|
429
|
+
// // sess.webRequest.onHeadersReceived(filter, onHeadersReceivedCB);
|
|
430
|
+
// // sess.webRequest.onBeforeSendHeaders(filter, onBeforeSendHeadersCB);
|
|
431
|
+
// sess.setCertificateVerifyProc(setCertificateVerifyProcCB);
|
|
432
|
+
// }
|
|
281
433
|
|
|
282
434
|
// ipcMain
|
|
283
435
|
eventEmmitter.on('AXE_RUNNER_CLOSE', (event, arg) => {
|
|
@@ -302,13 +454,17 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
302
454
|
}
|
|
303
455
|
browserWindows = undefined;
|
|
304
456
|
|
|
457
|
+
// NO_HTTP_ADD
|
|
458
|
+
_streamProtocolHandler = undefined;
|
|
459
|
+
|
|
305
460
|
httpServerStarted = false;
|
|
306
461
|
httpServerStartWasRequested = false;
|
|
307
462
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
463
|
+
// NO_HTTP_REMOVE
|
|
464
|
+
// if (httpServer) {
|
|
465
|
+
// httpServer.close();
|
|
466
|
+
// httpServer = undefined;
|
|
467
|
+
// }
|
|
312
468
|
|
|
313
469
|
let _timeOutID = setTimeout(() => {
|
|
314
470
|
_timeOutID = undefined;
|
|
@@ -340,6 +496,7 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
340
496
|
}
|
|
341
497
|
}
|
|
342
498
|
|
|
499
|
+
// clearSessions()
|
|
343
500
|
const sess = session.fromPartition(SESSION_PARTITION, { cache: true }); // || session.defaultSession;
|
|
344
501
|
if (sess) {
|
|
345
502
|
setTimeout(async () => {
|
|
@@ -395,7 +552,8 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
395
552
|
console.log(uarel);
|
|
396
553
|
}
|
|
397
554
|
// windows! file://C:\aa\bb\chapter.xhtml
|
|
398
|
-
|
|
555
|
+
|
|
556
|
+
const uarelObj = new URL(uarel.replace(/\\/g, "/"));
|
|
399
557
|
const windowsDrive = uarelObj.hostname ? `${uarelObj.hostname.toUpperCase()}:` : "";
|
|
400
558
|
if (LOG_DEBUG_URLS) {
|
|
401
559
|
console.log("######## URL 2");
|
|
@@ -443,8 +601,6 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
443
601
|
return;
|
|
444
602
|
}
|
|
445
603
|
|
|
446
|
-
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner free browser window in pool: ${browserWindow.ace__poolIndex}`);
|
|
447
|
-
|
|
448
604
|
browserWindow.ace__eventEmmitterSender = sender;
|
|
449
605
|
browserWindow.ace__replySent = false;
|
|
450
606
|
browserWindow.ace__timeout = undefined;
|
|
@@ -452,13 +608,15 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
452
608
|
browserWindow.ace__currentUrlOriginal = uarel;
|
|
453
609
|
browserWindow.ace__currentUrl = httpUrl;
|
|
454
610
|
|
|
611
|
+
if (LOG_DEBUG) console.log(`\n\n${ACE_LOG_PREFIX} axeRunner free browser window in pool: ${browserWindow.ace__poolIndex} ${browserWindow.ace__previousUrl} ${browserWindow.ace__currentUrlOriginal} ${browserWindow.ace__currentUrl}\n\n`);
|
|
612
|
+
|
|
455
613
|
browserWindow.webContents.once("did-start-loading", () => {
|
|
456
614
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-start-loading ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
|
|
457
615
|
});
|
|
458
616
|
// browserWindow.webContents.once("did-stop-loading", () => {
|
|
459
617
|
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-stop-loading ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
|
|
460
618
|
// });
|
|
461
|
-
|
|
619
|
+
const didFailLoadHandler = (event, errorCode, errorDescription, validatedURL, isMainFrame, frameProcessId, frameRoutingId) => {
|
|
462
620
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-fail-load ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`, "\n", `${errorCode} - ${errorDescription} - ${validatedURL} - ${isMainFrame} - ${frameProcessId} - ${frameRoutingId}`);
|
|
463
621
|
|
|
464
622
|
// https://cs.chromium.org/chromium/src/net/base/net_error_list.h
|
|
@@ -482,11 +640,16 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
|
482
640
|
err: `did-fail-load: ${errorCode} - ${errorDescription} - ${validatedURL} - ${isMainFrame} - ${frameProcessId} - ${frameRoutingId}`,
|
|
483
641
|
url: browserWindow.ace__currentUrlOriginal
|
|
484
642
|
});
|
|
485
|
-
}
|
|
643
|
+
};
|
|
644
|
+
browserWindow.webContents.once("did-fail-load", didFailLoadHandler);
|
|
486
645
|
// browserWindow.webContents.once("dom-ready", () => { // occurs early
|
|
487
646
|
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner dom-ready ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
|
|
488
647
|
// });
|
|
489
648
|
browserWindow.webContents.once("did-finish-load", () => {
|
|
649
|
+
// browserWindow.webContents.setMaxListeners(11+) ?
|
|
650
|
+
// (node:5505) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 did-fail-load listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
|
|
651
|
+
browserWindow.webContents.removeListener("did-fail-load", didFailLoadHandler);
|
|
652
|
+
|
|
490
653
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-finish-load ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
|
|
491
654
|
|
|
492
655
|
browserWindow.ace__TIME_executeJavaScript = process.hrtime();
|
|
@@ -577,7 +740,7 @@ new Promise((resolve, reject) => {
|
|
|
577
740
|
} else {
|
|
578
741
|
browserWindow.ace__loadUrlPending = httpUrl;
|
|
579
742
|
}
|
|
580
|
-
}
|
|
743
|
+
} // poolPush()
|
|
581
744
|
|
|
582
745
|
if (!httpServerStartWasRequested) { // lazy init
|
|
583
746
|
httpServerStartWasRequested = true;
|
|
@@ -586,19 +749,30 @@ new Promise((resolve, reject) => {
|
|
|
586
749
|
|
|
587
750
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner starting server ...`);
|
|
588
751
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
poolCheck();
|
|
594
|
-
}).catch((err) => {
|
|
752
|
+
// NO_HTTP_ADD
|
|
753
|
+
try {
|
|
754
|
+
startAxeServer(basedir, scripts, scriptContents);
|
|
755
|
+
} catch (err) {
|
|
595
756
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner server error`);
|
|
596
757
|
console.log(err);
|
|
597
758
|
browserWindow.ace__eventEmmitterSender.send("AXE_RUNNER_RUN_", {
|
|
598
759
|
err,
|
|
599
760
|
url: browserWindow.ace__currentUrlOriginal
|
|
600
761
|
});
|
|
601
|
-
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner server started`);
|
|
766
|
+
httpServerStarted = true;
|
|
767
|
+
poolCheck();
|
|
768
|
+
|
|
769
|
+
// NO_HTTP_REMOVE
|
|
770
|
+
// startAxeServer(basedir, scripts, scriptContents).then(() => {
|
|
771
|
+
// // ...
|
|
772
|
+
// httpServerStarted = true;
|
|
773
|
+
// }).catch((err) => {
|
|
774
|
+
// // ...
|
|
775
|
+
// });
|
|
602
776
|
} else {
|
|
603
777
|
poolPush();
|
|
604
778
|
}
|
|
@@ -609,7 +783,8 @@ axeRunnerInit.todo = true;
|
|
|
609
783
|
const filePathsExpressStaticNotExist = {};
|
|
610
784
|
function startAxeServer(basedir, scripts, scriptContents) {
|
|
611
785
|
|
|
612
|
-
|
|
786
|
+
// NO_HTTP_REMOVE
|
|
787
|
+
// return new Promise((resolve, reject) => {
|
|
613
788
|
|
|
614
789
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner startAxeServer...`);
|
|
615
790
|
|
|
@@ -626,16 +801,12 @@ function startAxeServer(basedir, scripts, scriptContents) {
|
|
|
626
801
|
scriptsMarkup += `<script data-ace="" src="/${HTTP_QUERY_PARAM}/${filename}"> </script>`;
|
|
627
802
|
});
|
|
628
803
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
// });
|
|
636
|
-
|
|
637
|
-
expressApp.basedir = basedir;
|
|
638
|
-
expressApp.use("/", (req, res, next) => {
|
|
804
|
+
// NO_HTTP_ADD
|
|
805
|
+
_streamProtocolHandler = async (
|
|
806
|
+
req,
|
|
807
|
+
callback,
|
|
808
|
+
headers) => {
|
|
809
|
+
const u = new URL(req.url);
|
|
639
810
|
|
|
640
811
|
for (const scriptPath of scripts) {
|
|
641
812
|
const filename = path.basename(scriptPath);
|
|
@@ -647,22 +818,29 @@ function startAxeServer(basedir, scripts, scriptContents) {
|
|
|
647
818
|
// if (LOG_DEBUG) console.log(js);
|
|
648
819
|
jsCache[scriptPath] = js;
|
|
649
820
|
} else {
|
|
650
|
-
|
|
821
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP already loaded ${scriptPath}`);
|
|
651
822
|
}
|
|
652
|
-
|
|
653
|
-
|
|
823
|
+
const buff = Buffer.from(js);
|
|
824
|
+
headers["Content-Length"] = buff.length.toString();
|
|
825
|
+
headers["Content-Type"] = "text/javascript";
|
|
826
|
+
callback({
|
|
827
|
+
data: bufferToStream(buff),
|
|
828
|
+
headers,
|
|
829
|
+
statusCode: 200,
|
|
830
|
+
});
|
|
654
831
|
return;
|
|
655
832
|
}
|
|
656
833
|
}
|
|
657
834
|
|
|
658
|
-
|
|
835
|
+
const queryParam = u.searchParams.get(HTTP_QUERY_PARAM) || undefined;
|
|
836
|
+
if (queryParam) {
|
|
659
837
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP intercept ${req.url}`);
|
|
660
838
|
|
|
661
839
|
if (LOG_DEBUG_URLS) {
|
|
662
840
|
console.log(">>>>>>>>>> URL 1");
|
|
663
841
|
console.log(req.url);
|
|
664
842
|
}
|
|
665
|
-
const ptn =
|
|
843
|
+
const ptn = u.pathname;
|
|
666
844
|
if (LOG_DEBUG_URLS) {
|
|
667
845
|
console.log(">>>>>>>>>> URL 2");
|
|
668
846
|
console.log(ptn);
|
|
@@ -672,7 +850,8 @@ function startAxeServer(basedir, scripts, scriptContents) {
|
|
|
672
850
|
console.log(">>>>>>>>>> URL 3");
|
|
673
851
|
console.log(pn);
|
|
674
852
|
}
|
|
675
|
-
|
|
853
|
+
|
|
854
|
+
let fileSystemPath = path.join(basedir, pn);
|
|
676
855
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} filepath to read: ${fileSystemPath}`);
|
|
677
856
|
if (!fs.existsSync(fileSystemPath)) {
|
|
678
857
|
fileSystemPath = pn;
|
|
@@ -683,7 +862,11 @@ function startAxeServer(basedir, scripts, scriptContents) {
|
|
|
683
862
|
fs.readFile(fileSystemPath, { encoding: "utf8" }, (err, html) => {
|
|
684
863
|
if (err) {
|
|
685
864
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML file load??! ${req.url}`);
|
|
686
|
-
|
|
865
|
+
callback({
|
|
866
|
+
data: null,
|
|
867
|
+
headers,
|
|
868
|
+
statusCode: 404,
|
|
869
|
+
});
|
|
687
870
|
return;
|
|
688
871
|
}
|
|
689
872
|
|
|
@@ -698,24 +881,86 @@ function startAxeServer(basedir, scripts, scriptContents) {
|
|
|
698
881
|
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML neither </head> nor </body>?! ${req.url}`);
|
|
699
882
|
}
|
|
700
883
|
|
|
701
|
-
|
|
702
|
-
|
|
884
|
+
const buff = Buffer.from(html);
|
|
885
|
+
headers["Content-Length"] = buff.length.toString();
|
|
886
|
+
headers["Content-Type"] = "application/xhtml+xml";
|
|
887
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} CALLBACK HEADERS ${req.url} ${JSON.stringify(headers)}`);
|
|
888
|
+
callback({
|
|
889
|
+
data: bufferToStream(buff),
|
|
890
|
+
headers,
|
|
891
|
+
statusCode: 200,
|
|
892
|
+
});
|
|
893
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} POST-CALLBACK ${req.url}`);
|
|
703
894
|
});
|
|
704
895
|
return;
|
|
705
896
|
}
|
|
706
897
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
898
|
+
// equivalent to Express static:
|
|
899
|
+
|
|
900
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} Express static emulate: ${req.url}`);
|
|
901
|
+
|
|
902
|
+
if (LOG_DEBUG_URLS) {
|
|
903
|
+
console.log(">>>>>>>>>>- URL 1");
|
|
904
|
+
console.log(req.url);
|
|
905
|
+
}
|
|
906
|
+
const ptn = u.pathname;
|
|
907
|
+
if (LOG_DEBUG_URLS) {
|
|
908
|
+
console.log(">>>>>>>>>>- URL 2");
|
|
909
|
+
console.log(ptn);
|
|
910
|
+
}
|
|
911
|
+
const pn = decodeURI(ptn);
|
|
912
|
+
if (LOG_DEBUG_URLS) {
|
|
913
|
+
console.log(">>>>>>>>>>- URL 3");
|
|
914
|
+
console.log(pn);
|
|
915
|
+
}
|
|
916
|
+
let fileSystemPath = path.join(basedir, pn);
|
|
917
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --filepath to read: ${fileSystemPath}`);
|
|
918
|
+
if (!fs.existsSync(fileSystemPath)) {
|
|
919
|
+
fileSystemPath = pn;
|
|
920
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --filepath to read (corrected): ${fileSystemPath}`);
|
|
921
|
+
}
|
|
922
|
+
try {
|
|
923
|
+
let mediaType = mime.lookup(fileSystemPath) || "stream/octet";
|
|
924
|
+
const stats = fs.statSync(fileSystemPath);
|
|
925
|
+
headers["Content-Length"] = stats.size;
|
|
926
|
+
headers["Content-Type"] = mediaType;
|
|
927
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --CALLBACK HEADERS ${req.url} ${JSON.stringify(headers)}`);
|
|
928
|
+
const steam = fs.createReadStream(fileSystemPath);
|
|
929
|
+
callback({
|
|
930
|
+
data: steam,
|
|
931
|
+
headers,
|
|
932
|
+
statusCode: 200,
|
|
933
|
+
});
|
|
934
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --POST-CALLBACK ${req.url}`);
|
|
935
|
+
} catch (fsErr) {
|
|
936
|
+
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --fsErr ${fsErr}`);
|
|
937
|
+
|
|
938
|
+
const buff = Buffer.from(`<html><body><p>Internal Server Error</p><p>fsErr: ${fsErr}</p></body></html>`);
|
|
939
|
+
headers["Content-Length"] = buff.length.toString();
|
|
940
|
+
callback({
|
|
941
|
+
data: bufferToStream(buff),
|
|
942
|
+
headers,
|
|
943
|
+
statusCode: 500,
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
if (isDev) { // handle WebInspector JS maps etc.
|
|
948
|
+
|
|
712
949
|
// const url = new URL(`https://fake.org${req.url}`);
|
|
713
950
|
// const pathname = url.pathname;
|
|
714
|
-
const pathname = decodeURI(
|
|
951
|
+
const pathname = decodeURI(u.pathname);
|
|
715
952
|
|
|
716
953
|
const filePath = path.join(basedir, pathname);
|
|
717
954
|
if (filePathsExpressStaticNotExist[filePath]) {
|
|
718
|
-
|
|
955
|
+
|
|
956
|
+
const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
|
|
957
|
+
headers["Content-Length"] = buff.length.toString();
|
|
958
|
+
headers["Content-Type"] = "plain/text";
|
|
959
|
+
callback({
|
|
960
|
+
data: bufferToStream(buff),
|
|
961
|
+
headers,
|
|
962
|
+
statusCode: 404,
|
|
963
|
+
});
|
|
719
964
|
return;
|
|
720
965
|
}
|
|
721
966
|
fsOriginal.exists(filePath, (exists) => {
|
|
@@ -726,13 +971,23 @@ function startAxeServer(basedir, scripts, scriptContents) {
|
|
|
726
971
|
console.log(`${ACE_LOG_PREFIX} HTTP FAIL fsOriginal.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
|
|
727
972
|
}
|
|
728
973
|
filePathsExpressStaticNotExist[filePath] = err.toString();
|
|
729
|
-
|
|
974
|
+
const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
|
|
975
|
+
headers["Content-Length"] = buff.length.toString();
|
|
976
|
+
headers["Content-Type"] = "plain/text";
|
|
977
|
+
callback({
|
|
978
|
+
data: bufferToStream(buff),
|
|
979
|
+
headers,
|
|
980
|
+
statusCode: 404,
|
|
981
|
+
});
|
|
730
982
|
} else {
|
|
731
983
|
// if (LOG_DEBUG) {
|
|
732
984
|
// console.log(`${ACE_LOG_PREFIX} HTTP OK fsOriginal.exists ${basedir} + ${req.url} => ${filePath}`);
|
|
733
985
|
// }
|
|
734
|
-
|
|
735
|
-
|
|
986
|
+
callback({
|
|
987
|
+
data: null,
|
|
988
|
+
headers,
|
|
989
|
+
statusCode: 500,
|
|
990
|
+
});
|
|
736
991
|
}
|
|
737
992
|
});
|
|
738
993
|
} else {
|
|
@@ -744,93 +999,122 @@ function startAxeServer(basedir, scripts, scriptContents) {
|
|
|
744
999
|
console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && fs.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
|
|
745
1000
|
}
|
|
746
1001
|
filePathsExpressStaticNotExist[filePath] = err.toString();
|
|
747
|
-
|
|
1002
|
+
const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
|
|
1003
|
+
headers["Content-Length"] = buff.length.toString();
|
|
1004
|
+
headers["Content-Type"] = "plain/text";
|
|
1005
|
+
callback({
|
|
1006
|
+
data: bufferToStream(buff),
|
|
1007
|
+
headers,
|
|
1008
|
+
statusCode: 404,
|
|
1009
|
+
});
|
|
748
1010
|
} else {
|
|
749
1011
|
if (LOG_DEBUG) {
|
|
750
1012
|
console.log(`${ACE_LOG_PREFIX} HTTP OK !fsOriginal.exists && fs.exists ${basedir} + ${req.url} => ${filePath}`);
|
|
751
1013
|
}
|
|
752
|
-
|
|
753
|
-
|
|
1014
|
+
callback({
|
|
1015
|
+
data: null,
|
|
1016
|
+
headers,
|
|
1017
|
+
statusCode: 500,
|
|
1018
|
+
});
|
|
754
1019
|
}
|
|
755
1020
|
});
|
|
756
1021
|
} else {
|
|
757
1022
|
if (LOG_DEBUG) {
|
|
758
1023
|
console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && !fs.exists ${basedir} + ${req.url} => ${filePath}`);
|
|
759
1024
|
}
|
|
760
|
-
|
|
1025
|
+
callback({
|
|
1026
|
+
data: null,
|
|
1027
|
+
headers,
|
|
1028
|
+
statusCode: 404,
|
|
1029
|
+
});
|
|
761
1030
|
}
|
|
762
1031
|
});
|
|
763
1032
|
}
|
|
764
1033
|
});
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
// https://expressjs.com/en/4x/api.html#express.static
|
|
769
|
-
const staticOptions = {
|
|
770
|
-
dotfiles: "ignore",
|
|
771
|
-
etag: true,
|
|
772
|
-
// fallthrough: false,
|
|
773
|
-
immutable: true,
|
|
774
|
-
// index: "index.html",
|
|
775
|
-
maxAge: "1d",
|
|
776
|
-
redirect: false,
|
|
777
|
-
// extensions: ["css", "otf"],
|
|
778
|
-
// setHeaders: (res, _path, _stat) => {
|
|
779
|
-
// // res.set('x-timestamp', Date.now())
|
|
780
|
-
// setResponseCORS(res);
|
|
781
|
-
// },
|
|
1034
|
+
}
|
|
782
1035
|
};
|
|
783
|
-
if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP static path ${basedir}`);
|
|
784
|
-
expressApp.use("/", express.static(basedir, staticOptions));
|
|
785
1036
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
1037
|
+
// NO_HTTP_REMOVE
|
|
1038
|
+
// expressApp = express();
|
|
1039
|
+
// // expressApp.enable('strict routing');
|
|
1040
|
+
// // expressApp.use("/", (req, res, next) => {
|
|
1041
|
+
// // if (LOG_DEBUG) console.log("HTTP: " + req.url);
|
|
1042
|
+
// // next();
|
|
1043
|
+
// // });
|
|
1044
|
+
// expressApp.basedir = basedir;
|
|
1045
|
+
// expressApp.use("/", (req, res, next) => {
|
|
1046
|
+
// next();
|
|
1047
|
+
// });
|
|
1048
|
+
// if (isDev) { // handle WebInspector JS maps etc.
|
|
1049
|
+
// expressApp.use("/", (req, res, next) => {
|
|
1050
|
+
// });
|
|
1051
|
+
// }
|
|
799
1052
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
1053
|
+
// // https://expressjs.com/en/4x/api.html#express.static
|
|
1054
|
+
// const staticOptions = {
|
|
1055
|
+
// dotfiles: "ignore",
|
|
1056
|
+
// etag: true,
|
|
1057
|
+
// // fallthrough: false,
|
|
1058
|
+
// immutable: true,
|
|
1059
|
+
// // index: "index.html",
|
|
1060
|
+
// maxAge: "1d",
|
|
1061
|
+
// redirect: false,
|
|
1062
|
+
// // extensions: ["css", "otf"],
|
|
1063
|
+
// // setHeaders: (res, _path, _stat) => {
|
|
1064
|
+
// // // res.set('x-timestamp', Date.now())
|
|
1065
|
+
// // setResponseCORS(res);
|
|
1066
|
+
// // },
|
|
1067
|
+
// };
|
|
1068
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP static path ${basedir}`);
|
|
1069
|
+
// expressApp.use("/", express.static(basedir, staticOptions));
|
|
1070
|
+
|
|
1071
|
+
// const startHttp = function () {
|
|
1072
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData...`);
|
|
1073
|
+
// generateSelfSignedData().then((certData) => {
|
|
1074
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData OK.`);
|
|
1075
|
+
|
|
1076
|
+
// httpServer = https.createServer({ key: certData.private, cert: certData.cert }, expressApp).listen(port, () => {
|
|
1077
|
+
// const p = httpServer.address().port;
|
|
1078
|
+
|
|
1079
|
+
// port = p;
|
|
1080
|
+
// ip = "127.0.0.1";
|
|
1081
|
+
// proto = "https";
|
|
1082
|
+
// rootUrl = `${proto}://${ip}:${port}`;
|
|
1083
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
|
|
1084
|
+
|
|
1085
|
+
// resolve();
|
|
1086
|
+
// });
|
|
1087
|
+
// }).catch((err) => {
|
|
1088
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} generateSelfSignedData error!`);
|
|
1089
|
+
// if (LOG_DEBUG) console.log(err);
|
|
1090
|
+
// httpServer = expressApp.listen(port, () => {
|
|
1091
|
+
// const p = httpServer.address().port;
|
|
1092
|
+
|
|
1093
|
+
// port = p;
|
|
1094
|
+
// ip = "127.0.0.1";
|
|
1095
|
+
// proto = "http";
|
|
1096
|
+
// rootUrl = `${proto}://${ip}:${port}`;
|
|
1097
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
|
|
1098
|
+
|
|
1099
|
+
// resolve();
|
|
1100
|
+
// });
|
|
1101
|
+
// });
|
|
1102
|
+
// }
|
|
818
1103
|
|
|
819
|
-
portfinder.getPortPromise().then((p) => {
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
}).catch((err) => {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
});
|
|
829
|
-
});
|
|
1104
|
+
// portfinder.getPortPromise().then((p) => {
|
|
1105
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port ${p}`);
|
|
1106
|
+
// port = p;
|
|
1107
|
+
// startHttp();
|
|
1108
|
+
// }).catch((err) => {
|
|
1109
|
+
// if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port error!`);
|
|
1110
|
+
// console.log(err);
|
|
1111
|
+
// port = 3000;
|
|
1112
|
+
// startHttp();
|
|
1113
|
+
// });
|
|
1114
|
+
// });
|
|
830
1115
|
}
|
|
831
1116
|
|
|
832
1117
|
function prepareLaunch(eventEmmitter, CONCURRENT_INSTANCES) {
|
|
833
|
-
|
|
834
1118
|
eventEmmitter.on('AXE_RUNNER_LAUNCH', (event, arg) => {
|
|
835
1119
|
// const payload = eventEmmitter.ace_notElectronIpcMainRenderer ? event : arg;
|
|
836
1120
|
const sender = eventEmmitter.ace_notElectronIpcMainRenderer ? eventEmmitter : event.sender;
|