tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 23d523ef3f5a4daa1062ff91a78030f239f529e2
parent 23935e4b50a957ebd2de9f2b57a60b1ad63ded54
Author: Valentin Gosu <valentin.gosu@gmail.com>
Date:   Tue, 25 Nov 2025 10:26:23 +0000

Bug 2001617 - Add Websocket with proxies test r=necko-reviewers,kershaw

Differential Revision: https://phabricator.services.mozilla.com/D273788

Diffstat:
Mnetwerk/protocol/websocket/WebSocketChannel.cpp | 2++
Mnetwerk/test/httpserver/NodeServer.sys.mjs | 2+-
Anetwerk/test/unit/test_websocket_proxy.js | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mnetwerk/test/unit/xpcshell.toml | 2++
4 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp @@ -3517,6 +3517,8 @@ WebSocketChannel::AsyncOpenNative(nsIURI* aURI, const nsACString& aOrigin, nsCOMPtr<nsIURI> localURI; nsCOMPtr<nsIChannel> localChannel; + LOG(("WebSocketChannel::AsyncOpen uri=%s", mURI->GetSpecOrDefault().get())); + rv = NS_MutateURI(mURI) .SetScheme(mEncrypted ? "https"_ns : "http"_ns) .Finalize(localURI); diff --git a/netwerk/test/httpserver/NodeServer.sys.mjs b/netwerk/test/httpserver/NodeServer.sys.mjs @@ -987,7 +987,7 @@ class NodeWebSocketHttp2ServerCode extends BaseNodeHTTPServerCode { } export class NodeWebSocketHttp2Server extends BaseNodeServer { - _protocol = "h2ws"; + _protocol = "wss"; /// Starts the server /// @port - default 0 /// when provided, will attempt to listen on that port. diff --git a/netwerk/test/unit/test_websocket_proxy.js b/netwerk/test/unit/test_websocket_proxy.js @@ -0,0 +1,95 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { + NodeWebSocketPlainServer, + NodeWebSocketServer, + NodeWebSocketHttp2Server, + NodeHTTPProxyServer, + NodeHTTPSProxyServer, + NodeHTTP2ProxyServer, + WebSocketConnection, + with_node_servers, +} = ChromeUtils.importESModule("resource://testing-common/NodeServer.sys.mjs"); + +async function channelOpenPromise(url, msg) { + let conn = new WebSocketConnection(); + let statusObj = await Promise.race([conn.open(url), conn.finished()]); + if (statusObj && statusObj.status != Cr.NS_OK) { + return [statusObj.status, "", null]; + } + let finalStatusPromise = conn.finished(); + conn.send(msg); + let res = await conn.receiveMessages(); + conn.close(); + let finalStatus = await finalStatusPromise; + + let proxyInfo = await conn.getProxyInfo(); + + return [finalStatus.status, res, proxyInfo?.type]; +} + +// We don't normally allow localhost channels to be proxied, but this +// is easier than updating all the certs and/or domains. +Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); +}); + +async function do_ws_requests(expectedProxyType) { + await with_node_servers( + [NodeWebSocketPlainServer, NodeWebSocketServer, NodeWebSocketHttp2Server], + async server => { + Assert.notEqual(server.port(), null); + await server.registerMessageHandler((data, ws) => { + ws.send(data); + }); + + let url = `${server.protocol()}://localhost:${server.port()}`; + const msg = `test ${server.constructor.name} with proxy`; + let [status, res, proxyType] = await channelOpenPromise(url, msg); + Assert.equal(status, Cr.NS_OK); + Assert.deepEqual(res, [msg]); + Assert.equal(proxyType, expectedProxyType, "WebSocket should use proxy"); + } + ); +} + +add_task(async function test_http_proxy() { + let proxy = new NodeHTTPProxyServer(); + await proxy.start(); + registerCleanupFunction(async () => { + await proxy.stop(); + }); + + await do_ws_requests("http"); + + await proxy.stop(); +}); + +add_task(async function test_https_proxy() { + let proxy = new NodeHTTPSProxyServer(); + await proxy.start(); + registerCleanupFunction(async () => { + await proxy.stop(); + }); + + await do_ws_requests("https"); + + await proxy.stop(); +}); + +add_task(async function test_http2_proxy() { + let proxy = new NodeHTTP2ProxyServer(); + await proxy.start(); + registerCleanupFunction(async () => { + await proxy.stop(); + }); + + await do_ws_requests("https"); + + await proxy.stop(); +}); diff --git a/netwerk/test/unit/xpcshell.toml b/netwerk/test/unit/xpcshell.toml @@ -1603,6 +1603,8 @@ run-sequentially = ["true"] # node server exceptions dont replay well ["test_websocket_offline.js"] +["test_websocket_proxy.js"] + ["test_websocket_server.js"] run-sequentially = ["true"] # node server exceptions dont replay well