tor-browser

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

commit 81568ecfb7bfe264c334797d7edbe72c52762299
parent 60b4755b5fd5f898d2a968029cbd4bbb9d725166
Author: agoloman <agoloman@mozilla.com>
Date:   Tue, 25 Nov 2025 14:11:00 +0200

Revert "Bug 2001617 - Add WebSocket with maque proxy test r=necko-reviewers,kershaw" for causing xpc failures @test_websocket_proxy.js.

This reverts commit 5ef8cd615dec98bacf2e01ed4e5f3c8c6e8fda21.

Revert "Bug 2001617 - Fix WS with masque proxy r=necko-reviewers,kershaw"

This reverts commit eba1592b1611912d988565848c1d43291bbcf2b8.

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

This reverts commit 23d523ef3f5a4daa1062ff91a78030f239f529e2.

Revert "Bug 2001617 - Add plaintext WS server r=necko-reviewers,kershaw"

This reverts commit 23935e4b50a957ebd2de9f2b57a60b1ad63ded54.

Diffstat:
Mnetwerk/protocol/http/ConnectionEntry.cpp | 17-----------------
Mnetwerk/protocol/http/ConnectionEntry.h | 3---
Mnetwerk/protocol/http/DnsAndConnectSocket.cpp | 30------------------------------
Mnetwerk/protocol/http/Http3Session.cpp | 8+-------
Mnetwerk/protocol/http/Http3StreamTunnel.cpp | 2+-
Mnetwerk/protocol/http/nsHttpConnectionMgr.cpp | 43-------------------------------------------
Mnetwerk/protocol/websocket/WebSocketChannel.cpp | 6++----
Mnetwerk/test/httpserver/NodeServer.sys.mjs | 59++++++-----------------------------------------------------
Mnetwerk/test/unit/http3_proxy_common.js | 66------------------------------------------------------------------
Mnetwerk/test/unit/test_http3_proxy.js | 1-
Dnetwerk/test/unit/test_websocket_proxy.js | 107-------------------------------------------------------------------------------
Mnetwerk/test/unit/test_websocket_server.js | 37-------------------------------------
Mnetwerk/test/unit/xpcshell.toml | 3---
13 files changed, 10 insertions(+), 372 deletions(-)

diff --git a/netwerk/protocol/http/ConnectionEntry.cpp b/netwerk/protocol/http/ConnectionEntry.cpp @@ -717,23 +717,6 @@ HttpConnectionBase* ConnectionEntry::GetH2orH3ActiveConn() { return nullptr; } -already_AddRefed<nsHttpConnection> ConnectionEntry::GetH2TunnelActiveConn() { - MOZ_ASSERT(OnSocketThread(), "not on socket thread"); - - for (const auto& conn : mActiveConns) { - RefPtr<nsHttpConnection> connTCP = do_QueryObject(conn); - if (connTCP && connTCP->UsingSpdy() && connTCP->CanDirectlyActivate()) { - LOG( - ("GetH2TunnelActiveConn() request for ent %p %s " - "found an H2 tunnel connection %p\n", - this, mConnInfo->HashKey().get(), connTCP.get())); - return connTCP.forget(); - } - } - - return nullptr; -} - void ConnectionEntry::CloseActiveConnections() { while (mActiveConns.Length()) { RefPtr<HttpConnectionBase> conn(mActiveConns[0]); diff --git a/netwerk/protocol/http/ConnectionEntry.h b/netwerk/protocol/http/ConnectionEntry.h @@ -74,9 +74,6 @@ class ConnectionEntry : public SupportsWeakPtr { void RemoveExtendedCONNECTConns(HttpConnectionBase* conn); HttpConnectionBase* GetH2orH3ActiveConn(); - // Find an H2 tunnel connection (nsHttpConnection with UsingSpdy()) in active - // connections. This is used for WebSocket/WebTransport through H3 proxy. - already_AddRefed<nsHttpConnection> GetH2TunnelActiveConn(); // Make an active spdy connection DontReuse. // TODO: this is a helper function and should nbe improved. bool MakeFirstActiveSpdyConnDontReuse(); diff --git a/netwerk/protocol/http/DnsAndConnectSocket.cpp b/netwerk/protocol/http/DnsAndConnectSocket.cpp @@ -24,7 +24,6 @@ #include "nsHttpHandler.h" #include "ConnectionEntry.h" #include "HttpConnectionUDP.h" -#include "NullHttpTransaction.h" #include "nsServiceManagerUtils.h" #include "mozilla/net/NeckoChannelParams.h" // For HttpActivityArgs. @@ -623,35 +622,6 @@ nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) { ent->InsertIntoActiveConns(conn); if (mIsHttp3) { - // For WebSocket through HTTP/3 proxy, queue the transaction to be - // dispatched when the H3 session is connected, and use a NullTransaction - // to drive the H3 connection establishment. - // We do NOT create a ConnectionHandle for the WebSocket transaction here - // because it will get a tunnel connection later, and setting a - // ConnectionHandle now would cause it to be reclaimed when cleared. - nsHttpTransaction* trans = pendingTransInfo->Transaction(); - if (trans->IsWebsocketUpgrade()) { - LOG( - ("DnsAndConnectSocket::SetupConn WebSocket through HTTP/3 proxy, " - "queueing for tunnel creation after H3 connected")); - // Put the transaction back in the pending queue so it can be - // dispatched through TryDispatchTransaction when the H3 session - // reports it's connected - RefPtr<PendingTransactionInfo> newPendingInfo = - new PendingTransactionInfo(trans); - ent->InsertTransaction(newPendingInfo); - - // Dispatch a NullHttpTransaction to drive the H3 proxy connection - // establishment - nsCOMPtr<nsIInterfaceRequestor> nullCallbacks; - trans->GetSecurityCallbacks(getter_AddRefs(nullCallbacks)); - RefPtr<nsAHttpTransaction> nullTrans = - new NullHttpTransaction(mConnInfo, nullCallbacks, mCaps); - rv = gHttpHandler->ConnMgr()->DispatchAbstractTransaction( - ent, nullTrans, mCaps, conn, 0); - return rv; - } - // Each connection must have a ConnectionHandle wrapper. // In case of Http < 2 the a ConnectionHandle is created for each // transaction in DispatchAbstractTransaction. diff --git a/netwerk/protocol/http/Http3Session.cpp b/netwerk/protocol/http/Http3Session.cpp @@ -1461,13 +1461,7 @@ nsresult Http3Session::TryActivating( if (mState == ZERORTT) { if (!aStream->Do0RTT()) { - // Stream can't do 0RTT - queue it for activation when the session - // reaches CONNECTED state via Finish0Rtt. - if (!mCannotDo0RTTStreams.Contains(aStream)) { - LOG(("Http3Session %p queuing stream %p for post-0RTT activation", this, - aStream)); - mCannotDo0RTTStreams.AppendElement(aStream); - } + MOZ_ASSERT(!mCannotDo0RTTStreams.Contains(aStream)); return NS_BASE_STREAM_WOULD_BLOCK; } } diff --git a/netwerk/protocol/http/Http3StreamTunnel.cpp b/netwerk/protocol/http/Http3StreamTunnel.cpp @@ -388,7 +388,7 @@ Http3TransportLayer::GetSecurityCallbacks( NS_IMETHODIMP Http3TransportLayer::SetSecurityCallbacks( nsIInterfaceRequestor* aSecurityCallbacks) { - return NS_OK; + return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -1402,49 +1402,6 @@ nsresult nsHttpConnectionMgr::TryDispatchTransaction( // look for existing spdy connection - that's always best because it is // essentially pipelining without head of line blocking - // For WebSocket/WebTransport through H3 proxy, we need to create a TCP - // tunnel through the H3 proxy first. But if there's already an H2 session - // available (from a previously established tunnel), we should use that - // instead of creating a new tunnel. - // The WebSocket transaction doesn't have a connection set (it was queued - // without one in DnsAndConnectSocket::SetupConn to avoid triggering reclaim - // when we clear it here). - if ((trans->IsWebsocketUpgrade() || trans->IsForWebTransport()) && - ent->IsHttp3ProxyConnection()) { - // First check if there's an H2 session available (from existing tunnel) - // This handles the case where the tunnel was already established and the - // WebSocket transaction was reset to wait for H2 negotiation. - // We can't use GetH2orH3ActiveConn because it skips H3 proxy entries when - // looking for H2 connections. We use GetH2TunnelActiveConn to directly - // look for an H2 tunnel connection in the active connections. - RefPtr<nsHttpConnection> h2Tunnel = ent->GetH2TunnelActiveConn(); - if (h2Tunnel) { - LOG( - ("TryDispatchTransaction: WebSocket through H3 proxy - using " - "existing H2 tunnel")); - return TryDispatchExtendedCONNECTransaction(ent, trans, h2Tunnel); - } - - // No H2 session available yet - create a tunnel through the H3 proxy - RefPtr<HttpConnectionBase> conn = GetH2orH3ActiveConn(ent, true, false); - RefPtr<HttpConnectionUDP> connUDP = do_QueryObject(conn); - if (connUDP) { - LOG(("TryDispatchTransaction: WebSocket through HTTP/3 proxy")); - RefPtr<HttpConnectionBase> tunnelConn; - nsresult rv = - connUDP->CreateTunnelStream(trans, getter_AddRefs(tunnelConn), true); - if (NS_FAILED(rv)) { - return rv; - } - ent->InsertIntoActiveConns(tunnelConn); - tunnelConn->SetInTunnel(); - if (trans->IsWebsocketUpgrade()) { - trans->SetIsHttp2Websocket(true); - } - return DispatchTransaction(ent, trans, tunnelConn); - } - } - RefPtr<HttpConnectionBase> conn = GetH2orH3ActiveConn( ent, (!StaticPrefs::network_http_http2_enabled() || diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp @@ -3517,8 +3517,6 @@ 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); @@ -3747,9 +3745,9 @@ WebSocketChannel::OnTransportAvailable(nsISocketTransport* aTransport, nsresult rv; rv = mTransport->SetEventSink(nullptr, nullptr); - if (NS_WARN_IF(NS_FAILED(rv))) return rv; + if (NS_FAILED(rv)) return rv; rv = mTransport->SetSecurityCallbacks(this); - if (NS_WARN_IF(NS_FAILED(rv))) return rv; + if (NS_FAILED(rv)) return rv; return OnTransportAvailableInternal(); } diff --git a/netwerk/test/httpserver/NodeServer.sys.mjs b/netwerk/test/httpserver/NodeServer.sys.mjs @@ -875,52 +875,6 @@ export class NodeWebSocketServer extends BaseNodeServer { } } -// unencrypted websocket server - -class NodeWebSocketPlainServerCode extends BaseNodeHTTPServerCode { - static async startServer(port) { - const http = require("http"); - global.server = http.createServer(BaseNodeHTTPServerCode.globalHandler); - - let node_ws_root = `${__dirname}/../node-ws`; - const WS = require(`${node_ws_root}/lib/websocket`); - WS.Server = require(`${node_ws_root}/lib/websocket-server`); - global.webSocketServer = new WS.Server({ server: global.server }); - global.webSocketServer.on("connection", function connection(ws) { - ws.on("message", data => - NodeWebSocketServerCode.messageHandler(data, ws) - ); - }); - - let serverPort = await ADB.listenAndForwardPort(global.server, port); - return serverPort; - } -} - -export class NodeWebSocketPlainServer extends BaseNodeServer { - _protocol = "ws"; - /// Starts the server - /// @port - default 0 - /// when provided, will attempt to listen on that port. - async start(port = 0) { - this.processId = await NodeServer.fork(); - - await this.execute(BaseNodeHTTPServerCode); - await this.execute(NodeWebSocketServerCode); - await this.execute(NodeWebSocketPlainServerCode); - await this.execute(ADB); - this._port = await this.execute( - `NodeWebSocketPlainServerCode.startServer(${port})` - ); - await this.execute(`global.path_handlers = {};`); - await this.execute(`global.wsInputHandler = null;`); - } - - async registerMessageHandler(handler) { - return this.execute(`global.wsInputHandler = ${handler.toString()}`); - } -} - // websocket http2 server // This code is inspired by // https://github.com/szmarczak/http2-wrapper/blob/master/examples/ws/server.js @@ -987,7 +941,7 @@ class NodeWebSocketHttp2ServerCode extends BaseNodeHTTPServerCode { } export class NodeWebSocketHttp2Server extends BaseNodeServer { - _protocol = "wss"; + _protocol = "h2ws"; /// Starts the server /// @port - default 0 /// when provided, will attempt to listen on that port. @@ -1075,11 +1029,10 @@ export class WebSocketConnection { } } - static makeWebSocketChan(url) { - let protocol = url.startsWith("wss:") ? "wss" : "ws"; - let chan = Cc[ - `@mozilla.org/network/protocol;1?name=${protocol}` - ].createInstance(Ci.nsIWebSocketChannel); + static makeWebSocketChan() { + let chan = Cc["@mozilla.org/network/protocol;1?name=wss"].createInstance( + Ci.nsIWebSocketChannel + ); chan.initLoadInfo( null, // aLoadingNode Services.scriptSecurityManager.getSystemPrincipal(), @@ -1091,7 +1044,7 @@ export class WebSocketConnection { } // Returns a promise that resolves when the websocket channel is opened. open(url) { - this._ws = WebSocketConnection.makeWebSocketChan(url); + this._ws = WebSocketConnection.makeWebSocketChan(); let uri = Services.io.newURI(url); this._ws.asyncOpen(uri, url, {}, 0, this, null); return this._openPromise; diff --git a/netwerk/test/unit/http3_proxy_common.js b/netwerk/test/unit/http3_proxy_common.js @@ -16,8 +16,6 @@ const { NodeHTTPSServer, NodeHTTP2Server, NodeHTTP2ProxyServer, - NodeWebSocketHttp2Server, - WebSocketConnection, } = ChromeUtils.importESModule("resource://testing-common/NodeServer.sys.mjs"); function makeChan(uri) { @@ -433,70 +431,6 @@ async function test_http_connect_fallback() { await server.stop(); } -/** - * Helper function to open a WebSocket connection - */ -async function wsChannelOpenPromise(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, ""]; - } - let finalStatusPromise = conn.finished(); - conn.send(msg); - let res = await conn.receiveMessages(); - conn.close(); - let finalStatus = await finalStatusPromise; - return [finalStatus.status, res]; -} - -/** - * Test WebSocket through H3 proxy using H2 WebSocket server - */ -async function test_http_connect_websocket() { - info("Running test_http_connect_websocket"); - Services.prefs.setBoolPref("network.http.http2.websockets", true); - - let wss = new NodeWebSocketHttp2Server(); - await wss.start(); - - registerCleanupFunction(async () => { - await wss.stop(); - }); - - Assert.notEqual(wss.port(), null); - await wss.registerMessageHandler((data, ws) => { - ws.send(data); - }); - - let url = `wss://alt1.example.com:${wss.port()}`; - const msg = "test h2 websocket through h3 proxy"; - let [status, res] = await wsChannelOpenPromise(url, msg); - Assert.equal(status, Cr.NS_OK); - Assert.deepEqual(res, [msg]); - - // Test multiple messages - let conn = new WebSocketConnection(); - await conn.open(url); - conn.send("message1"); - let mess1 = await conn.receiveMessages(); - Assert.deepEqual(mess1, ["message1"]); - - conn.send("message2"); - conn.send("message3"); - let mess2 = []; - while (mess2.length < 2) { - mess2 = mess2.concat(await conn.receiveMessages()); - } - Assert.deepEqual(mess2, ["message2", "message3"]); - - conn.close(); - let { status: finalStatus } = await conn.finished(); - Assert.equal(finalStatus, Cr.NS_OK); - - await wss.stop(); -} - async function test_inner_connection_fallback() { info("Running test_inner_connection_fallback"); let h3Port = Services.env.get("MOZHTTP3_PORT_NO_RESPONSE"); diff --git a/netwerk/test/unit/test_http3_proxy.js b/netwerk/test/unit/test_http3_proxy.js @@ -20,7 +20,6 @@ add_task(test_http_connect_invalid_host); add_task(test_concurrent_http_connect_tunnels); // TODO: Proxy needs to close the stream properly when socket failures occur // add_task(test_http_connect_stream_closure); -add_task(test_http_connect_websocket); add_task(test_connect_udp); add_task(test_http_connect_fallback); add_task(test_inner_connection_fallback); diff --git a/netwerk/test/unit/test_websocket_proxy.js b/netwerk/test/unit/test_websocket_proxy.js @@ -1,107 +0,0 @@ -/* 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"; - -/* import-globals-from http3_proxy_common.js */ - -const { - NodeWebSocketPlainServer, - NodeWebSocketServer, - NodeHTTPProxyServer, - NodeHTTPSProxyServer, -} = ChromeUtils.importESModule("resource://testing-common/NodeServer.sys.mjs"); - -add_setup(async function setup() { - do_get_profile(); -}); - -async function wsChannelOpen(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, - servers = [ - NodeWebSocketPlainServer, - NodeWebSocketServer, - NodeWebSocketHttp2Server, - ] -) { - await with_node_servers(servers, 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 wsChannelOpen(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(); -}); - -add_task(async function test_masque_proxy() { - await setup_http3_proxy(); - - await do_ws_requests("masque"); -}); diff --git a/netwerk/test/unit/test_websocket_server.js b/netwerk/test/unit/test_websocket_server.js @@ -9,7 +9,6 @@ /* import-globals-from head_channels.js */ const { - NodeWebSocketPlainServer, NodeWebSocketServer, NodeWebSocketHttp2Server, NodeHTTPProxyServer, @@ -67,41 +66,6 @@ async function channelOpenPromise(url, msg) { } // h1.1 direct -async function test_h1_plain_websocket_direct() { - let wss = new NodeWebSocketPlainServer(); - await wss.start(); - registerCleanupFunction(async () => wss.stop()); - Assert.notEqual(wss.port(), null); - await wss.registerMessageHandler((data, ws) => { - ws.send(data); - }); - let url = `ws://localhost:${wss.port()}`; - const msg = "test websocket"; - - let conn = new WebSocketConnection(); - await conn.open(url); - conn.send(msg); - let mess1 = await conn.receiveMessages(); - Assert.deepEqual(mess1, [msg]); - - // Now send 3 more, and check that we received all of them - conn.send(msg); - conn.send(msg); - conn.send(msg); - let mess2 = []; - while (mess2.length < 3) { - // receive could return 1, 2 or all 3 replies. - mess2 = mess2.concat(await conn.receiveMessages()); - } - Assert.deepEqual(mess2, [msg, msg, msg]); - - conn.close(); - let { status } = await conn.finished(); - - Assert.equal(status, Cr.NS_OK); -} - -// h1.1 direct async function test_h1_websocket_direct() { let wss = new NodeWebSocketServer(); await wss.start(); @@ -452,7 +416,6 @@ async function test_websocket_fallback() { checkConnectionActivities(observer.activites, "localhost", wss.port()); } -add_task(test_h1_plain_websocket_direct); add_task(test_h1_websocket_direct); add_task(test_h2_websocket_direct); add_task(test_h1_ws_with_secure_h1_proxy); diff --git a/netwerk/test/unit/xpcshell.toml b/netwerk/test/unit/xpcshell.toml @@ -1603,9 +1603,6 @@ run-sequentially = ["true"] # node server exceptions dont replay well ["test_websocket_offline.js"] -["test_websocket_proxy.js"] -head = "head_cookies.js head_channels.js head_cache.js head_http3.js http3_proxy_common.js" - ["test_websocket_server.js"] run-sequentially = ["true"] # node server exceptions dont replay well