Backed out 3 changesets (bug 1134073) for browser_net_statistics-01.js failures

Backed out a58743e540f5 (bug 1134073)
Backed out 616b2bbf8fd0 (bug 1134073)
Backed out 691b0e0a6ca1 (bug 1134073)

MozReview-Commit-ID: 3LwVxPXX8SZ
This commit is contained in:
Tim Nguyen 2016-06-04 19:01:29 +02:00
Родитель e9eb52b1c2
Коммит b45619ad94
19 изменённых файлов: 199 добавлений и 825 удалений

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

@ -39,10 +39,6 @@
- in the network table toolbar, above the "domain" column. -->
<!ENTITY netmonitorUI.toolbar.domain "Domain">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.cause): This is the label displayed
- in the network table toolbar, above the "cause" column. -->
<!ENTITY netmonitorUI.toolbar.cause "Cause">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.type): This is the label displayed
- in the network table toolbar, above the "type" column. -->
<!ENTITY netmonitorUI.toolbar.type "Type">

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

@ -433,13 +433,6 @@ var NetMonitorController = {
get supportsPerfStats() {
return this.tabClient &&
(this.tabClient.traits.reconfigure || !this._target.isApp);
},
/**
* Open a given source in Debugger
*/
viewSourceInDebugger(sourceURL, sourceLine) {
return this._toolbox.viewSourceInDebugger(sourceURL, sourceLine);
}
};
@ -636,14 +629,12 @@ NetworkEventsHandler.prototype = {
startedDateTime,
request: { method, url },
isXHR,
cause,
fromCache,
fromServiceWorker
} = networkInfo;
NetMonitorView.RequestsMenu.addRequest(
actor, startedDateTime, method, url, isXHR, cause, fromCache,
fromServiceWorker
actor, startedDateTime, method, url, isXHR, fromCache, fromServiceWorker
);
window.emit(EVENTS.NETWORK_EVENT, actor);
},

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

@ -30,9 +30,7 @@ const {ViewHelpers, Heritage, WidgetMethods, setNamedTimeout} =
* Localization convenience methods.
*/
const NET_STRINGS_URI = "chrome://devtools/locale/netmonitor.properties";
const WEBCONSOLE_STRINGS_URI = "chrome://devtools/locale/webconsole.properties";
var L10N = new LocalizationHelper(NET_STRINGS_URI);
const WEBCONSOLE_L10N = new LocalizationHelper(WEBCONSOLE_STRINGS_URI);
// ms
const WDA_DEFAULT_VERIFY_INTERVAL = 50;
@ -63,8 +61,6 @@ const RESIZE_REFRESH_RATE = 50;
// ms
const REQUESTS_REFRESH_RATE = 50;
const REQUESTS_TOOLTIP_POSITION = "topcenter bottomleft";
// tooltip show/hide delay in ms
const REQUESTS_TOOLTIP_TOGGLE_DELAY = 500;
// px
const REQUESTS_TOOLTIP_IMAGE_MAX_DIM = 400;
// px
@ -106,31 +102,6 @@ const CONTENT_MIME_TYPE_MAPPINGS = {
"/rss": Editor.modes.css,
"/css": Editor.modes.css
};
const LOAD_CAUSE_STRINGS = {
[Ci.nsIContentPolicy.TYPE_INVALID]: "invalid",
[Ci.nsIContentPolicy.TYPE_OTHER]: "other",
[Ci.nsIContentPolicy.TYPE_SCRIPT]: "script",
[Ci.nsIContentPolicy.TYPE_IMAGE]: "img",
[Ci.nsIContentPolicy.TYPE_STYLESHEET]: "stylesheet",
[Ci.nsIContentPolicy.TYPE_OBJECT]: "object",
[Ci.nsIContentPolicy.TYPE_DOCUMENT]: "document",
[Ci.nsIContentPolicy.TYPE_SUBDOCUMENT]: "subdocument",
[Ci.nsIContentPolicy.TYPE_REFRESH]: "refresh",
[Ci.nsIContentPolicy.TYPE_XBL]: "xbl",
[Ci.nsIContentPolicy.TYPE_PING]: "ping",
[Ci.nsIContentPolicy.TYPE_XMLHTTPREQUEST]: "xhr",
[Ci.nsIContentPolicy.TYPE_OBJECT_SUBREQUEST]: "objectSubdoc",
[Ci.nsIContentPolicy.TYPE_DTD]: "dtd",
[Ci.nsIContentPolicy.TYPE_FONT]: "font",
[Ci.nsIContentPolicy.TYPE_MEDIA]: "media",
[Ci.nsIContentPolicy.TYPE_WEBSOCKET]: "websocket",
[Ci.nsIContentPolicy.TYPE_CSP_REPORT]: "csp",
[Ci.nsIContentPolicy.TYPE_XSLT]: "xslt",
[Ci.nsIContentPolicy.TYPE_BEACON]: "beacon",
[Ci.nsIContentPolicy.TYPE_FETCH]: "fetch",
[Ci.nsIContentPolicy.TYPE_IMAGESET]: "imageset",
[Ci.nsIContentPolicy.TYPE_WEB_MANIFEST]: "webManifest"
};
const DEFAULT_EDITOR_CONFIG = {
mode: Editor.modes.text,
readOnly: true,
@ -460,20 +431,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this.userInputTimer = Cc["@mozilla.org/timer;1"]
.createInstance(Ci.nsITimer);
// Create a tooltip for the newly appended network request item.
this.tooltip = new Tooltip(document, {
closeOnEvents: [{
emitter: $("#requests-menu-contents"),
event: "scroll",
useCapture: true
}]
});
this.tooltip.startTogglingOnHover(this.widget, this._onHover, {
toggleDelay: REQUESTS_TOOLTIP_TOGGLE_DELAY,
interactive: true
});
this.tooltip.defaultPosition = REQUESTS_TOOLTIP_POSITION;
Prefs.filters.forEach(type => this.filterOn(type));
this.sortContents(this._byTiming);
@ -680,20 +637,15 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
* Specifies the request's url.
* @param boolean isXHR
* True if this request was initiated via XHR.
* @param object cause
* Specifies the request's cause. Has the following properties:
* - type: nsContentPolicyType constant
* - loadingDocumentUri: URI of the request origin
* - stacktrace: JS stacktrace of the request
* @param boolean fromCache
* Indicates if the result came from the browser cache
* @param boolean fromServiceWorker
* Indicates if the request has been intercepted by a Service Worker
*/
addRequest: function (id, startedDateTime, method, url, isXHR, cause,
fromCache, fromServiceWorker) {
this._addQueue.push([id, startedDateTime, method, url, isXHR, cause,
fromCache, fromServiceWorker]);
addRequest: function (id, startedDateTime, method, url, isXHR, fromCache,
fromServiceWorker) {
this._addQueue.push([id, startedDateTime, method, url, isXHR, fromCache,
fromServiceWorker]);
// Lazy updating is disabled in some tests.
if (!this.lazyUpdate) {
@ -933,8 +885,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
let selected = this.selectedItem.attachment;
// Create the element node for the network request item.
let menuView = this._createMenuView(selected.method, selected.url,
selected.cause);
let menuView = this._createMenuView(selected.method, selected.url);
// Append a network request item to this container.
let newItem = this.push([menuView], {
@ -1500,6 +1451,19 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
}
},
/**
* Refreshes the toggling anchor for the specified item's tooltip.
*
* @param object item
* The network request item in this container.
*/
refreshTooltip: function (item) {
let tooltip = item.attachment.tooltip;
tooltip.hide();
tooltip.startTogglingOnHover(item.target, this._onHover);
tooltip.defaultPosition = REQUESTS_TOOLTIP_POSITION;
},
/**
* Attaches security icon click listener for the given request menu item.
*
@ -1546,13 +1510,13 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
let widget = NetMonitorView.RequestsMenu.widget;
let isScrolledToBottom = widget.isScrolledToBottom();
for (let [id, startedDateTime, method, url, isXHR, cause, fromCache,
for (let [id, startedDateTime, method, url, isXHR, fromCache,
fromServiceWorker] of this._addQueue) {
// Convert the received date/time string to a unix timestamp.
let unixTime = Date.parse(startedDateTime);
// Create the element node for the network request item.
let menuView = this._createMenuView(method, url, cause);
let menuView = this._createMenuView(method, url);
// Remember the first and last event boundaries.
this._registerFirstRequestStart(unixTime);
@ -1566,12 +1530,22 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
method: method,
url: url,
isXHR: isXHR,
cause: cause,
fromCache: fromCache,
fromServiceWorker: fromServiceWorker
}
});
// Create a tooltip for the newly appended network request item.
requestItem.attachment.tooltip = new Tooltip(document, {
closeOnEvents: [{
emitter: $("#requests-menu-contents"),
event: "scroll",
useCapture: true
}]
});
this.refreshTooltip(requestItem);
if (id == this._preferredItemId) {
this.selectedItem = requestItem;
}
@ -1780,26 +1754,21 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
* Specifies the request method (e.g. "GET", "POST", etc.)
* @param string url
* Specifies the request's url.
* @param object cause
* Specifies the request's cause. Has two properties:
* - type: nsContentPolicyType constant
* - uri: URI of the request origin
* @return nsIDOMNode
* The network request view.
*/
_createMenuView: function (method, url, cause) {
_createMenuView: function (method, url) {
let template = $("#requests-menu-item-template");
let fragment = document.createDocumentFragment();
this.updateMenuView(template, "method", method);
this.updateMenuView(template, "url", url);
// Flatten the DOM by removing one redundant box (the template container).
for (let node of template.childNodes) {
fragment.appendChild(node.cloneNode(true));
}
this.updateMenuView(fragment, "method", method);
this.updateMenuView(fragment, "url", url);
this.updateMenuView(fragment, "cause", cause);
return fragment;
},
@ -1931,20 +1900,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
node.setAttribute("tooltiptext", value);
break;
}
case "cause": {
let labelNode = $(".requests-menu-cause-label", target);
let text = LOAD_CAUSE_STRINGS[value.type] || "unknown";
labelNode.setAttribute("value", text);
if (value.loadingDocumentUri) {
labelNode.setAttribute("tooltiptext", value.loadingDocumentUri);
}
let stackNode = $(".requests-menu-cause-stack", target);
if (value.stacktrace && value.stacktrace.length > 0) {
stackNode.removeAttribute("hidden");
}
break;
}
case "contentSize": {
let node = $(".requests-menu-size", target);
@ -2275,6 +2230,11 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
* Called when two items switch places, when the contents are sorted.
*/
_onSwap: function ({ detail: [firstItem, secondItem] }) {
// Sorting will create new anchor nodes for all the swapped request items
// in this container, so it's necessary to refresh the Tooltip instances.
this.refreshTooltip(firstItem);
this.refreshTooltip(secondItem);
// Reattach click listener to the security icons
this.attachSecurityIconClickListener(firstItem);
this.attachSecurityIconClickListener(secondItem);
@ -2292,92 +2252,28 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
*/
_onHover: Task.async(function* (target, tooltip) {
let requestItem = this.getItemForElement(target);
if (!requestItem) {
if (!requestItem || !requestItem.attachment.responseContent) {
return false;
}
let hovered = requestItem.attachment;
if (hovered.responseContent && target.closest(".requests-menu-icon-and-file")) {
return this._setTooltipImageContent(tooltip, requestItem);
} else if (hovered.cause && target.closest(".requests-menu-cause-stack")) {
return this._setTooltipStackTraceContent(tooltip, requestItem);
}
let { mimeType, text, encoding } = hovered.responseContent.content;
if (mimeType && mimeType.includes("image/") && (
target.classList.contains("requests-menu-icon") ||
target.classList.contains("requests-menu-file"))) {
let string = yield gNetwork.getString(text);
let anchor = $(".requests-menu-icon", requestItem.target);
let src = formDataURI(mimeType, encoding, string);
tooltip.setImageContent(src, {
maxDim: REQUESTS_TOOLTIP_IMAGE_MAX_DIM
});
return anchor;
}
return false;
}),
_setTooltipImageContent: Task.async(function* (tooltip, requestItem) {
let { mimeType, text, encoding } = requestItem.attachment.responseContent.content;
if (!mimeType || !mimeType.includes("image/")) {
return false;
}
let string = yield gNetwork.getString(text);
let anchor = $(".requests-menu-icon", requestItem.target);
let src = formDataURI(mimeType, encoding, string);
tooltip.setImageContent(src, {
maxDim: REQUESTS_TOOLTIP_IMAGE_MAX_DIM
});
return anchor;
}),
_setTooltipStackTraceContent: Task.async(function* (tooltip, requestItem) {
let {stacktrace} = requestItem.attachment.cause;
if (!stacktrace || stacktrace.length == 0) {
return false;
}
let doc = tooltip.doc;
let el = doc.createElement("vbox");
el.className = "requests-menu-stack-trace";
for (let f of stacktrace) {
let { functionName, filename, lineNumber, columnNumber } = f;
let frameEl = doc.createElement("hbox");
frameEl.className = "requests-menu-stack-frame devtools-monospace";
let funcEl = doc.createElement("label");
funcEl.className = "requests-menu-stack-frame-function-name";
funcEl.setAttribute("value",
functionName || WEBCONSOLE_L10N.getStr("stacktrace.anonymousFunction"));
frameEl.appendChild(funcEl);
let fileEl = doc.createElement("label");
fileEl.className = "requests-menu-stack-frame-file-name";
// Parse a stack frame in format "url -> url"
let sourceUrl = filename.split(" -> ").pop();
fileEl.setAttribute("value", sourceUrl);
fileEl.setAttribute("tooltiptext", sourceUrl);
fileEl.setAttribute("crop", "start");
frameEl.appendChild(fileEl);
let lineEl = doc.createElement("label");
lineEl.className = "requests-menu-stack-frame-line";
lineEl.setAttribute("value", `:${lineNumber}:${columnNumber}`);
frameEl.appendChild(lineEl);
frameEl.addEventListener("click", () => {
// avoid an ugly visual artefact when the view is switched to debugger and the
// tooltip is hidden only after a delay - the tooltip is moved outside the browser
// window.
tooltip.hide();
NetMonitorController.viewSourceInDebugger(filename, lineNumber);
}, false);
el.appendChild(frameEl);
}
tooltip.content = el;
tooltip.panel.setAttribute("wide", "");
return true;
}),
/**
* A handler that opens the security tab in the details view if secure or
* broken security indicator is clicked.

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

@ -221,17 +221,6 @@
flex="1">
</button>
</hbox>
<hbox id="requests-menu-cause-header-box"
class="requests-menu-header requests-menu-cause"
align="center">
<button id="requests-menu-cause-button"
class="requests-menu-header-button requests-menu-cause"
data-key="cause"
label="&netmonitorUI.toolbar.cause;"
crop="end"
flex="1">
</button>
</hbox>
<hbox id="requests-menu-type-header-box"
class="requests-menu-header requests-menu-type"
align="center">
@ -334,10 +323,6 @@
crop="end"
flex="1"/>
</hbox>
<hbox class="requests-menu-subitem requests-menu-cause" align="center">
<label class="requests-menu-cause-stack" value="JS" hidden="true"/>
<label class="plain requests-menu-cause-label" flex="1" crop="end"/>
</hbox>
<label class="plain requests-menu-subitem requests-menu-type"
crop="end"/>
<label class="plain requests-menu-subitem requests-menu-transferred"

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

@ -16,7 +16,6 @@ function NetMonitorPanel(iframeWindow, toolbox) {
this._view = this.panelWin.NetMonitorView;
this._controller = this.panelWin.NetMonitorController;
this._controller._target = this.target;
this._controller._toolbox = this._toolbox;
EventEmitter.decorate(this);
}

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

@ -4,7 +4,6 @@ subsuite = devtools
support-files =
dropmarker.svg
head.js
html_cause-test-page.html
html_content-type-test-page.html
html_content-type-without-cache-test-page.html
html_cors-test-page.html
@ -34,7 +33,6 @@ support-files =
sjs_content-type-test-server.sjs
sjs_cors-test-server.sjs
sjs_https-redirect-test-server.sjs
sjs_hsts-test-server.sjs
sjs_simple-test-server.sjs
sjs_sorting-test-server.sjs
sjs_status-codes-test-server.sjs
@ -49,8 +47,6 @@ skip-if = (toolkit == "cocoa" && e10s) # bug 1252254
[browser_net_api-calls.js]
[browser_net_autoscroll.js]
[browser_net_cached-status.js]
[browser_net_cause.js]
[browser_net_cause_redirect.js]
[browser_net_service-worker-status.js]
[browser_net_charts-01.js]
[browser_net_charts-02.js]

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

@ -1,102 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if request cause is reported correctly.
*/
const CAUSE_FILE_NAME = "html_cause-test-page.html";
const CAUSE_URL = EXAMPLE_URL + CAUSE_FILE_NAME;
const EXPECTED_REQUESTS = [
{
method: "GET",
url: CAUSE_URL,
causeType: "document",
causeUri: "",
// The document load is from JS function in e10s, native in non-e10s
hasStack: !gMultiProcessBrowser
},
{
method: "GET",
url: EXAMPLE_URL + "stylesheet_request",
causeType: "stylesheet",
causeUri: CAUSE_URL,
hasStack: false
},
{
method: "GET",
url: EXAMPLE_URL + "img_request",
causeType: "img",
causeUri: CAUSE_URL,
hasStack: false
},
{
method: "GET",
url: EXAMPLE_URL + "xhr_request",
causeType: "xhr",
causeUri: CAUSE_URL,
hasStack: { fn: "performXhrRequest", file: CAUSE_FILE_NAME, line: 22 }
},
{
method: "POST",
url: EXAMPLE_URL + "beacon_request",
causeType: "beacon",
causeUri: CAUSE_URL,
hasStack: { fn: "performBeaconRequest", file: CAUSE_FILE_NAME, line: 26 }
},
];
var test = Task.async(function* () {
// the initNetMonitor function clears the network request list after the
// page is loaded. That's why we first load a bogus page from SIMPLE_URL,
// and only then load the real thing from CAUSE_URL - we want to catch
// all the requests the page is making, not only the XHRs.
// We can't use about:blank here, because initNetMonitor checks that the
// page has actually made at least one request.
let [, debuggee, monitor] = yield initNetMonitor(SIMPLE_URL);
let { RequestsMenu } = monitor.panelWin.NetMonitorView;
RequestsMenu.lazyUpdate = false;
debuggee.location = CAUSE_URL;
yield waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length);
is(RequestsMenu.itemCount, EXPECTED_REQUESTS.length,
"All the page events should be recorded.");
EXPECTED_REQUESTS.forEach((spec, i) => {
let { method, url, causeType, causeUri, hasStack } = spec;
let requestItem = RequestsMenu.getItemAtIndex(i);
verifyRequestItemTarget(requestItem,
method, url, { cause: { type: causeType, loadingDocumentUri: causeUri } }
);
let { stacktrace } = requestItem.attachment.cause;
let stackLen = stacktrace ? stacktrace.length : 0;
if (hasStack) {
ok(stacktrace, `Request #${i} has a stacktrace`);
ok(stackLen > 0,
`Request #${i} (${causeType}) has a stacktrace with ${stackLen} items`);
// if "hasStack" is object, check the details about the top stack frame
if (typeof hasStack === "object") {
is(stacktrace[0].functionName, hasStack.fn,
`Request #${i} has the correct function on top of the JS stack`);
is(stacktrace[0].filename.split("/").pop(), hasStack.file,
`Request #${i} has the correct file on top of the JS stack`);
is(stacktrace[0].lineNumber, hasStack.line,
`Request #${i} has the correct line number on top of the JS stack`);
}
} else {
is(stackLen, 0, `Request #${i} (${causeType}) has an empty stacktrace`);
}
});
yield teardown(monitor);
finish();
});

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

@ -1,50 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if request JS stack is property reported if the request is internally
* redirected without hitting the network (HSTS is one of such cases)
*/
var test = Task.async(function* () {
const EXPECTED_REQUESTS = [
// Request to HTTP URL, redirects to HTTPS, has callstack
{ status: 302, hasStack: true },
// Serves HTTPS, sets the Strict-Transport-Security header, no stack
{ status: 200, hasStack: false },
// Second request to HTTP redirects to HTTPS internally
{ status: 200, hasStack: true },
];
let [, debuggee, monitor] = yield initNetMonitor(CUSTOM_GET_URL);
let { RequestsMenu } = monitor.panelWin.NetMonitorView;
RequestsMenu.lazyUpdate = false;
debuggee.performRequests(2, HSTS_SJS);
yield waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length);
EXPECTED_REQUESTS.forEach(({status, hasStack}, i) => {
let { attachment } = RequestsMenu.getItemAtIndex(i);
is(attachment.status, status, `Request #${i} has the expected status`);
let { stacktrace } = attachment.cause;
let stackLen = stacktrace ? stacktrace.length : 0;
if (hasStack) {
ok(stacktrace, `Request #${i} has a stacktrace`);
ok(stackLen > 0, `Request #${i} has a stacktrace with ${stackLen} items`);
} else {
is(stackLen, 0, `Request #${i} has an empty stacktrace`);
}
});
// Send a request to reset the HSTS policy to state before the test
debuggee.performRequests(1, HSTS_SJS + "?reset");
yield waitForNetworkEvents(monitor, 1);
yield teardown(monitor);
finish();
});

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

@ -23,7 +23,7 @@ add_task(function* test() {
yield onThumbnail;
info("Checking the image thumbnail after a few requests were made...");
yield showTooltipAndVerify(RequestsMenu.tooltip, RequestsMenu.items[5]);
yield showTooltipAndVerify(RequestsMenu.items[5]);
// 7 XHRs as before + 1 extra document reload
onEvents = waitForNetworkEvents(monitor, 8);
@ -36,7 +36,7 @@ add_task(function* test() {
yield onThumbnail;
info("Checking the image thumbnail after a reload.");
yield showTooltipAndVerify(RequestsMenu.tooltip, RequestsMenu.items[6]);
yield showTooltipAndVerify(RequestsMenu.items[6]);
yield teardown(monitor);
finish();
@ -45,7 +45,10 @@ add_task(function* test() {
* Show a tooltip on the {requestItem} and verify that it was displayed
* with the expected content.
*/
function* showTooltipAndVerify(tooltip, requestItem) {
function* showTooltipAndVerify(requestItem) {
let { tooltip } = requestItem.attachment;
ok(tooltip, "There should be a tooltip instance for the image request.");
let anchor = $(".requests-menu-file", requestItem.target);
yield showTooltipOn(tooltip, anchor);

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

@ -13,11 +13,11 @@ const URL = EXAMPLE_URL.replace("http:", "https:");
const TEST_URL = URL + "service-workers/status-codes.html";
var test = Task.async(function* () {
let [, debuggee, monitor] = yield initNetMonitor(TEST_URL, null, true);
let [tab, debuggee, monitor] = yield initNetMonitor(TEST_URL, null, true);
info("Starting test... ");
let { NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
let { document, L10N, NetMonitorView } = monitor.panelWin;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
const REQUEST_DATA = [
{
@ -29,8 +29,7 @@ var test = Task.async(function* () {
displayedStatus: "service worker",
type: "plain",
fullMimeType: "text/plain; charset=UTF-8"
},
stackFunctions: ["doXHR", "performRequests"]
}
},
];
@ -45,27 +44,12 @@ var test = Task.async(function* () {
for (let request of REQUEST_DATA) {
let item = RequestsMenu.getItemAtIndex(index);
info(`Verifying request #${index}`);
info("Verifying request #" + index);
yield verifyRequestItemTarget(item, request.method, request.uri, request.details);
let { stacktrace } = item.attachment.cause;
let stackLen = stacktrace ? stacktrace.length : 0;
ok(stacktrace, `Request #${index} has a stacktrace`);
ok(stackLen >= request.stackFunctions.length,
`Request #${index} has a stacktrace with enough (${stackLen}) items`);
request.stackFunctions.forEach((functionName, j) => {
is(stacktrace[j].functionName, functionName,
`Request #${index} has the correct function at position #${j} on the stack`);
});
index++;
}
info("Unregistering the service worker...");
yield debuggee.unregisterServiceWorker();
yield teardown(monitor);
finish();
});

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

@ -50,10 +50,6 @@ 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/devtools/client/netmonitor/test/sjs_cors-test-server.sjs";
const HSTS_SJS = EXAMPLE_URL + "sjs_hsts-test-server.sjs";
const HSTS_BASE_URL = EXAMPLE_URL;
const HSTS_PAGE_URL = CUSTOM_GET_URL;
const TEST_IMAGE = EXAMPLE_URL + "test-image.png";
const TEST_IMAGE_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
@ -288,7 +284,7 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
info("Widget index of item: " + widgetIndex);
info("Visible index of item: " + visibleIndex);
let { fuzzyUrl, status, statusText, cause, type, fullMimeType,
let { fuzzyUrl, status, statusText, type, fullMimeType,
transferred, size, time, displayedStatus } = aData;
let { attachment, target } = aRequestItem;
@ -340,15 +336,6 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
is(codeValue, status, "The displayed status code is correct.");
is(tooltip, status + " " + statusText, "The tooltip status is correct.");
}
if (cause !== undefined) {
let causeLabel = target.querySelector(".requests-menu-cause-label");
let value = causeLabel.getAttribute("value");
let tooltip = causeLabel.getAttribute("tooltiptext");
info("Displayed cause: " + value);
info("Tooltip cause: " + tooltip);
is(value, cause.type, "The displayed cause is correct.");
is(tooltip, cause.loadingDocumentUri, "The tooltip cause is correct.")
}
if (type !== undefined) {
let value = target.querySelector(".requests-menu-type").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-type").getAttribute("tooltiptext");

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

@ -1,33 +0,0 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>Network Monitor test page</title>
<link rel="stylesheet" type="text/css" href="stylesheet_request" />
</head>
<body>
<p>Request cause test</p>
<img src="img_request" />
<script type="text/javascript">
function performXhrRequest() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "xhr_request", true);
xhr.send();
}
function performBeaconRequest() {
navigator.sendBeacon("beacon_request");
}
performXhrRequest();
performBeaconRequest();
</script>
</body>
</html>

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

@ -2,14 +2,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
self.addEventListener("activate", event => {
// start controlling the already loaded page
event.waitUntil(self.clients.claim());
});
self.addEventListener("fetch", event => {
addEventListener("fetch", function (event) {
let response = new Response("Service worker response");
event.respondWith(response);
});

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

@ -15,44 +15,24 @@
<p>Status codes test</p>
<script type="text/javascript">
let swRegistration;
function registerServiceWorker() {
let sw = navigator.serviceWorker;
return sw.register("status-codes-service-worker.js")
.then(registration => {
swRegistration = registration;
console.log("Registered, scope is:", registration.scope);
return sw.ready;
}).then(() => {
// wait until the page is controlled
return new Promise(resolve => {
if (sw.controller) {
resolve();
} else {
sw.addEventListener('controllerchange', function onControllerChange() {
sw.removeEventListener('controllerchange', onControllerChange);
resolve();
});
}
});
}).catch(err => {
console.error("Registration failed");
});
function get(url) {
return new Promise(done => {
let iframe = document.createElement("iframe");
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.contentWindow.onload = done;
});
}
function unregisterServiceWorker() {
return swRegistration.unregister();
function registerServiceWorker() {
return navigator.serviceWorker.register("status-codes-service-worker.js")
.then(() => navigator.serviceWorker.ready);
}
function performRequests() {
return new Promise(function doXHR(done) {
let xhr = new XMLHttpRequest();
xhr.open("GET", "test/200", true);
xhr.onreadystatechange = done;
xhr.send(null);
});
return get("test/200");
}
</script>
</body>

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

@ -1,22 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function handleRequest(request, response) {
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
if (request.queryString === "reset") {
// Reset the HSTS policy, prevent influencing other tests
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Strict-Transport-Security", "max-age=0");
response.write("Resetting HSTS");
} else if (request.scheme === "http") {
response.setStatusLine(request.httpVersion, 302, "Found");
response.setHeader("Location", "https://" + request.host + request.path);
} else {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Strict-Transport-Security", "max-age=100");
response.write("Page was accessed over HTTPS!");
}
}

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

@ -246,25 +246,6 @@
width: 8vw;
}
.requests-menu-cause {
max-width: 8em;
width: 8vw;
}
.requests-menu-cause-stack {
background-color: var(--theme-body-color-alt);
color: var(--theme-body-background);
font-size: 8px;
font-weight: bold;
line-height: 10px;
border-radius: 3px;
padding: 0 2px;
margin: 0;
margin-inline-end: 3px;
-moz-user-select: none;
cursor: pointer;
}
.requests-menu-transferred {
max-width: 8em;
text-align: center;
@ -695,40 +676,6 @@
color: var(--theme-selection-color);
}
/* Requests menu stacktrace tooltip */
.requests-menu-stack-trace {
max-height: 400px;
width: 586px;
overflow-y: auto;
}
.requests-menu-stack-frame {
color: var(--theme-body-color-alt);
cursor: pointer;
display: flex;
}
.requests-menu-stack-frame:hover {
background-color: var(--theme-selection-background-semitransparent);
}
.requests-menu-stack-frame-function-name {
color: var(--theme-highlight-blue);
cursor: inherit;
flex-grow: 1;
}
.requests-menu-stack-frame-file-name {
cursor: inherit;
margin-inline-end: 0;
}
.requests-menu-stack-frame-line {
color: var(--theme-highlight-orange);
cursor: inherit;
margin-inline-start: 0;
}
/* Performance analysis buttons */
#requests-menu-network-summary-button {

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

@ -18,7 +18,6 @@ const ErrorDocs = require("devtools/server/actors/errordocs");
loader.lazyRequireGetter(this, "NetworkMonitor", "devtools/shared/webconsole/network-monitor", true);
loader.lazyRequireGetter(this, "NetworkMonitorChild", "devtools/shared/webconsole/network-monitor", true);
loader.lazyRequireGetter(this, "ConsoleProgressListener", "devtools/shared/webconsole/network-monitor", true);
loader.lazyRequireGetter(this, "StackTraceCollector", "devtools/shared/webconsole/network-monitor", true);
loader.lazyRequireGetter(this, "events", "sdk/event/core");
loader.lazyRequireGetter(this, "ServerLoggingListener", "devtools/shared/webconsole/server-logger", true);
loader.lazyRequireGetter(this, "JSPropertyProvider", "devtools/shared/webconsole/js-property-provider", true);
@ -599,12 +598,6 @@ WebConsoleActor.prototype =
break;
case "NetworkActivity":
if (!this.networkMonitor) {
// Create a StackTraceCollector that's going to be shared both by the
// NetworkMonitorChild (getting messages about requests from parent) and
// by the NetworkMonitor that directly watches service workers requests.
this.stackTraceCollector = new StackTraceCollector({ window, appId });
this.stackTraceCollector.init();
if (appId || messageManager) {
// Start a network monitor in the parent process to listen to
// most requests than happen in parent
@ -613,10 +606,12 @@ WebConsoleActor.prototype =
this.parentActor.actorID, this);
this.networkMonitor.init();
// Spawn also one in the child to listen to service workers
this.networkMonitorChild = new NetworkMonitor({ window }, this);
this.networkMonitorChild = new NetworkMonitor({ window: window },
this);
this.networkMonitorChild.init();
} else {
this.networkMonitor = new NetworkMonitor({ window }, this);
}
else {
this.networkMonitor = new NetworkMonitor({ window: window }, this);
this.networkMonitor.init();
}
}
@ -705,10 +700,6 @@ WebConsoleActor.prototype =
this.networkMonitorChild.destroy();
this.networkMonitorChild = null;
}
if (this.stackTraceCollector) {
this.stackTraceCollector.destroy();
this.stackTraceCollector = null;
}
stoppedListeners.push(listener);
break;
case "FileActivity":
@ -1837,7 +1828,6 @@ NetworkEventActor.prototype =
url: this._request.url,
method: this._request.method,
isXHR: this._isXHR,
cause: this._cause,
fromCache: this._fromCache,
fromServiceWorker: this._fromServiceWorker,
private: this._private,
@ -1883,7 +1873,6 @@ NetworkEventActor.prototype =
{
this._startedDateTime = aNetworkEvent.startedDateTime;
this._isXHR = aNetworkEvent.isXHR;
this._cause = aNetworkEvent.cause;
this._fromCache = aNetworkEvent.fromCache;
this._fromServiceWorker = aNetworkEvent.fromServiceWorker;

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

@ -100,7 +100,6 @@ WebConsoleClient.prototype = {
method: actor.method,
},
isXHR: actor.isXHR,
cause: actor.cause,
response: {},
timings: {},
// track the list of network event updates

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

@ -6,7 +6,7 @@
"use strict";
const {Cc, Ci, Cm, Cu, Cr, components} = require("chrome");
const {Cc, Ci, Cu, Cr} = require("chrome");
const Services = require("Services");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -36,236 +36,6 @@ const HTTP_TEMPORARY_REDIRECT = 307;
// The maximum number of bytes a NetworkResponseListener can hold: 1 MB
const RESPONSE_BODY_LIMIT = 1048576;
/**
* Check if a given network request should be logged by a network monitor
* based on the specified filters.
*
* @param nsIHttpChannel channel
* Request to check.
* @param filters
* NetworkMonitor filters to match against.
* @return boolean
* True if the network request should be logged, false otherwise.
*/
function matchRequest(channel, filters) {
// Log everything if no filter is specified
if (!filters.topFrame && !filters.window && !filters.appId) {
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 DevToolsUtils.testing check. We will move to a better way to serve
// its needs in bug 1167188, where this check should be removed.
if (!DevToolsUtils.testing && channel.loadInfo &&
channel.loadInfo.loadingDocument === null &&
channel.loadInfo.loadingPrincipal ===
Services.scriptSecurityManager.getSystemPrincipal()) {
return false;
}
if (filters.window) {
// Since frames support, this.window may not be the top level content
// frame, so that we can't only compare with win.top.
let win = NetworkHelper.getWindowForRequest(channel);
while (win) {
if (win == filters.window) {
return true;
}
if (win.parent == win) {
break;
}
win = win.parent;
}
}
if (filters.topFrame) {
let topFrame = NetworkHelper.getTopFrameForRequest(channel);
if (topFrame && topFrame === filters.topFrame) {
return true;
}
}
if (filters.appId) {
let appId = NetworkHelper.getAppIdForRequest(channel);
if (appId && appId == filters.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 (channel.loadInfo &&
channel.loadInfo.externalContentPolicyType ==
Ci.nsIContentPolicy.TYPE_BEACON) {
let nonE10sMatch = filters.window &&
channel.loadInfo.loadingDocument === filters.window.document;
const loadingPrincipal = channel.loadInfo.loadingPrincipal;
let e10sMatch = filters.topFrame &&
filters.topFrame.contentPrincipal &&
filters.topFrame.contentPrincipal.equals(loadingPrincipal) &&
filters.topFrame.contentPrincipal.URI.spec == channel.referrer.spec;
let b2gMatch = filters.appId && loadingPrincipal.appId === filters.appId;
if (nonE10sMatch || e10sMatch || b2gMatch) {
return true;
}
}
return false;
}
/**
* This is a nsIChannelEventSink implementation that monitors channel redirects and
* informs the registered StackTraceCollector about the old and new channels.
*/
const SINK_CLASS_DESCRIPTION = "NetworkMonitor Channel Event Sink";
const SINK_CLASS_ID = components.ID("{e89fa076-c845-48a8-8c45-2604729eba1d}");
const SINK_CONTRACT_ID = "@mozilla.org/network/monitor/channeleventsink;1";
const SINK_CATEGORY_NAME = "net-channel-event-sinks";
function ChannelEventSink() {
this.wrappedJSObject = this;
this.collectors = new Set();
}
ChannelEventSink.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannelEventSink]),
registerCollector(collector) {
this.collectors.add(collector);
},
unregisterCollector(collector) {
this.collectors.delete(collector);
if (this.collectors.size == 0) {
ChannelEventSinkFactory.unregister();
}
},
asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
for (let collector of this.collectors) {
try {
collector.onChannelRedirect(oldChannel, newChannel, flags);
} catch (ex) {
console.error("StackTraceCollector.onChannelRedirect threw an exception", ex);
}
}
callback.onRedirectVerifyCallback(Cr.NS_OK);
}
};
const ChannelEventSinkFactory = XPCOMUtils.generateSingletonFactory(ChannelEventSink);
ChannelEventSinkFactory.register = function () {
const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
if (registrar.isCIDRegistered(SINK_CLASS_ID)) {
return;
}
registrar.registerFactory(SINK_CLASS_ID,
SINK_CLASS_DESCRIPTION,
SINK_CONTRACT_ID,
ChannelEventSinkFactory);
XPCOMUtils.categoryManager.addCategoryEntry(SINK_CATEGORY_NAME, SINK_CONTRACT_ID,
SINK_CONTRACT_ID, false, true);
};
ChannelEventSinkFactory.unregister = function () {
const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
registrar.unregisterFactory(SINK_CLASS_ID, ChannelEventSinkFactory);
XPCOMUtils.categoryManager.deleteCategoryEntry(SINK_CATEGORY_NAME, SINK_CONTRACT_ID,
false);
};
ChannelEventSinkFactory.getService = function () {
// Make sure the ChannelEventSink service is registered before accessing it
ChannelEventSinkFactory.register();
return Cc[SINK_CONTRACT_ID].getService(Ci.nsIChannelEventSink).wrappedJSObject;
};
function StackTraceCollector(filters) {
this.filters = filters;
this.stacktracesById = new Map();
}
StackTraceCollector.prototype = {
init() {
Services.obs.addObserver(this, "http-on-opening-request", false);
ChannelEventSinkFactory.getService().registerCollector(this);
},
destroy() {
Services.obs.removeObserver(this, "http-on-opening-request");
ChannelEventSinkFactory.getService().unregisterCollector(this);
},
_saveStackTrace(channel, stacktrace) {
this.stacktracesById.set(channel.channelId, stacktrace);
},
observe(subject) {
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
if (!matchRequest(channel, this.filters)) {
return;
}
// Convert the nsIStackFrame XPCOM objects to a nice JSON that can be
// passed around through message managers etc.
let frame = components.stack;
let stacktrace = [];
if (frame && frame.caller) {
frame = frame.caller;
while (frame) {
stacktrace.push({
filename: frame.filename,
lineNumber: frame.lineNumber,
columnNumber: frame.columnNumber,
functionName: frame.name
});
if (frame.asyncCaller) {
frame = frame.asyncCaller;
} else {
frame = frame.caller;
}
}
}
this._saveStackTrace(channel, stacktrace);
},
onChannelRedirect(oldChannel, newChannel, flags) {
// We can be called with any nsIChannel, but are interested only in HTTP channels
try {
oldChannel.QueryInterface(Ci.nsIHttpChannel);
newChannel.QueryInterface(Ci.nsIHttpChannel);
} catch (ex) {
return;
}
let oldId = oldChannel.channelId;
let stacktrace = this.stacktracesById.get(oldId);
if (stacktrace) {
this.stacktracesById.delete(oldId);
this._saveStackTrace(newChannel, stacktrace);
}
},
getStackTrace(channelId) {
let trace = this.stacktracesById.get(channelId);
this.stacktracesById.delete(channelId);
return trace;
}
};
exports.StackTraceCollector = StackTraceCollector;
/**
* The network response listener implements the nsIStreamListener and
* nsIRequestObserver interfaces. This is used within the NetworkMonitor feature
@ -293,6 +63,7 @@ function NetworkResponseListener(owner, httpActivity) {
this._wrappedNotificationCallbacks = channel.notificationCallbacks;
channel.notificationCallbacks = this;
}
exports.NetworkResponseListener = NetworkResponseListener;
NetworkResponseListener.prototype = {
QueryInterface:
@ -691,7 +462,7 @@ NetworkResponseListener.prototype = {
* @param object filters
* Object with the filters to use for network requests:
* - window (nsIDOMWindow): filter network requests by the associated
* window object.
* window object.
* - appId (number): filter requests by the appId.
* - topFrame (nsIDOMElement): filter requests by their topFrameElement.
* Filters are optional. If any of these filters match the request is
@ -700,17 +471,23 @@ NetworkResponseListener.prototype = {
* @param object owner
* The network monitor owner. This object needs to hold:
* - onNetworkEvent(requestInfo, channel, networkMonitor).
* This method is invoked once for every new network request and it is
* given the following arguments: the initial network request
* information, and the channel. The third argument is the NetworkMonitor
* instance. onNetworkEvent() must return an object which holds several add*()
* methods which are used to add further network request/response
* information.
* - stackTraceCollector If the owner has this optional property, it will
* be used as a StackTraceCollector by the NetworkMonitor.
* This method is invoked once for every new network request and it is
* given the following arguments: the initial network request
* information, and the channel. The third argument is the NetworkMonitor
* instance.
* onNetworkEvent() must return an object which holds several add*()
* methods which are used to add further network request/response
* information.
*/
function NetworkMonitor(filters, owner) {
this.filters = filters;
if (filters) {
this.window = filters.window;
this.appId = filters.appId;
this.topFrame = filters.topFrame;
}
if (!this.window && !this.appId && !this.topFrame) {
this._logEverything = true;
}
this.owner = owner;
this.openRequests = {};
this.openResponses = {};
@ -718,11 +495,13 @@ function NetworkMonitor(filters, owner) {
DevToolsUtils.makeInfallible(this._httpResponseExaminer).bind(this);
this._serviceWorkerRequest = this._serviceWorkerRequest.bind(this);
}
exports.NetworkMonitor = NetworkMonitor;
NetworkMonitor.prototype = {
filters: null,
_logEverything: false,
window: null,
appId: null,
topFrame: null,
httpTransactionCodes: {
0x5001: "REQUEST_HEADER",
@ -787,7 +566,7 @@ NetworkMonitor.prototype = {
_serviceWorkerRequest: function (subject, topic, data) {
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
if (!matchRequest(channel, this.filters)) {
if (!this._matchRequest(channel)) {
return;
}
@ -823,7 +602,7 @@ NetworkMonitor.prototype = {
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
if (!matchRequest(channel, this.filters)) {
if (!this._matchRequest(channel)) {
return;
}
@ -977,6 +756,84 @@ NetworkMonitor.prototype = {
}
}),
/**
* Check if a given network request should be logged by this network monitor
* instance based on the current filters.
*
* @private
* @param nsIHttpChannel channel
* Request to check.
* @return boolean
* True if the network request should be logged, false otherwise.
*/
_matchRequest: function (channel) {
if (this._logEverything) {
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 DevToolsUtils.testing check. We will move to a better way to serve
// its needs in bug 1167188, where this check should be removed.
if (!DevToolsUtils.testing && channel.loadInfo &&
channel.loadInfo.loadingDocument === null &&
channel.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.
let win = NetworkHelper.getWindowForRequest(channel);
while (win) {
if (win == this.window) {
return true;
}
if (win.parent == win) {
break;
}
win = win.parent;
}
}
if (this.topFrame) {
let topFrame = NetworkHelper.getTopFrameForRequest(channel);
if (topFrame && topFrame === this.topFrame) {
return true;
}
}
if (this.appId) {
let appId = NetworkHelper.getAppIdForRequest(channel);
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 (channel.loadInfo &&
channel.loadInfo.externalContentPolicyType ==
Ci.nsIContentPolicy.TYPE_BEACON) {
let nonE10sMatch = this.window &&
channel.loadInfo.loadingDocument === this.window.document;
const loadingPrincipal = channel.loadInfo.loadingPrincipal;
let e10sMatch = this.topFrame &&
this.topFrame.contentPrincipal &&
this.topFrame.contentPrincipal.equals(loadingPrincipal) &&
this.topFrame.contentPrincipal.URI.spec == channel.referrer.spec;
let b2gMatch = this.appId && loadingPrincipal.appId === this.appId;
if (nonE10sMatch || e10sMatch || b2gMatch) {
return true;
}
}
return false;
},
/**
*
*/
@ -1000,7 +857,6 @@ NetworkMonitor.prototype = {
let event = {};
event.method = channel.requestMethod;
event.channelId = channel.channelId;
event.url = channel.URI.spec;
event.private = httpActivity.private;
event.headersSize = 0;
@ -1015,26 +871,12 @@ NetworkMonitor.prototype = {
event.headersSize = extraStringData.length;
}
// Determine the cause and if this is an XHR request.
let causeType = channel.loadInfo.externalContentPolicyType;
let loadingPrincipal = channel.loadInfo.loadingPrincipal;
let causeUri = loadingPrincipal ? loadingPrincipal.URI : null;
let stacktrace;
// If this is the parent process, there is no stackTraceCollector - the stack
// trace will be added in NetworkMonitorChild._onNewEvent.
if (this.owner.stackTraceCollector) {
stacktrace = this.owner.stackTraceCollector.getStackTrace(event.channelId);
}
event.cause = {
type: causeType,
loadingDocumentUri: causeUri ? causeUri.spec : null,
stacktrace
};
// Determine if this is an XHR request.
httpActivity.isXHR = event.isXHR =
(causeType === Ci.nsIContentPolicy.TYPE_XMLHTTPREQUEST ||
causeType === Ci.nsIContentPolicy.TYPE_FETCH);
(channel.loadInfo.externalContentPolicyType ===
Ci.nsIContentPolicy.TYPE_XMLHTTPREQUEST ||
channel.loadInfo.externalContentPolicyType ===
Ci.nsIContentPolicy.TYPE_FETCH);
// Determine the HTTP version.
let httpVersionMaj = {};
@ -1090,11 +932,12 @@ NetworkMonitor.prototype = {
* @return void
*/
_onRequestHeader: function (channel, timestamp, extraStringData) {
if (!matchRequest(channel, this.filters)) {
if (!this._matchRequest(channel)) {
return;
}
this._createNetworkEvent(channel, { timestamp, extraStringData });
this._createNetworkEvent(channel, { timestamp: timestamp,
extraStringData: extraStringData });
},
/**
@ -1384,7 +1227,8 @@ NetworkMonitor.prototype = {
this.openRequests = {};
this.openResponses = {};
this.owner = null;
this.filters = null;
this.window = null;
this.topFrame = null;
},
};
@ -1420,7 +1264,6 @@ function NetworkMonitorChild(appId, messageManager, connID, owner) {
this._onUpdateEvent = this._onUpdateEvent.bind(this);
this._netEvents = new Map();
}
exports.NetworkMonitorChild = NetworkMonitorChild;
NetworkMonitorChild.prototype = {
@ -1437,6 +1280,7 @@ NetworkMonitorChild.prototype = {
this._saveRequestAndResponseBodies = val;
this._messageManager.sendAsyncMessage("debug:netmonitor:" + this.connID, {
appId: this.appId,
action: "setPreferences",
preferences: {
saveRequestAndResponseBodies: this._saveRequestAndResponseBodies,
@ -1458,13 +1302,6 @@ NetworkMonitorChild.prototype = {
_onNewEvent: DevToolsUtils.makeInfallible(function _onNewEvent(msg) {
let {id, event} = msg.data;
// Try to add stack trace to the event data received from parent
if (this.owner.stackTraceCollector) {
event.cause.stacktrace =
this.owner.stackTraceCollector.getStackTrace(event.channelId);
}
let actor = this.owner.onNetworkEvent(event);
this._netEvents.set(id, Cu.getWeakReference(actor));
}),
@ -1611,12 +1448,11 @@ NetworkMonitorManager.prototype = {
* Message from the content.
*/
onNetMonitorMessage: DevToolsUtils.makeInfallible(function (msg) {
let {action} = msg.json;
let { action, appId } = msg.json;
// Pipe network monitor data from parent to child via the message manager.
switch (action) {
case "start":
if (!this.netMonitor) {
let {appId} = msg.json;
this.netMonitor = new NetworkMonitor({
topFrame: this.frame,
appId: appId,