Bug 1348253 - about:url-classifier: Providers information and update button. r=francois

The about:url-classifier supports following functions:
1. Provider section
  - Show update status for each provider, update status include
    last update time, next update time and last update status
  - Update button to manually trigger an update for the provider.

2. Debug section
  - Set MOZ_LOG Modules
  - Set MOZ_LOG_FILE

MozReview-Commit-ID: AHiveKEHSNC

--HG--
extra : rebase_source : b56e918de7f4eb30ad8eebc6d24ffaf2e76f4f4e
This commit is contained in:
Dimi Lee 2017-04-19 00:33:08 +08:00
Родитель e4927e7310
Коммит 647b77b7fc
11 изменённых файлов: 576 добавлений и 0 удалений

Просмотреть файл

@ -135,6 +135,10 @@ static const RedirEntry kRedirMap[] = {
"telemetry", "chrome://global/content/aboutTelemetry.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"url-classifier", "chrome://global/content/aboutUrlClassifier.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.html",
nsIAboutModule::ALLOW_SCRIPT

Просмотреть файл

@ -198,6 +198,7 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "webrtc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "printpreview", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "url-classifier", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_URI_LOADER_CONTRACTID, &kNS_URI_LOADER_CID },
{ NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &kNS_DOCUMENTLOADER_SERVICE_CID },
{ NS_HANDLERSERVICE_CONTRACTID, &kNS_CONTENTHANDLERSERVICE_CID, mozilla::Module::CONTENT_PROCESS_ONLY },

Просмотреть файл

@ -132,6 +132,13 @@ PROT_ListManager.prototype.getGethashUrl = function(tableName) {
return "";
}
PROT_ListManager.prototype.getUpdateUrl = function(tableName) {
if (this.tablesData[tableName] && this.tablesData[tableName].updateUrl) {
return this.tablesData[tableName].updateUrl;
}
return "";
}
/**
* Enable updates for some tables
* @param tables - an array of table names that need updating
@ -483,6 +490,12 @@ PROT_ListManager.prototype.makeUpdateRequestForEntry_ = function(updateUrl,
BindToObject(this.downloadError_, this, tableList, updateUrl))) {
// Our alarm gets reset in one of the 3 callbacks.
log("pending update, queued request until later");
} else {
let table = Object.keys(this.tablesData).find(key => {
return this.tablesData[key].updateUrl === updateUrl;
});
let provider = this.tablesData[table].provider;
Services.obs.notifyObservers(null, "safebrowsing-update-begin", provider);
}
}
@ -550,6 +563,8 @@ PROT_ListManager.prototype.updateSuccess_ = function(tableList, updateUrl,
log("Setting next update of " + provider + " to " + targetTime
+ " (" + delay + "ms from now)");
this.prefs_.setPref(nextUpdatePref, targetTime.toString());
Services.obs.notifyObservers(null, "safebrowsing-update-finished", "success");
}
/**
@ -563,6 +578,9 @@ PROT_ListManager.prototype.updateError_ = function(table, updateUrl, result) {
this.updateCheckers_[updateUrl] =
new G_Alarm(BindToObject(this.checkForUpdates, this, updateUrl),
this.updateInterval, false);
Services.obs.notifyObservers(null, "safebrowsing-update-finished",
"update error(" + result + ")");
}
/**
@ -589,6 +607,8 @@ PROT_ListManager.prototype.downloadError_ = function(table, updateUrl, status) {
new G_Alarm(BindToObject(this.checkForUpdates, this, updateUrl),
delay, false);
Services.obs.notifyObservers(null, "safebrowsing-update-finished",
"download error(" + status + ")");
}
PROT_ListManager.prototype.QueryInterface = function(iid) {

Просмотреть файл

@ -26,6 +26,11 @@ interface nsIUrlListManager : nsISupports
*/
ACString getGethashUrl(in ACString tableName);
/**
* Get the update url for this table
*/
ACString getUpdateUrl(in ACString tableName);
/**
* Add a table to the list of tables we are managing. The name is a
* string of the format provider_name-semantic_type-table_type. For
@ -64,4 +69,10 @@ interface nsIUrlListManager : nsISupports
*/
void safeLookup(in nsIPrincipal key,
in nsIUrlListManagerCallback cb);
/**
* This is currently used by about:url-classifier to force an update
* for the update url. Update may still fail because of backoff algorithm.
*/
boolean checkForUpdates(in ACString updateUrl);
};

Просмотреть файл

@ -0,0 +1,72 @@
/* 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/. */
html {
--aboutUrlClassifier-table-background: #ebebeb;
background-color: var(--in-content-page-background);
}
body {
margin: 40px 48px;
}
.major-section {
margin-top: 2em;
margin-bottom: 1em;
font-size: large;
text-align: start;
font-weight: bold;
}
table {
background-color: var(--aboutUrlClassifier-table-background);
color: var(--in-content-text-color);
font: message-box;
text-align: start;
width: 100%;
border: 1px solid var(--in-content-border-color);
border-spacing: 0px;
}
th, td {
border: 1px solid var(--in-content-border-color);
padding: 4px;
}
thead th {
text-align: center;
}
th {
text-align: start;
background-color: var(--in-content-table-header-background);
color: var(--in-content-selected-text);
}
th.column {
white-space: nowrap;
width: 0px;
}
td {
text-align: start;
border-color: var(--in-content-table-border-dark-color);
}
#provider-table > tbody > tr > td:last-child {
text-align: center;
}
#debug-table {
margin-top: 20px;
}
.options > .toggle-container-with-text {
display: inline-flex;
}
button {
margin-inline-start: 0;
margin-inline-end: 8px;
}

Просмотреть файл

@ -0,0 +1,335 @@
/* 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/. */
var Ci = Components.interfaces;
var Cc = Components.classes;
var Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
const bundle = Services.strings.createBundle(
"chrome://global/locale/aboutUrlClassifier.properties");
const UPDATE_BEGIN = "safebrowsing-update-begin";
const UPDATE_FINISH = "safebrowsing-update-finished";
const JSLOG_PREF = "browser.safebrowsing.debug";
const STR_NA = bundle.GetStringFromName("NotAvailable");
function unLoad() {
window.removeEventListener("unload", unLoad);
Provider.uninit();
Debug.uninit();
}
function onLoad() {
window.removeEventListener("load", onLoad);
window.addEventListener("unload", unLoad);
Provider.init();
Debug.init();
}
/*
* Provider
*/
var Provider = {
providers: null,
updatingProvider: "",
init() {
this.providers = new Set();
let branch = Services.prefs.getBranch("browser.safebrowsing.provider.");
let children = branch.getChildList("", {});
for (let child of children) {
this.providers.add(child.split(".")[0]);
}
this.register();
this.render();
this.refresh();
},
uninit() {
Services.obs.removeObserver(this.onBeginUpdate, UPDATE_BEGIN);
Services.obs.removeObserver(this.onFinishUpdate, UPDATE_FINISH);
},
onBeginUpdate(aSubject, aTopic, aData) {
this.updatingProvider = aData;
let p = this.updatingProvider;
// Disable update button for the provider while we are doing update.
document.getElementById("update-" + p).disabled = true;
let elem = document.getElementById(p + "-col-lastupdateresult");
elem.childNodes[0].nodeValue = bundle.GetStringFromName("Updating");
},
onFinishUpdate(aSubject, aTopic, aData) {
let p = this.updatingProvider;
this.updatingProvider = "";
// It is possible that we get update-finished event only because
// about::url-classifier is opened after update-begin event is fired.
if (p === "") {
this.refresh();
return;
}
this.refresh([p]);
document.getElementById("update-" + p).disabled = false;
let elem = document.getElementById(p + "-col-lastupdateresult");
elem.childNodes[0].nodeValue = aData;
},
register() {
// Handle begin update
this.onBeginUpdate = this.onBeginUpdate.bind(this);
Services.obs.addObserver(this.onBeginUpdate, UPDATE_BEGIN);
// Handle finish update
this.onFinishUpdate = this.onFinishUpdate.bind(this);
Services.obs.addObserver(this.onFinishUpdate, UPDATE_FINISH);
},
// This should only be called once because we assume number of providers
// won't change.
render() {
let tbody = document.getElementById("provider-table-body");
for (let provider of this.providers) {
let tr = document.createElement("tr");
let cols = document.getElementById("provider-head-row").childNodes;
for (let column of cols) {
if (!column.id) {
continue;
}
let td = document.createElement("td");
td.id = provider + "-" + column.id;
if (column.id === "col-update") {
let btn = document.createElement("button");
btn.id = "update-" + provider;
btn.addEventListener("click", () => { this.update(provider); });
let str = bundle.GetStringFromName("TriggerUpdate")
btn.appendChild(document.createTextNode(str));
td.appendChild(btn);
} else {
let str = column.id === "col-lastupdateresult" ? STR_NA : "";
td.appendChild(document.createTextNode(str));
}
tr.appendChild(td);
}
tbody.appendChild(tr);
}
},
refresh(listProviders = this.providers) {
for (let provider of listProviders) {
let values = {};
values["col-provider"] = provider;
let pref = "browser.safebrowsing.provider." + provider + ".lastupdatetime";
let lut = Services.prefs.getCharPref(pref, "");
values["col-lastupdatetime"] = lut ? new Date(lut * 1) : STR_NA;
pref = "browser.safebrowsing.provider." + provider + ".nextupdatetime";
let nut = Services.prefs.getCharPref(pref, "");
values["col-nextupdatetime"] = nut ? new Date(nut * 1) : STR_NA;
for (let key of Object.keys(values)) {
let elem = document.getElementById(provider + "-" + key);
elem.childNodes[0].nodeValue = values[key];
}
}
},
// Call update for the provider.
update(provider) {
let listmanager = Cc["@mozilla.org/url-classifier/listmanager;1"]
.getService(Ci.nsIUrlListManager);
let pref = "browser.safebrowsing.provider." + provider + ".lists";
let table = Services.prefs.getCharPref(pref, "").split(",")[0];
let updateUrl = listmanager.getUpdateUrl(table);
if (!listmanager.checkForUpdates(updateUrl)) {
// This may because of back-off algorithm.
let elem = document.getElementById(provider + "-col-lastupdateresult");
elem.childNodes[0].nodeValue = bundle.GetStringFromName("CannotUpdate");
}
},
};
/*
* Debug
*/
var Debug = {
// url-classifier NSPR Log modules.
modules: ["UrlClassifierDbService",
"nsChannelClassifier",
"UrlClassifierProtocolParser",
"UrlClassifierStreamUpdater",
"UrlClassifierPrefixSet",
"ApplicationReputation"],
init() {
this.register();
this.render();
this.refresh();
},
uninit() {
Services.prefs.removeObserver(JSLOG_PREF, this.refreshJSDebug);
},
register() {
this.refreshJSDebug = this.refreshJSDebug.bind(this);
Services.prefs.addObserver(JSLOG_PREF, this.refreshJSDebug);
},
render() {
// This function update the log module text field if we click
// safebrowsing log module check box.
function logModuleUpdate(module) {
let txt = document.getElementById("log-modules");
let chk = document.getElementById("chk-" + module);
let dst = chk.checked ? "," + module + ":5" : "";
let re = new RegExp(",?" + module + ":[0-9]");
let str = txt.value.replace(re, dst);
if (chk.checked) {
str = txt.value === str ? str + dst : str;
}
txt.value = str.replace(/^,/, "");
}
let setLog = document.getElementById("set-log-modules");
setLog.addEventListener("click", this.nsprlog);
let setLogFile = document.getElementById("set-log-file");
setLogFile.addEventListener("click", this.logfile);
let setJSLog = document.getElementById("js-log");
setJSLog.addEventListener("click", this.jslog);
let modules = document.getElementById("log-modules");
let sbModules = document.getElementById("sb-log-modules");
for (let module of this.modules) {
let container = document.createElement("div");
container.className = "toggle-container-with-text";
sbModules.appendChild(container);
let chk = document.createElement("input");
chk.id = "chk-" + module;
chk.type = "checkbox";
chk.checked = true;
chk.addEventListener("click", () => { logModuleUpdate(module) });
container.appendChild(chk, modules);
let label = document.createElement("label");
label.for = chk.id;
label.appendChild(document.createTextNode(module));
container.appendChild(label, modules);
}
this.modules.map(logModuleUpdate);
let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
file.append("safebrowsing.log");
let logFile = document.getElementById("log-file");
logFile.value = file.path;
let curLog = document.getElementById("cur-log-modules");
curLog.childNodes[0].nodeValue = "";
let curLogFile = document.getElementById("cur-log-file");
curLogFile.childNodes[0].nodeValue = "";
},
refresh() {
this.refreshJSDebug();
// Disable configure log modules if log modules are already set
// by environment variable.
let env = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
let logModules = env.get("MOZ_LOG") ||
env.get("MOZ_LOG_MODULES") ||
env.get("NSPR_LOG_MODULES");
if (logModules.length > 0) {
document.getElementById("set-log-modules").disabled = true;
for (let module of this.modules) {
document.getElementById("chk-" + module).disabled = true;
}
let curLogModules = document.getElementById("cur-log-modules");
curLogModules.childNodes[0].nodeValue = logModules;
}
// Disable set log file if log file is already set
// by environment variable.
let logFile = env.get("MOZ_LOG_FILE") || env.get("NSPR_LOG_FILE");
if (logFile.length > 0) {
document.getElementById("set-log-file").disabled = true;
document.getElementById("log-file").value = logFile;
}
},
refreshJSDebug() {
let enabled = Services.prefs.getBoolPref(JSLOG_PREF, false);
let jsChk = document.getElementById("js-log");
jsChk.checked = enabled;
let curJSLog = document.getElementById("cur-js-log");
curJSLog.childNodes[0].nodeValue = enabled ?
bundle.GetStringFromName("Enabled") :
bundle.GetStringFromName("Disabled");
},
jslog() {
let enabled = Services.prefs.getBoolPref(JSLOG_PREF, false);
Services.prefs.setBoolPref(JSLOG_PREF, !enabled);
},
nsprlog() {
// Turn off debugging for all the modules.
let children = Services.prefs.getBranch("logging.").getChildList("", {});
for (let pref of children) {
if (!pref.startsWith("config.")) {
Services.prefs.clearUserPref(`logging.${pref}`);
}
}
let value = document.getElementById("log-modules").value;
let logModules = value.split(",");
for (let module of logModules) {
let [key, value] = module.split(":");
Services.prefs.setIntPref(`logging.${key}`, parseInt(value, 10));
}
let curLogModules = document.getElementById("cur-log-modules");
curLogModules.childNodes[0].nodeValue = value;
},
logfile() {
let logFile = document.getElementById("log-file").value.trim();
Services.prefs.setCharPref("logging.config.LOG_FILE", logFile);
let curLogFile = document.getElementById("cur-log-file");
curLogFile.childNodes[0].nodeValue = logFile;
}
};

Просмотреть файл

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> %htmlDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> %globalDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> %brandDTD;
<!ENTITY % urlClassifierDTD SYSTEM "chrome://global/locale/aboutUrlClassifier.dtd"> %urlClassifierDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css" type="text/css"/>
<link rel="stylesheet" href="chrome://global/content/aboutUrlClassifier.css" type="text/css"/>
<script type="text/javascript" src="chrome://global/content/aboutUrlClassifier.js"></script>
</head>
<body onload="onLoad()" class="aboutPageWideContainer">
<h1>&aboutUrlClassifier.pageTitle;</h1>
<div id="provider">
<h2 class="major-section">&aboutUrlClassifier.providerTitle;</h2>
<table id="provider-table">
<thead>
<tr id="provider-head-row">
<th id="col-provider">&aboutUrlClassifier.provider;</th>
<th id="col-lastupdatetime">&aboutUrlClassifier.providerLastUpdateTime;</th>
<th id="col-nextupdatetime">&aboutUrlClassifier.providerNextUpdateTime;</th>
<th id="col-lastupdateresult">&aboutUrlClassifier.providerLastUpdateStatus;</th>
<th id="col-update">&aboutUrlClassifier.providerUpdateBtn;</th>
</tr>
</thead>
<tbody id="provider-table-body">
<!-- data is generated in javascript -->
</tbody>
</table>
</div>
<div id="debug">
<h2 class="major-section">&aboutUrlClassifier.debugTitle;</h2>
<div id="debug-modules" class="options">
<input id="log-modules" type="text" value=""/>
<button id="set-log-modules">&aboutUrlClassifier.debugModuleBtn;</button>
<br></br>
<input id="log-file" type="text" value=""/>
<button id="set-log-file">&aboutUrlClassifier.debugFileBtn;</button>
<br></br>
<div class="toggle-container-with-text">
<input id="js-log" type="checkbox"/>
<label for="js-log">&aboutUrlClassifier.debugJSLogChk;</label>
</div>
</div>
<table id="debug-table">
<tbody>
<tr>
<th class="column">&aboutUrlClassifier.debugSBModules;</th>
<td id="sb-log-modules">
</td>
</tr>
<tr>
<th class="column">&aboutUrlClassifier.debugModules;</th>
<td id="cur-log-modules">
</td>
</tr>
<tr>
<th class="column">&aboutUrlClassifier.debugSBJSModules;</th>
<td id="cur-js-log">
</td>
</tr>
<tr>
<th class="column">&aboutUrlClassifier.debugFile;</th>
<td id="cur-log-file">
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

Просмотреть файл

@ -33,6 +33,9 @@ toolkit.jar:
content/global/aboutTelemetry.js
content/global/aboutTelemetry.xhtml
content/global/aboutTelemetry.css
content/global/aboutUrlClassifier.js
content/global/aboutUrlClassifier.xhtml
content/global/aboutUrlClassifier.css
content/global/directionDetector.html
content/global/plugins.html
content/global/plugins.css

Просмотреть файл

@ -0,0 +1,29 @@
<!-- 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/. -->
<!-- LOCALIZATION NOTE the term "url-classifier" should not be translated. -->
<!ENTITY aboutUrlClassifier.pageTitle "Information about the url-classifier">
<!ENTITY aboutUrlClassifier.providerTitle "Provider">
<!ENTITY aboutUrlClassifier.provider "Provider">
<!ENTITY aboutUrlClassifier.providerLastUpdateTime "Last update time">
<!ENTITY aboutUrlClassifier.providerNextUpdateTime "Next update time">
<!ENTITY aboutUrlClassifier.providerLastUpdateStatus "Last update status">
<!ENTITY aboutUrlClassifier.providerUpdateBtn "Update">
<!ENTITY aboutUrlClassifier.lookupTitle "Lookup">
<!ENTITY aboutUrlClassifier.lookupUrl "Url">
<!ENTITY aboutUrlClassifier.lookupMatch "Match">
<!ENTITY aboutUrlClassifier.lookupMatchBtn "Check Match Result">
<!ENTITY aboutUrlClassifier.lookupLookup "Lookup">
<!ENTITY aboutUrlClassifier.lookupBtn "Check Lookup Result">
<!ENTITY aboutUrlClassifier.cacheTitle "Cache">
<!ENTITY aboutUrlClassifier.memoryTitle "Memory">
<!ENTITY aboutUrlClassifier.databaseTitle "Database">
<!ENTITY aboutUrlClassifier.debugTitle "Debug">
<!ENTITY aboutUrlClassifier.debugModuleBtn "Set Log Modules">
<!ENTITY aboutUrlClassifier.debugFileBtn "Set Log File">
<!ENTITY aboutUrlClassifier.debugJSLogChk "Set JS Log">
<!ENTITY aboutUrlClassifier.debugSBModules "Safe Browsing log modules">
<!ENTITY aboutUrlClassifier.debugModules "Current log modules">
<!ENTITY aboutUrlClassifier.debugSBJSModules "Safe Browsing JS log">
<!ENTITY aboutUrlClassifier.debugFile "Current log file">

Просмотреть файл

@ -0,0 +1,19 @@
# 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/.
TriggerUpdate = Trigger Update
NotAvailable = N/A
DisableSBJSLog = Disable Safe Browsing JS Log
EnableSBJSLog = Enable Safe Browsing JS Log
Enabled = Enabled
Disabled = Disabled
Updating = updating
CannotUpdate = cannot update

Просмотреть файл

@ -21,6 +21,8 @@
locale/@AB_CD@/global/aboutSupport.properties (%chrome/global/aboutSupport.properties)
locale/@AB_CD@/global/aboutTelemetry.dtd (%chrome/global/aboutTelemetry.dtd)
locale/@AB_CD@/global/aboutTelemetry.properties (%chrome/global/aboutTelemetry.properties)
locale/@AB_CD@/global/aboutUrlClassifier.dtd (%chrome/global/aboutUrlClassifier.dtd)
locale/@AB_CD@/global/aboutUrlClassifier.properties (%chrome/global/aboutUrlClassifier.properties)
locale/@AB_CD@/global/aboutWebrtc.properties (%chrome/global/aboutWebrtc.properties)
locale/@AB_CD@/global/autocomplete.properties (%chrome/global/autocomplete.properties)
locale/@AB_CD@/global/appPicker.dtd (%chrome/global/appPicker.dtd)