22 * License, v. 2.0. If a copy of the MPL was not distributed with this
33 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44
5- "use strict" ;
6-
7- /* import-globals-from head_cache.js */
8- /* import-globals-from head_cookies.js */
9- /* import-globals-from head_channels.js */
10-
11- const { NodeServer } = ChromeUtils . importESModule (
12- "resource://testing-common/httpd.sys.mjs"
13- ) ;
14- const { AppConstants } = ChromeUtils . importESModule (
15- "resource://gre/modules/AppConstants.sys.mjs"
16- ) ;
5+ import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs" ;
176
187/* globals require, __dirname, global, Buffer, process */
198
209class BaseNodeHTTPServerCode {
2110 static globalHandler ( req , resp ) {
22- let path = new URL ( req . url , "http ://example.com" ) . pathname ;
11+ let path = new URL ( req . url , "https ://example.com" ) . pathname ;
2312 let handler = global . path_handlers [ path ] ;
2413 if ( handler ) {
2514 return handler ( req , resp ) ;
@@ -161,7 +150,7 @@ class NodeHTTPServerCode extends BaseNodeHTTPServerCode {
161150 }
162151}
163152
164- class NodeHTTPServer extends BaseNodeServer {
153+ export class NodeHTTPServer extends BaseNodeServer {
165154 _protocol = "http" ;
166155 _version = "http/1.1" ;
167156 /// Starts the server
@@ -198,7 +187,7 @@ class NodeHTTPSServerCode extends BaseNodeHTTPServerCode {
198187 }
199188}
200189
201- class NodeHTTPSServer extends BaseNodeServer {
190+ export class NodeHTTPSServer extends BaseNodeServer {
202191 _protocol = "https" ;
203192 _version = "http/1.1" ;
204193 /// Starts the server
@@ -249,7 +238,7 @@ class NodeHTTP2ServerCode extends BaseNodeHTTPServerCode {
249238 }
250239}
251240
252- class NodeHTTP2Server extends BaseNodeServer {
241+ export class NodeHTTP2Server extends BaseNodeServer {
253242 _protocol = "https" ;
254243 _version = "h2" ;
255244 /// Starts the server
@@ -374,9 +363,6 @@ class BaseHTTPProxy extends BaseNodeServer {
374363 0
375364 ) ;
376365 pps . registerFilter ( this . filter , 10 ) ;
377- registerCleanupFunction ( ( ) => {
378- this . unregisterFilter ( ) ;
379- } ) ;
380366 }
381367
382368 unregisterFilter ( ) {
@@ -401,7 +387,7 @@ class BaseHTTPProxy extends BaseNodeServer {
401387
402388// HTTP1 Proxy
403389
404- class NodeProxyFilter {
390+ export class NodeProxyFilter {
405391 constructor ( type , host , port , flags ) {
406392 this . _type = type ;
407393 this . _host = host ;
@@ -438,7 +424,7 @@ class HTTPProxyCode {
438424 }
439425}
440426
441- class NodeHTTPProxyServer extends BaseHTTPProxy {
427+ export class NodeHTTPProxyServer extends BaseHTTPProxy {
442428 _protocol = "http" ;
443429 /// Starts the server
444430 /// @port - default 0
@@ -474,7 +460,7 @@ class HTTPSProxyCode {
474460 }
475461}
476462
477- class NodeHTTPSProxyServer extends BaseHTTPProxy {
463+ export class NodeHTTPSProxyServer extends BaseHTTPProxy {
478464 _protocol = "https" ;
479465 /// Starts the server
480466 /// @port - default 0
@@ -649,7 +635,7 @@ class HTTP2ProxyCode {
649635 }
650636}
651637
652- class NodeHTTP2ProxyServer extends BaseHTTPProxy {
638+ export class NodeHTTP2ProxyServer extends BaseHTTPProxy {
653639 _protocol = "https" ;
654640 /// Starts the server
655641 /// @port - default 0
@@ -699,9 +685,9 @@ class NodeWebSocketServerCode extends BaseNodeHTTPServerCode {
699685 ) ;
700686
701687 let node_ws_root = `${ __dirname } /../node-ws` ;
702- const WebSocket = require ( `${ node_ws_root } /lib/websocket` ) ;
703- WebSocket . Server = require ( `${ node_ws_root } /lib/websocket-server` ) ;
704- global . webSocketServer = new WebSocket . Server ( { server : global . server } ) ;
688+ const WS = require ( `${ node_ws_root } /lib/websocket` ) ;
689+ WS . Server = require ( `${ node_ws_root } /lib/websocket-server` ) ;
690+ global . webSocketServer = new WS . Server ( { server : global . server } ) ;
705691 global . webSocketServer . on ( "connection" , function connection ( ws ) {
706692 ws . on ( "message" , data =>
707693 NodeWebSocketServerCode . messageHandler ( data , ws )
@@ -713,7 +699,7 @@ class NodeWebSocketServerCode extends BaseNodeHTTPServerCode {
713699 }
714700}
715701
716- class NodeWebSocketServer extends BaseNodeServer {
702+ export class NodeWebSocketServer extends BaseNodeServer {
717703 _protocol = "wss" ;
718704 /// Starts the server
719705 /// @port - default 0
@@ -754,13 +740,13 @@ class NodeWebSocketHttp2ServerCode extends BaseNodeHTTPServerCode {
754740 global . h2Server = http2 . createSecureServer ( options ) ;
755741
756742 let node_ws_root = `${ __dirname } /../node-ws` ;
757- const WebSocket = require ( `${ node_ws_root } /lib/websocket` ) ;
743+ const WS = require ( `${ node_ws_root } /lib/websocket` ) ;
758744
759745 global . h2Server . on ( "stream" , ( stream , headers ) => {
760746 if ( headers [ ":method" ] === "CONNECT" ) {
761747 stream . respond ( ) ;
762748
763- const ws = new WebSocket ( null ) ;
749+ const ws = new WS ( null ) ;
764750 stream . setNoDelay = ( ) => { } ;
765751 ws . setSocket ( stream , Buffer . from ( "" ) , 100 * 1024 * 1024 ) ;
766752
@@ -783,7 +769,7 @@ class NodeWebSocketHttp2ServerCode extends BaseNodeHTTPServerCode {
783769 }
784770}
785771
786- class NodeWebSocketHttp2Server extends BaseNodeServer {
772+ export class NodeWebSocketHttp2Server extends BaseNodeServer {
787773 _protocol = "h2ws" ;
788774 /// Starts the server
789775 /// @port - default 0
@@ -808,37 +794,16 @@ class NodeWebSocketHttp2Server extends BaseNodeServer {
808794
809795// Helper functions
810796
811- async function with_node_servers ( arrayOfClasses , asyncClosure ) {
797+ export async function with_node_servers ( arrayOfClasses , asyncClosure ) {
812798 for ( let s of arrayOfClasses ) {
813799 let server = new s ( ) ;
814800 await server . start ( ) ;
815- registerCleanupFunction ( async ( ) => {
816- await server . stop ( ) ;
817- } ) ;
818801 await asyncClosure ( server ) ;
819802 await server . stop ( ) ;
820803 }
821804}
822805
823- // nsITLSServerSocket needs a certificate with a corresponding private key
824- // available. xpcshell tests can import the test file "client-cert.p12" using
825- // the password "password", resulting in a certificate with the common name
826- // "Test End-entity" being available with a corresponding private key.
827- function getTestServerCertificate ( ) {
828- const certDB = Cc [ "@mozilla.org/security/x509certdb;1" ] . getService (
829- Ci . nsIX509CertDB
830- ) ;
831- const certFile = do_get_file ( "client-cert.p12" ) ;
832- certDB . importPKCS12File ( certFile , "password" ) ;
833- for ( const cert of certDB . getCerts ( ) ) {
834- if ( cert . commonName == "Test End-entity" ) {
835- return cert ;
836- }
837- }
838- return null ;
839- }
840-
841- class WebSocketConnection {
806+ export class WebSocketConnection {
842807 constructor ( ) {
843808 this . _openPromise = new Promise ( resolve => {
844809 this . _openCallback = resolve ;
@@ -943,8 +908,11 @@ class WebSocketConnection {
943908 }
944909}
945910
946- class HTTP3Server {
911+ export class HTTP3Server {
947912 protocol ( ) {
913+ return "https" ;
914+ }
915+ version ( ) {
948916 return "h3" ;
949917 }
950918 origin ( ) {
@@ -989,3 +957,101 @@ class HTTP3Server {
989957 return undefined ;
990958 }
991959}
960+
961+ export class NodeServer {
962+ // Executes command in the context of a node server.
963+ // See handler in moz-http2.js
964+ //
965+ // Example use:
966+ // let id = NodeServer.fork(); // id is a random string
967+ // await NodeServer.execute(id, `"hello"`)
968+ // > "hello"
969+ // await NodeServer.execute(id, `(() => "hello")()`)
970+ // > "hello"
971+ // await NodeServer.execute(id, `(() => var_defined_on_server)()`)
972+ // > "0"
973+ // await NodeServer.execute(id, `var_defined_on_server`)
974+ // > "0"
975+ // function f(param) { if (param) return param; return "bla"; }
976+ // await NodeServer.execute(id, f); // Defines the function on the server
977+ // await NodeServer.execute(id, `f()`) // executes defined function
978+ // > "bla"
979+ // let result = await NodeServer.execute(id, `f("test")`);
980+ // > "test"
981+ // await NodeServer.kill(id); // shuts down the server
982+
983+ // Forks a new node server using moz-http2-child.js as a starting point
984+ static fork ( ) {
985+ return this . sendCommand ( "" , "/fork" ) ;
986+ }
987+ // Executes command in the context of the node server indicated by `id`
988+ static execute ( id , command ) {
989+ return this . sendCommand ( command , `/execute/${ id } ` ) ;
990+ }
991+ // Shuts down the server
992+ static kill ( id ) {
993+ return this . sendCommand ( "" , `/kill/${ id } ` ) ;
994+ }
995+
996+ // Issues a request to the node server (handler defined in moz-http2.js)
997+ // This method should not be called directly.
998+ static sendCommand ( command , path ) {
999+ let h2Port = Services . env . get ( "MOZNODE_EXEC_PORT" ) ;
1000+ if ( ! h2Port ) {
1001+ throw new Error ( "Could not find MOZNODE_EXEC_PORT" ) ;
1002+ }
1003+
1004+ let req = new XMLHttpRequest ( { mozAnon : true , mozSystem : true } ) ;
1005+ const serverIP =
1006+ AppConstants . platform == "android" ? "10.0.2.2" : "127.0.0.1" ;
1007+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
1008+ req . open ( "POST" , `http://${ serverIP } :${ h2Port } ${ path } ` ) ;
1009+ req . channel . QueryInterface ( Ci . nsIHttpChannelInternal ) . bypassProxy = true ;
1010+ req . channel . loadFlags |= Ci . nsIChannel . LOAD_BYPASS_URL_CLASSIFIER ;
1011+ // Prevent HTTPS-Only Mode from upgrading the request.
1012+ req . channel . loadInfo . httpsOnlyStatus |= Ci . nsILoadInfo . HTTPS_ONLY_EXEMPT ;
1013+ // Allow deprecated HTTP request from SystemPrincipal
1014+ req . channel . loadInfo . allowDeprecatedSystemRequests = true ;
1015+
1016+ // Passing a function to NodeServer.execute will define that function
1017+ // in node. It can be called in a later execute command.
1018+ let isFunction = function ( obj ) {
1019+ return ! ! ( obj && obj . constructor && obj . call && obj . apply ) ;
1020+ } ;
1021+ let payload = command ;
1022+ if ( isFunction ( command ) ) {
1023+ payload = `${ command . name } = ${ command . toString ( ) } ;` ;
1024+ }
1025+
1026+ return new Promise ( ( resolve , reject ) => {
1027+ req . onload = ( ) => {
1028+ let x = null ;
1029+
1030+ if ( req . statusText != "OK" ) {
1031+ reject ( `XHR request failed: ${ req . statusText } ` ) ;
1032+ return ;
1033+ }
1034+
1035+ try {
1036+ x = JSON . parse ( req . responseText ) ;
1037+ } catch ( e ) {
1038+ reject ( `Failed to parse ${ req . responseText } - ${ e } ` ) ;
1039+ return ;
1040+ }
1041+
1042+ if ( x . error ) {
1043+ let e = new Error ( x . error , "" , 0 ) ;
1044+ e . stack = x . errorStack ;
1045+ reject ( e ) ;
1046+ return ;
1047+ }
1048+ resolve ( x . result ) ;
1049+ } ;
1050+ req . onerror = e => {
1051+ reject ( e ) ;
1052+ } ;
1053+
1054+ req . send ( payload . toString ( ) ) ;
1055+ } ) ;
1056+ }
1057+ }
0 commit comments