tor-browser

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

test_event_sink.js (4645B)


      1 // This file tests channel event sinks (bug 315598 et al)
      2 
      3 "use strict";
      4 
      5 const { HttpServer } = ChromeUtils.importESModule(
      6  "resource://testing-common/httpd.sys.mjs"
      7 );
      8 
      9 ChromeUtils.defineLazyGetter(this, "URL", function () {
     10  return "http://localhost:" + httpserv.identity.primaryPort;
     11 });
     12 
     13 const sinkCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
     14 const sinkContract = "@mozilla.org/network/unittest/channeleventsink;1";
     15 
     16 const categoryName = "net-channel-event-sinks";
     17 
     18 /**
     19 * This object is both a factory and an nsIChannelEventSink implementation (so, it
     20 * is de-facto a service). It's also an interface requestor that gives out
     21 * itself when asked for nsIChannelEventSink.
     22 */
     23 var eventsink = {
     24  QueryInterface: ChromeUtils.generateQI(["nsIFactory", "nsIChannelEventSink"]),
     25  createInstance: function eventsink_ci(iid) {
     26    return this.QueryInterface(iid);
     27  },
     28 
     29  asyncOnChannelRedirect: function eventsink_onredir() {
     30    // veto
     31    this.called = true;
     32    throw Components.Exception("", Cr.NS_BINDING_ABORTED);
     33  },
     34 
     35  getInterface: function eventsink_gi(iid) {
     36    if (iid.equals(Ci.nsIChannelEventSink)) {
     37      return this;
     38    }
     39    throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
     40  },
     41 
     42  called: false,
     43 };
     44 
     45 var listener = {
     46  expectSinkCall: true,
     47 
     48  onStartRequest: function test_onStartR(request) {
     49    try {
     50      // Commenting out this check pending resolution of bug 255119
     51      //if (Components.isSuccessCode(request.status))
     52      //  do_throw("Channel should have a failure code!");
     53 
     54      // The current URI must be the original URI, as all redirects have been
     55      // cancelled
     56      if (
     57        !(request instanceof Ci.nsIChannel) ||
     58        !request.URI.equals(request.originalURI)
     59      ) {
     60        do_throw(
     61          "Wrong URI: Is <" +
     62            request.URI.spec +
     63            ">, should be <" +
     64            request.originalURI.spec +
     65            ">"
     66        );
     67      }
     68 
     69      if (request instanceof Ci.nsIHttpChannel) {
     70        // As we expect a blocked redirect, verify that we have a 3xx status
     71        Assert.equal(Math.floor(request.responseStatus / 100), 3);
     72        Assert.equal(request.requestSucceeded, false);
     73      }
     74 
     75      Assert.equal(eventsink.called, this.expectSinkCall);
     76    } catch (e) {
     77      do_throw("Unexpected exception: " + e);
     78    }
     79 
     80    throw Components.Exception("", Cr.NS_ERROR_ABORT);
     81  },
     82 
     83  onDataAvailable: function test_ODA() {
     84    do_throw("Should not get any data!");
     85  },
     86 
     87  onStopRequest: function test_onStopR() {
     88    if (this._iteration <= 2) {
     89      run_test_continued();
     90    } else {
     91      do_test_pending();
     92      httpserv.stop(do_test_finished);
     93    }
     94    do_test_finished();
     95  },
     96 
     97  _iteration: 1,
     98 };
     99 
    100 function makeChan(url) {
    101  return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
    102 }
    103 
    104 var httpserv = null;
    105 
    106 function run_test() {
    107  httpserv = new HttpServer();
    108  httpserv.registerPathHandler("/redirect", redirect);
    109  httpserv.registerPathHandler("/redirectfile", redirectfile);
    110  httpserv.start(-1);
    111 
    112  Components.manager.nsIComponentRegistrar.registerFactory(
    113    sinkCID,
    114    "Unit test Event sink",
    115    sinkContract,
    116    eventsink
    117  );
    118 
    119  // Step 1: Set the callbacks on the listener itself
    120  var chan = makeChan(URL + "/redirect");
    121  chan.notificationCallbacks = eventsink;
    122 
    123  chan.asyncOpen(listener);
    124 
    125  do_test_pending();
    126 }
    127 
    128 function run_test_continued() {
    129  eventsink.called = false;
    130 
    131  var chan;
    132  if (listener._iteration == 1) {
    133    // Step 2: Category entry
    134    Services.catMan.addCategoryEntry(
    135      categoryName,
    136      "unit test",
    137      sinkContract,
    138      false,
    139      true
    140    );
    141    chan = makeChan(URL + "/redirect");
    142  } else {
    143    // Step 3: Global contract id
    144    Services.catMan.deleteCategoryEntry(categoryName, "unit test", false);
    145    listener.expectSinkCall = false;
    146    chan = makeChan(URL + "/redirectfile");
    147  }
    148 
    149  listener._iteration++;
    150  chan.asyncOpen(listener);
    151 
    152  do_test_pending();
    153 }
    154 
    155 // PATHS
    156 
    157 // /redirect
    158 function redirect(metadata, response) {
    159  response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
    160  response.setHeader(
    161    "Location",
    162    "http://localhost:" + metadata.port + "/",
    163    false
    164  );
    165 
    166  var body = "Moved\n";
    167  response.bodyOutputStream.write(body, body.length);
    168 }
    169 
    170 // /redirectfile
    171 function redirectfile(metadata, response) {
    172  response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
    173  response.setHeader("Content-Type", "text/plain", false);
    174  response.setHeader("Location", "file:///etc/", false);
    175 
    176  var body = "Attempted to move to a file URI, but failed.\n";
    177  response.bodyOutputStream.write(body, body.length);
    178 }