Commit bf08b433 authored by rbpotter's avatar rbpotter Committed by Chromium LUCI CQ

Net internals: Use sendwithPromise

Remove use of CallJavascriptFunctionUnsafe from net_internals_ui.cc.

Update BrowserBridge to class based syntax and use sendWithPromise as
needed.

handler occurs like in production code, so cannot easily be stubbed
out with a TestBrowserProxy. Therefore, moved test observers to the
class being tested.

Note: Unlike many WebUI tests, these tests assume a round trip to the
Change-Id: Id2453205e1bdc912b5e20aeba12f1082ed09629d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2634129
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatardpapad <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845033}
parent 38e91765
...@@ -6,155 +6,59 @@ ...@@ -6,155 +6,59 @@
* This class provides a "bridge" for communicating between the javascript and * This class provides a "bridge" for communicating between the javascript and
* the browser. * the browser.
*/ */
const BrowserBridge = (function() { class BrowserBridge {
'use strict'; constructor() {}
/** //--------------------------------------------------------------------------
* @constructor // Messages sent to the browser
*/ //--------------------------------------------------------------------------
function BrowserBridge() { sendReloadProxySettings() {
assertFirstConstructorCall(BrowserBridge); chrome.send('reloadProxySettings');
// List of observers for various bits of browser state.
this.hstsObservers_ = [];
this.expectCTObservers_ = [];
this.setNetworkDebugModeObservers_ = [];
} }
cr.addSingletonGetter(BrowserBridge); sendClearBadProxies() {
chrome.send('clearBadProxies');
BrowserBridge.prototype = { }
//--------------------------------------------------------------------------
// Messages sent to the browser
//--------------------------------------------------------------------------
/**
* Wraps |chrome.send|.
* TODO(mattm): remove this and switch things to use chrome.send directly.
*/
send(value1, value2) {
if (arguments.length == 1) {
chrome.send(value1);
} else if (arguments.length == 2) {
chrome.send(value1, value2);
} else {
throw 'Unsupported number of arguments.';
}
},
sendReloadProxySettings() {
this.send('reloadProxySettings');
},
sendClearBadProxies() {
this.send('clearBadProxies');
},
sendClearHostResolverCache() {
this.send('clearHostResolverCache');
},
sendHSTSQuery(domain) {
this.send('hstsQuery', [domain]);
},
sendHSTSAdd(domain, sts_include_subdomains) {
this.send('hstsAdd', [domain, sts_include_subdomains]);
},
sendDomainSecurityPolicyDelete(domain) {
this.send('domainSecurityPolicyDelete', [domain]);
},
sendExpectCTQuery(domain) {
this.send('expectCTQuery', [domain]);
},
sendExpectCTAdd(domain, report_uri, enforce) {
this.send('expectCTAdd', [domain, report_uri, enforce]);
},
sendExpectCTTestReport(report_uri) {
this.send('expectCTTestReport', [report_uri]);
},
sendCloseIdleSockets() {
this.send('closeIdleSockets');
},
sendFlushSocketPools() {
this.send('flushSocketPools');
},
setNetworkDebugMode(subsystem) {
this.send('setNetworkDebugMode', [subsystem]);
},
//-------------------------------------------------------------------------- sendClearHostResolverCache() {
// Messages received from the browser. chrome.send('clearHostResolverCache');
//-------------------------------------------------------------------------- }
receive(command, params) { sendHSTSQuery(domain) {
this[command](params); return cr.sendWithPromise('hstsQuery', domain);
}, }
receivedHSTSResult(info) { sendHSTSAdd(domain, sts_include_subdomains) {
for (let i = 0; i < this.hstsObservers_.length; i++) { chrome.send('hstsAdd', [domain, sts_include_subdomains]);
this.hstsObservers_[i].onHSTSQueryResult(info); }
}
},
receivedExpectCTResult(info) { sendDomainSecurityPolicyDelete(domain) {
for (let i = 0; i < this.expectCTObservers_.length; i++) { chrome.send('domainSecurityPolicyDelete', [domain]);
this.expectCTObservers_[i].onExpectCTQueryResult(info); }
}
},
receivedExpectCTTestReportResult(result) { sendExpectCTQuery(domain) {
for (let i = 0; i < this.expectCTObservers_.length; i++) { return cr.sendWithPromise('expectCTQuery', domain);
this.expectCTObservers_[i].onExpectCTTestReportResult(result); }
}
},
receivedSetNetworkDebugMode(status) { sendExpectCTAdd(domain, report_uri, enforce) {
for (let i = 0; i < this.setNetworkDebugModeObservers_.length; i++) { chrome.send('expectCTAdd', [domain, report_uri, enforce]);
this.setNetworkDebugModeObservers_[i].onSetNetworkDebugMode(status); }
}
},
//-------------------------------------------------------------------------- sendExpectCTTestReport(report_uri) {
return cr.sendWithPromise('expectCTTestReport', report_uri);
}
/** sendCloseIdleSockets() {
* Adds a listener for the results of HSTS (HTTPS Strict Transport Security) chrome.send('closeIdleSockets');
* queries. The observer will be called back with: }
*
* observer.onHSTSQueryResult(result);
*/
addHSTSObserver(observer) {
this.hstsObservers_.push(observer);
},
/** sendFlushSocketPools() {
* Adds a listener for the results of Expect-CT queries. The observer will chrome.send('flushSocketPools');
* be called back with: }
*
* observer.onExpectCTQueryResult(result);
*/
addExpectCTObserver(observer) {
this.expectCTObservers_.push(observer);
},
/** setNetworkDebugMode(subsystem) {
* Adds a listener for network debugging mode status. The observer chrome.send('setNetworkDebugMode', [subsystem]);
* will be called back with: }
* }
* observer.onSetNetworkDebugMode(status);
*/
addSetNetworkDebugModeObserver(observer) {
this.setNetworkDebugModeObservers_.push(observer);
},
};
return BrowserBridge; cr.addSingletonGetter(BrowserBridge);
})();
...@@ -22,8 +22,9 @@ const DnsView = (function() { ...@@ -22,8 +22,9 @@ const DnsView = (function() {
// Call superclass's constructor. // Call superclass's constructor.
superClass.call(this, DnsView.MAIN_BOX_ID); superClass.call(this, DnsView.MAIN_BOX_ID);
$(DnsView.CLEAR_CACHE_BUTTON_ID).onclick = $(DnsView.CLEAR_CACHE_BUTTON_ID).onclick = () => {
g_browser.sendClearHostResolverCache.bind(g_browser); BrowserBridge.getInstance().sendClearHostResolverCache();
};
} }
DnsView.TAB_ID = 'tab-handle-dns'; DnsView.TAB_ID = 'tab-handle-dns';
......
...@@ -15,6 +15,7 @@ found in the LICENSE file. ...@@ -15,6 +15,7 @@ found in the LICENSE file.
<link rel="stylesheet" href="chromeos_view.css"> <link rel="stylesheet" href="chromeos_view.css">
<script src="chrome://resources/js/assert.js"></script> <script src="chrome://resources/js/assert.js"></script>
<script src="chrome://resources/js/util.js"></script> <script src="chrome://resources/js/util.js"></script>
<script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/cr.js"></script> <script src="chrome://resources/js/cr.js"></script>
<script src="chrome://net-internals/index.js"></script> <script src="chrome://net-internals/index.js"></script>
</head> </head>
......
...@@ -2,12 +2,6 @@ ...@@ -2,12 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/**
* Object to communicate between the renderer and the browser.
* @type {!BrowserBridge}
*/
let g_browser = null;
/** /**
* This class is the root view object of the page. It owns all the other * This class is the root view object of the page. It owns all the other
* views, and manages switching between them. It is also responsible for * views, and manages switching between them. It is also responsible for
...@@ -30,10 +24,6 @@ const MainView = (function() { ...@@ -30,10 +24,6 @@ const MainView = (function() {
document.body.classList.add('touch'); document.body.classList.add('touch');
} }
// This must be initialized before the tabs, so they can register as
// observers.
g_browser = BrowserBridge.getInstance();
// Create the tab switcher. // Create the tab switcher.
this.initTabs_(); this.initTabs_();
superClass.call(this, this.tabSwitcher_); superClass.call(this, this.tabSwitcher_);
......
...@@ -24,10 +24,12 @@ const ProxyView = (function() { ...@@ -24,10 +24,12 @@ const ProxyView = (function() {
superClass.call(this, ProxyView.MAIN_BOX_ID); superClass.call(this, ProxyView.MAIN_BOX_ID);
// Hook up the UI components. // Hook up the UI components.
$(ProxyView.RELOAD_SETTINGS_BUTTON_ID).onclick = $(ProxyView.RELOAD_SETTINGS_BUTTON_ID).onclick = () => {
g_browser.sendReloadProxySettings.bind(g_browser); BrowserBridge.getInstance().sendReloadProxySettings();
$(ProxyView.CLEAR_BAD_PROXIES_BUTTON_ID).onclick = };
g_browser.sendClearBadProxies.bind(g_browser); $(ProxyView.CLEAR_BAD_PROXIES_BUTTON_ID).onclick = () => {
BrowserBridge.getInstance().sendClearBadProxies();
};
} }
ProxyView.TAB_ID = 'tab-handle-proxy'; ProxyView.TAB_ID = 'tab-handle-proxy';
......
...@@ -46,11 +46,11 @@ const SocketsView = (function() { ...@@ -46,11 +46,11 @@ const SocketsView = (function() {
__proto__: superClass.prototype, __proto__: superClass.prototype,
closeIdleSockets() { closeIdleSockets() {
g_browser.sendCloseIdleSockets(); BrowserBridge.getInstance().sendCloseIdleSockets();
}, },
flushSocketPools() { flushSocketPools() {
g_browser.sendFlushSocketPools(); BrowserBridge.getInstance().sendFlushSocketPools();
} }
}; };
......
...@@ -67,11 +67,13 @@ class NetInternalsMessageHandler ...@@ -67,11 +67,13 @@ class NetInternalsMessageHandler
private: private:
network::mojom::NetworkContext* GetNetworkContext(); network::mojom::NetworkContext* GetNetworkContext();
// Calls g_browser.receive in the renderer, passing in |command| and |arg|. // Resolve JS |callback_id| with |result|.
// If the renderer is displaying a log file, the message will be ignored. // If the renderer is displaying a log file, the message will be ignored.
void SendJavascriptCommand(const std::string& command, base::Value arg); void ResolveCallbackWithResult(const std::string& callback_id,
base::Value result);
void OnExpectCTTestReportCallback(bool success); void OnExpectCTTestReportCallback(const std::string& callback_id,
bool success);
//-------------------------------- //--------------------------------
// Javascript message handlers: // Javascript message handlers:
...@@ -145,15 +147,6 @@ void NetInternalsMessageHandler::RegisterMessages() { ...@@ -145,15 +147,6 @@ void NetInternalsMessageHandler::RegisterMessages() {
base::Unretained(this))); base::Unretained(this)));
} }
void NetInternalsMessageHandler::SendJavascriptCommand(
const std::string& command,
base::Value arg) {
std::unique_ptr<base::Value> command_value(new base::Value(command));
DCHECK_CURRENTLY_ON(BrowserThread::UI);
web_ui()->CallJavascriptFunctionUnsafe("g_browser.receive",
*command_value.get(), arg);
}
void NetInternalsMessageHandler::OnReloadProxySettings( void NetInternalsMessageHandler::OnReloadProxySettings(
const base::ListValue* list) { const base::ListValue* list) {
GetNetworkContext()->ForceReloadProxyConfig(base::NullCallback()); GetNetworkContext()->ForceReloadProxyConfig(base::NullCallback());
...@@ -184,14 +177,23 @@ void NetInternalsMessageHandler::OnDomainSecurityPolicyDelete( ...@@ -184,14 +177,23 @@ void NetInternalsMessageHandler::OnDomainSecurityPolicyDelete(
} }
void NetInternalsMessageHandler::OnHSTSQuery(const base::ListValue* list) { void NetInternalsMessageHandler::OnHSTSQuery(const base::ListValue* list) {
// |list| should be: [<domain to query>]. std::string callback_id;
bool get_callback_id = list->GetString(0, &callback_id);
std::string domain; std::string domain;
bool get_domain_result = list->GetString(0, &domain); bool get_domain_result = list->GetString(1, &domain);
DCHECK(get_domain_result); DCHECK(get_domain_result && get_callback_id);
AllowJavascript();
GetNetworkContext()->GetHSTSState( GetNetworkContext()->GetHSTSState(
domain, base::BindOnce(&NetInternalsMessageHandler::SendJavascriptCommand, domain,
this->AsWeakPtr(), "receivedHSTSResult")); base::BindOnce(&NetInternalsMessageHandler::ResolveCallbackWithResult,
base::Unretained(this), callback_id));
}
void NetInternalsMessageHandler::ResolveCallbackWithResult(
const std::string& callback_id,
base::Value result) {
ResolveJavascriptCallback(base::Value(callback_id), result);
} }
void NetInternalsMessageHandler::OnHSTSAdd(const base::ListValue* list) { void NetInternalsMessageHandler::OnHSTSAdd(const base::ListValue* list) {
...@@ -214,19 +216,22 @@ void NetInternalsMessageHandler::OnHSTSAdd(const base::ListValue* list) { ...@@ -214,19 +216,22 @@ void NetInternalsMessageHandler::OnHSTSAdd(const base::ListValue* list) {
} }
void NetInternalsMessageHandler::OnExpectCTQuery(const base::ListValue* list) { void NetInternalsMessageHandler::OnExpectCTQuery(const base::ListValue* list) {
// |list| should be: [<domain to query>]. std::string callback_id;
std::string domain; std::string domain;
bool result = list->GetString(0, &domain); bool callback_result = list->GetString(0, &callback_id);
DCHECK(result); bool result = list->GetString(1, &domain);
DCHECK(result && callback_result);
url::Origin origin = url::Origin::Create(GURL("https://" + domain)); url::Origin origin = url::Origin::Create(GURL("https://" + domain));
AllowJavascript();
GetNetworkContext()->GetExpectCTState( GetNetworkContext()->GetExpectCTState(
domain, domain,
net::NetworkIsolationKey(origin /* top_frame_site */, net::NetworkIsolationKey(origin /* top_frame_site */,
origin /* frame_site */), origin /* frame_site */),
base::BindOnce(&NetInternalsMessageHandler::SendJavascriptCommand, base::BindOnce(&NetInternalsMessageHandler::ResolveCallbackWithResult,
this->AsWeakPtr(), "receivedExpectCTResult")); base::Unretained(this), callback_id));
} }
void NetInternalsMessageHandler::OnExpectCTAdd(const base::ListValue* list) { void NetInternalsMessageHandler::OnExpectCTAdd(const base::ListValue* list) {
...@@ -259,24 +264,29 @@ void NetInternalsMessageHandler::OnExpectCTAdd(const base::ListValue* list) { ...@@ -259,24 +264,29 @@ void NetInternalsMessageHandler::OnExpectCTAdd(const base::ListValue* list) {
void NetInternalsMessageHandler::OnExpectCTTestReport( void NetInternalsMessageHandler::OnExpectCTTestReport(
const base::ListValue* list) { const base::ListValue* list) {
// |list| should be: [<report URI>]. std::string callback_id;
std::string report_uri_str; std::string report_uri_str;
bool result = list->GetString(0, &report_uri_str); bool callback_result = list->GetString(0, &callback_id);
DCHECK(result); bool result = list->GetString(1, &report_uri_str);
DCHECK(result && callback_result);
GURL report_uri(report_uri_str); GURL report_uri(report_uri_str);
if (!report_uri.is_valid()) AllowJavascript();
if (!report_uri.is_valid()) {
ResolveCallbackWithResult(callback_id, base::Value("invalid"));
return; return;
}
GetNetworkContext()->SetExpectCTTestReport( GetNetworkContext()->SetExpectCTTestReport(
report_uri, report_uri,
base::BindOnce(&NetInternalsMessageHandler::OnExpectCTTestReportCallback, base::BindOnce(&NetInternalsMessageHandler::OnExpectCTTestReportCallback,
this->AsWeakPtr())); base::Unretained(this), callback_id));
} }
void NetInternalsMessageHandler::OnExpectCTTestReportCallback(bool success) { void NetInternalsMessageHandler::OnExpectCTTestReportCallback(
SendJavascriptCommand( const std::string& callback_id,
"receivedExpectCTTestReportResult", bool success) {
success ? base::Value("success") : base::Value("failure")); ResolveCallbackWithResult(
callback_id, success ? base::Value("success") : base::Value("failure"));
} }
void NetInternalsMessageHandler::OnFlushSocketPools( void NetInternalsMessageHandler::OnFlushSocketPools(
......
...@@ -121,7 +121,7 @@ CheckHSTSQueryResultTask.prototype = { ...@@ -121,7 +121,7 @@ CheckHSTSQueryResultTask.prototype = {
* Starts watching for the query results. * Starts watching for the query results.
*/ */
start: function() { start: function() {
g_browser.addHSTSObserver(this); DomainSecurityPolicyView.getInstance().addHSTSObserverForTest(this);
}, },
/** /**
...@@ -254,7 +254,7 @@ CheckExpectCTQueryResultTask.prototype = { ...@@ -254,7 +254,7 @@ CheckExpectCTQueryResultTask.prototype = {
* Starts watching for the query results. * Starts watching for the query results.
*/ */
start: function() { start: function() {
g_browser.addExpectCTObserver(this); DomainSecurityPolicyView.getInstance().addExpectCTObserverForTest(this);
}, },
/** /**
...@@ -392,7 +392,7 @@ SendTestReportTask.prototype = { ...@@ -392,7 +392,7 @@ SendTestReportTask.prototype = {
* Sends the test report and starts watching for the result. * Sends the test report and starts watching for the result.
*/ */
start: function() { start: function() {
g_browser.addExpectCTObserver(this); DomainSecurityPolicyView.getInstance().addExpectCTObserverForTest(this);
$(DomainSecurityPolicyView.TEST_REPORT_EXPECT_CT_INPUT_ID).value = $(DomainSecurityPolicyView.TEST_REPORT_EXPECT_CT_INPUT_ID).value =
this.reportURITask_.reportURI(); this.reportURITask_.reportURI();
$(DomainSecurityPolicyView.TEST_REPORT_EXPECT_CT_SUBMIT_ID).click(); $(DomainSecurityPolicyView.TEST_REPORT_EXPECT_CT_SUBMIT_ID).click();
......
...@@ -50,11 +50,6 @@ var NetInternalsTest = (function() { ...@@ -50,11 +50,6 @@ var NetInternalsTest = (function() {
setUp: function() { setUp: function() {
testing.Test.prototype.setUp.call(this); testing.Test.prototype.setUp.call(this);
// Wrap g_browser.receive around a test function so that assert and expect
// functions can be called from observers.
g_browser.receive = this.continueTest(
WhenTestDone.EXPECT, BrowserBridge.prototype.receive.bind(g_browser));
var runTest = this.deferRunTest(WhenTestDone.EXPECT); var runTest = this.deferRunTest(WhenTestDone.EXPECT);
window.setTimeout(runTest, 0); window.setTimeout(runTest, 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment