@daisy/ace-axe-runner-electron 1.2.3 → 1.2.6-alpha.3

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/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
- let expressApp;
36
- let httpServer;
37
- let port;
38
- let ip;
39
- let proto;
40
- let rootUrl;
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
 
@@ -182,8 +333,17 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
182
333
  urls: [],
183
334
  }, (details, callback) => {
184
335
  if (details.url
185
- && /^https?:\/\//.test(details.url)
186
- && ((rootUrl && !details.url.startsWith(rootUrl)) || (!rootUrl && !/^https?:\/\/127.0.0.1/.test(details.url)))
336
+ &&
337
+ (
338
+ /^file:\/\//.test(details.url)
339
+ ||
340
+ /^https?:\/\//.test(details.url)
341
+ // && (
342
+ // (rootUrl && !details.url.startsWith(rootUrl))
343
+ // ||
344
+ // (!rootUrl && !/^https?:\/\/127.0.0.1/.test(details.url))
345
+ // )
346
+ )
187
347
  ) {
188
348
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} onBeforeRequest BLOCK: ${details.url} (${rootUrl})`);
189
349
 
@@ -226,15 +386,18 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
226
386
  return;
227
387
  }
228
388
 
229
- app.on("certificate-error", (event, webContents, u, error, certificate, callback) => {
230
- if (u.indexOf(`${rootUrl}/`) === 0) {
231
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error OKAY ${u}`);
232
- callback(true);
233
- return;
234
- }
235
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error FAIL ${u}`);
236
- callback(false);
237
- });
389
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunnerInit firstTimeInit ...`);
390
+
391
+ // NO_HTTP_REMOVE
392
+ // app.on("certificate-error", (event, webContents, u, error, certificate, callback) => {
393
+ // if (u.indexOf(`${rootUrl}/`) === 0) {
394
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error OKAY ${u}`);
395
+ // callback(true);
396
+ // return;
397
+ // }
398
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error FAIL ${u}`);
399
+ // callback(false);
400
+ // });
238
401
 
239
402
  // const filter = { urls: ["*", "*://*/*"] };
240
403
 
@@ -259,25 +422,23 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
259
422
  // }
260
423
  // };
261
424
 
262
- const setCertificateVerifyProcCB = (request, callback) => {
263
-
264
- if (request.hostname === ip) {
265
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify OKAY ${request.hostname}`);
266
- callback(0); // OK
267
- return;
268
- }
269
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify FALLBACK ${request.hostname}`);
270
- callback(-3); // Chromium
271
- // callback(-2); // Fail
272
- };
273
-
274
- const sess = session.fromPartition(SESSION_PARTITION, { cache: true }); // || session.defaultSession;
275
-
276
- if (sess) {
277
- // sess.webRequest.onHeadersReceived(filter, onHeadersReceivedCB);
278
- // sess.webRequest.onBeforeSendHeaders(filter, onBeforeSendHeadersCB);
279
- sess.setCertificateVerifyProc(setCertificateVerifyProcCB);
280
- }
425
+ // NO_HTTP_REMOVE
426
+ // const setCertificateVerifyProcCB = (request, callback) => {
427
+ // if (request.hostname === ip) {
428
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify OKAY ${request.hostname}`);
429
+ // callback(0); // OK
430
+ // return;
431
+ // }
432
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify FALLBACK ${request.hostname}`);
433
+ // callback(-3); // Chromium
434
+ // // callback(-2); // Fail
435
+ // };
436
+ // const sess = session.fromPartition(SESSION_PARTITION, { cache: true }); // || session.defaultSession;
437
+ // if (sess) {
438
+ // // sess.webRequest.onHeadersReceived(filter, onHeadersReceivedCB);
439
+ // // sess.webRequest.onBeforeSendHeaders(filter, onBeforeSendHeadersCB);
440
+ // sess.setCertificateVerifyProc(setCertificateVerifyProcCB);
441
+ // }
281
442
 
282
443
  // ipcMain
283
444
  eventEmmitter.on('AXE_RUNNER_CLOSE', (event, arg) => {
@@ -302,13 +463,17 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
302
463
  }
303
464
  browserWindows = undefined;
304
465
 
466
+ // NO_HTTP_ADD
467
+ _streamProtocolHandler = undefined;
468
+
305
469
  httpServerStarted = false;
306
470
  httpServerStartWasRequested = false;
307
471
 
308
- if (httpServer) {
309
- httpServer.close();
310
- httpServer = undefined;
311
- }
472
+ // NO_HTTP_REMOVE
473
+ // if (httpServer) {
474
+ // httpServer.close();
475
+ // httpServer = undefined;
476
+ // }
312
477
 
313
478
  let _timeOutID = setTimeout(() => {
314
479
  _timeOutID = undefined;
@@ -340,6 +505,7 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
340
505
  }
341
506
  }
342
507
 
508
+ // clearSessions()
343
509
  const sess = session.fromPartition(SESSION_PARTITION, { cache: true }); // || session.defaultSession;
344
510
  if (sess) {
345
511
  setTimeout(async () => {
@@ -395,7 +561,8 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
395
561
  console.log(uarel);
396
562
  }
397
563
  // windows! file://C:\aa\bb\chapter.xhtml
398
- const uarelObj = url.parse(uarel.replace(/\\/g, "/"));
564
+
565
+ const uarelObj = new URL(uarel.replace(/\\/g, "/"));
399
566
  const windowsDrive = uarelObj.hostname ? `${uarelObj.hostname.toUpperCase()}:` : "";
400
567
  if (LOG_DEBUG_URLS) {
401
568
  console.log("######## URL 2");
@@ -443,8 +610,6 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
443
610
  return;
444
611
  }
445
612
 
446
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner free browser window in pool: ${browserWindow.ace__poolIndex}`);
447
-
448
613
  browserWindow.ace__eventEmmitterSender = sender;
449
614
  browserWindow.ace__replySent = false;
450
615
  browserWindow.ace__timeout = undefined;
@@ -452,13 +617,15 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
452
617
  browserWindow.ace__currentUrlOriginal = uarel;
453
618
  browserWindow.ace__currentUrl = httpUrl;
454
619
 
620
+ 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`);
621
+
455
622
  browserWindow.webContents.once("did-start-loading", () => {
456
623
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-start-loading ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
457
624
  });
458
625
  // browserWindow.webContents.once("did-stop-loading", () => {
459
626
  // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-stop-loading ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
460
627
  // });
461
- browserWindow.webContents.once("did-fail-load", (event, errorCode, errorDescription, validatedURL, isMainFrame, frameProcessId, frameRoutingId) => {
628
+ const didFailLoadHandler = (event, errorCode, errorDescription, validatedURL, isMainFrame, frameProcessId, frameRoutingId) => {
462
629
  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
630
 
464
631
  // https://cs.chromium.org/chromium/src/net/base/net_error_list.h
@@ -482,11 +649,16 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
482
649
  err: `did-fail-load: ${errorCode} - ${errorDescription} - ${validatedURL} - ${isMainFrame} - ${frameProcessId} - ${frameRoutingId}`,
483
650
  url: browserWindow.ace__currentUrlOriginal
484
651
  });
485
- });
652
+ };
653
+ browserWindow.webContents.once("did-fail-load", didFailLoadHandler);
486
654
  // browserWindow.webContents.once("dom-ready", () => { // occurs early
487
655
  // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner dom-ready ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
488
656
  // });
489
657
  browserWindow.webContents.once("did-finish-load", () => {
658
+ // browserWindow.webContents.setMaxListeners(11+) ?
659
+ // (node:5505) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 did-fail-load listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
660
+ browserWindow.webContents.removeListener("did-fail-load", didFailLoadHandler);
661
+
490
662
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-finish-load ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
491
663
 
492
664
  browserWindow.ace__TIME_executeJavaScript = process.hrtime();
@@ -577,7 +749,7 @@ new Promise((resolve, reject) => {
577
749
  } else {
578
750
  browserWindow.ace__loadUrlPending = httpUrl;
579
751
  }
580
- }
752
+ } // poolPush()
581
753
 
582
754
  if (!httpServerStartWasRequested) { // lazy init
583
755
  httpServerStartWasRequested = true;
@@ -586,19 +758,30 @@ new Promise((resolve, reject) => {
586
758
 
587
759
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner starting server ...`);
588
760
 
589
- startAxeServer(basedir, scripts, scriptContents).then(() => {
590
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner server started`);
591
- httpServerStarted = true;
592
-
593
- poolCheck();
594
- }).catch((err) => {
761
+ // NO_HTTP_ADD
762
+ try {
763
+ startAxeServer(basedir, scripts, scriptContents);
764
+ } catch (err) {
595
765
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner server error`);
596
766
  console.log(err);
597
767
  browserWindow.ace__eventEmmitterSender.send("AXE_RUNNER_RUN_", {
598
768
  err,
599
769
  url: browserWindow.ace__currentUrlOriginal
600
770
  });
601
- });
771
+ return;
772
+ }
773
+
774
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner server started`);
775
+ httpServerStarted = true;
776
+ poolCheck();
777
+
778
+ // NO_HTTP_REMOVE
779
+ // startAxeServer(basedir, scripts, scriptContents).then(() => {
780
+ // // ...
781
+ // httpServerStarted = true;
782
+ // }).catch((err) => {
783
+ // // ...
784
+ // });
602
785
  } else {
603
786
  poolPush();
604
787
  }
@@ -606,10 +789,11 @@ new Promise((resolve, reject) => {
606
789
  }
607
790
  axeRunnerInit.todo = true;
608
791
 
609
- const filePathsExpressStaticNotExist = {};
792
+ // const filePathsExpressStaticNotExist = {};
610
793
  function startAxeServer(basedir, scripts, scriptContents) {
611
794
 
612
- return new Promise((resolve, reject) => {
795
+ // NO_HTTP_REMOVE
796
+ // return new Promise((resolve, reject) => {
613
797
 
614
798
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner startAxeServer...`);
615
799
 
@@ -626,16 +810,12 @@ function startAxeServer(basedir, scripts, scriptContents) {
626
810
  scriptsMarkup += `<script data-ace="" src="/${HTTP_QUERY_PARAM}/${filename}"> </script>`;
627
811
  });
628
812
 
629
- expressApp = express();
630
- // expressApp.enable('strict routing');
631
-
632
- // expressApp.use("/", (req, res, next) => {
633
- // if (LOG_DEBUG) console.log("HTTP: " + req.url);
634
- // next();
635
- // });
636
-
637
- expressApp.basedir = basedir;
638
- expressApp.use("/", (req, res, next) => {
813
+ // NO_HTTP_ADD
814
+ _streamProtocolHandler = async (
815
+ req,
816
+ callback,
817
+ headers) => {
818
+ const u = new URL(req.url);
639
819
 
640
820
  for (const scriptPath of scripts) {
641
821
  const filename = path.basename(scriptPath);
@@ -647,22 +827,29 @@ function startAxeServer(basedir, scripts, scriptContents) {
647
827
  // if (LOG_DEBUG) console.log(js);
648
828
  jsCache[scriptPath] = js;
649
829
  } else {
650
- // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP already loaded ${scriptPath}`);
830
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP already loaded ${scriptPath}`);
651
831
  }
652
- res.setHeader("Content-Type", "text/javascript");
653
- res.send(js);
832
+ const buff = Buffer.from(js);
833
+ headers["Content-Length"] = buff.length.toString();
834
+ headers["Content-Type"] = "text/javascript";
835
+ callback({
836
+ data: bufferToStream(buff),
837
+ headers,
838
+ statusCode: 200,
839
+ });
654
840
  return;
655
841
  }
656
842
  }
657
843
 
658
- if (req.query[HTTP_QUERY_PARAM]) {
844
+ const queryParam = u.searchParams.get(HTTP_QUERY_PARAM) || undefined;
845
+ if (queryParam) {
659
846
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP intercept ${req.url}`);
660
847
 
661
848
  if (LOG_DEBUG_URLS) {
662
849
  console.log(">>>>>>>>>> URL 1");
663
850
  console.log(req.url);
664
851
  }
665
- const ptn = url.parse(req.url).pathname;
852
+ const ptn = u.pathname;
666
853
  if (LOG_DEBUG_URLS) {
667
854
  console.log(">>>>>>>>>> URL 2");
668
855
  console.log(ptn);
@@ -672,18 +859,35 @@ function startAxeServer(basedir, scripts, scriptContents) {
672
859
  console.log(">>>>>>>>>> URL 3");
673
860
  console.log(pn);
674
861
  }
675
- let fileSystemPath = path.join(expressApp.basedir, pn);
862
+
863
+ let fileSystemPath = path.join(basedir, pn);
676
864
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} filepath to read: ${fileSystemPath}`);
677
865
  if (!fs.existsSync(fileSystemPath)) {
678
866
  fileSystemPath = pn;
679
867
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} filepath to read (corrected): ${fileSystemPath}`);
868
+ if (!fs.existsSync(fileSystemPath)) {
869
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} FILE DOES NOT EXIST!! ${fileSystemPath}`);
870
+
871
+ const buff = Buffer.from(`<html><body><p>Internal Server Error</p><p>404?! ${fileSystemPath}</p></body></html>`);
872
+ headers["Content-Length"] = buff.length.toString();
873
+ callback({
874
+ data: bufferToStream(buff),
875
+ headers,
876
+ statusCode: 404,
877
+ });
878
+ return;
879
+ }
680
880
  }
681
881
 
682
882
  // let html = fs.readFileSync(fileSystemPath, { encoding: "utf8" });
683
883
  fs.readFile(fileSystemPath, { encoding: "utf8" }, (err, html) => {
684
884
  if (err) {
685
885
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML file load??! ${req.url}`);
686
- res.status(404).end();
886
+ callback({
887
+ data: null,
888
+ headers,
889
+ statusCode: 404,
890
+ });
687
891
  return;
688
892
  }
689
893
 
@@ -698,139 +902,252 @@ function startAxeServer(basedir, scripts, scriptContents) {
698
902
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML neither </head> nor </body>?! ${req.url}`);
699
903
  }
700
904
 
701
- res.setHeader("Content-Type", "application/xhtml+xml");
702
- res.send(html);
905
+ const buff = Buffer.from(html);
906
+ headers["Content-Length"] = buff.length.toString();
907
+ headers["Content-Type"] = "application/xhtml+xml";
908
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} CALLBACK HEADERS ${req.url} ${JSON.stringify(headers)}`);
909
+ callback({
910
+ data: bufferToStream(buff),
911
+ headers,
912
+ statusCode: 200,
913
+ });
914
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} POST-CALLBACK ${req.url}`);
703
915
  });
704
916
  return;
705
917
  }
706
918
 
707
- next();
708
- });
709
-
710
- if (isDev) { // handle WebInspector JS maps etc.
711
- expressApp.use("/", (req, res, next) => {
712
- // const url = new URL(`https://fake.org${req.url}`);
713
- // const pathname = url.pathname;
714
- const pathname = decodeURI(url.parse(req.url).pathname);
715
-
716
- const filePath = path.join(basedir, pathname);
717
- if (filePathsExpressStaticNotExist[filePath]) {
718
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
919
+ // equivalent to Express static:
920
+
921
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} Express static emulate: ${req.url}`);
922
+
923
+ if (LOG_DEBUG_URLS) {
924
+ console.log(">>>>>>>>>>- URL 1");
925
+ console.log(req.url);
926
+ }
927
+ const ptn = u.pathname;
928
+ if (LOG_DEBUG_URLS) {
929
+ console.log(">>>>>>>>>>- URL 2");
930
+ console.log(ptn);
931
+ }
932
+ const pn = decodeURI(ptn);
933
+ if (LOG_DEBUG_URLS) {
934
+ console.log(">>>>>>>>>>- URL 3");
935
+ console.log(pn);
936
+ }
937
+ let fileSystemPath = path.join(basedir, pn);
938
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --filepath to read: ${fileSystemPath}`);
939
+ if (!fs.existsSync(fileSystemPath)) {
940
+ fileSystemPath = pn;
941
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --filepath to read (corrected): ${fileSystemPath}`);
942
+ if (!fs.existsSync(fileSystemPath)) {
943
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --FILE DOES NOT EXIST!! ${fileSystemPath}`);
944
+
945
+ const buff = Buffer.from(`<html><body><p>Internal Server Error</p><p>404?! ${fileSystemPath}</p></body></html>`);
946
+ headers["Content-Length"] = buff.length.toString();
947
+ callback({
948
+ data: bufferToStream(buff),
949
+ headers,
950
+ statusCode: 404,
951
+ });
719
952
  return;
720
953
  }
721
- fsOriginal.exists(filePath, (exists) => {
722
- if (exists) {
723
- fsOriginal.readFile(filePath, undefined, (err, data) => {
724
- if (err) {
725
- if (LOG_DEBUG) {
726
- console.log(`${ACE_LOG_PREFIX} HTTP FAIL fsOriginal.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
727
- }
728
- filePathsExpressStaticNotExist[filePath] = err.toString();
729
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
730
- } else {
731
- // if (LOG_DEBUG) {
732
- // console.log(`${ACE_LOG_PREFIX} HTTP OK fsOriginal.exists ${basedir} + ${req.url} => ${filePath}`);
733
- // }
734
- next();
735
- // res.send(data);
736
- }
737
- });
738
- } else {
739
- fs.exists(filePath, (exists) => {
740
- if (exists) {
741
- fs.readFile(filePath, undefined, (err, data) => {
742
- if (err) {
743
- if (LOG_DEBUG) {
744
- console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && fs.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
745
- }
746
- filePathsExpressStaticNotExist[filePath] = err.toString();
747
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
748
- } else {
749
- if (LOG_DEBUG) {
750
- console.log(`${ACE_LOG_PREFIX} HTTP OK !fsOriginal.exists && fs.exists ${basedir} + ${req.url} => ${filePath}`);
751
- }
752
- next();
753
- // res.send(data);
754
- }
755
- });
756
- } else {
757
- if (LOG_DEBUG) {
758
- console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && !fs.exists ${basedir} + ${req.url} => ${filePath}`);
759
- }
760
- res.status(404).end();
761
- }
762
- });
763
- }
954
+ }
955
+ try {
956
+ let mediaType = mime.lookup(fileSystemPath) || "stream/octet";
957
+ const stats = fs.statSync(fileSystemPath);
958
+ headers["Content-Length"] = stats.size;
959
+ headers["Content-Type"] = mediaType;
960
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --CALLBACK HEADERS ${req.url} ${JSON.stringify(headers)}`);
961
+ const steam = fs.createReadStream(fileSystemPath);
962
+ callback({
963
+ data: steam,
964
+ headers,
965
+ statusCode: 200,
764
966
  });
765
- });
766
- }
967
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --POST-CALLBACK ${req.url}`);
968
+ } catch (fsErr) {
969
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --fsErr ${fsErr}`);
767
970
 
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
- // },
782
- };
783
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP static path ${basedir}`);
784
- expressApp.use("/", express.static(basedir, staticOptions));
785
-
786
- const startHttp = function () {
787
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData...`);
788
- generateSelfSignedData().then((certData) => {
789
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData OK.`);
971
+ const buff = Buffer.from(`<html><body><p>Internal Server Error</p><p>fsErr: ${fsErr}</p></body></html>`);
972
+ headers["Content-Length"] = buff.length.toString();
973
+ callback({
974
+ data: bufferToStream(buff),
975
+ headers,
976
+ statusCode: 500,
977
+ });
978
+ }
790
979
 
791
- httpServer = https.createServer({ key: certData.private, cert: certData.cert }, expressApp).listen(port, () => {
792
- const p = httpServer.address().port;
980
+ // if (isDev) { // handle WebInspector JS maps etc.
981
+
982
+ // // const url = new URL(`https://fake.org${req.url}`);
983
+ // // const pathname = url.pathname;
984
+ // const pathname = decodeURI(u.pathname);
985
+
986
+ // const filePath = path.join(basedir, pathname);
987
+ // if (filePathsExpressStaticNotExist[filePath]) {
988
+
989
+ // const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
990
+ // headers["Content-Length"] = buff.length.toString();
991
+ // headers["Content-Type"] = "plain/text";
992
+ // callback({
993
+ // data: bufferToStream(buff),
994
+ // headers,
995
+ // statusCode: 404,
996
+ // });
997
+ // return;
998
+ // }
999
+ // fsOriginal.exists(filePath, (exists) => {
1000
+ // if (exists) {
1001
+ // fsOriginal.readFile(filePath, undefined, (err, data) => {
1002
+ // if (err) {
1003
+ // if (LOG_DEBUG) {
1004
+ // console.log(`${ACE_LOG_PREFIX} HTTP FAIL fsOriginal.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
1005
+ // }
1006
+ // filePathsExpressStaticNotExist[filePath] = err.toString();
1007
+ // const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
1008
+ // headers["Content-Length"] = buff.length.toString();
1009
+ // headers["Content-Type"] = "plain/text";
1010
+ // callback({
1011
+ // data: bufferToStream(buff),
1012
+ // headers,
1013
+ // statusCode: 404,
1014
+ // });
1015
+ // } else {
1016
+ // // if (LOG_DEBUG) {
1017
+ // // console.log(`${ACE_LOG_PREFIX} HTTP OK fsOriginal.exists ${basedir} + ${req.url} => ${filePath}`);
1018
+ // // }
1019
+ // callback({
1020
+ // data: null,
1021
+ // headers,
1022
+ // statusCode: 500,
1023
+ // });
1024
+ // }
1025
+ // });
1026
+ // } else {
1027
+ // fs.exists(filePath, (exists) => {
1028
+ // if (exists) {
1029
+ // fs.readFile(filePath, undefined, (err, data) => {
1030
+ // if (err) {
1031
+ // if (LOG_DEBUG) {
1032
+ // console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && fs.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
1033
+ // }
1034
+ // filePathsExpressStaticNotExist[filePath] = err.toString();
1035
+ // const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
1036
+ // headers["Content-Length"] = buff.length.toString();
1037
+ // headers["Content-Type"] = "plain/text";
1038
+ // callback({
1039
+ // data: bufferToStream(buff),
1040
+ // headers,
1041
+ // statusCode: 404,
1042
+ // });
1043
+ // } else {
1044
+ // if (LOG_DEBUG) {
1045
+ // console.log(`${ACE_LOG_PREFIX} HTTP OK !fsOriginal.exists && fs.exists ${basedir} + ${req.url} => ${filePath}`);
1046
+ // }
1047
+ // callback({
1048
+ // data: null,
1049
+ // headers,
1050
+ // statusCode: 500,
1051
+ // });
1052
+ // }
1053
+ // });
1054
+ // } else {
1055
+ // if (LOG_DEBUG) {
1056
+ // console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && !fs.exists ${basedir} + ${req.url} => ${filePath}`);
1057
+ // }
1058
+ // callback({
1059
+ // data: null,
1060
+ // headers,
1061
+ // statusCode: 404,
1062
+ // });
1063
+ // }
1064
+ // });
1065
+ // }
1066
+ // });
1067
+ // }
1068
+ };
793
1069
 
794
- port = p;
795
- ip = "127.0.0.1";
796
- proto = "https";
797
- rootUrl = `${proto}://${ip}:${port}`;
798
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
1070
+ // NO_HTTP_REMOVE
1071
+ // expressApp = express();
1072
+ // // expressApp.enable('strict routing');
1073
+ // // expressApp.use("/", (req, res, next) => {
1074
+ // // if (LOG_DEBUG) console.log("HTTP: " + req.url);
1075
+ // // next();
1076
+ // // });
1077
+ // expressApp.basedir = basedir;
1078
+ // expressApp.use("/", (req, res, next) => {
1079
+ // next();
1080
+ // });
1081
+ // if (isDev) { // handle WebInspector JS maps etc.
1082
+ // expressApp.use("/", (req, res, next) => {
1083
+ // });
1084
+ // }
799
1085
 
800
- resolve();
801
- });
802
- }).catch((err) => {
803
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} generateSelfSignedData error!`);
804
- if (LOG_DEBUG) console.log(err);
805
- httpServer = expressApp.listen(port, () => {
806
- const p = httpServer.address().port;
807
-
808
- port = p;
809
- ip = "127.0.0.1";
810
- proto = "http";
811
- rootUrl = `${proto}://${ip}:${port}`;
812
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
813
-
814
- resolve();
815
- });
816
- });
817
- }
1086
+ // // https://expressjs.com/en/4x/api.html#express.static
1087
+ // const staticOptions = {
1088
+ // dotfiles: "ignore",
1089
+ // etag: true,
1090
+ // // fallthrough: false,
1091
+ // immutable: true,
1092
+ // // index: "index.html",
1093
+ // maxAge: "1d",
1094
+ // redirect: false,
1095
+ // // extensions: ["css", "otf"],
1096
+ // // setHeaders: (res, _path, _stat) => {
1097
+ // // // res.set('x-timestamp', Date.now())
1098
+ // // setResponseCORS(res);
1099
+ // // },
1100
+ // };
1101
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP static path ${basedir}`);
1102
+ // expressApp.use("/", express.static(basedir, staticOptions));
1103
+
1104
+ // const startHttp = function () {
1105
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData...`);
1106
+ // generateSelfSignedData().then((certData) => {
1107
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData OK.`);
1108
+
1109
+ // httpServer = https.createServer({ key: certData.private, cert: certData.cert }, expressApp).listen(port, () => {
1110
+ // const p = httpServer.address().port;
1111
+
1112
+ // port = p;
1113
+ // ip = "127.0.0.1";
1114
+ // proto = "https";
1115
+ // rootUrl = `${proto}://${ip}:${port}`;
1116
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
1117
+
1118
+ // resolve();
1119
+ // });
1120
+ // }).catch((err) => {
1121
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} generateSelfSignedData error!`);
1122
+ // if (LOG_DEBUG) console.log(err);
1123
+ // httpServer = expressApp.listen(port, () => {
1124
+ // const p = httpServer.address().port;
1125
+
1126
+ // port = p;
1127
+ // ip = "127.0.0.1";
1128
+ // proto = "http";
1129
+ // rootUrl = `${proto}://${ip}:${port}`;
1130
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
1131
+
1132
+ // resolve();
1133
+ // });
1134
+ // });
1135
+ // }
818
1136
 
819
- portfinder.getPortPromise().then((p) => {
820
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port ${p}`);
821
- port = p;
822
- startHttp();
823
- }).catch((err) => {
824
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port error!`);
825
- console.log(err);
826
- port = 3000;
827
- startHttp();
828
- });
829
- });
1137
+ // portfinder.getPortPromise().then((p) => {
1138
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port ${p}`);
1139
+ // port = p;
1140
+ // startHttp();
1141
+ // }).catch((err) => {
1142
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port error!`);
1143
+ // console.log(err);
1144
+ // port = 3000;
1145
+ // startHttp();
1146
+ // });
1147
+ // });
830
1148
  }
831
1149
 
832
1150
  function prepareLaunch(eventEmmitter, CONCURRENT_INSTANCES) {
833
-
834
1151
  eventEmmitter.on('AXE_RUNNER_LAUNCH', (event, arg) => {
835
1152
  // const payload = eventEmmitter.ace_notElectronIpcMainRenderer ? event : arg;
836
1153
  const sender = eventEmmitter.ace_notElectronIpcMainRenderer ? eventEmmitter : event.sender;