test_protocolproxyservice.js (28864B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // This testcase exercises the Protocol Proxy Service 8 9 // These are the major sub tests: 10 // run_filter_test(); 11 // run_filter_test2() 12 // run_filter_test3() 13 // run_pref_test(); 14 // run_pac_test(); 15 // run_pac_cancel_test(); 16 // run_proxy_host_filters_test(); 17 // run_myipaddress_test(); 18 // run_failed_script_test(); 19 // run_isresolvable_test(); 20 21 "use strict"; 22 23 var ios = Services.io; 24 var pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(); 25 var prefs = Services.prefs; 26 var again = true; 27 28 /** 29 * Test nsIProtocolHandler that allows proxying, but doesn't allow HTTP 30 * proxying. 31 */ 32 function TestProtocolHandler() {} 33 TestProtocolHandler.prototype = { 34 QueryInterface: ChromeUtils.generateQI(["nsIProtocolHandler"]), 35 scheme: "moz-test", 36 defaultPort: -1, 37 protocolFlags: 38 Ci.nsIProtocolHandler.URI_NOAUTH | 39 Ci.nsIProtocolHandler.URI_NORELATIVE | 40 Ci.nsIProtocolHandler.ALLOWS_PROXY | 41 Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD, 42 newChannel() { 43 throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); 44 }, 45 allowPort() { 46 return true; 47 }, 48 }; 49 50 function TestProtocolHandlerFactory() {} 51 TestProtocolHandlerFactory.prototype = { 52 createInstance(iid) { 53 return new TestProtocolHandler().QueryInterface(iid); 54 }, 55 }; 56 57 function register_test_protocol_handler() { 58 var reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); 59 reg.registerFactory( 60 Components.ID("{4ea7dd3a-8cae-499c-9f18-e1de773ca25b}"), 61 "TestProtocolHandler", 62 "@mozilla.org/network/protocol;1?name=moz-test", 63 new TestProtocolHandlerFactory() 64 ); 65 } 66 67 function check_proxy(pi, type, host, port, flags, timeout, hasNext) { 68 Assert.notEqual(pi, null); 69 Assert.equal(pi.type, type); 70 Assert.equal(pi.host, host); 71 Assert.equal(pi.port, port); 72 if (flags != -1) { 73 Assert.equal(pi.flags, flags); 74 } 75 if (timeout != -1) { 76 Assert.equal(pi.failoverTimeout, timeout); 77 } 78 if (hasNext) { 79 Assert.notEqual(pi.failoverProxy, null); 80 } else { 81 Assert.equal(pi.failoverProxy, null); 82 } 83 } 84 85 function TestFilter(type, host, port, flags, timeout) { 86 this._type = type; 87 this._host = host; 88 this._port = port; 89 this._flags = flags; 90 this._timeout = timeout; 91 } 92 TestFilter.prototype = { 93 _type: "", 94 _host: "", 95 _port: -1, 96 _flags: 0, 97 _timeout: 0, 98 QueryInterface: ChromeUtils.generateQI(["nsIProtocolProxyFilter"]), 99 applyFilter(uri, pi, cb) { 100 var pi_tail = pps.newProxyInfo( 101 this._type, 102 this._host, 103 this._port, 104 "", 105 "", 106 this._flags, 107 this._timeout, 108 null 109 ); 110 if (pi) { 111 pi.failoverProxy = pi_tail; 112 } else { 113 pi = pi_tail; 114 } 115 cb.onProxyFilterResult(pi); 116 }, 117 }; 118 119 function BasicFilter() {} 120 BasicFilter.prototype = { 121 QueryInterface: ChromeUtils.generateQI(["nsIProtocolProxyFilter"]), 122 applyFilter(uri, pi, cb) { 123 cb.onProxyFilterResult( 124 pps.newProxyInfo( 125 "http", 126 "localhost", 127 8080, 128 "", 129 "", 130 0, 131 10, 132 pps.newProxyInfo("direct", "", -1, "", "", 0, 0, null) 133 ) 134 ); 135 }, 136 }; 137 138 function BasicChannelFilter() {} 139 BasicChannelFilter.prototype = { 140 QueryInterface: ChromeUtils.generateQI(["nsIProtocolProxyChannelFilter"]), 141 applyFilter(channel, pi, cb) { 142 cb.onProxyFilterResult( 143 pps.newProxyInfo( 144 "http", 145 channel.URI.host, 146 7777, 147 "", 148 "", 149 0, 150 10, 151 pps.newProxyInfo("direct", "", -1, "", "", 0, 0, null) 152 ) 153 ); 154 }, 155 }; 156 157 function resolveCallback() {} 158 resolveCallback.prototype = { 159 nextFunction: null, 160 161 QueryInterface: ChromeUtils.generateQI(["nsIProtocolProxyCallback"]), 162 163 onProxyAvailable(req, channel, pi) { 164 this.nextFunction(pi); 165 }, 166 }; 167 168 function run_filter_test() { 169 var channel = NetUtil.newChannel({ 170 uri: "http://www.mozilla.org/", 171 loadUsingSystemPrincipal: true, 172 }); 173 174 // Verify initial state 175 var cb = new resolveCallback(); 176 cb.nextFunction = filter_test0_1; 177 pps.asyncResolve(channel, 0, cb); 178 } 179 180 var filter01; 181 var filter02; 182 183 function filter_test0_1(pi) { 184 Assert.equal(pi, null); 185 186 // Push a filter and verify the results 187 188 filter01 = new BasicFilter(); 189 filter02 = new BasicFilter(); 190 pps.registerFilter(filter01, 10); 191 pps.registerFilter(filter02, 20); 192 193 var cb = new resolveCallback(); 194 cb.nextFunction = filter_test0_2; 195 var channel = NetUtil.newChannel({ 196 uri: "http://www.mozilla.org/", 197 loadUsingSystemPrincipal: true, 198 }); 199 pps.asyncResolve(channel, 0, cb); 200 } 201 202 function filter_test0_2(pi) { 203 check_proxy(pi, "http", "localhost", 8080, 0, 10, true); 204 check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); 205 206 pps.unregisterFilter(filter02); 207 208 var cb = new resolveCallback(); 209 cb.nextFunction = filter_test0_3; 210 var channel = NetUtil.newChannel({ 211 uri: "http://www.mozilla.org/", 212 loadUsingSystemPrincipal: true, 213 }); 214 pps.asyncResolve(channel, 0, cb); 215 } 216 217 function filter_test0_3(pi) { 218 check_proxy(pi, "http", "localhost", 8080, 0, 10, true); 219 check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); 220 221 // Remove filter and verify that we return to the initial state 222 223 pps.unregisterFilter(filter01); 224 225 var cb = new resolveCallback(); 226 cb.nextFunction = filter_test0_4; 227 var channel = NetUtil.newChannel({ 228 uri: "http://www.mozilla.org/", 229 loadUsingSystemPrincipal: true, 230 }); 231 pps.asyncResolve(channel, 0, cb); 232 } 233 234 var filter03; 235 236 function filter_test0_4(pi) { 237 Assert.equal(pi, null); 238 filter03 = new BasicChannelFilter(); 239 pps.registerChannelFilter(filter03, 10); 240 var cb = new resolveCallback(); 241 cb.nextFunction = filter_test0_5; 242 var channel = NetUtil.newChannel({ 243 uri: "http://www.mozilla.org/", 244 loadUsingSystemPrincipal: true, 245 }); 246 pps.asyncResolve(channel, 0, cb); 247 } 248 249 function filter_test0_5(pi) { 250 pps.unregisterChannelFilter(filter03); 251 check_proxy(pi, "http", "www.mozilla.org", 7777, 0, 10, true); 252 check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); 253 run_filter_test_uri(); 254 } 255 256 function run_filter_test_uri() { 257 var cb = new resolveCallback(); 258 cb.nextFunction = filter_test_uri0_1; 259 var uri = ios.newURI("http://www.mozilla.org/"); 260 pps.asyncResolve(uri, 0, cb); 261 } 262 263 function filter_test_uri0_1(pi) { 264 Assert.equal(pi, null); 265 266 // Push a filter and verify the results 267 268 filter01 = new BasicFilter(); 269 filter02 = new BasicFilter(); 270 pps.registerFilter(filter01, 10); 271 pps.registerFilter(filter02, 20); 272 273 var cb = new resolveCallback(); 274 cb.nextFunction = filter_test_uri0_2; 275 var uri = ios.newURI("http://www.mozilla.org/"); 276 pps.asyncResolve(uri, 0, cb); 277 } 278 279 function filter_test_uri0_2(pi) { 280 check_proxy(pi, "http", "localhost", 8080, 0, 10, true); 281 check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); 282 283 pps.unregisterFilter(filter02); 284 285 var cb = new resolveCallback(); 286 cb.nextFunction = filter_test_uri0_3; 287 var uri = ios.newURI("http://www.mozilla.org/"); 288 pps.asyncResolve(uri, 0, cb); 289 } 290 291 function filter_test_uri0_3(pi) { 292 check_proxy(pi, "http", "localhost", 8080, 0, 10, true); 293 check_proxy(pi.failoverProxy, "direct", "", -1, 0, 0, false); 294 295 // Remove filter and verify that we return to the initial state 296 297 pps.unregisterFilter(filter01); 298 299 var cb = new resolveCallback(); 300 cb.nextFunction = filter_test_uri0_4; 301 var uri = ios.newURI("http://www.mozilla.org/"); 302 pps.asyncResolve(uri, 0, cb); 303 } 304 305 function filter_test_uri0_4(pi) { 306 Assert.equal(pi, null); 307 run_filter_test2(); 308 } 309 310 var filter11; 311 var filter12; 312 313 function run_filter_test2() { 314 // Push a filter and verify the results 315 316 filter11 = new TestFilter("http", "foo", 8080, 0, 10); 317 filter12 = new TestFilter("http", "bar", 8090, 0, 10); 318 pps.registerFilter(filter11, 20); 319 pps.registerFilter(filter12, 10); 320 321 var cb = new resolveCallback(); 322 cb.nextFunction = filter_test1_1; 323 var channel = NetUtil.newChannel({ 324 uri: "http://www.mozilla.org/", 325 loadUsingSystemPrincipal: true, 326 }); 327 pps.asyncResolve(channel, 0, cb); 328 } 329 330 function filter_test1_1(pi) { 331 check_proxy(pi, "http", "bar", 8090, 0, 10, true); 332 check_proxy(pi.failoverProxy, "http", "foo", 8080, 0, 10, false); 333 334 pps.unregisterFilter(filter12); 335 336 var cb = new resolveCallback(); 337 cb.nextFunction = filter_test1_2; 338 var channel = NetUtil.newChannel({ 339 uri: "http://www.mozilla.org/", 340 loadUsingSystemPrincipal: true, 341 }); 342 pps.asyncResolve(channel, 0, cb); 343 } 344 345 function filter_test1_2(pi) { 346 check_proxy(pi, "http", "foo", 8080, 0, 10, false); 347 348 // Remove filter and verify that we return to the initial state 349 350 pps.unregisterFilter(filter11); 351 352 var cb = new resolveCallback(); 353 cb.nextFunction = filter_test1_3; 354 var channel = NetUtil.newChannel({ 355 uri: "http://www.mozilla.org/", 356 loadUsingSystemPrincipal: true, 357 }); 358 pps.asyncResolve(channel, 0, cb); 359 } 360 361 function filter_test1_3(pi) { 362 Assert.equal(pi, null); 363 run_filter_test3(); 364 } 365 366 var filter_3_1; 367 368 function run_filter_test3() { 369 var channel = NetUtil.newChannel({ 370 uri: "http://www.mozilla.org/", 371 loadUsingSystemPrincipal: true, 372 }); 373 // Push a filter and verify the results asynchronously 374 375 filter_3_1 = new TestFilter("http", "foo", 8080, 0, 10); 376 pps.registerFilter(filter_3_1, 20); 377 378 var cb = new resolveCallback(); 379 cb.nextFunction = filter_test3_1; 380 pps.asyncResolve(channel, 0, cb); 381 } 382 383 function filter_test3_1(pi) { 384 check_proxy(pi, "http", "foo", 8080, 0, 10, false); 385 pps.unregisterFilter(filter_3_1); 386 run_pref_test(); 387 } 388 389 function run_pref_test() { 390 var channel = NetUtil.newChannel({ 391 uri: "http://www.mozilla.org/", 392 loadUsingSystemPrincipal: true, 393 }); 394 // Verify 'direct' setting 395 396 prefs.setIntPref("network.proxy.type", 0); 397 398 var cb = new resolveCallback(); 399 cb.nextFunction = pref_test1_1; 400 pps.asyncResolve(channel, 0, cb); 401 } 402 403 function pref_test1_1(pi) { 404 Assert.equal(pi, null); 405 406 // Verify 'manual' setting 407 prefs.setIntPref("network.proxy.type", 1); 408 409 var cb = new resolveCallback(); 410 cb.nextFunction = pref_test1_2; 411 var channel = NetUtil.newChannel({ 412 uri: "http://www.mozilla.org/", 413 loadUsingSystemPrincipal: true, 414 }); 415 pps.asyncResolve(channel, 0, cb); 416 } 417 418 function pref_test1_2(pi) { 419 // nothing yet configured 420 Assert.equal(pi, null); 421 422 // try HTTP configuration 423 prefs.setCharPref("network.proxy.http", "foopy"); 424 prefs.setIntPref("network.proxy.http_port", 8080); 425 426 var cb = new resolveCallback(); 427 cb.nextFunction = pref_test1_3; 428 var channel = NetUtil.newChannel({ 429 uri: "http://www.mozilla.org/", 430 loadUsingSystemPrincipal: true, 431 }); 432 pps.asyncResolve(channel, 0, cb); 433 } 434 435 function pref_test1_3(pi) { 436 check_proxy(pi, "http", "foopy", 8080, 0, -1, false); 437 438 prefs.setCharPref("network.proxy.http", ""); 439 prefs.setIntPref("network.proxy.http_port", 0); 440 441 // try SOCKS configuration 442 prefs.setCharPref("network.proxy.socks", "barbar"); 443 prefs.setIntPref("network.proxy.socks_port", 1203); 444 445 var cb = new resolveCallback(); 446 cb.nextFunction = pref_test1_4; 447 var channel = NetUtil.newChannel({ 448 uri: "http://www.mozilla.org/", 449 loadUsingSystemPrincipal: true, 450 }); 451 pps.asyncResolve(channel, 0, cb); 452 } 453 454 function pref_test1_4(pi) { 455 check_proxy(pi, "socks", "barbar", 1203, 1, -1, false); 456 run_pac_test(); 457 } 458 459 function TestResolveCallback(type, nexttest) { 460 this.type = type; 461 this.nexttest = nexttest; 462 } 463 TestResolveCallback.prototype = { 464 QueryInterface: ChromeUtils.generateQI(["nsIProtocolProxyCallback"]), 465 466 onProxyAvailable: function TestResolveCallback_onProxyAvailable( 467 req, 468 channel, 469 pi, 470 status 471 ) { 472 dump("*** channelURI=" + channel.URI.spec + ", status=" + status + "\n"); 473 474 if (this.type == null) { 475 Assert.equal(pi, null); 476 } else { 477 Assert.notEqual(req, null); 478 Assert.notEqual(channel, null); 479 Assert.equal(status, 0); 480 Assert.notEqual(pi, null); 481 check_proxy(pi, this.type, "foopy", 8080, 1, -1, true); 482 check_proxy(pi.failoverProxy, "direct", "", -1, -1, -1, false); 483 } 484 485 this.nexttest(); 486 }, 487 }; 488 489 var originalTLSProxy; 490 491 function run_pac_test() { 492 var pac = 493 "data:text/plain," + 494 "function FindProxyForURL(url, host) {" + 495 ' return "PROXY foopy:8080; DIRECT";' + 496 "}"; 497 var channel = NetUtil.newChannel({ 498 uri: "http://www.mozilla.org/", 499 loadUsingSystemPrincipal: true, 500 }); 501 // Configure PAC 502 503 prefs.setIntPref("network.proxy.type", 2); 504 prefs.setCharPref("network.proxy.autoconfig_url", pac); 505 pps.asyncResolve(channel, 0, new TestResolveCallback("http", run_pac2_test)); 506 } 507 508 function run_pac2_test() { 509 var pac = 510 "data:text/plain," + 511 "function FindProxyForURL(url, host) {" + 512 ' return "HTTPS foopy:8080; DIRECT";' + 513 "}"; 514 var channel = NetUtil.newChannel({ 515 uri: "http://www.mozilla.org/", 516 loadUsingSystemPrincipal: true, 517 }); 518 // Configure PAC 519 originalTLSProxy = prefs.getBoolPref("network.proxy.proxy_over_tls"); 520 521 prefs.setCharPref("network.proxy.autoconfig_url", pac); 522 prefs.setBoolPref("network.proxy.proxy_over_tls", true); 523 524 pps.asyncResolve(channel, 0, new TestResolveCallback("https", run_pac3_test)); 525 } 526 527 function run_pac3_test() { 528 var pac = 529 "data:text/plain," + 530 "function FindProxyForURL(url, host) {" + 531 ' return "HTTPS foopy:8080; DIRECT";' + 532 "}"; 533 var channel = NetUtil.newChannel({ 534 uri: "http://www.mozilla.org/", 535 loadUsingSystemPrincipal: true, 536 }); 537 // Configure PAC 538 prefs.setCharPref("network.proxy.autoconfig_url", pac); 539 prefs.setBoolPref("network.proxy.proxy_over_tls", false); 540 541 pps.asyncResolve(channel, 0, new TestResolveCallback(null, run_pac4_test)); 542 } 543 544 function run_pac4_test() { 545 // Bug 1251332 546 let wRange = [ 547 ["SUN", "MON", "SAT", "MON"], // for Sun 548 ["SUN", "TUE", "SAT", "TUE"], // for Mon 549 ["MON", "WED", "SAT", "WED"], // for Tue 550 ["TUE", "THU", "SAT", "THU"], // for Wed 551 ["WED", "FRI", "WED", "SUN"], // for Thu 552 ["THU", "SAT", "THU", "SUN"], // for Fri 553 ["FRI", "SAT", "FRI", "SUN"], // for Sat 554 ]; 555 let today = new Date().getDay(); 556 var pac = 557 "data:text/plain," + 558 "function FindProxyForURL(url, host) {" + 559 ' if (weekdayRange("' + 560 wRange[today][0] + 561 '", "' + 562 wRange[today][1] + 563 '") &&' + 564 ' weekdayRange("' + 565 wRange[today][2] + 566 '", "' + 567 wRange[today][3] + 568 '")) {' + 569 ' return "PROXY foopy:8080; DIRECT";' + 570 " }" + 571 "}"; 572 var channel = NetUtil.newChannel({ 573 uri: "http://www.mozilla.org/", 574 loadUsingSystemPrincipal: true, 575 }); 576 // Configure PAC 577 578 prefs.setIntPref("network.proxy.type", 2); 579 prefs.setCharPref("network.proxy.autoconfig_url", pac); 580 pps.asyncResolve( 581 channel, 582 0, 583 new TestResolveCallback("http", run_utf8_pac_test) 584 ); 585 } 586 587 function run_utf8_pac_test() { 588 var pac = 589 "data:text/plain;charset=UTF-8," + 590 "function FindProxyForURL(url, host) {" + 591 " /*" + 592 " U+00A9 COPYRIGHT SIGN: %C2%A9," + 593 " U+0B87 TAMIL LETTER I: %E0%AE%87," + 594 " U+10398 UGARITIC LETTER THANNA: %F0%90%8E%98 " + 595 " */" + 596 ' var multiBytes = "%C2%A9 %E0%AE%87 %F0%90%8E%98"; ' + 597 " /* 6 UTF-16 units above if PAC script run as UTF-8; 11 units if run as Latin-1 */ " + 598 " return multiBytes.length === 6 " + 599 ' ? "PROXY foopy:8080; DIRECT" ' + 600 ' : "PROXY epicfail-utf8:12345; DIRECT";' + 601 "}"; 602 603 var channel = NetUtil.newChannel({ 604 uri: "http://www.mozilla.org/", 605 loadUsingSystemPrincipal: true, 606 }); 607 608 // Configure PAC 609 prefs.setIntPref("network.proxy.type", 2); 610 prefs.setCharPref("network.proxy.autoconfig_url", pac); 611 612 pps.asyncResolve( 613 channel, 614 0, 615 new TestResolveCallback("http", run_latin1_pac_test) 616 ); 617 } 618 619 function run_latin1_pac_test() { 620 var pac = 621 "data:text/plain," + 622 "function FindProxyForURL(url, host) {" + 623 " /* A too-long encoding of U+0000, so not valid UTF-8 */ " + 624 ' var multiBytes = "%C0%80"; ' + 625 " /* 2 UTF-16 units because interpreted as Latin-1 */ " + 626 " return multiBytes.length === 2 " + 627 ' ? "PROXY foopy:8080; DIRECT" ' + 628 ' : "PROXY epicfail-latin1:12345; DIRECT";' + 629 "}"; 630 631 var channel = NetUtil.newChannel({ 632 uri: "http://www.mozilla.org/", 633 loadUsingSystemPrincipal: true, 634 }); 635 636 // Configure PAC 637 prefs.setIntPref("network.proxy.type", 2); 638 prefs.setCharPref("network.proxy.autoconfig_url", pac); 639 640 pps.asyncResolve( 641 channel, 642 0, 643 new TestResolveCallback("http", finish_pac_test) 644 ); 645 } 646 647 function finish_pac_test() { 648 prefs.setBoolPref("network.proxy.proxy_over_tls", originalTLSProxy); 649 run_pac_cancel_test(); 650 } 651 652 function TestResolveCancelationCallback() {} 653 TestResolveCancelationCallback.prototype = { 654 QueryInterface: ChromeUtils.generateQI(["nsIProtocolProxyCallback"]), 655 656 onProxyAvailable: function TestResolveCancelationCallback_onProxyAvailable( 657 req, 658 channel, 659 pi, 660 status 661 ) { 662 dump("*** channelURI=" + channel.URI.spec + ", status=" + status + "\n"); 663 664 Assert.notEqual(req, null); 665 Assert.notEqual(channel, null); 666 Assert.equal(status, Cr.NS_ERROR_ABORT); 667 Assert.equal(pi, null); 668 669 prefs.setCharPref("network.proxy.autoconfig_url", ""); 670 prefs.setIntPref("network.proxy.type", 0); 671 672 run_proxy_host_filters_test(); 673 }, 674 }; 675 676 function run_pac_cancel_test() { 677 var channel = NetUtil.newChannel({ 678 uri: "http://www.mozilla.org/", 679 loadUsingSystemPrincipal: true, 680 }); 681 // Configure PAC 682 var pac = 683 "data:text/plain," + 684 "function FindProxyForURL(url, host) {" + 685 ' return "PROXY foopy:8080; DIRECT";' + 686 "}"; 687 prefs.setIntPref("network.proxy.type", 2); 688 prefs.setCharPref("network.proxy.autoconfig_url", pac); 689 690 var req = pps.asyncResolve(channel, 0, new TestResolveCancelationCallback()); 691 req.cancel(Cr.NS_ERROR_ABORT); 692 } 693 694 var hostList; 695 var hostIDX; 696 var bShouldBeFiltered; 697 var hostNextFX; 698 699 function check_host_filters(hl, shouldBe, nextFX) { 700 hostList = hl; 701 hostIDX = 0; 702 bShouldBeFiltered = shouldBe; 703 hostNextFX = nextFX; 704 705 if (hostList.length > hostIDX) { 706 check_host_filter(hostIDX); 707 } 708 } 709 710 function check_host_filters_cb() { 711 hostIDX++; 712 if (hostList.length > hostIDX) { 713 check_host_filter(hostIDX); 714 } else { 715 hostNextFX(); 716 } 717 } 718 719 function check_host_filter(i) { 720 dump( 721 "*** uri=" + hostList[i] + " bShouldBeFiltered=" + bShouldBeFiltered + "\n" 722 ); 723 var channel = NetUtil.newChannel({ 724 uri: hostList[i], 725 loadUsingSystemPrincipal: true, 726 }); 727 var cb = new resolveCallback(); 728 cb.nextFunction = host_filter_cb; 729 pps.asyncResolve(channel, 0, cb); 730 } 731 732 function host_filter_cb(proxy) { 733 if (bShouldBeFiltered) { 734 Assert.equal(proxy, null); 735 } else { 736 Assert.notEqual(proxy, null); 737 // Just to be sure, let's check that the proxy is correct 738 // - this should match the proxy setup in the calling function 739 check_proxy(proxy, "http", "foopy", 8080, 0, -1, false); 740 } 741 check_host_filters_cb(); 742 } 743 744 // Verify that hists in the host filter list are not proxied 745 // refers to "network.proxy.no_proxies_on" 746 747 var uriStrUseProxyList; 748 var hostFilterList; 749 var uriStrFilterList; 750 751 function run_proxy_host_filters_test() { 752 // Get prefs object from DOM 753 // Setup a basic HTTP proxy configuration 754 // - pps.resolve() needs this to return proxy info for non-filtered hosts 755 prefs.setIntPref("network.proxy.type", 1); 756 prefs.setCharPref("network.proxy.http", "foopy"); 757 prefs.setIntPref("network.proxy.http_port", 8080); 758 759 // Setup host filter list string for "no_proxies_on" 760 hostFilterList = 761 "www.mozilla.org, www.google.com, www.apple.com, " + 762 ".domain, .domain2.org"; 763 prefs.setCharPref("network.proxy.no_proxies_on", hostFilterList); 764 Assert.equal( 765 prefs.getCharPref("network.proxy.no_proxies_on"), 766 hostFilterList 767 ); 768 769 // Check the hosts that should be filtered out 770 uriStrFilterList = [ 771 "http://www.mozilla.org/", 772 "http://www.google.com/", 773 "http://www.apple.com/", 774 "http://somehost.domain/", 775 "http://someotherhost.domain/", 776 "http://somehost.domain2.org/", 777 "http://somehost.subdomain.domain2.org/", 778 ]; 779 check_host_filters(uriStrFilterList, true, host_filters_1); 780 } 781 782 function host_filters_1() { 783 // Check the hosts that should be proxied 784 uriStrUseProxyList = [ 785 "http://www.mozilla.com/", 786 "http://mail.google.com/", 787 "http://somehost.domain.co.uk/", 788 "http://somelocalhost/", 789 ]; 790 check_host_filters(uriStrUseProxyList, false, host_filters_2); 791 } 792 793 function host_filters_2() { 794 // Set no_proxies_on to include local hosts 795 prefs.setCharPref( 796 "network.proxy.no_proxies_on", 797 hostFilterList + ", <local>" 798 ); 799 Assert.equal( 800 prefs.getCharPref("network.proxy.no_proxies_on"), 801 hostFilterList + ", <local>" 802 ); 803 // Amend lists - move local domain to filtered list 804 uriStrFilterList.push(uriStrUseProxyList.pop()); 805 check_host_filters(uriStrFilterList, true, host_filters_3); 806 } 807 808 function host_filters_3() { 809 check_host_filters(uriStrUseProxyList, false, host_filters_4); 810 } 811 812 function host_filters_4() { 813 // Cleanup 814 prefs.setCharPref("network.proxy.no_proxies_on", ""); 815 Assert.equal(prefs.getCharPref("network.proxy.no_proxies_on"), ""); 816 817 run_myipaddress_test(); 818 } 819 820 function run_myipaddress_test() { 821 // This test makes sure myIpAddress() comes up with some valid 822 // IP address other than localhost. The DUT must be configured with 823 // an Internet route for this to work - though no Internet traffic 824 // should be created. 825 826 var pac = 827 "data:text/plain," + 828 "var pacUseMultihomedDNS = true;\n" + 829 "function FindProxyForURL(url, host) {" + 830 ' return "PROXY " + myIpAddress() + ":1234";' + 831 "}"; 832 833 // no traffic to this IP is ever sent, it is just a public IP that 834 // does not require DNS to determine a route. 835 var channel = NetUtil.newChannel({ 836 uri: "http://192.0.43.10/", 837 loadUsingSystemPrincipal: true, 838 }); 839 prefs.setIntPref("network.proxy.type", 2); 840 prefs.setCharPref("network.proxy.autoconfig_url", pac); 841 842 var cb = new resolveCallback(); 843 cb.nextFunction = myipaddress_callback; 844 pps.asyncResolve(channel, 0, cb); 845 } 846 847 function myipaddress_callback(pi) { 848 Assert.notEqual(pi, null); 849 Assert.equal(pi.type, "http"); 850 Assert.equal(pi.port, 1234); 851 852 // make sure we didn't return localhost 853 Assert.notEqual(pi.host, null); 854 Assert.notEqual(pi.host, "127.0.0.1"); 855 Assert.notEqual(pi.host, "::1"); 856 857 run_myipaddress_test_2(); 858 } 859 860 function run_myipaddress_test_2() { 861 // test that myIPAddress() can be used outside of the scope of 862 // FindProxyForURL(). bug 829646. 863 864 var pac = 865 "data:text/plain," + 866 "var pacUseMultihomedDNS = true;\n" + 867 "var myaddr = myIpAddress(); " + 868 "function FindProxyForURL(url, host) {" + 869 ' return "PROXY " + myaddr + ":5678";' + 870 "}"; 871 872 var channel = NetUtil.newChannel({ 873 uri: "http://www.mozilla.org/", 874 loadUsingSystemPrincipal: true, 875 }); 876 prefs.setIntPref("network.proxy.type", 2); 877 prefs.setCharPref("network.proxy.autoconfig_url", pac); 878 879 var cb = new resolveCallback(); 880 cb.nextFunction = myipaddress2_callback; 881 pps.asyncResolve(channel, 0, cb); 882 } 883 884 function myipaddress2_callback(pi) { 885 Assert.notEqual(pi, null); 886 Assert.equal(pi.type, "http"); 887 Assert.equal(pi.port, 5678); 888 889 // make sure we didn't return localhost 890 Assert.notEqual(pi.host, null); 891 Assert.notEqual(pi.host, "127.0.0.1"); 892 Assert.notEqual(pi.host, "::1"); 893 894 run_failed_script_test(); 895 } 896 897 function run_failed_script_test() { 898 // test to make sure we go direct with invalid PAC 899 // eslint-disable-next-line no-useless-concat 900 var pac = "data:text/plain," + "\nfor(;\n"; 901 902 var channel = NetUtil.newChannel({ 903 uri: "http://www.mozilla.org/", 904 loadUsingSystemPrincipal: true, 905 }); 906 prefs.setIntPref("network.proxy.type", 2); 907 prefs.setCharPref("network.proxy.autoconfig_url", pac); 908 909 var cb = new resolveCallback(); 910 cb.nextFunction = failed_script_callback; 911 pps.asyncResolve(channel, 0, cb); 912 } 913 914 var directFilter; 915 const TEST_URI = "http://doesnt-exist.example:7247/"; 916 917 function failed_script_callback(pi) { 918 // we should go direct 919 Assert.equal(pi, null); 920 921 // test that we honor filters when configured to go direct 922 prefs.setIntPref("network.proxy.type", 0); 923 directFilter = new TestFilter("http", "127.0.0.1", 7246, 0, 0); 924 pps.registerFilter(directFilter, 10); 925 926 // test that on-modify-request contains the proxy info too 927 var obs = Cc["@mozilla.org/observer-service;1"].getService(); 928 obs = obs.QueryInterface(Ci.nsIObserverService); 929 obs.addObserver(directFilterListener, "http-on-modify-request"); 930 931 var ssm = Services.scriptSecurityManager; 932 let uri = TEST_URI; 933 var chan = NetUtil.newChannel({ 934 uri, 935 loadingPrincipal: ssm.createContentPrincipal(Services.io.newURI(uri), {}), 936 securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT, 937 contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT, 938 }); 939 940 chan.asyncOpen(directFilterListener); 941 } 942 943 var directFilterListener = { 944 onModifyRequestCalled: false, 945 946 onStartRequest: function test_onStart() {}, 947 onDataAvailable: function test_OnData() {}, 948 949 onStopRequest: function test_onStop(request) { 950 // check on the PI from the channel itself 951 request.QueryInterface(Ci.nsIProxiedChannel); 952 check_proxy(request.proxyInfo, "http", "127.0.0.1", 7246, 0, 0, false); 953 pps.unregisterFilter(directFilter); 954 955 // check on the PI from on-modify-request 956 Assert.ok(this.onModifyRequestCalled); 957 var obs = Cc["@mozilla.org/observer-service;1"].getService(); 958 obs = obs.QueryInterface(Ci.nsIObserverService); 959 obs.removeObserver(this, "http-on-modify-request"); 960 961 run_isresolvable_test(); 962 }, 963 964 observe(subject, topic) { 965 if ( 966 topic === "http-on-modify-request" && 967 subject instanceof Ci.nsIHttpChannel && 968 subject instanceof Ci.nsIProxiedChannel 969 ) { 970 info("check proxy in observe uri=" + subject.URI.spec); 971 if (subject.URI.spec != TEST_URI) { 972 return; 973 } 974 check_proxy(subject.proxyInfo, "http", "127.0.0.1", 7246, 0, 0, false); 975 this.onModifyRequestCalled = true; 976 } 977 }, 978 }; 979 980 function run_isresolvable_test() { 981 // test a non resolvable host in the pac file 982 983 var pac = 984 "data:text/plain," + 985 "function FindProxyForURL(url, host) {" + 986 ' if (isResolvable("nonexistant.lan.onion"))' + 987 ' return "DIRECT";' + 988 ' return "PROXY 127.0.0.1:1234";' + 989 "}"; 990 991 var channel = NetUtil.newChannel({ 992 uri: "http://www.mozilla.org/", 993 loadUsingSystemPrincipal: true, 994 }); 995 prefs.setIntPref("network.proxy.type", 2); 996 prefs.setCharPref("network.proxy.autoconfig_url", pac); 997 998 var cb = new resolveCallback(); 999 cb.nextFunction = isresolvable_callback; 1000 pps.asyncResolve(channel, 0, cb); 1001 } 1002 1003 function isresolvable_callback(pi) { 1004 Assert.notEqual(pi, null); 1005 Assert.equal(pi.type, "http"); 1006 Assert.equal(pi.port, 1234); 1007 Assert.equal(pi.host, "127.0.0.1"); 1008 1009 run_localhost_pac(); 1010 } 1011 1012 function run_localhost_pac() { 1013 // test localhost in the pac file 1014 1015 var pac = 1016 "data:text/plain," + 1017 "function FindProxyForURL(url, host) {" + 1018 ' return "PROXY totallycrazy:1234";' + 1019 "}"; 1020 1021 // Use default filter list string for "no_proxies_on" ("localhost, 127.0.0.1") 1022 prefs.clearUserPref("network.proxy.no_proxies_on"); 1023 var channel = NetUtil.newChannel({ 1024 uri: "http://localhost/", 1025 loadUsingSystemPrincipal: true, 1026 }); 1027 prefs.setIntPref("network.proxy.type", 2); 1028 prefs.setCharPref("network.proxy.autoconfig_url", pac); 1029 1030 var cb = new resolveCallback(); 1031 cb.nextFunction = localhost_callback; 1032 pps.asyncResolve(channel, 0, cb); 1033 } 1034 1035 function localhost_callback(pi) { 1036 Assert.equal(pi, null); // no proxy! 1037 1038 prefs.setIntPref("network.proxy.type", 0); 1039 1040 if (mozinfo.socketprocess_networking && again) { 1041 info("run test again"); 1042 again = false; 1043 cleanUp(); 1044 prefs.setBoolPref("network.proxy.parse_pac_on_socket_process", true); 1045 run_filter_test(); 1046 } else { 1047 cleanUp(); 1048 do_test_finished(); 1049 } 1050 } 1051 1052 function cleanUp() { 1053 prefs.clearUserPref("network.proxy.type"); 1054 prefs.clearUserPref("network.proxy.http"); 1055 prefs.clearUserPref("network.proxy.http_port"); 1056 prefs.clearUserPref("network.proxy.socks"); 1057 prefs.clearUserPref("network.proxy.socks_port"); 1058 prefs.clearUserPref("network.proxy.autoconfig_url"); 1059 prefs.clearUserPref("network.proxy.proxy_over_tls"); 1060 prefs.clearUserPref("network.proxy.no_proxies_on"); 1061 prefs.clearUserPref("network.proxy.parse_pac_on_socket_process"); 1062 } 1063 1064 function run_test() { 1065 register_test_protocol_handler(); 1066 1067 prefs.setBoolPref("network.proxy.parse_pac_on_socket_process", false); 1068 // start of asynchronous test chain 1069 run_filter_test(); 1070 do_test_pending(); 1071 }