tor-browser

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

test_alt-data_cross_process.js (4092B)


      1 /**
      2 * Test for the "alternative data stream" stored withing a cache entry.
      3 *
      4 * - we load a URL with preference for an alt data (check what we get is the raw data,
      5 *   since there was nothing previously cached)
      6 * - we store the alt data along the channel (to the cache entry)
      7 * - we flush the HTTP cache
      8 * - we reload the same URL using a new channel, again prefering the alt data be loaded
      9 * - this time the alt data must arive
     10 */
     11 
     12 "use strict";
     13 
     14 const { HttpServer } = ChromeUtils.importESModule(
     15  "resource://testing-common/httpd.sys.mjs"
     16 );
     17 
     18 ChromeUtils.defineLazyGetter(this, "URL", function () {
     19  return "http://localhost:" + httpServer.identity.primaryPort + "/content";
     20 });
     21 
     22 var httpServer = null;
     23 
     24 function make_channel(url) {
     25  return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
     26 }
     27 
     28 function inChildProcess() {
     29  return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
     30 }
     31 
     32 const responseContent = "response body";
     33 const responseContent2 = "response body 2";
     34 const altContent = "!@#$%^&*()";
     35 const altContentType = "text/binary";
     36 
     37 var servedNotModified = false;
     38 var shouldPassRevalidation = true;
     39 
     40 var cache_storage = null;
     41 
     42 function contentHandler(metadata, response) {
     43  response.setHeader("Content-Type", "text/plain");
     44  response.setHeader("Cache-Control", "no-cache");
     45  response.setHeader("ETag", "test-etag1");
     46 
     47  let etag;
     48  try {
     49    etag = metadata.getHeader("If-None-Match");
     50  } catch (ex) {
     51    etag = "";
     52  }
     53 
     54  if (etag == "test-etag1" && shouldPassRevalidation) {
     55    response.setStatusLine(metadata.httpVersion, 304, "Not Modified");
     56    servedNotModified = true;
     57  } else {
     58    var content = shouldPassRevalidation ? responseContent : responseContent2;
     59    response.bodyOutputStream.write(content, content.length);
     60  }
     61 }
     62 
     63 function check_has_alt_data_in_index(aHasAltData, callback) {
     64  if (inChildProcess()) {
     65    callback();
     66    return;
     67  }
     68 
     69  syncWithCacheIOThread(() => {
     70    var hasAltData = {};
     71    cache_storage.getCacheIndexEntryAttrs(createURI(URL), "", hasAltData, {});
     72    Assert.equal(hasAltData.value, aHasAltData);
     73    callback();
     74  }, true);
     75 }
     76 
     77 // This file is loaded as part of test_alt-data_cross_process_wrap.js.
     78 // eslint-disable-next-line no-unused-vars
     79 function run_test() {
     80  httpServer = new HttpServer();
     81  httpServer.registerPathHandler("/content", contentHandler);
     82  httpServer.start(-1);
     83  do_test_pending();
     84 
     85  asyncOpen();
     86 }
     87 
     88 function asyncOpen() {
     89  var chan = make_channel(URL);
     90 
     91  var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
     92  cc.preferAlternativeDataType(
     93    altContentType,
     94    "",
     95    Ci.nsICacheInfoChannel.ASYNC
     96  );
     97 
     98  chan.asyncOpen(new ChannelListener(readServerContent, null));
     99 }
    100 
    101 function readServerContent(request, buffer) {
    102  var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
    103 
    104  Assert.equal(buffer, responseContent);
    105  Assert.equal(cc.alternativeDataType, "");
    106  check_has_alt_data_in_index(false, () => {
    107    executeSoon(() => {
    108      var os = cc.openAlternativeOutputStream(
    109        altContentType,
    110        altContent.length
    111      );
    112      os.write(altContent, altContent.length);
    113      os.close();
    114 
    115      executeSoon(flushAndOpenAltChannel);
    116    });
    117  });
    118 }
    119 
    120 function flushAndOpenAltChannel() {
    121  // We need to do a GC pass to ensure the cache entry has been freed.
    122  gc();
    123  do_send_remote_message("flush");
    124  do_await_remote_message("flushed").then(() => {
    125    openAltChannel();
    126  });
    127 }
    128 
    129 function openAltChannel() {
    130  var chan = make_channel(URL);
    131  var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
    132  cc.preferAlternativeDataType(
    133    altContentType,
    134    "",
    135    Ci.nsICacheInfoChannel.ASYNC
    136  );
    137 
    138  chan.asyncOpen(new ChannelListener(readAltContent, null));
    139 }
    140 
    141 function readAltContent(request, buffer) {
    142  var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
    143 
    144  Assert.equal(servedNotModified, true);
    145  Assert.equal(cc.alternativeDataType, altContentType);
    146  Assert.equal(buffer, altContent);
    147 
    148  // FINISH
    149  do_send_remote_message("done");
    150  do_await_remote_message("finish").then(() => {
    151    httpServer.stop(do_test_finished);
    152  });
    153 }