@daisy/ace-axe-runner-electron 1.2.5 → 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/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,120 @@ 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 ? this.buffer.slice(this.alreadyRead) : this.buffer;
95
+
96
+ if (size) {
97
+ let l = size;
98
+ if (size > chunk.length) {
99
+ l = chunk.length;
100
+ }
101
+
102
+ chunk = chunk.slice(0, l);
103
+ }
104
+
105
+ this.alreadyRead += chunk.length;
106
+ this.push(chunk);
107
+ }
108
+ }
109
+ function bufferToStream(buffer) {
110
+ return new BufferReadableStream(buffer);
111
+ }
112
+
113
+ let _streamProtocolHandler = undefined;
114
+ const streamProtocolHandler = async (req, callback) => {
115
+
116
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} streamProtocolHandler req.url: ${req.url}`);
117
+ const u = new URL(req.url);
118
+
119
+ if (LOG_DEBUG) {
120
+ Object.keys(req.headers).forEach(header => {
121
+ const val = req.headers[header];
122
+
123
+ console.log(`${ACE_LOG_PREFIX} streamProtocolHandler req.header: ${header} => ${val}`);
124
+
125
+ // if (val) {
126
+ // headers[header] = val;
127
+ // }
128
+ });
129
+ }
130
+
131
+ let ref = u.origin;
132
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} streamProtocolHandler u.origin: ${ref}`);
133
+ if (req.referrer && req.referrer.trim()) {
134
+ ref = req.referrer;
135
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} streamProtocolHandler req.referrer: ${ref}`);
136
+ }
137
+
138
+ const headers = {};
139
+
140
+ if (ref && ref !== "null" && !/^https?:\/\/localhost.+/.test(ref) && !/^https?:\/\/127\.0\.0\.1.+/.test(ref)) {
141
+ headers.referer = ref;
142
+ } else {
143
+ headers.referer = `${ACE_ELECTRON_HTTP_PROTOCOL}://0.0.0.0/`;
144
+ }
145
+
146
+ // CORS everything!
147
+ headers["Access-Control-Allow-Origin"] = "*";
148
+ headers["Access-Control-Allow-Methods"] = "GET, HEAD, OPTIONS"; // POST, DELETE, PUT, PATCH
149
+ // tslint:disable-next-line:max-line-length
150
+ 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";
151
+ // tslint:disable-next-line:max-line-length
152
+ 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";
153
+
154
+ if (!_streamProtocolHandler) {
155
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} !? _streamProtocolHandler`);
156
+
157
+ const buff = Buffer.from("<html><body><p>Internal Server Error</p><p>!_streamProtocolHandler</p></body></html>");
158
+ headers["Content-Length"] = buff.length.toString();
159
+ callback({
160
+ data: bufferToStream(buff),
161
+ headers,
162
+ statusCode: 500
163
+ });
164
+ return;
165
+ }
166
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} BEFORE _streamProtocolHandler ${req.url}`);
167
+ await _streamProtocolHandler(req, callback, headers);
168
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} AFTER _streamProtocolHandler ${req.url}`);
169
+ };
170
+ app.whenReady().then(async () => {
171
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} Electron app ready`);
172
+
173
+ // try {
174
+ // await clearSessions();
175
+ // } catch (err) {
176
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} clearSessions fail?`);
177
+ // }
178
+
179
+ // if (session.defaultSession) {
180
+ // session.defaultSession.protocol.registerStreamProtocol(
181
+ // ACE_ELECTRON_HTTP_PROTOCOL,
182
+ // streamProtocolHandler);
183
+ // }
184
+ const sess = session.fromPartition(SESSION_PARTITION, { cache: true });
185
+ if (sess) {
186
+ sess.protocol.registerStreamProtocol(ACE_ELECTRON_HTTP_PROTOCOL, streamProtocolHandler);
187
+
188
+ sess.setPermissionRequestHandler((wc, permission, callback) => {
189
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} setPermissionRequestHandler ${wc.getURL()} => ${permission}`);
190
+ callback(true);
191
+ });
192
+ }
193
+ });
194
+
53
195
  function loadUrl(browserWindow) {
54
196
  browserWindow.ace__loadUrlPending = undefined;
55
197
 
@@ -151,6 +293,8 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
151
293
  }
152
294
  axeRunnerInit.todo = false;
153
295
 
296
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunnerInit TODO ...`);
297
+
154
298
  const firstTimeInit = _firstTimeInit;
155
299
  _firstTimeInit = false;
156
300
 
@@ -224,15 +368,18 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
224
368
  return;
225
369
  }
226
370
 
227
- app.on("certificate-error", (event, webContents, u, error, certificate, callback) => {
228
- if (u.indexOf(`${rootUrl}/`) === 0) {
229
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error OKAY ${u}`);
230
- callback(true);
231
- return;
232
- }
233
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error FAIL ${u}`);
234
- callback(false);
235
- });
371
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunnerInit firstTimeInit ...`);
372
+
373
+ // NO_HTTP_REMOVE
374
+ // app.on("certificate-error", (event, webContents, u, error, certificate, callback) => {
375
+ // if (u.indexOf(`${rootUrl}/`) === 0) {
376
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error OKAY ${u}`);
377
+ // callback(true);
378
+ // return;
379
+ // }
380
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert error FAIL ${u}`);
381
+ // callback(false);
382
+ // });
236
383
 
237
384
  // const filter = { urls: ["*", "*://*/*"] };
238
385
 
@@ -257,25 +404,23 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
257
404
  // }
258
405
  // };
259
406
 
260
- const setCertificateVerifyProcCB = (request, callback) => {
261
-
262
- if (request.hostname === ip) {
263
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify OKAY ${request.hostname}`);
264
- callback(0); // OK
265
- return;
266
- }
267
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify FALLBACK ${request.hostname}`);
268
- callback(-3); // Chromium
269
- // callback(-2); // Fail
270
- };
271
-
272
- const sess = session.fromPartition(SESSION_PARTITION, { cache: true }); // || session.defaultSession;
273
-
274
- if (sess) {
275
- // sess.webRequest.onHeadersReceived(filter, onHeadersReceivedCB);
276
- // sess.webRequest.onBeforeSendHeaders(filter, onBeforeSendHeadersCB);
277
- sess.setCertificateVerifyProc(setCertificateVerifyProcCB);
278
- }
407
+ // NO_HTTP_REMOVE
408
+ // const setCertificateVerifyProcCB = (request, callback) => {
409
+ // if (request.hostname === ip) {
410
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify OKAY ${request.hostname}`);
411
+ // callback(0); // OK
412
+ // return;
413
+ // }
414
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTPS cert verify FALLBACK ${request.hostname}`);
415
+ // callback(-3); // Chromium
416
+ // // callback(-2); // Fail
417
+ // };
418
+ // const sess = session.fromPartition(SESSION_PARTITION, { cache: true }); // || session.defaultSession;
419
+ // if (sess) {
420
+ // // sess.webRequest.onHeadersReceived(filter, onHeadersReceivedCB);
421
+ // // sess.webRequest.onBeforeSendHeaders(filter, onBeforeSendHeadersCB);
422
+ // sess.setCertificateVerifyProc(setCertificateVerifyProcCB);
423
+ // }
279
424
 
280
425
  // ipcMain
281
426
  eventEmmitter.on('AXE_RUNNER_CLOSE', (event, arg) => {
@@ -300,13 +445,17 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
300
445
  }
301
446
  browserWindows = undefined;
302
447
 
448
+ // NO_HTTP_ADD
449
+ _streamProtocolHandler = undefined;
450
+
303
451
  httpServerStarted = false;
304
452
  httpServerStartWasRequested = false;
305
453
 
306
- if (httpServer) {
307
- httpServer.close();
308
- httpServer = undefined;
309
- }
454
+ // NO_HTTP_REMOVE
455
+ // if (httpServer) {
456
+ // httpServer.close();
457
+ // httpServer = undefined;
458
+ // }
310
459
 
311
460
  let _timeOutID = setTimeout(() => {
312
461
  _timeOutID = undefined;
@@ -338,6 +487,7 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
338
487
  }
339
488
  }
340
489
 
490
+ // clearSessions()
341
491
  const sess = session.fromPartition(SESSION_PARTITION, { cache: true }); // || session.defaultSession;
342
492
  if (sess) {
343
493
  setTimeout(async () => {
@@ -382,7 +532,8 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
382
532
  console.log(uarel);
383
533
  }
384
534
  // windows! file://C:\aa\bb\chapter.xhtml
385
- const uarelObj = url.parse(uarel.replace(/\\/g, "/"));
535
+
536
+ const uarelObj = new URL(uarel.replace(/\\/g, "/"));
386
537
  const windowsDrive = uarelObj.hostname ? `${uarelObj.hostname.toUpperCase()}:` : "";
387
538
  if (LOG_DEBUG_URLS) {
388
539
  console.log("######## URL 2");
@@ -429,8 +580,6 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
429
580
  return;
430
581
  }
431
582
 
432
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner free browser window in pool: ${browserWindow.ace__poolIndex}`);
433
-
434
583
  browserWindow.ace__eventEmmitterSender = sender;
435
584
  browserWindow.ace__replySent = false;
436
585
  browserWindow.ace__timeout = undefined;
@@ -438,13 +587,15 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
438
587
  browserWindow.ace__currentUrlOriginal = uarel;
439
588
  browserWindow.ace__currentUrl = httpUrl;
440
589
 
590
+ 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`);
591
+
441
592
  browserWindow.webContents.once("did-start-loading", () => {
442
593
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-start-loading ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
443
594
  });
444
595
  // browserWindow.webContents.once("did-stop-loading", () => {
445
596
  // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-stop-loading ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
446
597
  // });
447
- browserWindow.webContents.once("did-fail-load", (event, errorCode, errorDescription, validatedURL, isMainFrame, frameProcessId, frameRoutingId) => {
598
+ const didFailLoadHandler = (event, errorCode, errorDescription, validatedURL, isMainFrame, frameProcessId, frameRoutingId) => {
448
599
  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}`);
449
600
 
450
601
  // https://cs.chromium.org/chromium/src/net/base/net_error_list.h
@@ -469,11 +620,16 @@ function axeRunnerInit(eventEmmitter, CONCURRENT_INSTANCES) {
469
620
  err: `did-fail-load: ${errorCode} - ${errorDescription} - ${validatedURL} - ${isMainFrame} - ${frameProcessId} - ${frameRoutingId}`,
470
621
  url: browserWindow.ace__currentUrlOriginal
471
622
  });
472
- });
623
+ };
624
+ browserWindow.webContents.once("did-fail-load", didFailLoadHandler);
473
625
  // browserWindow.webContents.once("dom-ready", () => { // occurs early
474
626
  // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner dom-ready ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
475
627
  // });
476
628
  browserWindow.webContents.once("did-finish-load", () => {
629
+ // browserWindow.webContents.setMaxListeners(11+) ?
630
+ // (node:5505) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 did-fail-load listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
631
+ browserWindow.webContents.removeListener("did-fail-load", didFailLoadHandler);
632
+
477
633
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner did-finish-load ${browserWindow.ace__poolIndex} ${browserWindow.ace__currentUrlOriginal} --- ${browserWindow.ace__currentUrl}`);
478
634
 
479
635
  browserWindow.ace__TIME_executeJavaScript = process.hrtime();
@@ -562,7 +718,7 @@ new Promise((resolve, reject) => {
562
718
  } else {
563
719
  browserWindow.ace__loadUrlPending = httpUrl;
564
720
  }
565
- }
721
+ } // poolPush()
566
722
 
567
723
  if (!httpServerStartWasRequested) {
568
724
  // lazy init
@@ -572,19 +728,30 @@ new Promise((resolve, reject) => {
572
728
 
573
729
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner starting server ...`);
574
730
 
575
- startAxeServer(basedir, scripts, scriptContents).then(() => {
576
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner server started`);
577
- httpServerStarted = true;
578
-
579
- poolCheck();
580
- }).catch(err => {
731
+ // NO_HTTP_ADD
732
+ try {
733
+ startAxeServer(basedir, scripts, scriptContents);
734
+ } catch (err) {
581
735
  if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner server error`);
582
736
  console.log(err);
583
737
  browserWindow.ace__eventEmmitterSender.send("AXE_RUNNER_RUN_", {
584
738
  err,
585
739
  url: browserWindow.ace__currentUrlOriginal
586
740
  });
587
- });
741
+ return;
742
+ }
743
+
744
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner server started`);
745
+ httpServerStarted = true;
746
+ poolCheck();
747
+
748
+ // NO_HTTP_REMOVE
749
+ // startAxeServer(basedir, scripts, scriptContents).then(() => {
750
+ // // ...
751
+ // httpServerStarted = true;
752
+ // }).catch((err) => {
753
+ // // ...
754
+ // });
588
755
  } else {
589
756
  poolPush();
590
757
  }
@@ -595,229 +762,336 @@ axeRunnerInit.todo = true;
595
762
  const filePathsExpressStaticNotExist = {};
596
763
  function startAxeServer(basedir, scripts, scriptContents) {
597
764
 
598
- return new Promise((resolve, reject) => {
765
+ // NO_HTTP_REMOVE
766
+ // return new Promise((resolve, reject) => {
599
767
 
600
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner startAxeServer...`);
768
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner startAxeServer...`);
601
769
 
602
- let scriptsMarkup = "";
603
- scriptContents.forEach(scriptCode => {
604
- scriptsMarkup += `<script data-ace="" type="text/javascript">
770
+ let scriptsMarkup = "";
771
+ scriptContents.forEach(scriptCode => {
772
+ scriptsMarkup += `<script data-ace="" type="text/javascript">
605
773
  // <![CDATA[
606
774
  ${scriptCode}
607
775
  // ]]>
608
776
  </script>`;
609
- });
610
- scripts.forEach(scriptPath => {
611
- const filename = path.basename(scriptPath);
612
- scriptsMarkup += `<script data-ace="" src="/${HTTP_QUERY_PARAM}/${filename}"> </script>`;
613
- });
777
+ });
778
+ scripts.forEach(scriptPath => {
779
+ const filename = path.basename(scriptPath);
780
+ scriptsMarkup += `<script data-ace="" src="/${HTTP_QUERY_PARAM}/${filename}"> </script>`;
781
+ });
614
782
 
615
- expressApp = express();
616
- // expressApp.enable('strict routing');
617
-
618
- // expressApp.use("/", (req, res, next) => {
619
- // if (LOG_DEBUG) console.log("HTTP: " + req.url);
620
- // next();
621
- // });
622
-
623
- expressApp.basedir = basedir;
624
- expressApp.use("/", (req, res, next) => {
625
-
626
- for (const scriptPath of scripts) {
627
- const filename = path.basename(scriptPath);
628
- if (req.url.endsWith(`${HTTP_QUERY_PARAM}/${filename}`)) {
629
- let js = jsCache[scriptPath];
630
- if (!js) {
631
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP loading ${scriptPath}`);
632
- js = fs.readFileSync(scriptPath, { encoding: "utf8" });
633
- // if (LOG_DEBUG) console.log(js);
634
- jsCache[scriptPath] = js;
635
- } else {
636
- // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP already loaded ${scriptPath}`);
637
- }
638
- res.setHeader("Content-Type", "text/javascript");
639
- res.send(js);
640
- return;
783
+ // NO_HTTP_ADD
784
+ _streamProtocolHandler = async (req, callback, headers) => {
785
+ const u = new URL(req.url);
786
+
787
+ for (const scriptPath of scripts) {
788
+ const filename = path.basename(scriptPath);
789
+ if (req.url.endsWith(`${HTTP_QUERY_PARAM}/${filename}`)) {
790
+ let js = jsCache[scriptPath];
791
+ if (!js) {
792
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP loading ${scriptPath}`);
793
+ js = fs.readFileSync(scriptPath, { encoding: "utf8" });
794
+ // if (LOG_DEBUG) console.log(js);
795
+ jsCache[scriptPath] = js;
796
+ } else {
797
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP already loaded ${scriptPath}`);
641
798
  }
799
+ const buff = Buffer.from(js);
800
+ headers["Content-Length"] = buff.length.toString();
801
+ headers["Content-Type"] = "text/javascript";
802
+ callback({
803
+ data: bufferToStream(buff),
804
+ headers,
805
+ statusCode: 200
806
+ });
807
+ return;
642
808
  }
809
+ }
643
810
 
644
- if (req.query[HTTP_QUERY_PARAM]) {
645
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP intercept ${req.url}`);
811
+ const queryParam = u.searchParams.get(HTTP_QUERY_PARAM) || undefined;
812
+ if (queryParam) {
813
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP intercept ${req.url}`);
646
814
 
647
- if (LOG_DEBUG_URLS) {
648
- console.log(">>>>>>>>>> URL 1");
649
- console.log(req.url);
650
- }
651
- const ptn = url.parse(req.url).pathname;
652
- if (LOG_DEBUG_URLS) {
653
- console.log(">>>>>>>>>> URL 2");
654
- console.log(ptn);
655
- }
656
- const pn = decodeURI(ptn);
657
- if (LOG_DEBUG_URLS) {
658
- console.log(">>>>>>>>>> URL 3");
659
- console.log(pn);
660
- }
661
- let fileSystemPath = path.join(expressApp.basedir, pn);
662
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} filepath to read: ${fileSystemPath}`);
663
- if (!fs.existsSync(fileSystemPath)) {
664
- fileSystemPath = pn;
665
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} filepath to read (corrected): ${fileSystemPath}`);
666
- }
815
+ if (LOG_DEBUG_URLS) {
816
+ console.log(">>>>>>>>>> URL 1");
817
+ console.log(req.url);
818
+ }
819
+ const ptn = u.pathname;
820
+ if (LOG_DEBUG_URLS) {
821
+ console.log(">>>>>>>>>> URL 2");
822
+ console.log(ptn);
823
+ }
824
+ const pn = decodeURI(ptn);
825
+ if (LOG_DEBUG_URLS) {
826
+ console.log(">>>>>>>>>> URL 3");
827
+ console.log(pn);
828
+ }
667
829
 
668
- // let html = fs.readFileSync(fileSystemPath, { encoding: "utf8" });
669
- fs.readFile(fileSystemPath, { encoding: "utf8" }, (err, html) => {
670
- if (err) {
671
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML file load??! ${req.url}`);
672
- res.status(404).end();
673
- return;
674
- }
830
+ let fileSystemPath = path.join(basedir, pn);
831
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} filepath to read: ${fileSystemPath}`);
832
+ if (!fs.existsSync(fileSystemPath)) {
833
+ fileSystemPath = pn;
834
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} filepath to read (corrected): ${fileSystemPath}`);
835
+ }
836
+
837
+ // let html = fs.readFileSync(fileSystemPath, { encoding: "utf8" });
838
+ fs.readFile(fileSystemPath, { encoding: "utf8" }, (err, html) => {
839
+ if (err) {
840
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML file load??! ${req.url}`);
841
+ callback({
842
+ data: null,
843
+ headers,
844
+ statusCode: 404
845
+ });
846
+ return;
847
+ }
675
848
 
676
- // if (LOG_DEBUG) console.log(html);
849
+ // if (LOG_DEBUG) console.log(html);
677
850
 
678
- if (html.match(/<\/head>/)) {
679
- html = html.replace(/<\/head>/, `${scriptsMarkup}</head>`);
680
- } else if (html.match(/<\/body>/)) {
681
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML no </head>? (using </body>) ${req.url}`);
682
- html = html.replace(/<\/body>/, `${scriptsMarkup}</body>`);
683
- } else {
684
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML neither </head> nor </body>?! ${req.url}`);
685
- }
851
+ if (html.match(/<\/head>/)) {
852
+ html = html.replace(/<\/head>/, `${scriptsMarkup}</head>`);
853
+ } else if (html.match(/<\/body>/)) {
854
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML no </head>? (using </body>) ${req.url}`);
855
+ html = html.replace(/<\/body>/, `${scriptsMarkup}</body>`);
856
+ } else {
857
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTML neither </head> nor </body>?! ${req.url}`);
858
+ }
686
859
 
687
- res.setHeader("Content-Type", "application/xhtml+xml");
688
- res.send(html);
860
+ const buff = Buffer.from(html);
861
+ headers["Content-Length"] = buff.length.toString();
862
+ headers["Content-Type"] = "application/xhtml+xml";
863
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} CALLBACK HEADERS ${req.url} ${JSON.stringify(headers)}`);
864
+ callback({
865
+ data: bufferToStream(buff),
866
+ headers,
867
+ statusCode: 200
689
868
  });
690
- return;
691
- }
869
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} POST-CALLBACK ${req.url}`);
870
+ });
871
+ return;
872
+ }
692
873
 
693
- next();
694
- });
874
+ // equivalent to Express static:
875
+
876
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} Express static emulate: ${req.url}`);
877
+
878
+ if (LOG_DEBUG_URLS) {
879
+ console.log(">>>>>>>>>>- URL 1");
880
+ console.log(req.url);
881
+ }
882
+ const ptn = u.pathname;
883
+ if (LOG_DEBUG_URLS) {
884
+ console.log(">>>>>>>>>>- URL 2");
885
+ console.log(ptn);
886
+ }
887
+ const pn = decodeURI(ptn);
888
+ if (LOG_DEBUG_URLS) {
889
+ console.log(">>>>>>>>>>- URL 3");
890
+ console.log(pn);
891
+ }
892
+ let fileSystemPath = path.join(basedir, pn);
893
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --filepath to read: ${fileSystemPath}`);
894
+ if (!fs.existsSync(fileSystemPath)) {
895
+ fileSystemPath = pn;
896
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --filepath to read (corrected): ${fileSystemPath}`);
897
+ }
898
+ try {
899
+ let mediaType = mime.lookup(fileSystemPath) || "stream/octet";
900
+ const stats = fs.statSync(fileSystemPath);
901
+ headers["Content-Length"] = stats.size;
902
+ headers["Content-Type"] = mediaType;
903
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --CALLBACK HEADERS ${req.url} ${JSON.stringify(headers)}`);
904
+ const steam = fs.createReadStream(fileSystemPath);
905
+ callback({
906
+ data: steam,
907
+ headers,
908
+ statusCode: 200
909
+ });
910
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --POST-CALLBACK ${req.url}`);
911
+ } catch (fsErr) {
912
+ if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} --fsErr ${fsErr}`);
913
+
914
+ const buff = Buffer.from(`<html><body><p>Internal Server Error</p><p>fsErr: ${fsErr}</p></body></html>`);
915
+ headers["Content-Length"] = buff.length.toString();
916
+ callback({
917
+ data: bufferToStream(buff),
918
+ headers,
919
+ statusCode: 500
920
+ });
921
+ }
695
922
 
696
923
  if (isDev) {
697
924
  // handle WebInspector JS maps etc.
698
- expressApp.use("/", (req, res, next) => {
699
- // const url = new URL(`https://fake.org${req.url}`);
700
- // const pathname = url.pathname;
701
- const pathname = decodeURI(url.parse(req.url).pathname);
702
-
703
- const filePath = path.join(basedir, pathname);
704
- if (filePathsExpressStaticNotExist[filePath]) {
705
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
706
- return;
707
- }
708
- fsOriginal.exists(filePath, exists => {
709
- if (exists) {
710
- fsOriginal.readFile(filePath, undefined, (err, data) => {
711
- if (err) {
712
- if (LOG_DEBUG) {
713
- console.log(`${ACE_LOG_PREFIX} HTTP FAIL fsOriginal.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
714
- }
715
- filePathsExpressStaticNotExist[filePath] = err.toString();
716
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
717
- } else {
718
- // if (LOG_DEBUG) {
719
- // console.log(`${ACE_LOG_PREFIX} HTTP OK fsOriginal.exists ${basedir} + ${req.url} => ${filePath}`);
720
- // }
721
- next();
722
- // res.send(data);
925
+
926
+ // const url = new URL(`https://fake.org${req.url}`);
927
+ // const pathname = url.pathname;
928
+ const pathname = decodeURI(u.pathname);
929
+
930
+ const filePath = path.join(basedir, pathname);
931
+ if (filePathsExpressStaticNotExist[filePath]) {
932
+
933
+ const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
934
+ headers["Content-Length"] = buff.length.toString();
935
+ headers["Content-Type"] = "plain/text";
936
+ callback({
937
+ data: bufferToStream(buff),
938
+ headers,
939
+ statusCode: 404
940
+ });
941
+ return;
942
+ }
943
+ fsOriginal.exists(filePath, exists => {
944
+ if (exists) {
945
+ fsOriginal.readFile(filePath, undefined, (err, data) => {
946
+ if (err) {
947
+ if (LOG_DEBUG) {
948
+ console.log(`${ACE_LOG_PREFIX} HTTP FAIL fsOriginal.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
723
949
  }
724
- });
725
- } else {
726
- fs.exists(filePath, exists => {
727
- if (exists) {
728
- fs.readFile(filePath, undefined, (err, data) => {
729
- if (err) {
730
- if (LOG_DEBUG) {
731
- console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && fs.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
732
- }
733
- filePathsExpressStaticNotExist[filePath] = err.toString();
734
- res.status(404).send(filePathsExpressStaticNotExist[filePath]);
735
- } else {
736
- if (LOG_DEBUG) {
737
- console.log(`${ACE_LOG_PREFIX} HTTP OK !fsOriginal.exists && fs.exists ${basedir} + ${req.url} => ${filePath}`);
738
- }
739
- next();
740
- // res.send(data);
950
+ filePathsExpressStaticNotExist[filePath] = err.toString();
951
+ const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
952
+ headers["Content-Length"] = buff.length.toString();
953
+ headers["Content-Type"] = "plain/text";
954
+ callback({
955
+ data: bufferToStream(buff),
956
+ headers,
957
+ statusCode: 404
958
+ });
959
+ } else {
960
+ // if (LOG_DEBUG) {
961
+ // console.log(`${ACE_LOG_PREFIX} HTTP OK fsOriginal.exists ${basedir} + ${req.url} => ${filePath}`);
962
+ // }
963
+ callback({
964
+ data: null,
965
+ headers,
966
+ statusCode: 500
967
+ });
968
+ }
969
+ });
970
+ } else {
971
+ fs.exists(filePath, exists => {
972
+ if (exists) {
973
+ fs.readFile(filePath, undefined, (err, data) => {
974
+ if (err) {
975
+ if (LOG_DEBUG) {
976
+ console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && fs.exists && ERR ${basedir} + ${req.url} => ${filePath}`, err);
977
+ }
978
+ filePathsExpressStaticNotExist[filePath] = err.toString();
979
+ const buff = Buffer.from(filePathsExpressStaticNotExist[filePath]);
980
+ headers["Content-Length"] = buff.length.toString();
981
+ headers["Content-Type"] = "plain/text";
982
+ callback({
983
+ data: bufferToStream(buff),
984
+ headers,
985
+ statusCode: 404
986
+ });
987
+ } else {
988
+ if (LOG_DEBUG) {
989
+ console.log(`${ACE_LOG_PREFIX} HTTP OK !fsOriginal.exists && fs.exists ${basedir} + ${req.url} => ${filePath}`);
741
990
  }
742
- });
743
- } else {
744
- if (LOG_DEBUG) {
745
- console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && !fs.exists ${basedir} + ${req.url} => ${filePath}`);
991
+ callback({
992
+ data: null,
993
+ headers,
994
+ statusCode: 500
995
+ });
746
996
  }
747
- res.status(404).end();
997
+ });
998
+ } else {
999
+ if (LOG_DEBUG) {
1000
+ console.log(`${ACE_LOG_PREFIX} HTTP FAIL !fsOriginal.exists && !fs.exists ${basedir} + ${req.url} => ${filePath}`);
748
1001
  }
749
- });
750
- }
751
- });
1002
+ callback({
1003
+ data: null,
1004
+ headers,
1005
+ statusCode: 404
1006
+ });
1007
+ }
1008
+ });
1009
+ }
752
1010
  });
753
1011
  }
1012
+ };
754
1013
 
755
- // https://expressjs.com/en/4x/api.html#express.static
756
- const staticOptions = {
757
- dotfiles: "ignore",
758
- etag: true,
759
- // fallthrough: false,
760
- immutable: true,
761
- // index: "index.html",
762
- maxAge: "1d",
763
- redirect: false
764
- // extensions: ["css", "otf"],
765
- // setHeaders: (res, _path, _stat) => {
766
- // // res.set('x-timestamp', Date.now())
767
- // setResponseCORS(res);
768
- // },
769
- };
770
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP static path ${basedir}`);
771
- expressApp.use("/", express.static(basedir, staticOptions));
1014
+ // NO_HTTP_REMOVE
1015
+ // expressApp = express();
1016
+ // // expressApp.enable('strict routing');
1017
+ // // expressApp.use("/", (req, res, next) => {
1018
+ // // if (LOG_DEBUG) console.log("HTTP: " + req.url);
1019
+ // // next();
1020
+ // // });
1021
+ // expressApp.basedir = basedir;
1022
+ // expressApp.use("/", (req, res, next) => {
1023
+ // next();
1024
+ // });
1025
+ // if (isDev) { // handle WebInspector JS maps etc.
1026
+ // expressApp.use("/", (req, res, next) => {
1027
+ // });
1028
+ // }
1029
+
1030
+ // // https://expressjs.com/en/4x/api.html#express.static
1031
+ // const staticOptions = {
1032
+ // dotfiles: "ignore",
1033
+ // etag: true,
1034
+ // // fallthrough: false,
1035
+ // immutable: true,
1036
+ // // index: "index.html",
1037
+ // maxAge: "1d",
1038
+ // redirect: false,
1039
+ // // extensions: ["css", "otf"],
1040
+ // // setHeaders: (res, _path, _stat) => {
1041
+ // // // res.set('x-timestamp', Date.now())
1042
+ // // setResponseCORS(res);
1043
+ // // },
1044
+ // };
1045
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} HTTP static path ${basedir}`);
1046
+ // expressApp.use("/", express.static(basedir, staticOptions));
772
1047
 
773
- const startHttp = function () {
774
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData...`);
775
- generateSelfSignedData().then(certData => {
776
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData OK.`);
1048
+ // const startHttp = function () {
1049
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData...`);
1050
+ // generateSelfSignedData().then((certData) => {
1051
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner generateSelfSignedData OK.`);
777
1052
 
778
- httpServer = https.createServer({ key: certData.private, cert: certData.cert }, expressApp).listen(port, () => {
779
- const p = httpServer.address().port;
1053
+ // httpServer = https.createServer({ key: certData.private, cert: certData.cert }, expressApp).listen(port, () => {
1054
+ // const p = httpServer.address().port;
780
1055
 
781
- port = p;
782
- ip = "127.0.0.1";
783
- proto = "https";
784
- rootUrl = `${proto}://${ip}:${port}`;
785
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
1056
+ // port = p;
1057
+ // ip = "127.0.0.1";
1058
+ // proto = "https";
1059
+ // rootUrl = `${proto}://${ip}:${port}`;
1060
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
786
1061
 
787
- resolve();
788
- });
789
- }).catch(err => {
790
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} generateSelfSignedData error!`);
791
- if (LOG_DEBUG) console.log(err);
792
- httpServer = expressApp.listen(port, () => {
793
- const p = httpServer.address().port;
794
-
795
- port = p;
796
- ip = "127.0.0.1";
797
- proto = "http";
798
- rootUrl = `${proto}://${ip}:${port}`;
799
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
800
-
801
- resolve();
802
- });
803
- });
804
- };
805
-
806
- portfinder.getPortPromise().then(p => {
807
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port ${p}`);
808
- port = p;
809
- startHttp();
810
- }).catch(err => {
811
- if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port error!`);
812
- console.log(err);
813
- port = 3000;
814
- startHttp();
815
- });
816
- });
1062
+ // resolve();
1063
+ // });
1064
+ // }).catch((err) => {
1065
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} generateSelfSignedData error!`);
1066
+ // if (LOG_DEBUG) console.log(err);
1067
+ // httpServer = expressApp.listen(port, () => {
1068
+ // const p = httpServer.address().port;
1069
+
1070
+ // port = p;
1071
+ // ip = "127.0.0.1";
1072
+ // proto = "http";
1073
+ // rootUrl = `${proto}://${ip}:${port}`;
1074
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} server URL ${rootUrl}`);
1075
+
1076
+ // resolve();
1077
+ // });
1078
+ // });
1079
+ // }
1080
+
1081
+ // portfinder.getPortPromise().then((p) => {
1082
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port ${p}`);
1083
+ // port = p;
1084
+ // startHttp();
1085
+ // }).catch((err) => {
1086
+ // if (LOG_DEBUG) console.log(`${ACE_LOG_PREFIX} axeRunner HTTP port error!`);
1087
+ // console.log(err);
1088
+ // port = 3000;
1089
+ // startHttp();
1090
+ // });
1091
+ // });
817
1092
  }
818
1093
 
819
1094
  function prepareLaunch(eventEmmitter, CONCURRENT_INSTANCES) {
820
-
821
1095
  eventEmmitter.on('AXE_RUNNER_LAUNCH', (event, arg) => {
822
1096
  // const payload = eventEmmitter.ace_notElectronIpcMainRenderer ? event : arg;
823
1097
  const sender = eventEmmitter.ace_notElectronIpcMainRenderer ? eventEmmitter : event.sender;