gecko-dev/toolkit/content/aboutNetworking.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

594 строки
18 KiB
JavaScript
Исходник Обычный вид История

/* 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";
Bug 1514594: Part 3 - Change ChromeUtils.import API. *** Bug 1514594: Part 3a - Change ChromeUtils.import to return an exports object; not pollute global. r=mccr8 This changes the behavior of ChromeUtils.import() to return an exports object, rather than a module global, in all cases except when `null` is passed as a second argument, and changes the default behavior not to pollute the global scope with the module's exports. Thus, the following code written for the old model: ChromeUtils.import("resource://gre/modules/Services.jsm"); is approximately the same as the following, in the new model: var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); Since the two behaviors are mutually incompatible, this patch will land with a scripted rewrite to update all existing callers to use the new model rather than the old. *** Bug 1514594: Part 3b - Mass rewrite all JS code to use the new ChromeUtils.import API. rs=Gijs This was done using the followng script: https://bitbucket.org/kmaglione/m-c-rewrites/src/tip/processors/cu-import-exports.jsm *** Bug 1514594: Part 3c - Update ESLint plugin for ChromeUtils.import API changes. r=Standard8 Differential Revision: https://phabricator.services.mozilla.com/D16747 *** Bug 1514594: Part 3d - Remove/fix hundreds of duplicate imports from sync tests. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16748 *** Bug 1514594: Part 3e - Remove no-op ChromeUtils.import() calls. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16749 *** Bug 1514594: Part 3f.1 - Cleanup various test corner cases after mass rewrite. r=Gijs *** Bug 1514594: Part 3f.2 - Cleanup various non-test corner cases after mass rewrite. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16750 --HG-- extra : rebase_source : 359574ee3064c90f33bf36c2ebe3159a24cc8895 extra : histedit_source : b93c8f42808b1599f9122d7842d2c0b3e656a594%2C64a3a4e3359dc889e2ab2b49461bab9e27fc10a7
2019-01-17 21:18:31 +03:00
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const FileUtils = ChromeUtils.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
);
2020-01-07 15:35:17 +03:00
const gNetLinkSvc =
Cc["@mozilla.org/network/network-link-service;1"] &&
Cc["@mozilla.org/network/network-link-service;1"].getService(
Ci.nsINetworkLinkService
);
const gDNSService = Cc["@mozilla.org/network/dns-service;1"].getService(
Ci.nsIDNSService
);
const gRequestNetworkingData = {
http: gDashboard.requestHttpConnections,
sockets: gDashboard.requestSockets,
dns: gDashboard.requestDNSInfo,
websockets: gDashboard.requestWebsocketConnections,
dnslookuptool: () => {},
logging: () => {},
rcwn: gDashboard.requestRcwnStats,
networkid: displayNetworkID,
};
const gDashboardCallbacks = {
http: displayHttp,
sockets: displaySockets,
dns: displayDns,
websockets: displayWebsockets,
rcwn: displayRcwnStats,
};
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].httpVersion));
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 suffixContent = document.getElementById("dns_suffix_content");
let suffixParent = suffixContent.parentNode;
let suffixes = [];
try {
suffixes = gNetLinkSvc.dnsSuffixList; // May throw
} catch (e) {}
let suffix_tbody = document.createElement("tbody");
suffix_tbody.id = "dns_suffix_content";
for (let suffix of suffixes) {
let row = document.createElement("tr");
row.appendChild(col(suffix));
suffix_tbody.appendChild(row);
}
suffixParent.replaceChild(suffix_tbody, suffixContent);
let trr_url_tbody = document.createElement("tbody");
trr_url_tbody.id = "dns_trr_url";
let trr_url = document.createElement("tr");
trr_url.appendChild(col(gDNSService.currentTrrURI));
trr_url_tbody.appendChild(trr_url);
let prevURL = document.getElementById("dns_trr_url");
prevURL.parentNode.replaceChild(trr_url_tbody, prevURL);
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));
row.appendChild(col(data.entries[i].trr));
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));
row.appendChild(col(data.entries[i].originAttributesSuffix));
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 displayRcwnStats(data) {
let status = Services.prefs.getBoolPref("network.http.rcwn.enabled");
let linkType = Ci.nsINetworkLinkService.LINK_TYPE_UNKNOWN;
try {
linkType = gNetLinkSvc.linkType;
} catch (e) {}
if (
!(
linkType == Ci.nsINetworkLinkService.LINK_TYPE_UNKNOWN ||
linkType == Ci.nsINetworkLinkService.LINK_TYPE_ETHERNET ||
linkType == Ci.nsINetworkLinkService.LINK_TYPE_USB ||
linkType == Ci.nsINetworkLinkService.LINK_TYPE_WIFI
)
) {
status = false;
}
let cacheWon = data.rcwnCacheWonCount;
let netWon = data.rcwnNetWonCount;
let total = data.totalNetworkRequests;
let cacheSlow = data.cacheSlowCount;
let cacheNotSlow = data.cacheNotSlowCount;
document.getElementById("rcwn_status").innerText = status;
document.getElementById("total_req_count").innerText = total;
document.getElementById("rcwn_cache_won_count").innerText = cacheWon;
document.getElementById("rcwn_cache_net_count").innerText = netWon;
document.getElementById("rcwn_cache_slow").innerText = cacheSlow;
document.getElementById("rcwn_cache_not_slow").innerText = cacheNotSlow;
// Keep in sync with CachePerfStats::EDataType in CacheFileUtils.h
const perfStatTypes = ["open", "read", "write", "entryopen"];
const perfStatFieldNames = ["avgShort", "avgLong", "stddevLong"];
for (let typeIndex in perfStatTypes) {
for (let statFieldIndex in perfStatFieldNames) {
document.getElementById(
"rcwn_perfstats_" +
perfStatTypes[typeIndex] +
"_" +
perfStatFieldNames[statFieldIndex]
).innerText =
data.perfStats[typeIndex][perfStatFieldNames[statFieldIndex]];
}
}
}
function displayNetworkID() {
try {
let linkIsUp = gNetLinkSvc.isLinkUp;
let linkStatusKnown = gNetLinkSvc.linkStatusKnown;
let networkID = gNetLinkSvc.networkID;
document.getElementById("networkid_isUp").innerText = linkIsUp;
2020-01-07 15:35:17 +03:00
document.getElementById(
"networkid_statusKnown"
).innerText = linkStatusKnown;
document.getElementById("networkid_id").innerText = networkID;
} catch (e) {
document.getElementById("networkid_isUp").innerText = "<unknown>";
document.getElementById("networkid_statusKnown").innerText = "<unknown>";
document.getElementById("networkid_id").innerText = "<unknown>";
}
}
function requestAllNetworkingData() {
for (let id in gRequestNetworkingData) {
requestNetworkingDataForTab(id);
}
}
function requestNetworkingDataForTab(id) {
gRequestNetworkingData[id](gDashboardCallbacks[id]);
}
let gInited = false;
function init() {
if (gInited) {
return;
}
gInited = true;
gDashboard.enableLogging = true;
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 clearDNSCache = document.getElementById("clearDNSCache");
clearDNSCache.addEventListener("click", function() {
gDNSService.clearCache(true);
});
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;
}
if (location.hash) {
let sectionButton = document.getElementById(
"category-" + location.hash.substring(1)
);
if (sectionButton) {
sectionButton.click();
}
}
}
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) {
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) {
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 lastColon = module.lastIndexOf(":");
let key = module.slice(0, lastColon);
let value = parseInt(module.slice(lastColon + 1), 10);
Services.prefs.setIntPref(`logging.${key}`, value);
}
}
updateLogModules();
}
function startLogging() {
setLogFile();
setLogModules();
}
function stopLogging() {
clearLogModules();
// clear the log file as well
Services.prefs.clearUserPref("logging.config.LOG_FILE");
updateLogFile();
}
function show(button) {
let current_tab = document.querySelector(".active");
let category = button.getAttribute("id").substring("category-".length);
let content = document.getElementById(category);
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;
location.hash = category;
}
function setAutoRefreshInterval(checkBox) {
let active_tab = document.querySelector(".active");
checkBox.interval = setInterval(function() {
requestNetworkingDataForTab(active_tab.id);
}, REFRESH_INTERVAL_MS);
}
// We use the pageshow event instead of onload. This is needed because sometimes
// the page is loaded via session-restore/bfcache. In such cases we need to call
// init() to keep the page behaviour consistent with the ticked checkboxes.
// Mostly the issue is with the autorefresh checkbox.
window.addEventListener("pageshow", function() {
init();
});
function doLookup() {
let host = document.getElementById("host").value;
if (host) {
try {
gDashboard.requestDNSLookup(host, displayDNSLookup);
} catch (e) {}
try {
gDashboard.requestDNSHTTPSRRLookup(host, displayHTTPSRRLookup);
} catch (e) {}
}
}
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);
}
function displayHTTPSRRLookup(data) {
let cont = document.getElementById("https_rr_content");
let parent = cont.parentNode;
let new_cont = document.createElement("tbody");
new_cont.setAttribute("id", "https_rr_content");
if (data.answer) {
for (let record of data.records) {
let row = document.createElement("tr");
let alpn = record.alpn ? `alpn="${record.alpn.alpn}" ` : "";
let noDefaultAlpn = record.noDefaultAlpn ? "noDefaultAlpn " : "";
let port = record.port ? `port="${record.port.port}" ` : "";
let echConfig = record.echConfig
? `echConfig="${record.echConfig.echConfig}" `
: "";
let ODoHConfig = record.ODoHConfig
? `ODoHConfig="${record.ODoHConfig.ODoHConfig}" `
: "";
let ipv4hint = "";
let ipv6hint = "";
if (record.ipv4Hint) {
let ipv4Str = "";
for (let addr of record.ipv4Hint.address) {
ipv4Str += `${addr}, `;
}
// Remove ", " at the end.
ipv4Str = ipv4Str.slice(0, -2);
ipv4hint = `ipv4hint="${ipv4Str}" `;
}
if (record.ipv6Hint) {
let ipv6Str = "";
for (let addr of record.ipv6Hint.address) {
ipv6Str += `${addr}, `;
}
// Remove ", " at the end.
ipv6Str = ipv6Str.slice(0, -2);
ipv6hint = `ipv6hint="${ipv6Str}" `;
}
let str = `${record.priority} ${record.targetName} `;
str += `(${alpn}${noDefaultAlpn}${port}`;
str += `${ipv4hint}${echConfig}${ipv6hint}`;
str += `${ODoHConfig})`;
row.appendChild(col(str));
new_cont.appendChild(row);
}
} else {
new_cont.appendChild(col(data.error));
}
parent.replaceChild(new_cont, cont);
}