Commit 45184e90 authored by Arthur Edelstein's avatar Arthur Edelstein Committed by Georg Koppen
Browse files

Bug 21547: Fix circuit display under e10s

parent 7c712a4e
Loading
Loading
Loading
Loading
+48 −22
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ let createTorCircuitDisplay = (function () {
"use strict";

// Mozilla utilities
const Cu = Components.utils;
const { Cu : utils , Ci : interfaces } = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");

@@ -34,7 +34,7 @@ Cu.import("resource://gre/modules/Task.jsm");
let { controller } = Cu.import("resource://torbutton/modules/tor-control-port.js", {});

// Utility functions
let { bindPrefAndInit } = Cu.import("resource://torbutton/modules/utils.js", {});
let { bindPrefAndInit, observe } = Cu.import("resource://torbutton/modules/utils.js", {});

// Make the TorButton logger available.
let logger = Cc["@torproject.org/torbutton-logger;1"]
@@ -47,7 +47,10 @@ let logger = Cc["@torproject.org/torbutton-logger;1"]
let credentialsToNodeDataMap = {},
    // A mutable map that reports `true` for IDs of "mature" circuits
    // (those that have conveyed a stream).
    knownCircuitIDs = {};
    knownCircuitIDs = {},
    // A mutable map that records the SOCKS credentials for the
    // latest channels for each browser.
    browserToCredentialsMap = new Map();

// __trimQuotes(s)__.
// Removes quotation marks around a quoted string.
@@ -154,6 +157,42 @@ let collectIsolationData = function (aController, updateUI) {
    }).then(null, Cu.reportError));
};

// __browserForChannel(channel)__.
// Returns the browser that loaded a given channel.
let browserForChannel = function (channel) {
  if (!channel) return null;
  let chan = channel.QueryInterface(Ci.nsIChannel);
  let callbacks = chan.notificationCallbacks;
  if (!callbacks) return null;
  let loadContext;
  try {
    loadContext = callbacks.getInterface(Ci.nsILoadContext);
  } catch (e) {
    // Ignore
    return null;
  }
  if (!loadContext) return null;
  return loadContext.topFrameElement;
};

// __collectBrowserCredentials()__.
// Starts observing http channels. Each channel's proxyInfo
// username and password is recorded for the channel's browser.
let collectBrowserCredentials = function () {
  return observe("http-on-modify-request", chan => {
    try {
      let proxyInfo = chan.QueryInterface(Ci.nsIProxiedChannel).proxyInfo;
      let browser = browserForChannel(chan);
      if (browser && proxyInfo) {
          browserToCredentialsMap.set(browser, [proxyInfo.username,
                                                proxyInfo.password]);
      }
    } catch (e) {
      logger.eclog(3, `Error collecting browser credentials: ${e.message}, ${chan.URI.spec}`);
    }
  });
};

// ## User interface

// __torbuttonBundle__.
@@ -221,24 +260,6 @@ let nodeLines = function (nodeData) {
  return result;
};

// __getSOCKSCredentials(browser)__.
// Reads the SOCKS credentials for the corresponding browser object.
let getSOCKSCredentialsForBrowser = function (browser) {
  if (browser === null) return null;
  let docShell = browser.docShell;
  if (docShell === null) return null;
  let channel = docShell.currentDocumentChannel;
  if (channel === null) return null;
  if (channel instanceof Ci.nsIMultiPartChannel) {
    channel = channel.baseChannel;
  }
  if (channel === null) return null;
  if (!(channel instanceof Ci.nsIProxiedChannel)) return null;
  let proxyInfo = channel.proxyInfo;
  if (proxyInfo === null) return null;
  return [proxyInfo.username, proxyInfo.password];
};

// __onionSiteRelayLine__.
// When we have an onion site, we simply show the word '(relay)'.
let onionSiteRelayLine = "<li class='relay'>(" + uiString("relay") + ")</li>";
@@ -249,7 +270,7 @@ let onionSiteRelayLine = "<li class='relay'>(" + uiString("relay") + ")</li>";
let updateCircuitDisplay = function () {
  let selectedBrowser = gBrowser.selectedBrowser;
  if (selectedBrowser) {
    let credentials = getSOCKSCredentialsForBrowser(selectedBrowser),
    let credentials = browserToCredentialsMap.get(selectedBrowser),
        nodeData = null;
    if (credentials) {
      let [SOCKS_username, SOCKS_password] = credentials;
@@ -319,12 +340,16 @@ let syncDisplayWithSelectedTab = (function() {
let setupDisplay = function (ipcFile, host, port, password, enablePrefName) {
  let myController = null,
      stopCollectingIsolationData = null,
      stopCollectingBrowserCredentials = null,
      stop = function() {
        syncDisplayWithSelectedTab(false);
        if (myController) {
          if (stopCollectingIsolationData) {
	    stopCollectingIsolationData();
          }
          if (stopCollectingBrowserCredentials) {
            stopCollectingBrowserCredentials();
          }
          myController = null;
        }
      },
@@ -340,6 +365,7 @@ let setupDisplay = function (ipcFile, host, port, password, enablePrefName) {
          });
          syncDisplayWithSelectedTab(true);
          stopCollectingIsolationData = collectIsolationData(myController, updateCircuitDisplay);
          stopCollectingBrowserCredentials = collectBrowserCredentials();
       }
     };
  try {