summaryrefslogtreecommitdiffstats
path: root/toolkit/content/aboutNetworking.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/aboutNetworking.js')
-rw-r--r--toolkit/content/aboutNetworking.js414
1 files changed, 414 insertions, 0 deletions
diff --git a/toolkit/content/aboutNetworking.js b/toolkit/content/aboutNetworking.js
new file mode 100644
index 000000000..9400ae9d7
--- /dev/null
+++ b/toolkit/content/aboutNetworking.js
@@ -0,0 +1,414 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+const FileUtils = Cu.import("resource://gre/modules/FileUtils.jsm").FileUtils
+const gEnv = Cc["@mozilla.org/process/environment;1"]
+ .getService(Ci.nsIEnvironment);
+const gDashboard = Cc['@mozilla.org/network/dashboard;1']
+ .getService(Ci.nsIDashboard);
+const gDirServ = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIDirectoryServiceProvider);
+
+const gRequestNetworkingData = {
+ "http": gDashboard.requestHttpConnections,
+ "sockets": gDashboard.requestSockets,
+ "dns": gDashboard.requestDNSInfo,
+ "websockets": gDashboard.requestWebsocketConnections
+};
+const gDashboardCallbacks = {
+ "http": displayHttp,
+ "sockets": displaySockets,
+ "dns": displayDns,
+ "websockets": displayWebsockets
+};
+
+const REFRESH_INTERVAL_MS = 3000;
+
+function col(element) {
+ let col = document.createElement('td');
+ let content = document.createTextNode(element);
+ col.appendChild(content);
+ return col;
+}
+
+function displayHttp(data) {
+ let cont = document.getElementById('http_content');
+ let parent = cont.parentNode;
+ let new_cont = document.createElement('tbody');
+ new_cont.setAttribute('id', 'http_content');
+
+ for (let i = 0; i < data.connections.length; i++) {
+ let row = document.createElement('tr');
+ row.appendChild(col(data.connections[i].host));
+ row.appendChild(col(data.connections[i].port));
+ row.appendChild(col(data.connections[i].spdy));
+ row.appendChild(col(data.connections[i].ssl));
+ row.appendChild(col(data.connections[i].active.length));
+ row.appendChild(col(data.connections[i].idle.length));
+ new_cont.appendChild(row);
+ }
+
+ parent.replaceChild(new_cont, cont);
+}
+
+function displaySockets(data) {
+ let cont = document.getElementById('sockets_content');
+ let parent = cont.parentNode;
+ let new_cont = document.createElement('tbody');
+ new_cont.setAttribute('id', 'sockets_content');
+
+ for (let i = 0; i < data.sockets.length; i++) {
+ let row = document.createElement('tr');
+ row.appendChild(col(data.sockets[i].host));
+ row.appendChild(col(data.sockets[i].port));
+ row.appendChild(col(data.sockets[i].tcp));
+ row.appendChild(col(data.sockets[i].active));
+ row.appendChild(col(data.sockets[i].sent));
+ row.appendChild(col(data.sockets[i].received));
+ new_cont.appendChild(row);
+ }
+
+ parent.replaceChild(new_cont, cont);
+}
+
+function displayDns(data) {
+ let cont = document.getElementById('dns_content');
+ let parent = cont.parentNode;
+ let new_cont = document.createElement('tbody');
+ new_cont.setAttribute('id', 'dns_content');
+
+ for (let i = 0; i < data.entries.length; i++) {
+ let row = document.createElement('tr');
+ row.appendChild(col(data.entries[i].hostname));
+ row.appendChild(col(data.entries[i].family));
+ let column = document.createElement('td');
+
+ for (let j = 0; j < data.entries[i].hostaddr.length; j++) {
+ column.appendChild(document.createTextNode(data.entries[i].hostaddr[j]));
+ column.appendChild(document.createElement('br'));
+ }
+
+ row.appendChild(column);
+ row.appendChild(col(data.entries[i].expiration));
+ new_cont.appendChild(row);
+ }
+
+ parent.replaceChild(new_cont, cont);
+}
+
+function displayWebsockets(data) {
+ let cont = document.getElementById('websockets_content');
+ let parent = cont.parentNode;
+ let new_cont = document.createElement('tbody');
+ new_cont.setAttribute('id', 'websockets_content');
+
+ for (let i = 0; i < data.websockets.length; i++) {
+ let row = document.createElement('tr');
+ row.appendChild(col(data.websockets[i].hostport));
+ row.appendChild(col(data.websockets[i].encrypted));
+ row.appendChild(col(data.websockets[i].msgsent));
+ row.appendChild(col(data.websockets[i].msgreceived));
+ row.appendChild(col(data.websockets[i].sentsize));
+ row.appendChild(col(data.websockets[i].receivedsize));
+ new_cont.appendChild(row);
+ }
+
+ parent.replaceChild(new_cont, cont);
+}
+
+function requestAllNetworkingData() {
+ for (let id in gRequestNetworkingData)
+ requestNetworkingDataForTab(id);
+}
+
+function requestNetworkingDataForTab(id) {
+ gRequestNetworkingData[id](gDashboardCallbacks[id]);
+}
+
+function init() {
+ gDashboard.enableLogging = true;
+ if (Services.prefs.getBoolPref("network.warnOnAboutNetworking")) {
+ let div = document.getElementById("warning_message");
+ div.classList.add("active");
+ div.hidden = false;
+ document.getElementById("confpref").addEventListener("click", confirm);
+ }
+
+ requestAllNetworkingData();
+
+ let autoRefresh = document.getElementById("autorefcheck");
+ if (autoRefresh.checked)
+ setAutoRefreshInterval(autoRefresh);
+
+ autoRefresh.addEventListener("click", function() {
+ let refrButton = document.getElementById("refreshButton");
+ if (this.checked) {
+ setAutoRefreshInterval(this);
+ refrButton.disabled = "disabled";
+ } else {
+ clearInterval(this.interval);
+ refrButton.disabled = null;
+ }
+ });
+
+ let refr = document.getElementById("refreshButton");
+ refr.addEventListener("click", requestAllNetworkingData);
+ if (document.getElementById("autorefcheck").checked)
+ refr.disabled = "disabled";
+
+ // Event delegation on #categories element
+ let menu = document.getElementById("categories");
+ menu.addEventListener("click", function click(e) {
+ if (e.target && e.target.parentNode == menu)
+ show(e.target);
+ });
+
+ let dnsLookupButton = document.getElementById("dnsLookupButton");
+ dnsLookupButton.addEventListener("click", function() {
+ doLookup();
+ });
+
+ let setLogButton = document.getElementById("set-log-file-button");
+ setLogButton.addEventListener("click", setLogFile);
+
+ let setModulesButton = document.getElementById("set-log-modules-button");
+ setModulesButton.addEventListener("click", setLogModules);
+
+ let startLoggingButton = document.getElementById("start-logging-button");
+ startLoggingButton.addEventListener("click", startLogging);
+
+ let stopLoggingButton = document.getElementById("stop-logging-button");
+ stopLoggingButton.addEventListener("click", stopLogging);
+
+ try {
+ let file = gDirServ.getFile("TmpD", {});
+ file.append("log.txt");
+ document.getElementById("log-file").value = file.path;
+ } catch (e) {
+ console.error(e);
+ }
+
+ // Update the value of the log file.
+ updateLogFile();
+
+ // Update the active log modules
+ updateLogModules();
+
+ // If we can't set the file and the modules at runtime,
+ // the start and stop buttons wouldn't really do anything.
+ if (setLogButton.disabled && setModulesButton.disabled) {
+ startLoggingButton.disabled = true;
+ stopLoggingButton.disabled = true;
+ }
+}
+
+function updateLogFile() {
+ let logPath = "";
+
+ // Try to get the environment variable for the log file
+ logPath = gEnv.get("MOZ_LOG_FILE") || gEnv.get("NSPR_LOG_FILE");
+ let currentLogFile = document.getElementById("current-log-file");
+ let setLogFileButton = document.getElementById("set-log-file-button");
+
+ // If the log file was set from an env var, we disable the ability to set it
+ // at runtime.
+ if (logPath.length > 0) {
+ currentLogFile.innerText = logPath;
+ setLogFileButton.disabled = true;
+ } else {
+ // There may be a value set by a pref.
+ currentLogFile.innerText = gDashboard.getLogPath();
+ }
+}
+
+function updateLogModules() {
+ // Try to get the environment variable for the log file
+ let logModules = gEnv.get("MOZ_LOG") ||
+ gEnv.get("MOZ_LOG_MODULES") ||
+ gEnv.get("NSPR_LOG_MODULES");
+ let currentLogModules = document.getElementById("current-log-modules");
+ let setLogModulesButton = document.getElementById("set-log-modules-button");
+ if (logModules.length > 0) {
+ currentLogModules.innerText = logModules;
+ // If the log modules are set by an environment variable at startup, do not
+ // allow changing them throught a pref. It would be difficult to figure out
+ // which ones are enabled and which ones are not. The user probably knows
+ // what he they are doing.
+ setLogModulesButton.disabled = true;
+ } else {
+ let activeLogModules = [];
+ try {
+ if (Services.prefs.getBoolPref("logging.config.add_timestamp")) {
+ activeLogModules.push("timestamp");
+ }
+ } catch (e) {}
+ try {
+ if (Services.prefs.getBoolPref("logging.config.sync")) {
+ activeLogModules.push("sync");
+ }
+ } catch (e) {}
+
+ let children = Services.prefs.getBranch("logging.").getChildList("", {});
+
+ for (let pref of children) {
+ if (pref.startsWith("config.")) {
+ continue;
+ }
+
+ try {
+ let value = Services.prefs.getIntPref(`logging.${pref}`);
+ activeLogModules.push(`${pref}:${value}`);
+ } catch (e) {
+ console.error(e);
+ }
+ }
+
+ currentLogModules.innerText = activeLogModules.join(",");
+ }
+}
+
+function setLogFile() {
+ let setLogButton = document.getElementById("set-log-file-button");
+ if (setLogButton.disabled) {
+ // There's no point trying since it wouldn't work anyway.
+ return;
+ }
+ let logFile = document.getElementById("log-file").value.trim();
+ Services.prefs.setCharPref("logging.config.LOG_FILE", logFile);
+ updateLogFile();
+}
+
+function clearLogModules() {
+ // Turn off all the modules.
+ let children = Services.prefs.getBranch("logging.").getChildList("", {});
+ for (let pref of children) {
+ if (!pref.startsWith("config.")) {
+ Services.prefs.clearUserPref(`logging.${pref}`);
+ }
+ }
+ Services.prefs.clearUserPref("logging.config.add_timestamp");
+ Services.prefs.clearUserPref("logging.config.sync");
+ updateLogModules();
+}
+
+function setLogModules() {
+ let setLogModulesButton = document.getElementById("set-log-modules-button");
+ if (setLogModulesButton.disabled) {
+ // The modules were set via env var, so we shouldn't try to change them.
+ return;
+ }
+
+ let modules = document.getElementById("log-modules").value.trim();
+
+ // Clear previously set log modules.
+ clearLogModules();
+
+ let logModules = modules.split(",");
+ for (let module of logModules) {
+ if (module == "timestamp") {
+ Services.prefs.setBoolPref("logging.config.add_timestamp", true);
+ } else if (module == "rotate") {
+ // XXX: rotate is not yet supported.
+ } else if (module == "append") {
+ // XXX: append is not yet supported.
+ } else if (module == "sync") {
+ Services.prefs.setBoolPref("logging.config.sync", true);
+ } else {
+ let [key, value] = module.split(":");
+ Services.prefs.setIntPref(`logging.${key}`, parseInt(value, 10));
+ }
+ }
+
+ updateLogModules();
+}
+
+function startLogging() {
+ setLogFile();
+ setLogModules();
+}
+
+function stopLogging() {
+ clearLogModules();
+ // clear the log file as well
+ Services.prefs.clearUserPref("logging.config.LOG_FILE");
+ updateLogFile();
+}
+
+function confirm () {
+ let div = document.getElementById("warning_message");
+ div.classList.remove("active");
+ div.hidden = true;
+ let warnBox = document.getElementById("warncheck");
+ Services.prefs.setBoolPref("network.warnOnAboutNetworking", warnBox.checked);
+}
+
+function show(button) {
+ let current_tab = document.querySelector(".active");
+ let content = document.getElementById(button.getAttribute("value"));
+ if (current_tab == content)
+ return;
+ current_tab.classList.remove("active");
+ current_tab.hidden = true;
+ content.classList.add("active");
+ content.hidden = false;
+
+ let current_button = document.querySelector("[selected=true]");
+ current_button.removeAttribute("selected");
+ button.setAttribute("selected", "true");
+
+ let autoRefresh = document.getElementById("autorefcheck");
+ if (autoRefresh.checked) {
+ clearInterval(autoRefresh.interval);
+ setAutoRefreshInterval(autoRefresh);
+ }
+
+ let title = document.getElementById("sectionTitle");
+ title.textContent = button.children[0].textContent;
+}
+
+function setAutoRefreshInterval(checkBox) {
+ let active_tab = document.querySelector(".active");
+ checkBox.interval = setInterval(function() {
+ requestNetworkingDataForTab(active_tab.id);
+ }, REFRESH_INTERVAL_MS);
+}
+
+window.addEventListener("DOMContentLoaded", function load() {
+ window.removeEventListener("DOMContentLoaded", load);
+ init();
+});
+
+function doLookup() {
+ let host = document.getElementById("host").value;
+ if (host) {
+ gDashboard.requestDNSLookup(host, displayDNSLookup);
+ }
+}
+
+function displayDNSLookup(data) {
+ let cont = document.getElementById("dnslookuptool_content");
+ let parent = cont.parentNode;
+ let new_cont = document.createElement("tbody");
+ new_cont.setAttribute("id", "dnslookuptool_content");
+
+ if (data.answer) {
+ for (let address of data.address) {
+ let row = document.createElement("tr");
+ row.appendChild(col(address));
+ new_cont.appendChild(row);
+ }
+ }
+ else {
+ new_cont.appendChild(col(data.error));
+ }
+
+ parent.replaceChild(new_cont, cont);
+}