tor-browser

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

channel-event-sink.js (2858B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const { ComponentUtils } = ChromeUtils.importESModule(
      8  "resource://gre/modules/ComponentUtils.sys.mjs",
      9  { global: "contextual" }
     10 );
     11 
     12 /**
     13 * THIS is a nsIChannelEventSink implementation that monitors channel redirects and
     14 * informs the registered "collectors" about the old and new channels.
     15 */
     16 const SINK_CLASS_DESCRIPTION = "NetworkMonitor Channel Event Sink";
     17 const SINK_CLASS_ID = Components.ID("{e89fa076-c845-48a8-8c45-2604729eba1d}");
     18 const SINK_CONTRACT_ID = "@mozilla.org/network/monitor/channeleventsink;1";
     19 const SINK_CATEGORY_NAME = "net-channel-event-sinks";
     20 
     21 class ChannelEventSink {
     22  constructor() {
     23    this.wrappedJSObject = this;
     24    this.collectors = new Set();
     25  }
     26 
     27  QueryInterface = ChromeUtils.generateQI(["nsIChannelEventSink"]);
     28 
     29  registerCollector(collector) {
     30    this.collectors.add(collector);
     31  }
     32 
     33  unregisterCollector(collector) {
     34    this.collectors.delete(collector);
     35 
     36    if (this.collectors.size == 0) {
     37      ChannelEventSinkFactory.unregister();
     38    }
     39  }
     40 
     41  // eslint-disable-next-line no-shadow
     42  asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
     43    for (const collector of this.collectors) {
     44      try {
     45        collector.onChannelRedirect(oldChannel, newChannel, flags);
     46      } catch (ex) {
     47        console.error(
     48          "ChannelEventSink collector's 'onChannelRedirect' threw an exception",
     49          ex
     50        );
     51      }
     52    }
     53    callback.onRedirectVerifyCallback(Cr.NS_OK);
     54  }
     55 }
     56 
     57 const ChannelEventSinkFactory =
     58  ComponentUtils.generateSingletonFactory(ChannelEventSink);
     59 
     60 ChannelEventSinkFactory.register = function () {
     61  const registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
     62  if (registrar.isCIDRegistered(SINK_CLASS_ID)) {
     63    return;
     64  }
     65 
     66  registrar.registerFactory(
     67    SINK_CLASS_ID,
     68    SINK_CLASS_DESCRIPTION,
     69    SINK_CONTRACT_ID,
     70    ChannelEventSinkFactory
     71  );
     72 
     73  Services.catMan.addCategoryEntry(
     74    SINK_CATEGORY_NAME,
     75    SINK_CONTRACT_ID,
     76    SINK_CONTRACT_ID,
     77    false,
     78    true
     79  );
     80 };
     81 
     82 ChannelEventSinkFactory.unregister = function () {
     83  const registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
     84  registrar.unregisterFactory(SINK_CLASS_ID, ChannelEventSinkFactory);
     85 
     86  Services.catMan.deleteCategoryEntry(
     87    SINK_CATEGORY_NAME,
     88    SINK_CONTRACT_ID,
     89    false
     90  );
     91 };
     92 
     93 ChannelEventSinkFactory.getService = function () {
     94  // Make sure the ChannelEventSink service is registered before accessing it
     95  ChannelEventSinkFactory.register();
     96 
     97  return Cc[SINK_CONTRACT_ID].getService(Ci.nsIChannelEventSink)
     98    .wrappedJSObject;
     99 };
    100 exports.ChannelEventSinkFactory = ChannelEventSinkFactory;