From bc6a80e79482362f0e972e4b35af7a16501f6ce9 Mon Sep 17 00:00:00 2001 From: Junior Hsu Date: Tue, 24 Dec 2019 19:51:09 +0000 Subject: [PATCH] Bug 1601671 - make websocket support proxying on SOCKS/HTTPS, r=michal This is something less hacky to the best of my knowledge. Both passing preferable proxy table and letting system setting handle `ws`/`wss` touch the code of all platforms, which is more fragile. Differential Revision: https://phabricator.services.mozilla.com/D57176 --HG-- extra : moz-landing-system : lando --- netwerk/base/nsProtocolProxyService.cpp | 21 +++++++++++++- netwerk/test/unit/test_bug1177909.js | 37 +++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/netwerk/base/nsProtocolProxyService.cpp b/netwerk/base/nsProtocolProxyService.cpp index aede9d922b6a2..572dfe3fca79b 100644 --- a/netwerk/base/nsProtocolProxyService.cpp +++ b/netwerk/base/nsProtocolProxyService.cpp @@ -2109,7 +2109,26 @@ nsresult nsProtocolProxyService::Resolve_Internal(nsIChannel* channel, // now try the system proxy settings for this particular url if (NS_SUCCEEDED(mSystemProxySettings->GetProxyForURI(spec, scheme, host, port, pacString))) { - ProcessPACString(pacString, 0, result); + nsCOMPtr pi; + ProcessPACString(pacString, 0, getter_AddRefs(pi)); + + if (flags & RESOLVE_PREFER_SOCKS_PROXY && + flags & RESOLVE_PREFER_HTTPS_PROXY) { + nsAutoCString type; + pi->GetType(type); + // DIRECT from ProcessPACString indicates that system proxy settings + // are not configured to use SOCKS proxy. Try https proxy as a + // secondary preferrable proxy. This is mainly for websocket whose + // proxy precedence is SOCKS > HTTPS > DIRECT. + if (type.EqualsLiteral(kProxyType_DIRECT)) { + scheme.AssignLiteral(kProxyType_HTTPS); + if (NS_SUCCEEDED(mSystemProxySettings->GetProxyForURI( + spec, scheme, host, port, pacString))) { + ProcessPACString(pacString, 0, getter_AddRefs(pi)); + } + } + } + pi.forget(result); return NS_OK; } } diff --git a/netwerk/test/unit/test_bug1177909.js b/netwerk/test/unit/test_bug1177909.js index 210d624fbebe8..223aaa623bcec 100644 --- a/netwerk/test/unit/test_bug1177909.js +++ b/netwerk/test/unit/test_bug1177909.js @@ -22,9 +22,12 @@ XPCOMUtils.defineLazyGetter(this, "systemSettings", function() { if (aPort != -1) { return "SOCKS5 http://localhost:9050"; } - if (aScheme == "http" || aScheme == "https" || aScheme == "ftp") { + if (aScheme == "http" || aScheme == "ftp") { return "PROXY http://localhost:8080"; } + if (aScheme == "https") { + return "HTTPS https://localhost:8080"; + } return "DIRECT"; }, }; @@ -79,7 +82,7 @@ add_task(async function testHttpsProxy() { let pi = await TestProxyTypeByURI("https://www.mozilla.org/"); equal(pi.host, "localhost", "Expected proxy host to be localhost"); equal(pi.port, 8080, "Expected proxy port to be 8080"); - equal(pi.type, "http", "Expected proxy type to be http"); + equal(pi.type, "https", "Expected proxy type to be https"); }); add_task(async function testFtpProxy() { @@ -137,6 +140,7 @@ add_task(async function testWebSocketProxy() { .finalize(); let proxyFlags = + Ci.nsIProtocolProxyService.RESOLVE_PREFER_SOCKS_PROXY | Ci.nsIProtocolProxyService.RESOLVE_PREFER_HTTPS_PROXY | Ci.nsIProtocolProxyService.RESOLVE_ALWAYS_TUNNEL; @@ -157,5 +161,32 @@ add_task(async function testWebSocketProxy() { let pi = await TestProxyType(chan, proxyFlags); equal(pi.host, "localhost", "Expected proxy host to be localhost"); equal(pi.port, 8080, "Expected proxy port to be 8080"); - equal(pi.type, "http", "Expected proxy type to be http"); + equal(pi.type, "https", "Expected proxy type to be https"); +}); + +add_task(async function testPreferHttpsProxy() { + let uri = Cc["@mozilla.org/network/standard-url-mutator;1"] + .createInstance(Ci.nsIURIMutator) + .setSpec("http://mozilla.org/") + .finalize(); + let proxyFlags = Ci.nsIProtocolProxyService.RESOLVE_PREFER_HTTPS_PROXY; + + let ioService = Cc["@mozilla.org/network/io-service;1"].getService( + Ci.nsIIOService + ); + let chan = ioService.newChannelFromURIWithProxyFlags( + uri, + null, + proxyFlags, + null, + Services.scriptSecurityManager.getSystemPrincipal(), + null, + Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + Ci.nsIContentPolicy.TYPE_OTHER + ); + + let pi = await TestProxyType(chan, proxyFlags); + equal(pi.host, "localhost", "Expected proxy host to be localhost"); + equal(pi.port, 8080, "Expected proxy port to be 8080"); + equal(pi.type, "https", "Expected proxy type to be https"); });