# HG changeset patch # User Panos Astithas The network panel should only record beacons from the monitored page (bug 1160837). r=ochameau diff --git a/browser/devtools/netmonitor/netmonitor-view.js b/browser/devtools/netmonitor/netmonitor-view.js index eab8725..4b848a1 100644 --- a/browser/devtools/netmonitor/netmonitor-view.js +++ b/browser/devtools/netmonitor/netmonitor-view.js @@ -175,16 +175,20 @@ let NetMonitorView = { } }, /** * Gets the current mode for this tool. * @return string (e.g, "network-inspector-view" or "network-statistics-view") */ get currentFrontendMode() { + // The getter may be called from a timeout after the panel is destroyed. + if (!this._body.selectedPanel) { + return null; + } return this._body.selectedPanel.id; }, /** * Toggles between the frontend view modes ("Inspector" vs. "Statistics"). */ toggleFrontendMode: function() { if (this.currentFrontendMode != "network-inspector-view") { diff --git a/browser/devtools/netmonitor/test/browser.ini b/browser/devtools/netmonitor/test/browser.ini index 89766e7..d86b41e 100644 --- a/browser/devtools/netmonitor/test/browser.ini +++ b/browser/devtools/netmonitor/test/browser.ini @@ -16,16 +16,17 @@ support-files = html_json-text-mime-test-page.html html_jsonp-test-page.html html_navigate-test-page.html html_params-test-page.html html_post-data-test-page.html html_post-raw-test-page.html html_post-raw-with-headers-test-page.html html_simple-test-page.html + html_send-beacon.html html_sorting-test-page.html html_statistics-test-page.html html_status-codes-test-page.html html_api-calls-test-page.html html_copy-as-curl.html html_curl-utils.html sjs_content-type-test-server.sjs sjs_cors-test-server.sjs @@ -94,16 +95,18 @@ skip-if = e10s # Bug 1091612 [browser_net_security-details.js] [browser_net_security-error.js] [browser_net_security-icon-click.js] [browser_net_security-redirect.js] [browser_net_security-state.js] [browser_net_security-tab-deselect.js] [browser_net_security-tab-visibility.js] [browser_net_security-warnings.js] +[browser_net_send-beacon.js] +[browser_net_send-beacon-other-tab.js] [browser_net_simple-init.js] [browser_net_simple-request-data.js] [browser_net_simple-request-details.js] [browser_net_simple-request.js] [browser_net_sort-01.js] [browser_net_sort-02.js] [browser_net_sort-03.js] [browser_net_statistics-01.js] diff --git a/browser/devtools/netmonitor/test/browser_net_send-beacon-other-tab.js b/browser/devtools/netmonitor/test/browser_net_send-beacon-other-tab.js new file mode 100644 index 0000000..aad9e55 --- /dev/null +++ b/browser/devtools/netmonitor/test/browser_net_send-beacon-other-tab.js @@ -0,0 +1,31 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests if beacons from other tabs are properly ignored. + */ + +let test = Task.async(function*() { + let [, debuggee, monitor] = yield initNetMonitor(SIMPLE_URL); + let { RequestsMenu } = monitor.panelWin.NetMonitorView; + RequestsMenu.lazyUpdate = false; + + let tab = yield addTab(SEND_BEACON_URL); + let beaconDebuggee = tab.linkedBrowser.contentWindow.wrappedJSObject; + info("Beacon tab added successfully."); + + is(RequestsMenu.itemCount, 0, "The requests menu should be empty."); + + beaconDebuggee.performRequest(); + debuggee.location.reload(); + + yield waitForNetworkEvents(monitor, 1); + is(RequestsMenu.itemCount, 1, "Only the reload should be recorded."); + let request = RequestsMenu.getItemAtIndex(0); + is(request.attachment.method, "GET", "The method is correct."); + is(request.attachment.status, "200", "The status is correct."); + + yield teardown(monitor); + removeTab(tab); + finish(); +}); diff --git a/browser/devtools/netmonitor/test/browser_net_send-beacon.js b/browser/devtools/netmonitor/test/browser_net_send-beacon.js new file mode 100644 index 0000000..d37f92a --- /dev/null +++ b/browser/devtools/netmonitor/test/browser_net_send-beacon.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests if beacons are handled correctly. + */ + +let test = Task.async(function*() { + let [, debuggee, monitor] = yield initNetMonitor(SEND_BEACON_URL); + let { RequestsMenu } = monitor.panelWin.NetMonitorView; + + RequestsMenu.lazyUpdate = false; + + is(RequestsMenu.itemCount, 0, "The requests menu should be empty."); + + debuggee.performRequest(); + + yield waitForNetworkEvents(monitor, 1); + is(RequestsMenu.itemCount, 1, "The beacon should be recorded."); + let request = RequestsMenu.getItemAtIndex(0); + is(request.attachment.method, "POST", "The method is correct."); + ok(request.attachment.url.endsWith("beacon_request"), "The URL is correct."); + is(request.attachment.status, "404", "The status is correct."); + + yield teardown(monitor); + finish(); +}); diff --git a/browser/devtools/netmonitor/test/head.js b/browser/devtools/netmonitor/test/head.js index 75e30b3..d555d11 100644 --- a/browser/devtools/netmonitor/test/head.js +++ b/browser/devtools/netmonitor/test/head.js @@ -35,16 +35,17 @@ const JSON_TEXT_MIME_URL = EXAMPLE_URL + "html_json-text-mime-test-page.html"; const SORTING_URL = EXAMPLE_URL + "html_sorting-test-page.html"; const FILTERING_URL = EXAMPLE_URL + "html_filter-test-page.html"; const INFINITE_GET_URL = EXAMPLE_URL + "html_infinite-get-page.html"; const CUSTOM_GET_URL = EXAMPLE_URL + "html_custom-get-page.html"; const SINGLE_GET_URL = EXAMPLE_URL + "html_single-get-page.html"; const STATISTICS_URL = EXAMPLE_URL + "html_statistics-test-page.html"; const CURL_URL = EXAMPLE_URL + "html_copy-as-curl.html"; const CURL_UTILS_URL = EXAMPLE_URL + "html_curl-utils.html"; +const SEND_BEACON_URL = EXAMPLE_URL + "html_send-beacon.html"; const SIMPLE_SJS = EXAMPLE_URL + "sjs_simple-test-server.sjs"; const CONTENT_TYPE_SJS = EXAMPLE_URL + "sjs_content-type-test-server.sjs"; const STATUS_CODES_SJS = EXAMPLE_URL + "sjs_status-codes-test-server.sjs"; const SORTING_SJS = EXAMPLE_URL + "sjs_sorting-test-server.sjs"; const HTTPS_REDIRECT_SJS = EXAMPLE_URL + "sjs_https-redirect-test-server.sjs"; const CORS_SJS_PATH = "/browser/browser/devtools/netmonitor/test/sjs_cors-test-server.sjs"; diff --git a/browser/devtools/netmonitor/test/html_send-beacon.html b/browser/devtools/netmonitor/test/html_send-beacon.html new file mode 100644 index 0000000..95cc005 --- /dev/null +++ b/browser/devtools/netmonitor/test/html_send-beacon.html @@ -0,0 +1,23 @@ + + + + + + + + + + Network Monitor test page + + + +

Send beacon test

+ + + + diff --git a/toolkit/devtools/webconsole/network-monitor.js b/toolkit/devtools/webconsole/network-monitor.js index d1fd4cb..f37acc9 100644 --- a/toolkit/devtools/webconsole/network-monitor.js +++ b/toolkit/devtools/webconsole/network-monitor.js @@ -10,17 +10,26 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); loader.lazyGetter(this, "NetworkHelper", () => require("devtools/toolkit/webconsole/network-helper")); loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm"); loader.lazyImporter(this, "DevToolsUtils", "resource://gre/modules/devtools/DevToolsUtils.jsm"); loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm"); loader.lazyServiceGetter(this, "gActivityDistributor", "@mozilla.org/network/http-activity-distributor;1", "nsIHttpActivityDistributor"); -loader.lazyImporter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm"); +loader.lazyGetter(this, "gTesting", () => { + let testing = false; + try { + const { gDevTools } = require("resource:///modules/devtools/gDevTools.jsm"); + testing = gDevTools.testing; + } catch (e) { + // gDevTools is not present on B2G. + } + return testing; +}); /////////////////////////////////////////////////////////////////////////////// // Network logging /////////////////////////////////////////////////////////////////////////////// // The maximum uint32 value. const PR_UINT32_MAX = 4294967295; @@ -742,17 +751,17 @@ NetworkMonitor.prototype = { return true; } // Ignore requests from chrome or add-on code when we are monitoring // content. // TODO: one particular test (browser_styleeditor_fetch-from-cache.js) needs // the gDevTools.testing check. We will move to a better way to serve its // needs in bug 1167188, where this check should be removed. - if (!gDevTools.testing && aChannel.loadInfo && + if (!gTesting && aChannel.loadInfo && aChannel.loadInfo.loadingDocument === null && aChannel.loadInfo.loadingPrincipal === Services.scriptSecurityManager.getSystemPrincipal()) { return false; } if (this.window) { // Since frames support, this.window may not be the top level content // frame, so that we can't only compare with win.top. @@ -763,36 +772,48 @@ NetworkMonitor.prototype = { } if (win.parent == win) { break; } win = win.parent; } } - if (aChannel.loadInfo) { - if (aChannel.loadInfo.contentPolicyType == Ci.nsIContentPolicy.TYPE_BEACON) { - return true; - } - } - if (this.topFrame) { let topFrame = NetworkHelper.getTopFrameForRequest(aChannel); if (topFrame && topFrame === this.topFrame) { return true; } } if (this.appId) { let appId = NetworkHelper.getAppIdForRequest(aChannel); if (appId && appId == this.appId) { return true; } } + // The following check is necessary because beacon channels don't come + // associated with a load group. Bug 1160837 will hopefully introduce a + // platform fix that will render the following code entirely useless. + if (aChannel.loadInfo && + aChannel.loadInfo.contentPolicyType == Ci.nsIContentPolicy.TYPE_BEACON) { + let nonE10sMatch = this.window && + aChannel.loadInfo.loadingDocument === this.window.document; + let e10sMatch = this.topFrame && + this.topFrame.contentPrincipal && + this.topFrame.contentPrincipal.equals(aChannel.loadInfo.loadingPrincipal) && + this.topFrame.contentPrincipal.URI.spec == aChannel.referrer.spec; + let b2gMatch = this.appId && + aChannel.loadInfo.loadingPrincipal.appId === this.appId; + if (nonE10sMatch || e10sMatch || b2gMatch) { + return true; + } + } + return false; }, /** * */ _createNetworkEvent: function(aChannel, { timestamp, extraStringData, fromCache }) { let win = NetworkHelper.getWindowForRequest(aChannel);