test_bug1177909.js (7598B)
1 "use strict"; 2 3 const { MockRegistrar } = ChromeUtils.importESModule( 4 "resource://testing-common/MockRegistrar.sys.mjs" 5 ); 6 7 XPCOMUtils.defineLazyServiceGetter( 8 this, 9 "gProxyService", 10 "@mozilla.org/network/protocol-proxy-service;1", 11 Ci.nsIProtocolProxyService 12 ); 13 14 ChromeUtils.defineLazyGetter(this, "systemSettings", function () { 15 return { 16 QueryInterface: ChromeUtils.generateQI(["nsISystemProxySettings"]), 17 18 mainThreadOnly: true, 19 PACURI: null, 20 21 getProxyForURI(aSpec, aScheme, aHost, aPort) { 22 if (aPort != -1) { 23 return "SOCKS5 http://localhost:9050"; 24 } 25 if (aScheme == "http") { 26 return "PROXY http://localhost:8080"; 27 } 28 if (aScheme == "https") { 29 return "HTTPS https://localhost:8080"; 30 } 31 return "DIRECT"; 32 }, 33 }; 34 }); 35 36 let gMockProxy = MockRegistrar.register( 37 "@mozilla.org/system-proxy-settings;1", 38 systemSettings 39 ); 40 41 registerCleanupFunction(() => { 42 MockRegistrar.unregister(gMockProxy); 43 }); 44 45 function makeChannel(uri) { 46 return NetUtil.newChannel({ 47 uri, 48 loadUsingSystemPrincipal: true, 49 }); 50 } 51 52 async function TestProxyType(chan, flags) { 53 Services.prefs.setIntPref( 54 "network.proxy.type", 55 Ci.nsIProtocolProxyService.PROXYCONFIG_SYSTEM 56 ); 57 58 return new Promise(resolve => { 59 gProxyService.asyncResolve(chan, flags, { 60 onProxyAvailable(req, uri, pi) { 61 resolve(pi); 62 }, 63 }); 64 }); 65 } 66 67 async function TestProxyTypeByURI(uri) { 68 return TestProxyType(makeChannel(uri), 0); 69 } 70 71 add_task(async function testHttpProxy() { 72 let pi = await TestProxyTypeByURI("http://www.mozilla.org/"); 73 equal(pi.host, "localhost", "Expected proxy host to be localhost"); 74 equal(pi.port, 8080, "Expected proxy port to be 8080"); 75 equal(pi.type, "http", "Expected proxy type to be http"); 76 }); 77 78 add_task(async function testHttpsProxy() { 79 let pi = await TestProxyTypeByURI("https://www.mozilla.org/"); 80 equal(pi.host, "localhost", "Expected proxy host to be localhost"); 81 equal(pi.port, 8080, "Expected proxy port to be 8080"); 82 equal(pi.type, "https", "Expected proxy type to be https"); 83 }); 84 85 add_task(async function testSocksProxy() { 86 let pi = await TestProxyTypeByURI("http://www.mozilla.org:1234/"); 87 equal(pi.host, "localhost", "Expected proxy host to be localhost"); 88 equal(pi.port, 9050, "Expected proxy port to be 8080"); 89 equal(pi.type, "socks", "Expected proxy type to be http"); 90 }); 91 92 add_task(async function testDirectProxy() { 93 // Do what |WebSocketChannel::AsyncOpen| do, but do not prefer https proxy. 94 let proxyURI = Cc["@mozilla.org/network/standard-url-mutator;1"] 95 .createInstance(Ci.nsIURIMutator) 96 .setSpec("wss://ws.mozilla.org/") 97 .finalize(); 98 let uri = proxyURI.mutate().setScheme("https").finalize(); 99 100 let chan = Services.io.newChannelFromURIWithProxyFlags( 101 uri, 102 proxyURI, 103 0, 104 null, 105 Services.scriptSecurityManager.getSystemPrincipal(), 106 null, 107 Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, 108 Ci.nsIContentPolicy.TYPE_OTHER 109 ); 110 111 let pi = await TestProxyType(chan, 0); 112 equal(pi, null, "Expected proxy host to be null"); 113 }); 114 115 add_task(async function testWebSocketProxy() { 116 // Do what |WebSocketChannel::AsyncOpen| do 117 let proxyURI = Cc["@mozilla.org/network/standard-url-mutator;1"] 118 .createInstance(Ci.nsIURIMutator) 119 .setSpec("wss://ws.mozilla.org/") 120 .finalize(); 121 let uri = proxyURI.mutate().setScheme("https").finalize(); 122 123 let proxyFlags = 124 Ci.nsIProtocolProxyService.RESOLVE_PREFER_SOCKS_PROXY | 125 Ci.nsIProtocolProxyService.RESOLVE_PREFER_HTTPS_PROXY | 126 Ci.nsIProtocolProxyService.RESOLVE_ALWAYS_TUNNEL; 127 128 let chan = Services.io.newChannelFromURIWithProxyFlags( 129 uri, 130 proxyURI, 131 proxyFlags, 132 null, 133 Services.scriptSecurityManager.getSystemPrincipal(), 134 null, 135 Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, 136 Ci.nsIContentPolicy.TYPE_OTHER 137 ); 138 139 let pi = await TestProxyType(chan, proxyFlags); 140 equal(pi.host, "localhost", "Expected proxy host to be localhost"); 141 equal(pi.port, 8080, "Expected proxy port to be 8080"); 142 equal(pi.type, "https", "Expected proxy type to be https"); 143 }); 144 145 add_task(async function testPreferHttpsProxy() { 146 let uri = Cc["@mozilla.org/network/standard-url-mutator;1"] 147 .createInstance(Ci.nsIURIMutator) 148 .setSpec("http://mozilla.org/") 149 .finalize(); 150 let proxyFlags = Ci.nsIProtocolProxyService.RESOLVE_PREFER_HTTPS_PROXY; 151 152 let chan = Services.io.newChannelFromURIWithProxyFlags( 153 uri, 154 null, 155 proxyFlags, 156 null, 157 Services.scriptSecurityManager.getSystemPrincipal(), 158 null, 159 Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, 160 Ci.nsIContentPolicy.TYPE_OTHER 161 ); 162 163 let pi = await TestProxyType(chan, proxyFlags); 164 equal(pi.host, "localhost", "Expected proxy host to be localhost"); 165 equal(pi.port, 8080, "Expected proxy port to be 8080"); 166 equal(pi.type, "https", "Expected proxy type to be https"); 167 }); 168 169 add_task(async function testProxyHttpsToHttpIsBlocked() { 170 // Ensure that regressions of bug 1702417 will be detected by the next test 171 const turnUri = Services.io.newURI("http://turn.example.com/"); 172 const proxyFlags = 173 Ci.nsIProtocolProxyService.RESOLVE_PREFER_HTTPS_PROXY | 174 Ci.nsIProtocolProxyService.RESOLVE_ALWAYS_TUNNEL; 175 176 const fakeContentPrincipal = 177 Services.scriptSecurityManager.createContentPrincipalFromOrigin( 178 "https://example.com" 179 ); 180 181 const chan = Services.io.newChannelFromURIWithProxyFlags( 182 turnUri, 183 null, 184 proxyFlags, 185 null, 186 fakeContentPrincipal, 187 fakeContentPrincipal, 188 Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, 189 Ci.nsIContentPolicy.TYPE_OTHER 190 ); 191 192 const pi = await TestProxyType(chan, proxyFlags); 193 equal(pi.host, "localhost", "Expected proxy host to be localhost"); 194 equal(pi.port, 8080, "Expected proxy port to be 8080"); 195 equal(pi.type, "https", "Expected proxy type to be https"); 196 197 const csm = Cc["@mozilla.org/contentsecuritymanager;1"].getService( 198 Ci.nsIContentSecurityManager 199 ); 200 201 try { 202 csm.performSecurityCheck(chan, null); 203 Assert.ok( 204 false, 205 "performSecurityCheck should fail (due to mixed content blocking)" 206 ); 207 } catch (e) { 208 Assert.equal( 209 e.result, 210 Cr.NS_ERROR_CONTENT_BLOCKED, 211 "performSecurityCheck should throw NS_ERROR_CONTENT_BLOCKED" 212 ); 213 } 214 }); 215 216 add_task(async function testProxyHttpsToTurnTcpWorks() { 217 // Test for bug 1702417 218 const turnUri = Services.io.newURI("http://turn.example.com/"); 219 const proxyFlags = 220 Ci.nsIProtocolProxyService.RESOLVE_PREFER_HTTPS_PROXY | 221 Ci.nsIProtocolProxyService.RESOLVE_ALWAYS_TUNNEL; 222 223 const fakeContentPrincipal = 224 Services.scriptSecurityManager.createContentPrincipalFromOrigin( 225 "https://example.com" 226 ); 227 228 const chan = Services.io.newChannelFromURIWithProxyFlags( 229 turnUri, 230 null, 231 proxyFlags, 232 null, 233 fakeContentPrincipal, 234 fakeContentPrincipal, 235 Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, 236 // This is what allows this to avoid mixed content blocking 237 Ci.nsIContentPolicy.TYPE_PROXIED_WEBRTC_MEDIA 238 ); 239 240 const pi = await TestProxyType(chan, proxyFlags); 241 equal(pi.host, "localhost", "Expected proxy host to be localhost"); 242 equal(pi.port, 8080, "Expected proxy port to be 8080"); 243 equal(pi.type, "https", "Expected proxy type to be https"); 244 245 const csm = Cc["@mozilla.org/contentsecuritymanager;1"].getService( 246 Ci.nsIContentSecurityManager 247 ); 248 249 csm.performSecurityCheck(chan, null); 250 Assert.ok(true, "performSecurityCheck should succeed"); 251 });