bug 1158264 - Flag requests coming from service workers. r=vporof

This commit is contained in:
Alexandre Poirot
2016-01-14 05:53:00 -08:00
parent 62d2ea9ddd
commit 33bb7367a8
12 changed files with 233 additions and 22 deletions

View File

@@ -74,6 +74,16 @@ netmonitor.security.hostHeader=Host %S:
# Organization: <Not Available> # Organization: <Not Available>
netmonitor.security.notAvailable=<Not Available> netmonitor.security.notAvailable=<Not Available>
# LOCALIZATION NOTE (netmonitor.status.cached):
# This string is used as tooltip text over the status icon when a request is
# served from cached.
netmonitor.status.cached=cached
# LOCALIZATION NOTE (netmonitor.status.serviceWorker):
# This string is used as tooltip text over the status icon when a request is
# served from a service worker.
netmonitor.status.serviceWorker=service worker
# LOCALIZATION NOTE (collapseDetailsPane): This is the tooltip for the button # LOCALIZATION NOTE (collapseDetailsPane): This is the tooltip for the button
# that collapses the network details pane in the UI. # that collapses the network details pane in the UI.
collapseDetailsPane=Hide request details collapseDetailsPane=Hide request details
@@ -184,6 +194,11 @@ networkMenu.sizeUnavailable=—
# cached. # cached.
networkMenu.sizeCached=cached networkMenu.sizeCached=cached
# LOCALIZATION NOTE (networkMenu.sizeServiceWorker): This is the label displayed
# in the network menu specifying the transferred of a request computed
# by a service worker.
networkMenu.sizeServiceWorker=service worker
# LOCALIZATION NOTE (networkMenu.totalMS): This is the label displayed # LOCALIZATION NOTE (networkMenu.totalMS): This is the label displayed
# in the network menu specifying the time for a request to finish (in milliseconds). # in the network menu specifying the time for a request to finish (in milliseconds).
networkMenu.totalMS=→ %S ms networkMenu.totalMS=→ %S ms

View File

@@ -606,10 +606,10 @@ NetworkEventsHandler.prototype = {
* The network request information. * The network request information.
*/ */
_onNetworkEvent: function(type, networkInfo) { _onNetworkEvent: function(type, networkInfo) {
let { actor, startedDateTime, request: { method, url }, isXHR, fromCache } = networkInfo; let { actor, startedDateTime, request: { method, url }, isXHR, fromCache, fromServiceWorker } = networkInfo;
NetMonitorView.RequestsMenu.addRequest( NetMonitorView.RequestsMenu.addRequest(
actor, startedDateTime, method, url, isXHR, fromCache actor, startedDateTime, method, url, isXHR, fromCache, fromServiceWorker
); );
window.emit(EVENTS.NETWORK_EVENT, actor); window.emit(EVENTS.NETWORK_EVENT, actor);
}, },

View File

@@ -538,9 +538,11 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
* True if this request was initiated via XHR. * True if this request was initiated via XHR.
* @param boolean aFromCache * @param boolean aFromCache
* Indicates if the result came from the browser cache * Indicates if the result came from the browser cache
* @param boolean aFromServiceWorker
* Indicates if the request has been intercepted by a Service Worker
*/ */
addRequest: function(aId, aStartedDateTime, aMethod, aUrl, aIsXHR, aFromCache) { addRequest: function(aId, aStartedDateTime, aMethod, aUrl, aIsXHR, aFromCache, aFromServiceWorker) {
this._addQueue.push([aId, aStartedDateTime, aMethod, aUrl, aIsXHR, aFromCache]); this._addQueue.push([aId, aStartedDateTime, aMethod, aUrl, aIsXHR, aFromCache, aFromServiceWorker]);
// Lazy updating is disabled in some tests. // Lazy updating is disabled in some tests.
if (!this.lazyUpdate) { if (!this.lazyUpdate) {
@@ -1349,7 +1351,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
let widget = NetMonitorView.RequestsMenu.widget; let widget = NetMonitorView.RequestsMenu.widget;
let isScrolledToBottom = widget.isScrolledToBottom(); let isScrolledToBottom = widget.isScrolledToBottom();
for (let [id, startedDateTime, method, url, isXHR, fromCache] of this._addQueue) { for (let [id, startedDateTime, method, url, isXHR, fromCache, fromServiceWorker] of this._addQueue) {
// Convert the received date/time string to a unix timestamp. // Convert the received date/time string to a unix timestamp.
let unixTime = Date.parse(startedDateTime); let unixTime = Date.parse(startedDateTime);
@@ -1368,7 +1370,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
method: method, method: method,
url: url, url: url,
isXHR: isXHR, isXHR: isXHR,
fromCache: fromCache fromCache: fromCache,
fromServiceWorker: fromServiceWorker
} }
}); });
@@ -1470,7 +1473,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
requestItem.attachment.status = value; requestItem.attachment.status = value;
this.updateMenuView(requestItem, key, { this.updateMenuView(requestItem, key, {
status: value, status: value,
cached: requestItem.attachment.fromCache cached: requestItem.attachment.fromCache,
serviceWorker: requestItem.attachment.fromServiceWorker
}); });
break; break;
case "statusText": case "statusText":
@@ -1479,6 +1483,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
requestItem.attachment.statusText); requestItem.attachment.statusText);
if(requestItem.attachment.fromCache) { if(requestItem.attachment.fromCache) {
text += " (cached)"; text += " (cached)";
} else if(requestItem.attachment.fromServiceWorker) {
text += " (service worker)";
} }
this.updateMenuView(requestItem, key, text); this.updateMenuView(requestItem, key, text);
@@ -1495,6 +1501,10 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
requestItem.attachment.transferredSize = 0; requestItem.attachment.transferredSize = 0;
this.updateMenuView(requestItem, key, 'cached'); this.updateMenuView(requestItem, key, 'cached');
} }
else if(requestItem.attachment.fromServiceWorker) {
requestItem.attachment.transferredSize = 0;
this.updateMenuView(requestItem, key, 'service worker');
}
else { else {
requestItem.attachment.transferredSize = value; requestItem.attachment.transferredSize = value;
this.updateMenuView(requestItem, key, value); this.updateMenuView(requestItem, key, value);
@@ -1523,7 +1533,9 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
case "eventTimings": case "eventTimings":
requestItem.attachment.eventTimings = value; requestItem.attachment.eventTimings = value;
this._createWaterfallView( this._createWaterfallView(
requestItem, value.timings, requestItem.attachment.fromCache requestItem, value.timings,
requestItem.attachment.fromCache ||
requestItem.attachment.fromServiceWorker
); );
break; break;
} }
@@ -1682,7 +1694,16 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
} }
case "status": { case "status": {
let node = $(".requests-menu-status-icon", target); let node = $(".requests-menu-status-icon", target);
node.setAttribute("code", aValue.cached ? "cached" : aValue.status); let code;
if (aValue.cached) {
code = L10N.getStr("netmonitor.status.cached");
code = "cached";
} else if (aValue.serviceWorker) {
code = L10N.getStr("netmonitor.status.serviceWorker");
} else {
code = aValue.status;
}
node.setAttribute("code", code);
let codeNode = $(".requests-menu-status-code", target); let codeNode = $(".requests-menu-status-code", target);
codeNode.setAttribute("value", aValue.status); codeNode.setAttribute("value", aValue.status);
break; break;
@@ -1712,6 +1733,10 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
text = L10N.getStr("networkMenu.sizeCached"); text = L10N.getStr("networkMenu.sizeCached");
node.classList.add('theme-comment'); node.classList.add('theme-comment');
} }
else if(aValue === "service worker") {
text = L10N.getStr("networkMenu.sizeServiceWorker");
node.classList.add('theme-comment');
}
else { else {
let kb = aValue / 1024; let kb = aValue / 1024;
let size = L10N.numberWithDecimals(kb, CONTENT_SIZE_DECIMALS); let size = L10N.numberWithDecimals(kb, CONTENT_SIZE_DECIMALS);
@@ -1763,7 +1788,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
* @param object aTimings * @param object aTimings
* An object containing timing information. * An object containing timing information.
* @param boolean aFromCache * @param boolean aFromCache
* Indicates if the result came from the browser cache * Indicates if the result came from the browser cache or a service worker
*/ */
_createWaterfallView: function(aItem, aTimings, aFromCache) { _createWaterfallView: function(aItem, aTimings, aFromCache) {
let { target, attachment } = aItem; let { target, attachment } = aItem;
@@ -2690,7 +2715,15 @@ NetworkDetailsView.prototype = {
} }
if (aData.status) { if (aData.status) {
$("#headers-summary-status-circle").setAttribute("code", aData.fromCache ? "cached" : aData.status); let code;
if (aData.fromCache) {
code = L10N.getStr("netmonitor.status.cached");
} else if (aData.fromServiceWorker) {
code = L10N.getStr("netmonitor.status.serviceWorker");
} else {
code = aData.status;
}
$("#headers-summary-status-circle").setAttribute("code", code);
$("#headers-summary-status-value").setAttribute("value", aData.status + " " + aData.statusText); $("#headers-summary-status-value").setAttribute("value", aData.status + " " + aData.statusText);
$("#headers-summary-status").removeAttribute("hidden"); $("#headers-summary-status").removeAttribute("hidden");
} else { } else {

View File

@@ -36,6 +36,8 @@ support-files =
sjs_sorting-test-server.sjs sjs_sorting-test-server.sjs
sjs_status-codes-test-server.sjs sjs_status-codes-test-server.sjs
test-image.png test-image.png
service-workers/status-codes.html
service-workers/status-codes-service-worker.js
[browser_net_aaa_leaktest.js] [browser_net_aaa_leaktest.js]
[browser_net_accessibility-01.js] [browser_net_accessibility-01.js]
@@ -43,6 +45,7 @@ support-files =
[browser_net_api-calls.js] [browser_net_api-calls.js]
[browser_net_autoscroll.js] [browser_net_autoscroll.js]
[browser_net_cached-status.js] [browser_net_cached-status.js]
[browser_net_service-worker-status.js]
[browser_net_charts-01.js] [browser_net_charts-01.js]
[browser_net_charts-02.js] [browser_net_charts-02.js]
[browser_net_charts-03.js] [browser_net_charts-03.js]

View File

@@ -61,7 +61,7 @@ var test = Task.async(function*() {
details: { details: {
status: 200, status: 200,
statusText: "OK (cached)", statusText: "OK (cached)",
fromCache: true, displayedStatus : "cached",
type: "plain", type: "plain",
fullMimeType: "text/plain; charset=utf-8" fullMimeType: "text/plain; charset=utf-8"
} }
@@ -72,7 +72,7 @@ var test = Task.async(function*() {
details: { details: {
status: 301, status: 301,
statusText: "Moved Permanently (cached)", statusText: "Moved Permanently (cached)",
fromCache: true, displayedStatus: "cached",
type: "html", type: "html",
fullMimeType: "text/html; charset=utf-8" fullMimeType: "text/html; charset=utf-8"
} }

View File

@@ -0,0 +1,55 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if requests intercepted by service workers have the correct status code
*/
// Service workers only work on https
const URL = EXAMPLE_URL.replace("http:", "https:");
const TEST_URL = URL + "service-workers/status-codes.html";
var test = Task.async(function*() {
let [tab, debuggee, monitor] = yield initNetMonitor(TEST_URL, null, true);
info("Starting test... ");
let { document, L10N, NetMonitorView } = monitor.panelWin;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
const REQUEST_DATA = [
{
method: 'GET',
uri: URL + "service-workers/test/200",
details: {
status: 200,
statusText: 'OK (service worker)',
displayedStatus: 'service worker',
type: "plain",
fullMimeType: "text/plain; charset=UTF-8"
}
},
];
info("Registering the service worker...");
yield debuggee.registerServiceWorker();
info("Performing requests...");
debuggee.performRequests();
yield waitForNetworkEvents(monitor, REQUEST_DATA.length);
let index = 0;
for (let request of REQUEST_DATA) {
let item = RequestsMenu.getItemAtIndex(index);
info("Verifying request #" + index);
yield verifyRequestItemTarget(item, request.method, request.uri, request.details);
index++;
}
yield teardown(monitor);
finish();
});

View File

@@ -283,7 +283,7 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
info("Visible index of item: " + visibleIndex); info("Visible index of item: " + visibleIndex);
let { fuzzyUrl, status, statusText, type, fullMimeType, let { fuzzyUrl, status, statusText, type, fullMimeType,
transferred, size, time, fromCache } = aData; transferred, size, time, displayedStatus } = aData;
let { attachment, target } = aRequestItem let { attachment, target } = aRequestItem
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL); let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
@@ -330,7 +330,7 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
info("Displayed status: " + value); info("Displayed status: " + value);
info("Displayed code: " + codeValue); info("Displayed code: " + codeValue);
info("Tooltip status: " + tooltip); info("Tooltip status: " + tooltip);
is(value, fromCache ? "cached" : status, "The displayed status is correct."); is(value, displayedStatus ? displayedStatus : status, "The displayed status is correct.");
is(codeValue, status, "The displayed status code is correct."); is(codeValue, status, "The displayed status code is correct.");
is(tooltip, status + " " + statusText, "The tooltip status is correct."); is(tooltip, status + " " + statusText, "The tooltip status is correct.");
} }

View File

@@ -0,0 +1,8 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
addEventListener("fetch", function(event) {
let response = new Response("Service worker response");
event.respondWith(response);
});

View File

@@ -0,0 +1,39 @@
<!-- 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>
</head>
<body>
<p>Status codes test</p>
<script type="text/javascript">
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 registerServiceWorker() {
return navigator.serviceWorker.register("status-codes-service-worker.js")
.then(() => navigator.serviceWorker.ready);
}
function performRequests() {
return get("test/200");
}
</script>
</body>
</html>

View File

@@ -283,6 +283,11 @@ WebConsoleActor.prototype =
*/ */
networkMonitor: null, networkMonitor: null,
/**
* The NetworkMonitor instance living in the same (child) process.
*/
networkMonitorChild: null,
/** /**
* The ConsoleProgressListener instance. * The ConsoleProgressListener instance.
*/ */
@@ -343,6 +348,10 @@ WebConsoleActor.prototype =
this.networkMonitor.destroy(); this.networkMonitor.destroy();
this.networkMonitor = null; this.networkMonitor = null;
} }
if (this.networkMonitorChild) {
this.networkMonitorChild.destroy();
this.networkMonitorChild = null;
}
if (this.consoleProgressListener) { if (this.consoleProgressListener) {
this.consoleProgressListener.destroy(); this.consoleProgressListener.destroy();
this.consoleProgressListener = null; this.consoleProgressListener = null;
@@ -587,15 +596,22 @@ WebConsoleActor.prototype =
case "NetworkActivity": case "NetworkActivity":
if (!this.networkMonitor) { if (!this.networkMonitor) {
if (appId || messageManager) { if (appId || messageManager) {
// Start a network monitor in the parent process to listen to
// most requests than happen in parent
this.networkMonitor = this.networkMonitor =
new NetworkMonitorChild(appId, messageManager, new NetworkMonitorChild(appId, messageManager,
this.parentActor.actorID, this); this.parentActor.actorID, this);
this.networkMonitor.init();
// Spawn also one in the child to listen to service workers
this.networkMonitorChild = new NetworkMonitor({ window: window },
this);
this.networkMonitorChild.init();
} }
else { else {
this.networkMonitor = new NetworkMonitor({ window: window }, this); this.networkMonitor = new NetworkMonitor({ window: window }, this);
}
this.networkMonitor.init(); this.networkMonitor.init();
} }
}
startedListeners.push(listener); startedListeners.push(listener);
break; break;
case "FileActivity": case "FileActivity":
@@ -677,6 +693,10 @@ WebConsoleActor.prototype =
this.networkMonitor.destroy(); this.networkMonitor.destroy();
this.networkMonitor = null; this.networkMonitor = null;
} }
if (this.networkMonitorChild) {
this.networkMonitorChild.destroy();
this.networkMonitorChild = null;
}
stoppedListeners.push(listener); stoppedListeners.push(listener);
break; break;
case "FileActivity": case "FileActivity":
@@ -1734,6 +1754,7 @@ NetworkEventActor.prototype =
method: this._request.method, method: this._request.method,
isXHR: this._isXHR, isXHR: this._isXHR,
fromCache: this._fromCache, fromCache: this._fromCache,
fromServiceWorker: this._fromServiceWorker,
private: this._private, private: this._private,
}; };
}, },
@@ -1778,6 +1799,7 @@ NetworkEventActor.prototype =
this._startedDateTime = aNetworkEvent.startedDateTime; this._startedDateTime = aNetworkEvent.startedDateTime;
this._isXHR = aNetworkEvent.isXHR; this._isXHR = aNetworkEvent.isXHR;
this._fromCache = aNetworkEvent.fromCache; this._fromCache = aNetworkEvent.fromCache;
this._fromServiceWorker = aNetworkEvent.fromServiceWorker;
for (let prop of ['method', 'url', 'httpVersion', 'headersSize']) { for (let prop of ['method', 'url', 'httpVersion', 'headersSize']) {
this._request[prop] = aNetworkEvent[prop]; this._request[prop] = aNetworkEvent[prop];

View File

@@ -105,7 +105,8 @@ WebConsoleClient.prototype = {
timings: {}, timings: {},
updates: [], // track the list of network event updates updates: [], // track the list of network event updates
private: actor.private, private: actor.private,
fromCache: actor.fromCache fromCache: actor.fromCache,
fromServiceWorker: actor.fromServiceWorker
}; };
this._networkRequests.set(actor.actor, networkInfo); this._networkRequests.set(actor.actor, networkInfo);

View File

@@ -491,6 +491,7 @@ function NetworkMonitor(aFilters, aOwner)
this.openResponses = {}; this.openResponses = {};
this._httpResponseExaminer = this._httpResponseExaminer =
DevToolsUtils.makeInfallible(this._httpResponseExaminer).bind(this); DevToolsUtils.makeInfallible(this._httpResponseExaminer).bind(this);
this._serviceWorkerRequest = this._serviceWorkerRequest.bind(this);
} }
exports.NetworkMonitor = NetworkMonitor; exports.NetworkMonitor = NetworkMonitor;
@@ -546,15 +547,35 @@ NetworkMonitor.prototype = {
{ {
this.responsePipeSegmentSize = Services.prefs this.responsePipeSegmentSize = Services.prefs
.getIntPref("network.buffer.cache.size"); .getIntPref("network.buffer.cache.size");
this.interceptedChannels = new Set();
gActivityDistributor.addObserver(this);
if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT) { if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT) {
gActivityDistributor.addObserver(this);
Services.obs.addObserver(this._httpResponseExaminer, Services.obs.addObserver(this._httpResponseExaminer,
"http-on-examine-response", false); "http-on-examine-response", false);
Services.obs.addObserver(this._httpResponseExaminer, Services.obs.addObserver(this._httpResponseExaminer,
"http-on-examine-cached-response", false); "http-on-examine-cached-response", false);
} }
// In child processes, only watch for service worker requests
// everything else only happens in the parent process
Services.obs.addObserver(this._serviceWorkerRequest,
"service-worker-synthesized-response", false);
},
_serviceWorkerRequest: function(aSubject, aTopic, aData)
{
let channel = aSubject.QueryInterface(Ci.nsIHttpChannel);
if (!this._matchRequest(channel)) {
return;
}
this.interceptedChannels.add(aSubject);
// On e10s, we never receive http-on-examine-cached-response, so fake one.
if (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT) {
this._httpResponseExaminer(channel, "http-on-examine-cached-response");
}
}, },
/** /**
@@ -628,10 +649,18 @@ NetworkMonitor.prototype = {
this.openResponses[response.id] = response; this.openResponses[response.id] = response;
if (aTopic === "http-on-examine-cached-response") { if (aTopic === "http-on-examine-cached-response") {
// Service worker requests emits cached-reponse notification on non-e10s,
// and we fake one on e10s.
let fromServiceWorker = this.interceptedChannels.has(channel);
this.interceptedChannels.delete(channel);
// If this is a cached response, there never was a request event // If this is a cached response, there never was a request event
// so we need to construct one here so the frontend gets all the // so we need to construct one here so the frontend gets all the
// expected events. // expected events.
let httpActivity = this._createNetworkEvent(channel, { fromCache: true }); let httpActivity = this._createNetworkEvent(channel, {
fromCache: !fromServiceWorker,
fromServiceWorker: fromServiceWorker
});
httpActivity.owner.addResponseStart({ httpActivity.owner.addResponseStart({
httpVersion: response.httpVersion, httpVersion: response.httpVersion,
remoteAddress: "", remoteAddress: "",
@@ -806,7 +835,7 @@ NetworkMonitor.prototype = {
/** /**
* *
*/ */
_createNetworkEvent: function(aChannel, { timestamp, extraStringData, fromCache }) { _createNetworkEvent: function(aChannel, { timestamp, extraStringData, fromCache, fromServiceWorker }) {
let win = NetworkHelper.getWindowForRequest(aChannel); let win = NetworkHelper.getWindowForRequest(aChannel);
let httpActivity = this.createActivityObject(aChannel); let httpActivity = this.createActivityObject(aChannel);
@@ -830,6 +859,7 @@ NetworkMonitor.prototype = {
event.headersSize = 0; event.headersSize = 0;
event.startedDateTime = (timestamp ? new Date(Math.round(timestamp / 1000)) : new Date()).toISOString(); event.startedDateTime = (timestamp ? new Date(Math.round(timestamp / 1000)) : new Date()).toISOString();
event.fromCache = fromCache; event.fromCache = fromCache;
event.fromServiceWorker = fromServiceWorker;
if (extraStringData) { if (extraStringData) {
event.headersSize = extraStringData.length; event.headersSize = extraStringData.length;
@@ -1189,12 +1219,17 @@ NetworkMonitor.prototype = {
destroy: function NM_destroy() destroy: function NM_destroy()
{ {
if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT) { if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT) {
gActivityDistributor.removeObserver(this);
Services.obs.removeObserver(this._httpResponseExaminer, Services.obs.removeObserver(this._httpResponseExaminer,
"http-on-examine-response"); "http-on-examine-response");
Services.obs.removeObserver(this._httpResponseExaminer,
"http-on-examine-cached-response");
} }
gActivityDistributor.removeObserver(this); Services.obs.removeObserver(this._serviceWorkerRequest,
"service-worker-synthesized-response");
this.interceptedChannels.clear();
this.openRequests = {}; this.openRequests = {};
this.openResponses = {}; this.openResponses = {};
this.owner = null; this.owner = null;