tor-browser

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

test_private_channel.js (4979B)


      1 const { NetUtil } = ChromeUtils.importESModule(
      2  "resource://gre/modules/NetUtil.sys.mjs"
      3 );
      4 const { HttpServer } = ChromeUtils.importESModule(
      5  "resource://testing-common/httpd.sys.mjs"
      6 );
      7 
      8 const ReferrerInfo = Components.Constructor(
      9  "@mozilla.org/referrer-info;1",
     10  "nsIReferrerInfo",
     11  "init"
     12 );
     13 
     14 var server = new HttpServer();
     15 server.registerPathHandler("/image.png", imageHandler);
     16 server.start(-1);
     17 
     18 /* import-globals-from image_load_helpers.js */
     19 load("image_load_helpers.js");
     20 
     21 var gHits = 0;
     22 
     23 var gIoService = Services.io;
     24 var gPublicLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
     25  Ci.imgILoader
     26 );
     27 var gPrivateLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
     28  Ci.imgILoader
     29 );
     30 gPrivateLoader.QueryInterface(Ci.imgICache).respectPrivacyNotifications();
     31 
     32 var nonPrivateLoadContext = Cu.createLoadContext();
     33 var privateLoadContext = Cu.createPrivateLoadContext();
     34 
     35 function imageHandler(metadata, response) {
     36  gHits++;
     37  response.setHeader("Cache-Control", "max-age=10000", false);
     38  response.setStatusLine(metadata.httpVersion, 200, "OK");
     39  response.setHeader("Content-Type", "image/png", false);
     40  var body = atob(
     41    "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
     42  );
     43  response.bodyOutputStream.write(body, body.length);
     44 }
     45 
     46 var requests = [];
     47 var listeners = [];
     48 
     49 var gImgPath = "http://localhost:" + server.identity.primaryPort + "/image.png";
     50 
     51 function setup_chan(path, isPrivate, callback) {
     52  var uri = NetUtil.newURI(gImgPath);
     53  var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL;
     54  var principal = Services.scriptSecurityManager.createContentPrincipal(uri, {
     55    privateBrowsingId: isPrivate ? 1 : 0,
     56  });
     57  var chan = NetUtil.newChannel({
     58    uri,
     59    loadingPrincipal: principal,
     60    securityFlags,
     61    contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE,
     62  });
     63  chan.notificationCallbacks = isPrivate
     64    ? privateLoadContext
     65    : nonPrivateLoadContext;
     66  var channelListener = new ChannelListener();
     67  chan.asyncOpen(channelListener);
     68 
     69  var listener = new ImageListener(null, callback);
     70  var outlistener = {};
     71  var loader = isPrivate ? gPrivateLoader : gPublicLoader;
     72  var outer = Cc["@mozilla.org/image/tools;1"]
     73    .getService(Ci.imgITools)
     74    .createScriptedObserver(listener);
     75  listeners.push(outer);
     76  requests.push(
     77    loader.loadImageWithChannelXPCOM(chan, outer, null, outlistener)
     78  );
     79  channelListener.outputListener = outlistener.value;
     80  listener.synchronous = false;
     81 }
     82 
     83 function loadImage(isPrivate, callback) {
     84  var listener = new ImageListener(null, callback);
     85  var outer = Cc["@mozilla.org/image/tools;1"]
     86    .getService(Ci.imgITools)
     87    .createScriptedObserver(listener);
     88  var uri = gIoService.newURI(gImgPath);
     89  var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(
     90    Ci.nsILoadGroup
     91  );
     92  loadGroup.notificationCallbacks = isPrivate
     93    ? privateLoadContext
     94    : nonPrivateLoadContext;
     95  var loader = isPrivate ? gPrivateLoader : gPublicLoader;
     96  var referrerInfo = new ReferrerInfo(
     97    Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
     98    true,
     99    null
    100  );
    101  requests.push(
    102    loader.loadImageXPCOM(
    103      uri,
    104      null,
    105      referrerInfo,
    106      null,
    107      loadGroup,
    108      outer,
    109      null,
    110      0,
    111      null
    112    )
    113  );
    114  listener.synchronous = false;
    115 }
    116 
    117 function run_loadImage_tests() {
    118  function observer() {
    119    Services.obs.removeObserver(observer, "cacheservice:empty-cache");
    120    gHits = 0;
    121    loadImage(false, function () {
    122      loadImage(false, function () {
    123        loadImage(true, function () {
    124          loadImage(true, function () {
    125            Assert.equal(gHits, 2);
    126            server.stop(do_test_finished);
    127          });
    128        });
    129      });
    130    });
    131  }
    132 
    133  for (let loader of [gPublicLoader, gPrivateLoader]) {
    134    loader.QueryInterface(Ci.imgICache).clearCache(); // no parameter=all
    135  }
    136  Services.obs.addObserver(observer, "cacheservice:empty-cache");
    137  let cs = Services.cache2;
    138  cs.clear();
    139 }
    140 
    141 function cleanup() {
    142  for (var i = 0; i < requests.length; ++i) {
    143    requests[i].cancelAndForgetObserver(0);
    144  }
    145 }
    146 
    147 function run_test() {
    148  registerCleanupFunction(cleanup);
    149 
    150  do_test_pending();
    151 
    152  Services.prefs.setBoolPref("network.http.rcwn.enabled", false);
    153 
    154  // We create a public channel that loads an image, then an identical
    155  // one that should cause a cache read. We then create a private channel
    156  // and load the same image, and do that a second time to ensure a cache
    157  // read. In total, we should cause two separate http responses to occur,
    158  // since the private channels shouldn't be able to use the public cache.
    159  setup_chan("/image.png", false, function () {
    160    setup_chan("/image.png", false, function () {
    161      setup_chan("/image.png", true, function () {
    162        setup_chan("/image.png", true, function () {
    163          Assert.equal(gHits, 2);
    164          run_loadImage_tests();
    165        });
    166      });
    167    });
    168  });
    169 }