@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/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
 
@@ -226,15 +377,18 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
226
377
  return;
227
378
  }
228
379
 
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
- });
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
- 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
- }
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
- if (httpServer) {
309
- httpServer.close();
310
- httpServer = undefined;
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
- const uarelObj = url.parse(uarel.replace(/\\/g, "/"));
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
- browserWindow.webContents.once("did-fail-load", (event, errorCode, errorDescription, validatedURL, isMainFrame, frameProcessId, frameRoutingId) => {
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
- 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) => {
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
- return new Promise((resolve, reject) => {
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
- 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) => {
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
- // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP already loaded ${scriptPath}`);
821
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP already loaded ${scriptPath}`);
651
822
  }
652
- res.setHeader("Content-Type", "text/javascript");
653
- res.send(js);
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
- if (req.query[HTTP_QUERY_PARAM]) {
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 = url.parse(req.url).pathname;
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
- let fileSystemPath = path.join(expressApp.basedir, pn);
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
- res.status(404).end();
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
- res.setHeader("Content-Type", "application/xhtml+xml");
702
- res.send(html);
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
- next();
708
- });
709
-
710
- if (isDev) { // handle WebInspector JS maps etc.
711
- expressApp.use("/", (req, res, next) => {
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(url.parse(req.url).pathname);
951
+ const pathname = decodeURI(u.pathname);
715
952
 
716
953
  const filePath = path.join(basedir, pathname);
717
954
  if (filePathsExpressStaticNotExist[filePath]) {
718
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
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
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
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
- next();
735
- // res.send(data);
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
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
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
- next();
753
- // res.send(data);
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
- res.status(404).end();
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
- 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.`);
790
-
791
- httpServer = https.createServer({ key: certData.private, cert: certData.cert }, expressApp).listen(port, () => {
792
- const p = httpServer.address().port;
793
-
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}`);
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
- 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
- }
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
- 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
- });
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;