test_websocket_proxy.js (3282B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 /* import-globals-from http3_proxy_common.js */ 8 9 const { 10 NodeWebSocketPlainServer, 11 NodeWebSocketServer, 12 NodeHTTPProxyServer, 13 NodeHTTPSProxyServer, 14 } = ChromeUtils.importESModule("resource://testing-common/NodeServer.sys.mjs"); 15 16 const { AppConstants } = ChromeUtils.importESModule( 17 "resource://gre/modules/AppConstants.sys.mjs" 18 ); 19 20 add_setup(async function setup() { 21 do_get_profile(); 22 }); 23 24 async function wsChannelOpen(url, msg) { 25 let conn = new WebSocketConnection(); 26 let statusObj = await Promise.race([conn.open(url), conn.finished()]); 27 if (statusObj && statusObj.status != Cr.NS_OK) { 28 return [statusObj.status, "", null]; 29 } 30 let finalStatusPromise = conn.finished(); 31 conn.send(msg); 32 let res = await conn.receiveMessages(); 33 conn.close(); 34 let finalStatus = await finalStatusPromise; 35 36 let proxyInfo = await conn.getProxyInfo(); 37 38 return [finalStatus.status, res, proxyInfo?.type]; 39 } 40 41 // We don't normally allow localhost channels to be proxied, but this 42 // is easier than updating all the certs and/or domains. 43 Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true); 44 registerCleanupFunction(() => { 45 Services.prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); 46 }); 47 48 async function do_ws_requests( 49 expectedProxyType, 50 servers = [ 51 NodeWebSocketPlainServer, 52 NodeWebSocketServer, 53 NodeWebSocketHttp2Server, 54 ] 55 ) { 56 await with_node_servers(servers, async server => { 57 Assert.notEqual(server.port(), null); 58 await server.registerMessageHandler((data, ws) => { 59 ws.send(data); 60 }); 61 62 let url = `${server.protocol()}://localhost:${server.port()}`; 63 const msg = `test ${server.constructor.name} with proxy`; 64 let [status, res, proxyType] = await wsChannelOpen(url, msg); 65 Assert.equal(status, Cr.NS_OK); 66 Assert.deepEqual(res, [msg]); 67 Assert.equal(proxyType, expectedProxyType, "WebSocket should use proxy"); 68 }); 69 } 70 71 add_task(async function test_http_proxy() { 72 let proxy = new NodeHTTPProxyServer(); 73 await proxy.start(); 74 registerCleanupFunction(async () => { 75 await proxy.stop(); 76 }); 77 78 await do_ws_requests("http"); 79 80 await proxy.stop(); 81 }); 82 83 add_task(async function test_https_proxy() { 84 let proxy = new NodeHTTPSProxyServer(); 85 await proxy.start(); 86 registerCleanupFunction(async () => { 87 await proxy.stop(); 88 }); 89 90 await do_ws_requests("https"); 91 92 await proxy.stop(); 93 }); 94 95 add_task(async function test_http2_proxy() { 96 let proxy = new NodeHTTP2ProxyServer(); 97 await proxy.start(); 98 registerCleanupFunction(async () => { 99 await proxy.stop(); 100 }); 101 102 await do_ws_requests("https"); 103 104 await proxy.stop(); 105 }); 106 107 // Skipped on Android due to H3 proxy server not working - Bug 1982955 108 // Also doesn't work on msix - Bug 1808049 109 add_task( 110 { 111 skip_if: () => 112 AppConstants.platform == "android" || 113 (AppConstants.platform === "win" && 114 Services.sysinfo.getProperty("hasWinPackageId")), 115 }, 116 async function test_masque_proxy() { 117 await setup_http3_proxy(); 118 119 await do_ws_requests("masque"); 120 } 121 );