|
3 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
|
5 | 5 | import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; |
| 6 | +import { NetUtil } from "resource://gre/modules/NetUtil.sys.mjs"; |
6 | 7 |
|
7 | 8 | /* globals require, __dirname, global, Buffer, process */ |
8 | 9 |
|
@@ -114,6 +115,73 @@ class BaseNodeServer { |
114 | 115 | return `localhost`; |
115 | 116 | } |
116 | 117 |
|
| 118 | + static async installCert(filename) { |
| 119 | + if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) { |
| 120 | + // Can't install cert from content process. |
| 121 | + return; |
| 122 | + } |
| 123 | + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( |
| 124 | + Ci.nsIX509CertDB |
| 125 | + ); |
| 126 | + |
| 127 | + function readFile(file) { |
| 128 | + let fstream = Cc[ |
| 129 | + "@mozilla.org/network/file-input-stream;1" |
| 130 | + ].createInstance(Ci.nsIFileInputStream); |
| 131 | + fstream.init(file, -1, 0, 0); |
| 132 | + let data = NetUtil.readInputStreamToString(fstream, fstream.available()); |
| 133 | + fstream.close(); |
| 134 | + return data; |
| 135 | + } |
| 136 | + |
| 137 | + // Find the root directory that contains netwerk/ |
| 138 | + let currentDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); |
| 139 | + let rootDir = currentDir.clone(); |
| 140 | + |
| 141 | + // XXX(valentin) The certs are stored in netwerk/test/unit |
| 142 | + // Walk up until the dir contains netwerk/ |
| 143 | + // This is hacky, but the alternative would also require |
| 144 | + // us to walk up the path to the root dir. |
| 145 | + while (rootDir) { |
| 146 | + let netwerkDir = rootDir.clone(); |
| 147 | + netwerkDir.append("netwerk"); |
| 148 | + if (netwerkDir.exists() && netwerkDir.isDirectory()) { |
| 149 | + break; |
| 150 | + } |
| 151 | + let parent = rootDir.parent; |
| 152 | + if (!parent || parent.equals(rootDir)) { |
| 153 | + // Reached filesystem root, fallback to current directory |
| 154 | + rootDir = currentDir; |
| 155 | + break; |
| 156 | + } |
| 157 | + rootDir = parent; |
| 158 | + } |
| 159 | + |
| 160 | + let certFile = rootDir.clone(); |
| 161 | + certFile.append("netwerk"); |
| 162 | + certFile.append("test"); |
| 163 | + certFile.append("unit"); |
| 164 | + certFile.append(filename); |
| 165 | + |
| 166 | + try { |
| 167 | + let pem = readFile(certFile) |
| 168 | + .replace(/-----BEGIN CERTIFICATE-----/, "") |
| 169 | + .replace(/-----END CERTIFICATE-----/, "") |
| 170 | + .replace(/[\r\n]/g, ""); |
| 171 | + certdb.addCertFromBase64(pem, "CTu,u,u"); |
| 172 | + } catch (e) { |
| 173 | + let errStr = e.toString(); |
| 174 | + console.log(`Error installing cert ${errStr}`); |
| 175 | + if (errStr.includes("0x805a1fe8")) { |
| 176 | + // Can't install the cert without a profile |
| 177 | + // Let's show an error, otherwise this will be difficult to diagnose. |
| 178 | + console.log( |
| 179 | + `!!! BaseNodeServer.installCert > Make sure your unit test calls do_get_profile()` |
| 180 | + ); |
| 181 | + } |
| 182 | + } |
| 183 | + } |
| 184 | + |
117 | 185 | /// Stops the server |
118 | 186 | async stop() { |
119 | 187 | if (this.processId) { |
@@ -194,6 +262,9 @@ export class NodeHTTPSServer extends BaseNodeServer { |
194 | 262 | /// @port - default 0 |
195 | 263 | /// when provided, will attempt to listen on that port. |
196 | 264 | async start(port = 0) { |
| 265 | + if (!this._skipCert) { |
| 266 | + await BaseNodeServer.installCert("http2-ca.pem"); |
| 267 | + } |
197 | 268 | this.processId = await NodeServer.fork(); |
198 | 269 |
|
199 | 270 | await this.execute(BaseNodeHTTPServerCode); |
@@ -245,6 +316,9 @@ export class NodeHTTP2Server extends BaseNodeServer { |
245 | 316 | /// @port - default 0 |
246 | 317 | /// when provided, will attempt to listen on that port. |
247 | 318 | async start(port = 0) { |
| 319 | + if (!this._skipCert) { |
| 320 | + await BaseNodeServer.installCert("http2-ca.pem"); |
| 321 | + } |
248 | 322 | this.processId = await NodeServer.fork(); |
249 | 323 |
|
250 | 324 | await this.execute(BaseNodeHTTPServerCode); |
@@ -466,6 +540,9 @@ export class NodeHTTPSProxyServer extends BaseHTTPProxy { |
466 | 540 | /// @port - default 0 |
467 | 541 | /// when provided, will attempt to listen on that port. |
468 | 542 | async start(port = 0) { |
| 543 | + if (!this._skipCert) { |
| 544 | + await BaseNodeServer.installCert("proxy-ca.pem"); |
| 545 | + } |
469 | 546 | this.processId = await NodeServer.fork(); |
470 | 547 |
|
471 | 548 | await this.execute(BaseProxyCode); |
@@ -641,6 +718,9 @@ export class NodeHTTP2ProxyServer extends BaseHTTPProxy { |
641 | 718 | /// @port - default 0 |
642 | 719 | /// when provided, will attempt to listen on that port. |
643 | 720 | async start(port = 0, auth, maxConcurrentStreams = 100) { |
| 721 | + if (!this._skipCert) { |
| 722 | + await BaseNodeServer.installCert("proxy-ca.pem"); |
| 723 | + } |
644 | 724 | this.processId = await NodeServer.fork(); |
645 | 725 |
|
646 | 726 | await this.execute(BaseProxyCode); |
@@ -705,6 +785,9 @@ export class NodeWebSocketServer extends BaseNodeServer { |
705 | 785 | /// @port - default 0 |
706 | 786 | /// when provided, will attempt to listen on that port. |
707 | 787 | async start(port = 0) { |
| 788 | + if (!this._skipCert) { |
| 789 | + await BaseNodeServer.installCert("http2-ca.pem"); |
| 790 | + } |
708 | 791 | this.processId = await NodeServer.fork(); |
709 | 792 |
|
710 | 793 | await this.execute(BaseNodeHTTPServerCode); |
@@ -775,6 +858,9 @@ export class NodeWebSocketHttp2Server extends BaseNodeServer { |
775 | 858 | /// @port - default 0 |
776 | 859 | /// when provided, will attempt to listen on that port. |
777 | 860 | async start(port = 0, fallbackToH1 = false) { |
| 861 | + if (!this._skipCert) { |
| 862 | + await BaseNodeServer.installCert("http2-ca.pem"); |
| 863 | + } |
778 | 864 | this.processId = await NodeServer.fork(); |
779 | 865 |
|
780 | 866 | await this.execute(BaseNodeHTTPServerCode); |
|
0 commit comments