tor-browser

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

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 }