Bug 1788762 - Migrate devtools network observer to an ES module r=ochameau

This is a very basic migration from commonjs modules to ESM for all modules related to network observation.
A few classes have been introduced instead of prototype-based classes, but otherwise the code remains mostly untouched.

We can followup to introduce private fields and methods if there's interest?

Differential Revision: https://phabricator.services.mozilla.com/D156968
This commit is contained in:
Julian Descottes 2022-10-17 19:56:18 +00:00
Родитель 256f083ad2
Коммит 989055a6f7
32 изменённых файлов: 498 добавлений и 470 удалений

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

@ -4,11 +4,11 @@
"use strict";
loader.lazyRequireGetter(
this,
"NetworkHelper",
"resource://devtools/shared/webconsole/network-helper.js"
);
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
NetworkHelper: "resource://devtools/shared/webconsole/NetworkHelper.sys.mjs",
});
const {
getTheme,
@ -121,7 +121,7 @@ Converter.prototype = {
this.listener.onStartRequest(request);
// Initialize stuff.
const win = NetworkHelper.getWindowForRequest(request);
const win = lazy.NetworkHelper.getWindowForRequest(request);
if (!win || !Components.isSuccessCode(request.status)) {
return;
}

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

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* NetworkObserver is the main class in DevTools to observe network requests
* out of many events fired by the platform code.
@ -12,45 +10,25 @@
// Enable logging all platform events this module listen to
const DEBUG_PLATFORM_EVENTS = false;
loader.lazyRequireGetter(
this,
"ChannelMap",
"resource://devtools/server/actors/network-monitor/utils/channel-map.js",
true
);
loader.lazyRequireGetter(
this,
"NetworkUtils",
"resource://devtools/server/actors/network-monitor/utils/network-utils.js"
);
loader.lazyRequireGetter(
this,
"NetworkHelper",
"resource://devtools/shared/webconsole/network-helper.js"
);
loader.lazyRequireGetter(
this,
"DevToolsUtils",
"resource://devtools/shared/DevToolsUtils.js"
);
loader.lazyRequireGetter(
this,
"NetworkThrottleManager",
"resource://devtools/shared/webconsole/throttle.js",
true
);
loader.lazyServiceGetter(
this,
"gActivityDistributor",
"@mozilla.org/network/http-activity-distributor;1",
"nsIHttpActivityDistributor"
);
loader.lazyRequireGetter(
this,
"NetworkResponseListener",
"resource://devtools/server/actors/network-monitor/network-response-listener.js",
true
);
const lazy = {};
import { DevToolsInfaillibleUtils } from "resource://devtools/shared/DevToolsInfaillibleUtils.sys.mjs";
ChromeUtils.defineESModuleGetters(lazy, {
ChannelMap:
"resource://devtools/server/actors/network-monitor/utils/ChannelMap.sys.mjs",
NetworkHelper: "resource://devtools/shared/webconsole/NetworkHelper.sys.mjs",
NetworkResponseListener:
"resource://devtools/server/actors/network-monitor/NetworkResponseListener.sys.mjs",
NetworkThrottleManager:
"resource://devtools/shared/webconsole/Throttle.sys.mjs",
NetworkUtils:
"resource://devtools/server/actors/network-monitor/utils/NetworkUtils.sys.mjs",
});
const gActivityDistributor = Cc[
"@mozilla.org/network/http-activity-distributor;1"
].getService(Ci.nsIHttpActivityDistributor);
function logPlatformEvent(eventName, channel, message = "") {
if (!DEBUG_PLATFORM_EVENTS) {
@ -94,45 +72,43 @@ const HTTP_TEMPORARY_REDIRECT = 307;
* onNetworkEvent() must return an object which holds several add*()
* methods which are used to add further network request/response information.
* - shouldIgnoreChannel(channel) [optional]
* In additional to `NetworkUtils.matchRequest`, allow to ignore even more
* In additional to `lazy.NetworkUtils.matchRequest`, allow to ignore even more
* requests.
*/
function NetworkObserver(filters, owner) {
this.filters = filters;
this.owner = owner;
export class NetworkObserver {
constructor(filters, owner) {
this.filters = filters;
this.owner = owner;
this.openRequests = new ChannelMap();
this.openResponses = new ChannelMap();
this.openRequests = new lazy.ChannelMap();
this.openResponses = new lazy.ChannelMap();
this.blockedURLs = [];
this.blockedURLs = [];
this._httpResponseExaminer = DevToolsUtils.makeInfallible(
this._httpResponseExaminer
).bind(this);
this._httpModifyExaminer = DevToolsUtils.makeInfallible(
this._httpModifyExaminer
).bind(this);
this._httpFailedOpening = DevToolsUtils.makeInfallible(
this._httpFailedOpening
).bind(this);
this._httpStopRequest = DevToolsUtils.makeInfallible(
this._httpStopRequest
).bind(this);
this._serviceWorkerRequest = this._serviceWorkerRequest.bind(this);
this._httpResponseExaminer = DevToolsInfaillibleUtils.makeInfallible(
this._httpResponseExaminer
).bind(this);
this._httpModifyExaminer = DevToolsInfaillibleUtils.makeInfallible(
this._httpModifyExaminer
).bind(this);
this._httpFailedOpening = DevToolsInfaillibleUtils.makeInfallible(
this._httpFailedOpening
).bind(this);
this._httpStopRequest = DevToolsInfaillibleUtils.makeInfallible(
this._httpStopRequest
).bind(this);
this._serviceWorkerRequest = this._serviceWorkerRequest.bind(this);
this._throttleData = null;
this._throttler = null;
// This is ultimately used by NetworkHelper.parseSecurityInfo to avoid
// repeatedly decoding already-seen certificates.
this._decodedCertificateCache = new Map();
}
this._throttleData = null;
this._throttler = null;
// This is ultimately used by NetworkHelper.parseSecurityInfo to avoid
// repeatedly decoding already-seen certificates.
this._decodedCertificateCache = new Map();
}
exports.NetworkObserver = NetworkObserver;
filters = null;
NetworkObserver.prototype = {
filters: null,
httpTransactionCodes: {
httpTransactionCodes = {
0x5001: "REQUEST_HEADER",
0x5002: "REQUEST_BODY_SENT",
0x5003: "RESPONSE_START",
@ -149,36 +125,36 @@ NetworkObserver.prototype = {
0x804b0006: "STATUS_RECEIVING_FROM",
0x804b000c: "STATUS_TLS_STARTING",
0x804b000d: "STATUS_TLS_ENDING",
},
};
httpDownloadActivities: [
httpDownloadActivities = [
gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_START,
gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_HEADER,
gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE,
gActivityDistributor.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE,
],
];
// Network response bodies are piped through a buffer of the given size (in
// bytes).
responsePipeSegmentSize: null,
responsePipeSegmentSize = null;
owner: null,
owner = null;
/**
* Whether to save the bodies of network requests and responses.
* @type boolean
*/
saveRequestAndResponseBodies: true,
saveRequestAndResponseBodies = true;
/**
* Object that holds the HTTP activity objects for ongoing requests.
*/
openRequests: null,
openRequests = null;
/**
* Object that holds response headers coming from this._httpResponseExaminer.
*/
openResponses: null,
openResponses = null;
/**
* The network monitor initializer.
@ -216,24 +192,24 @@ NetworkObserver.prototype = {
this._serviceWorkerRequest,
"service-worker-synthesized-response"
);
},
}
get throttleData() {
return this._throttleData;
},
}
set throttleData(value) {
this._throttleData = value;
// Clear out any existing throttlers
this._throttler = null;
},
}
_getThrottler() {
if (this.throttleData !== null && this._throttler === null) {
this._throttler = new NetworkThrottleManager(this.throttleData);
this._throttler = new lazy.NetworkThrottleManager(this.throttleData);
}
return this._throttler;
},
}
/**
* Given a network channel, should this observer ignore this request
@ -251,10 +227,10 @@ NetworkObserver.prototype = {
) {
return true;
}
return !NetworkUtils.matchRequest(channel, this.filters);
},
return !lazy.NetworkUtils.matchRequest(channel, this.filters);
}
_decodedCertificateCache: null,
_decodedCertificateCache = null;
_serviceWorkerRequest(subject, topic, data) {
const channel = subject.QueryInterface(Ci.nsIHttpChannel);
@ -269,7 +245,7 @@ NetworkObserver.prototype = {
// Service workers never fire http-on-examine-cached-response, so fake one.
this._httpResponseExaminer(channel, "http-on-examine-cached-response");
},
}
/**
* Observes for http-on-failed-opening-request notification to catch any
@ -295,13 +271,13 @@ NetworkObserver.prototype = {
// Ignore preload requests to avoid duplicity request entries in
// the Network panel. If a preload fails (for whatever reason)
// then the platform kicks off another 'real' request.
if (NetworkUtils.isPreloadRequest(channel)) {
if (lazy.NetworkUtils.isPreloadRequest(channel)) {
return;
}
const blockedCode = channel.loadInfo.requestBlockingReason;
this._httpResponseExaminer(subject, topic, blockedCode);
},
}
_httpStopRequest(subject, topic) {
if (
@ -366,7 +342,7 @@ NetworkObserver.prototype = {
});
}
}
},
}
/**
* Observe notifications for the http-on-examine-response topic, coming from
@ -437,7 +413,7 @@ NetworkObserver.prototype = {
if (setCookieHeaders.length) {
response.cookies = setCookieHeaders.reduce((result, header) => {
const cookies = NetworkHelper.parseSetCookieHeader(header);
const cookies = lazy.NetworkHelper.parseSetCookieHeader(header);
return result.concat(cookies);
}, []);
}
@ -513,7 +489,7 @@ NetworkObserver.prototype = {
} else if (topic === "http-on-failed-opening-request") {
this._createNetworkEvent(channel, { blockedReason });
}
},
}
/**
* Observe notifications for the http-on-modify-request topic, coming from
@ -537,7 +513,7 @@ NetworkObserver.prototype = {
this._onRequestBodySent(httpActivity);
throttler.manageUpload(channel);
}
},
}
/**
* A helper function for observeActivity. This does whatever work
@ -582,7 +558,7 @@ NetworkObserver.prototype = {
default:
break;
}
},
}
getActivityTypeString(activityType, activitySubtype) {
if (
@ -603,7 +579,7 @@ NetworkObserver.prototype = {
}
}
return "unexpected-activity-types:" + activityType + ":" + activitySubtype;
},
}
/**
* Begin observing HTTP traffic that originates inside the current tab.
@ -617,7 +593,7 @@ NetworkObserver.prototype = {
* @param number extraSizeData
* @param string extraStringData
*/
observeActivity: DevToolsUtils.makeInfallible(function(
observeActivity = DevToolsInfaillibleUtils.makeInfallible(function(
channel,
activityType,
activitySubtype,
@ -693,7 +669,7 @@ NetworkObserver.prototype = {
extraStringData
);
}
}),
});
/**
* Craft the "event" object passed to the Watcher class in order
@ -726,7 +702,7 @@ NetworkObserver.prototype = {
};
}
const event = NetworkUtils.createNetworkEvent(channel, {
const event = lazy.NetworkUtils.createNetworkEvent(channel, {
timestamp,
fromCache,
fromServiceWorker,
@ -749,11 +725,15 @@ NetworkObserver.prototype = {
this._setupResponseListener(httpActivity, fromCache);
}
NetworkUtils.fetchRequestHeadersAndCookies(channel, httpActivity.owner, {
extraStringData,
});
lazy.NetworkUtils.fetchRequestHeadersAndCookies(
channel,
httpActivity.owner,
{
extraStringData,
}
);
return httpActivity;
},
}
/**
* Handler for ACTIVITY_SUBTYPE_REQUEST_HEADER. When a request starts the
@ -773,7 +753,7 @@ NetworkObserver.prototype = {
}
this._createNetworkEvent(channel, { timestamp, extraStringData });
},
}
/**
* Find an HTTP activity object for the channel.
@ -785,7 +765,7 @@ NetworkObserver.prototype = {
*/
_findActivityObject(channel) {
return this.openRequests.getChannelById(channel.channelId);
},
}
/**
* Find an existing HTTP activity object, or create a new one. This
@ -804,7 +784,7 @@ NetworkObserver.prototype = {
createOrGetActivityObject(channel) {
let httpActivity = this._findActivityObject(channel);
if (!httpActivity) {
const win = NetworkHelper.getWindowForRequest(channel);
const win = lazy.NetworkHelper.getWindowForRequest(channel);
const charset = win ? win.document.characterSet : null;
httpActivity = {
@ -831,7 +811,7 @@ NetworkObserver.prototype = {
}
return httpActivity;
},
}
/**
* Block a request based on certain filtering options.
@ -846,7 +826,7 @@ NetworkObserver.prototype = {
}
this.blockedURLs.push(filter.url);
},
}
/**
* Unblock a request based on certain filtering options.
@ -861,7 +841,7 @@ NetworkObserver.prototype = {
}
this.blockedURLs = this.blockedURLs.filter(url => url != filter.url);
},
}
/**
* Updates the list of blocked request strings
@ -870,7 +850,7 @@ NetworkObserver.prototype = {
*/
setBlockedUrls(urls) {
this.blockedURLs = urls || [];
},
}
/**
* Returns a list of blocked requests
@ -878,7 +858,7 @@ NetworkObserver.prototype = {
*/
getBlockedUrls() {
return this.blockedURLs;
},
}
/**
* Setup the network response listener for the given HTTP activity. The
@ -910,7 +890,7 @@ NetworkObserver.prototype = {
sink.init(false, false, this.responsePipeSegmentSize, PR_UINT32_MAX, null);
// Add listener for the response body.
const newListener = new NetworkResponseListener(
const newListener = new lazy.NetworkResponseListener(
this,
httpActivity,
this._decodedCertificateCache
@ -927,7 +907,7 @@ NetworkObserver.prototype = {
const originalListener = channel.setNewListener(tee);
tee.init(originalListener, sink.outputStream, newListener);
},
}
/**
* Handler for ACTIVITY_SUBTYPE_REQUEST_BODY_SENT. The request body is logged
@ -944,7 +924,7 @@ NetworkObserver.prototype = {
return;
}
let sentBody = NetworkHelper.readPostTextFromRequest(
let sentBody = lazy.NetworkHelper.readPostTextFromRequest(
httpActivity.channel,
httpActivity.charset
);
@ -957,12 +937,12 @@ NetworkObserver.prototype = {
// If the request URL is the same as the current page URL, then
// we can try to get the posted text from the page directly.
// This check is necessary as otherwise the
// NetworkHelper.readPostTextFromPageViaWebNav()
// lazy.NetworkHelper.readPostTextFromPageViaWebNav()
// function is called for image requests as well but these
// are not web pages and as such don't store the posted text
// in the cache of the webpage.
const webNav = this.window.docShell.QueryInterface(Ci.nsIWebNavigation);
sentBody = NetworkHelper.readPostTextFromPageViaWebNav(
sentBody = lazy.NetworkHelper.readPostTextFromPageViaWebNav(
webNav,
httpActivity.charset
);
@ -971,7 +951,7 @@ NetworkObserver.prototype = {
if (sentBody !== null) {
httpActivity.sentBody = sentBody;
}
},
}
/**
* Handler for ACTIVITY_SUBTYPE_RESPONSE_HEADER. This method stores
@ -1035,7 +1015,7 @@ NetworkObserver.prototype = {
response.discardResponseBody = httpActivity.discardResponseBody;
httpActivity.owner.addResponseStart(response, extraStringData);
},
}
/**
* Handler for ACTIVITY_SUBTYPE_TRANSACTION_CLOSE. This method updates the HAR
@ -1058,7 +1038,7 @@ NetworkObserver.prototype = {
serverTimings
);
}
},
}
_getBlockedTiming(timings) {
if (timings.STATUS_RESOLVING && timings.STATUS_CONNECTING_TO) {
@ -1068,7 +1048,7 @@ NetworkObserver.prototype = {
}
return -1;
},
}
_getDnsTiming(timings) {
if (timings.STATUS_RESOLVING && timings.STATUS_RESOLVED) {
@ -1076,7 +1056,7 @@ NetworkObserver.prototype = {
}
return -1;
},
}
_getConnectTiming(timings) {
if (timings.STATUS_CONNECTING_TO && timings.STATUS_CONNECTED_TO) {
@ -1086,7 +1066,7 @@ NetworkObserver.prototype = {
}
return -1;
},
}
_getReceiveTiming(timings) {
if (timings.RESPONSE_START && timings.RESPONSE_COMPLETE) {
@ -1094,7 +1074,7 @@ NetworkObserver.prototype = {
}
return -1;
},
}
_getWaitTiming(timings) {
if (timings.RESPONSE_START) {
@ -1105,7 +1085,7 @@ NetworkObserver.prototype = {
}
return -1;
},
}
_getSslTiming(timings) {
if (timings.STATUS_TLS_STARTING && timings.STATUS_TLS_ENDING) {
@ -1113,7 +1093,7 @@ NetworkObserver.prototype = {
}
return -1;
},
}
_getSendTiming(timings) {
if (timings.STATUS_SENDING_TO) {
@ -1123,7 +1103,7 @@ NetworkObserver.prototype = {
}
return -1;
},
}
_getDataFromTimedChannel(timedChannel) {
const lookUpArr = [
@ -1158,7 +1138,7 @@ NetworkObserver.prototype = {
})(),
};
}, {});
},
}
_getSecureConnectionStartTimeInfo(timings) {
let secureConnectionStartTime = 0;
@ -1181,7 +1161,7 @@ NetworkObserver.prototype = {
secureConnectionStartTime,
secureConnectionStartTimeRelative,
};
},
}
_getStartSendingTimeInfo(timings, connectStartTimeTc) {
let startSendingTime = 0;
@ -1202,7 +1182,7 @@ NetworkObserver.prototype = {
}
}
return { startSendingTime, startSendingTimeRelative };
},
}
/**
* Update the HTTP activity object to include timing information as in the HAR
@ -1353,7 +1333,7 @@ NetworkObserver.prototype = {
timings: harTimings,
offsets: ot.offsets,
};
},
}
_extractServerTimings(channel) {
if (!channel || !channel.serverTiming) {
@ -1372,11 +1352,11 @@ NetworkObserver.prototype = {
}
return serverTimings;
},
}
_convertTimeToMs(timing) {
return Math.max(Math.round(timing / 1000), -1);
},
}
_calculateOffsetAndTotalTime(
harTimings,
@ -1426,7 +1406,7 @@ NetworkObserver.prototype = {
total: totalTime,
offsets,
};
},
}
_sendRequestBody(httpActivity) {
if (httpActivity.sentBody !== null) {
@ -1443,7 +1423,7 @@ NetworkObserver.prototype = {
});
httpActivity.sentBody = null;
}
},
}
/*
* Clears all open requests and responses
@ -1451,7 +1431,7 @@ NetworkObserver.prototype = {
clear() {
this.openRequests.clear();
this.openResponses.clear();
},
}
/**
* Suspend observer activity. This is called when the Network monitor actor stops
@ -1493,8 +1473,8 @@ NetworkObserver.prototype = {
this._throttler = null;
this._decodedCertificateCache.clear();
this.clear();
},
};
}
}
function gSequenceId() {
return gSequenceId.n++;

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

@ -2,26 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
loader.lazyRequireGetter(
this,
"NetworkHelper",
"resource://devtools/shared/webconsole/network-helper.js"
);
loader.lazyRequireGetter(
this,
"CacheEntry",
"resource://devtools/shared/platform/cache-entry.js",
true
);
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
ChromeUtils.defineModuleGetter(
lazy,
"NetUtil",
"resource://gre/modules/NetUtil.jsm"
);
ChromeUtils.defineESModuleGetters(lazy, {
CacheEntry: "resource://devtools/shared/platform/CacheEntry.sys.mjs",
NetworkHelper: "resource://devtools/shared/webconsole/NetworkHelper.sys.mjs",
});
XPCOMUtils.defineLazyModuleGetters(lazy, {
NetUtil: "resource://gre/modules/NetUtil.jsm",
});
// Network logging
@ -46,31 +38,28 @@ ChromeUtils.defineModuleGetter(
* A Map of certificate fingerprints to decoded certificates, to avoid
* repeatedly decoding previously-seen certificates.
*/
function NetworkResponseListener(owner, httpActivity, decodedCertificateCache) {
this.owner = owner;
this.receivedData = "";
this.httpActivity = httpActivity;
this.bodySize = 0;
// Indicates if the response had a size greater than response body limit.
this.truncated = false;
// Note that this is really only needed for the non-e10s case.
// See bug 1309523.
const channel = this.httpActivity.channel;
this._wrappedNotificationCallbacks = channel.notificationCallbacks;
channel.notificationCallbacks = this;
this._decodedCertificateCache = decodedCertificateCache;
}
exports.NetworkResponseListener = NetworkResponseListener;
NetworkResponseListener.prototype = {
QueryInterface: ChromeUtils.generateQI([
"nsIStreamListener",
"nsIInputStreamCallback",
"nsIRequestObserver",
"nsIInterfaceRequestor",
]),
export class NetworkResponseListener {
constructor(owner, httpActivity, decodedCertificateCache) {
this.QueryInterface = ChromeUtils.generateQI([
"nsIStreamListener",
"nsIInputStreamCallback",
"nsIRequestObserver",
"nsIInterfaceRequestor",
]);
this.owner = owner;
this.receivedData = "";
this.httpActivity = httpActivity;
this.bodySize = 0;
// Indicates if the response had a size greater than response body limit.
this.truncated = false;
// Note that this is really only needed for the non-e10s case.
// See bug 1309523.
const channel = this.httpActivity.channel;
this._wrappedNotificationCallbacks = channel.notificationCallbacks;
channel.notificationCallbacks = this;
this._decodedCertificateCache = decodedCertificateCache;
}
// nsIInterfaceRequestor implementation
/**
@ -85,7 +74,7 @@ NetworkResponseListener.prototype = {
return this._wrappedNotificationCallbacks.getInterface(iid);
}
throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
},
}
/**
* Forward notifications for interfaces this object implements, in case other
@ -103,62 +92,62 @@ NetworkResponseListener.prototype = {
throw e;
}
}
},
}
/**
* This NetworkResponseListener tracks the NetworkObserver.openResponses object
* to find the associated uncached headers.
* @private
*/
_foundOpenResponse: false,
_foundOpenResponse = false;
/**
* If the channel already had notificationCallbacks, hold them here internally
* so that we can forward getInterface requests to that object.
*/
_wrappedNotificationCallbacks: null,
_wrappedNotificationCallbacks = null;
/**
* A Map of certificate fingerprints to decoded certificates, to avoid repeatedly
* decoding previously-seen certificates.
*/
_decodedCertificateCache: null,
_decodedCertificateCache = null;
/**
* The response listener owner.
*/
owner: null,
owner = null;
/**
* The response will be written into the outputStream of this nsIPipe.
* Both ends of the pipe must be blocking.
*/
sink: null,
sink = null;
/**
* The HttpActivity object associated with this response.
*/
httpActivity: null,
httpActivity = null;
/**
* Stores the received data as a string.
*/
receivedData: null,
receivedData = null;
/**
* The uncompressed, decoded response body size.
*/
bodySize: null,
bodySize = null;
/**
* Response size on the wire, potentially compressed / encoded.
*/
transferredSize: null,
transferredSize = null;
/**
* The nsIRequest we are started for.
*/
request: null,
request = null;
/**
* Set the async listener for the given nsIAsyncInputStream. This allows us to
@ -175,7 +164,7 @@ NetworkResponseListener.prototype = {
setAsyncListener(stream, listener) {
// Asynchronously wait for the stream to be readable or closed.
stream.asyncWait(listener, 0, 0, Services.tm.mainThread);
},
}
/**
* Stores the received data, if request/response body logging is enabled. It
@ -202,7 +191,7 @@ NetworkResponseListener.prototype = {
"devtools.netmonitor.responseBodyLimit"
);
if (this.receivedData.length <= limit || limit == 0) {
this.receivedData += NetworkHelper.convertToUnicode(
this.receivedData += lazy.NetworkHelper.convertToUnicode(
data,
request.contentCharset
);
@ -212,7 +201,7 @@ NetworkResponseListener.prototype = {
this.truncated = true;
}
}
},
}
/**
* See documentation at
@ -261,7 +250,7 @@ NetworkResponseListener.prototype = {
if (!charset) {
charset = this.httpActivity.charset;
}
NetworkHelper.loadFromCache(
lazy.NetworkHelper.loadFromCache(
this.httpActivity.url,
charset,
this._onComplete.bind(this)
@ -313,7 +302,7 @@ NetworkResponseListener.prototype = {
}
// Asynchronously wait for the data coming from the request.
this.setAsyncListener(this.sink.inputStream, this);
},
}
/**
* Parse security state of this request and report it to the client.
@ -332,7 +321,7 @@ NetworkResponseListener.prototype = {
// was a redirect from http to https, the request object seems to contain
// security info for the https request after redirect.
const secinfo = this.httpActivity.channel.securityInfo;
const info = await NetworkHelper.parseSecurityInfo(
const info = await lazy.NetworkHelper.parseSecurityInfo(
secinfo,
this.request.loadInfo.originAttributes,
this.httpActivity,
@ -350,7 +339,7 @@ NetworkResponseListener.prototype = {
}
this.httpActivity.owner.addSecurityInfo(info, isRacing);
},
}
/**
* Fetches cache information from CacheEntry
@ -358,12 +347,12 @@ NetworkResponseListener.prototype = {
*/
_fetchCacheInformation() {
const httpActivity = this.httpActivity;
CacheEntry.getCacheEntry(this.request, descriptor => {
lazy.CacheEntry.getCacheEntry(this.request, descriptor => {
httpActivity.owner.addResponseCache({
responseCache: descriptor,
});
});
},
}
/**
* Handle the onStopRequest by closing the sink output stream.
@ -379,7 +368,7 @@ NetworkResponseListener.prototype = {
}
this._findOpenResponse();
this.sink.outputStream.close();
},
}
// nsIProgressEventSink implementation
@ -392,11 +381,11 @@ NetworkResponseListener.prototype = {
// Need to forward as well to keep things like Download Manager's progress
// bar working properly.
this._forwardNotification(Ci.nsIProgressEventSink, "onProgress", arguments);
},
}
onStatus() {
this._forwardNotification(Ci.nsIProgressEventSink, "onStatus", arguments);
},
}
/**
* Find the open response object associated to the current request. The
@ -426,7 +415,7 @@ NetworkResponseListener.prototype = {
this.httpActivity.owner.addResponseHeaders(openResponse.headers);
this.httpActivity.owner.addResponseCookies(openResponse.cookies);
},
}
/**
* Clean up the response listener once the response input stream is closed.
@ -463,7 +452,7 @@ NetworkResponseListener.prototype = {
if (!charset) {
charset = this.httpActivity.charset;
}
NetworkHelper.loadFromCache(
lazy.NetworkHelper.loadFromCache(
this.httpActivity.url,
charset,
this._onComplete.bind(this)
@ -471,7 +460,7 @@ NetworkResponseListener.prototype = {
} else {
this._onComplete();
}
},
}
/**
* Handler for when the response completes. This function cleans up the
@ -485,7 +474,7 @@ NetworkResponseListener.prototype = {
// Make sure all the security and response content info are sent
this._getResponseContent(data);
this._onSecurityInfo.then(() => this._destroy());
},
}
/**
* Create the response object and send it to the client.
@ -508,7 +497,7 @@ NetworkResponseListener.prototype = {
if (
!response.mimeType ||
!NetworkHelper.isTextMimeType(response.mimeType)
!lazy.NetworkHelper.isTextMimeType(response.mimeType)
) {
response.encoding = "base64";
try {
@ -546,7 +535,7 @@ NetworkResponseListener.prototype = {
blockedReason: reason,
blockingExtension: id,
});
},
}
_destroy() {
this._wrappedNotificationCallbacks = null;
@ -556,7 +545,7 @@ NetworkResponseListener.prototype = {
this.converter = null;
this.request = null;
this.owner = null;
},
}
/**
* The nsIInputStreamCallback for when the request input stream is ready -
@ -598,5 +587,5 @@ NetworkResponseListener.prototype = {
this.onStreamClose();
this.offset = 0;
}
},
};
}
}

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

@ -15,9 +15,9 @@ DevToolsModules(
"network-event-actor.js",
"network-event.js",
"network-monitor.js",
"network-observer.js",
"network-parent.js",
"network-response-listener.js",
"NetworkObserver.sys.mjs",
"NetworkResponseListener.sys.mjs",
"stack-trace-collector.js",
"websocket-actor.js",
)

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

@ -19,11 +19,10 @@ ChromeUtils.defineModuleGetter(
"resource://gre/modules/NetUtil.jsm"
);
loader.lazyRequireGetter(
this,
"NetworkUtils",
"resource://devtools/server/actors/network-monitor/utils/network-utils.js"
);
ChromeUtils.defineESModuleGetters(lazy, {
NetworkUtils:
"resource://devtools/server/actors/network-monitor/utils/NetworkUtils.sys.mjs",
});
loader.lazyRequireGetter(
this,
@ -79,7 +78,7 @@ const NetworkContentActor = ActorClassWithSpec(networkContentSpec, {
securityFlags:
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
contentPolicyType:
NetworkUtils.stringToCauseType(cause.type) ||
lazy.NetworkUtils.stringToCauseType(cause.type) ||
Ci.nsIContentPolicy.TYPE_OTHER,
});

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

@ -12,12 +12,13 @@ const {
networkMonitorSpec,
} = require("resource://devtools/shared/specs/network-monitor.js");
loader.lazyRequireGetter(
this,
"NetworkObserver",
"resource://devtools/server/actors/network-monitor/network-observer.js",
true
);
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
NetworkObserver:
"resource://devtools/server/actors/network-monitor/NetworkObserver.sys.mjs",
});
loader.lazyRequireGetter(
this,
"NetworkEventActor",
@ -59,7 +60,7 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
// Immediately start watching for new request according to `filters`.
// NetworkMonitor will call `onNetworkEvent` method.
this.observer = new NetworkObserver(filters, this);
this.observer = new lazy.NetworkObserver(filters, this);
this.observer.init();
this.stackTraces = new Set();

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

@ -4,17 +4,19 @@
"use strict";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
NetworkUtils:
"resource://devtools/server/actors/network-monitor/utils/NetworkUtils.sys.mjs",
});
loader.lazyRequireGetter(
this,
"ChannelEventSinkFactory",
"resource://devtools/server/actors/network-monitor/channel-event-sink.js",
true
);
loader.lazyRequireGetter(
this,
"NetworkUtils",
"resource://devtools/server/actors/network-monitor/utils/network-utils.js"
);
loader.lazyRequireGetter(
this,
"WebConsoleUtils",
@ -102,7 +104,7 @@ StackTraceCollector.prototype = {
}
}
if (!NetworkUtils.matchRequest(channel, this.filters)) {
if (!lazy.NetworkUtils.matchRequest(channel, this.filters)) {
return;
}

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

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/* global FinalizationRegistry, WeakRef */
/**
@ -23,7 +21,7 @@
*
* So, this custom map solves aforementioned issues.
*/
class ChannelMap {
export class ChannelMap {
constructor() {
this.weakMap = new WeakMap();
this.refMap = new Map();
@ -74,5 +72,3 @@ class ChannelMap {
this.refMap.clear();
}
}
exports.ChannelMap = ChannelMap;

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

@ -2,19 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const {
wildcardToRegExp,
} = require("resource://devtools/server/actors/network-monitor/utils/wildcard-to-regexp.js");
const lazy = {};
loader.lazyRequireGetter(
this,
"NetworkHelper",
"resource://devtools/shared/webconsole/network-helper.js"
);
ChromeUtils.defineESModuleGetters(lazy, {
NetworkHelper: "resource://devtools/shared/webconsole/NetworkHelper.sys.mjs",
wildcardToRegExp:
"resource://devtools/server/actors/network-monitor/utils/WildcardToRegexp.sys.mjs",
});
loader.lazyGetter(this, "tpFlagsMask", () => {
XPCOMUtils.defineLazyGetter(lazy, "tpFlagsMask", () => {
const trackingProtectionLevel2Enabled = Services.prefs
.getStringPref("urlclassifier.trackingTable")
.includes("content-track-digest256");
@ -54,11 +52,7 @@ const LOAD_CAUSE_STRINGS = {
[Ci.nsIContentPolicy.TYPE_WEB_IDENTITY]: "webidentity",
};
exports.causeTypeToString = function(
causeType,
loadFlags,
internalContentPolicyType
) {
function causeTypeToString(causeType, loadFlags, internalContentPolicyType) {
let prefix = "";
if (
(causeType == Ci.nsIContentPolicy.TYPE_IMAGESET ||
@ -69,19 +63,19 @@ exports.causeTypeToString = function(
}
return prefix + LOAD_CAUSE_STRINGS[causeType] || "unknown";
};
}
exports.stringToCauseType = function(value) {
function stringToCauseType(value) {
return Object.keys(LOAD_CAUSE_STRINGS).find(
key => LOAD_CAUSE_STRINGS[key] === value
);
};
}
function isChannelFromSystemPrincipal(channel) {
let principal = null;
let browsingContext = channel.loadInfo.browsingContext;
if (!browsingContext) {
const topFrame = NetworkHelper.getTopFrameForRequest(channel);
const topFrame = lazy.NetworkHelper.getTopFrameForRequest(channel);
if (topFrame) {
browsingContext = topFrame.browsingContext;
} else {
@ -107,20 +101,20 @@ function isChannelFromSystemPrincipal(channel) {
* @param {*} channel
* @returns {number}
*/
exports.getChannelBrowsingContextID = function(channel) {
function getChannelBrowsingContextID(channel) {
if (channel.loadInfo.browsingContextID) {
return channel.loadInfo.browsingContextID;
}
// At least WebSocket channel aren't having a browsingContextID set on their loadInfo
// We fallback on top frame element, which works, but will be wrong for WebSocket
// in same-process iframes...
const topFrame = NetworkHelper.getTopFrameForRequest(channel);
const topFrame = lazy.NetworkHelper.getTopFrameForRequest(channel);
// topFrame is typically null for some chrome requests like favicons
if (topFrame && topFrame.browsingContext) {
return topFrame.browsingContext.id;
}
return null;
};
}
/**
* Get the innerWindowId for the channel.
@ -128,20 +122,20 @@ exports.getChannelBrowsingContextID = function(channel) {
* @param {*} channel
* @returns {number}
*/
exports.getChannelInnerWindowId = function(channel) {
function getChannelInnerWindowId(channel) {
if (channel.loadInfo.innerWindowID) {
return channel.loadInfo.innerWindowID;
}
// At least WebSocket channel aren't having a browsingContextID set on their loadInfo
// We fallback on top frame element, which works, but will be wrong for WebSocket
// in same-process iframes...
const topFrame = NetworkHelper.getTopFrameForRequest(channel);
const topFrame = lazy.NetworkHelper.getTopFrameForRequest(channel);
// topFrame is typically null for some chrome requests like favicons
if (topFrame?.browsingContext?.currentWindowGlobal) {
return topFrame.browsingContext.currentWindowGlobal.innerWindowId;
}
return null;
};
}
/**
* Does this channel represent a Preload request.
@ -149,7 +143,7 @@ exports.getChannelInnerWindowId = function(channel) {
* @param {*} channel
* @returns {boolean}
*/
exports.isPreloadRequest = function(channel) {
function isPreloadRequest(channel) {
const type = channel.loadInfo.internalContentPolicyType;
return (
type == Ci.nsIContentPolicy.TYPE_INTERNAL_SCRIPT_PRELOAD ||
@ -158,7 +152,7 @@ exports.isPreloadRequest = function(channel) {
type == Ci.nsIContentPolicy.TYPE_INTERNAL_STYLESHEET_PRELOAD ||
type == Ci.nsIContentPolicy.TYPE_INTERNAL_FONT_PRELOAD
);
};
}
/**
* Creates a network event based on the channel.
@ -166,7 +160,7 @@ exports.isPreloadRequest = function(channel) {
* @param {*} channel
* @return {Object} event - The network event
*/
exports.createNetworkEvent = function(
function createNetworkEvent(
channel,
{
timestamp,
@ -202,7 +196,7 @@ exports.createNetworkEvent = function(
if (channel instanceof Ci.nsIClassifiedChannel) {
event.isThirdPartyTrackingResource = !!(
channel.isThirdPartyTrackingResource() &&
(channel.thirdPartyClassificationFlags & tpFlagsMask) == 0
(channel.thirdPartyClassificationFlags & lazy.tpFlagsMask) == 0
);
}
const referrerInfo = channel.referrerInfo;
@ -275,7 +269,9 @@ exports.createNetworkEvent = function(
if (blockedReason !== undefined) {
// We were definitely blocked, but the blocker didn't say why.
event.blockedReason = "unknown";
} else if (blockedURLs.some(url => wildcardToRegExp(url).test(event.url))) {
} else if (
blockedURLs.some(url => lazy.wildcardToRegExp(url).test(event.url))
) {
channel.cancel(Cr.NS_BINDING_ABORTED);
event.blockedReason = "devtools";
}
@ -293,7 +289,7 @@ exports.createNetworkEvent = function(
channel.isMainDocumentChannel && channel.loadInfo.isTopLevelLoad;
return event;
};
}
/**
* For a given channel, with its associated http activity object,
@ -305,7 +301,7 @@ exports.createNetworkEvent = function(
* @param {*} owner - The network event actor
* @param {Object} extraStringData - The uncached response headers.
*/
exports.fetchRequestHeadersAndCookies = function(
function fetchRequestHeadersAndCookies(
channel,
owner,
{ extraStringData = "" }
@ -325,12 +321,12 @@ exports.fetchRequestHeadersAndCookies = function(
});
if (cookieHeader) {
cookies = NetworkHelper.parseCookieHeader(cookieHeader);
cookies = lazy.NetworkHelper.parseCookieHeader(cookieHeader);
}
owner.addRequestHeaders(headers, extraStringData);
owner.addRequestCookies(cookies);
};
}
/**
* Check if a given network request should be logged by a network monitor
@ -372,7 +368,7 @@ function matchRequest(channel, filters) {
if (type == "browser-element") {
if (!channel.loadInfo.browsingContext) {
const topFrame = NetworkHelper.getTopFrameForRequest(channel);
const topFrame = lazy.NetworkHelper.getTopFrameForRequest(channel);
// `topFrame` is typically null for some chrome requests like favicons
// And its `browsingContext` attribute might be null if the request happened
// while the tab is being closed.
@ -406,7 +402,7 @@ function matchRequest(channel, filters) {
} catch (e) {
return false;
}
const win = NetworkHelper.getWindowForRequest(channel);
const win = lazy.NetworkHelper.getWindowForRequest(channel);
return windows.includes(win);
}
@ -436,7 +432,7 @@ function legacyMatchRequest(channel, filters) {
}
if (filters.window) {
let win = NetworkHelper.getWindowForRequest(channel);
let win = lazy.NetworkHelper.getWindowForRequest(channel);
if (filters.matchExactWindow) {
return win == filters.window;
}
@ -456,7 +452,7 @@ function legacyMatchRequest(channel, filters) {
}
if (filters.browserId) {
const topFrame = NetworkHelper.getTopFrameForRequest(channel);
const topFrame = lazy.NetworkHelper.getTopFrameForRequest(channel);
// `topFrame` is typically null for some chrome requests like favicons
// And its `browsingContext` attribute might be null if the request happened
// while the tab is being closed.
@ -484,4 +480,14 @@ function legacyMatchRequest(channel, filters) {
return false;
}
exports.matchRequest = matchRequest;
export const NetworkUtils = {
causeTypeToString,
createNetworkEvent,
fetchRequestHeadersAndCookies,
getChannelBrowsingContextID,
getChannelInnerWindowId,
isPreloadRequest,
matchRequest,
stringToCauseType,
};

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

@ -2,12 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Create a RegExp from a given wildcard string.
*/
function wildcardToRegExp(s) {
export function wildcardToRegExp(s) {
return new RegExp(
s
.split("*")
@ -16,7 +14,6 @@ function wildcardToRegExp(s) {
"i"
);
}
exports.wildcardToRegExp = wildcardToRegExp;
/**
* Escapes all special RegExp characters in the given string.

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

@ -4,4 +4,8 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules("channel-map.js", "network-utils.js", "wildcard-to-regexp.js")
DevToolsModules(
"ChannelMap.sys.mjs",
"NetworkUtils.sys.mjs",
"WildcardToRegexp.sys.mjs",
)

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

@ -11,11 +11,12 @@ loader.lazyRequireGetter(
true
);
loader.lazyRequireGetter(
this,
"NetworkUtils",
"resource://devtools/server/actors/network-monitor/utils/network-utils.js"
);
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
NetworkUtils:
"resource://devtools/server/actors/network-monitor/utils/NetworkUtils.sys.mjs",
});
/**
* Handles network events from the content process
@ -72,12 +73,12 @@ class NetworkEventContentWatcher {
// Ignore preload requests to avoid duplicity request entries in
// the Network panel. If a preload fails (for whatever reason)
// then the platform kicks off another 'real' request.
if (NetworkUtils.isPreloadRequest(channel)) {
if (lazy.NetworkUtils.isPreloadRequest(channel)) {
return;
}
if (
!NetworkUtils.matchRequest(channel, {
!lazy.NetworkUtils.matchRequest(channel, {
targetActor: this.targetActor,
})
) {
@ -104,7 +105,7 @@ class NetworkEventContentWatcher {
const channel = subject.QueryInterface(Ci.nsIHttpChannel);
if (
!NetworkUtils.matchRequest(channel, {
!lazy.NetworkUtils.matchRequest(channel, {
targetActor: this.targetActor,
})
) {
@ -137,7 +138,10 @@ class NetworkEventContentWatcher {
channel,
{ networkEventOptions, resourceOverrides, onNetworkEventUpdate }
) {
const event = NetworkUtils.createNetworkEvent(channel, networkEventOptions);
const event = lazy.NetworkUtils.createNetworkEvent(
channel,
networkEventOptions
);
const actor = new NetworkEventActor(
this.conn,
@ -170,7 +174,7 @@ class NetworkEventContentWatcher {
}
this.onAvailable([resource]);
NetworkUtils.fetchRequestHeadersAndCookies(channel, actor, {});
lazy.NetworkUtils.fetchRequestHeadersAndCookies(channel, actor, {});
}
/*

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

@ -15,11 +15,12 @@ loader.lazyRequireGetter(
true
);
loader.lazyRequireGetter(
this,
"NetworkUtils",
"resource://devtools/server/actors/network-monitor/utils/network-utils.js"
);
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
NetworkUtils:
"resource://devtools/server/actors/network-monitor/utils/NetworkUtils.sys.mjs",
});
class NetworkEventStackTracesWatcher {
/**
@ -110,7 +111,7 @@ class NetworkEventStackTracesWatcher {
}
if (
!NetworkUtils.matchRequest(channel, {
!lazy.NetworkUtils.matchRequest(channel, {
targetActor: this.targetActor,
})
) {

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

@ -13,18 +13,14 @@ const { WatcherRegistry } = ChromeUtils.importESModule(
);
const Targets = require("resource://devtools/server/actors/targets/index.js");
loader.lazyRequireGetter(
this,
"NetworkObserver",
"resource://devtools/server/actors/network-monitor/network-observer.js",
true
);
const lazy = {};
loader.lazyRequireGetter(
this,
"NetworkUtils",
"resource://devtools/server/actors/network-monitor/utils/network-utils.js"
);
ChromeUtils.defineESModuleGetters(lazy, {
NetworkObserver:
"resource://devtools/server/actors/network-monitor/NetworkObserver.sys.mjs",
NetworkUtils:
"resource://devtools/server/actors/network-monitor/utils/NetworkUtils.sys.mjs",
});
loader.lazyRequireGetter(
this,
@ -60,7 +56,7 @@ class NetworkEventWatcher {
this.onNetworkEventUpdated = onUpdated;
// Boolean to know if we keep previous document network events or not.
this.persist = false;
this.listener = new NetworkObserver(
this.listener = new lazy.NetworkObserver(
{ sessionContext: watcherActor.sessionContext },
{
onNetworkEvent: this.onNetworkEvent.bind(this),
@ -234,7 +230,7 @@ class NetworkEventWatcher {
);
if (isParentProcessOnlyBrowserToolbox) {
// We should ignore all requests coming from BrowsingContext running in another process
const browsingContextID = NetworkUtils.getChannelBrowsingContextID(
const browsingContextID = lazy.NetworkUtils.getChannelBrowsingContextID(
channel
);
const browsingContext = BrowsingContext.get(browsingContextID);

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

@ -31,6 +31,13 @@ const DevToolsUtils = require("resource://devtools/shared/DevToolsUtils.js");
const ErrorDocs = require("resource://devtools/server/actors/errordocs.js");
const Targets = require("resource://devtools/server/actors/targets/index.js");
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
NetworkUtils:
"resource://devtools/server/actors/network-monitor/utils/NetworkUtils.sys.mjs",
});
loader.lazyRequireGetter(
this,
"evalWithDebugger",
@ -61,7 +68,6 @@ loader.lazyRequireGetter(
"resource://devtools/shared/webconsole/js-property-provider.js",
true
);
const lazy = {};
ChromeUtils.defineModuleGetter(
lazy,
"NetUtil",
@ -102,11 +108,6 @@ loader.lazyRequireGetter(
"resource://devtools/shared/constants.js",
true
);
loader.lazyRequireGetter(
this,
"NetworkUtils",
"resource://devtools/server/actors/network-monitor/utils/network-utils.js"
);
// Generated by /devtools/shared/webconsole/GenerateReservedWordsJS.py
loader.lazyRequireGetter(
@ -1848,7 +1849,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
loadingNode: doc,
securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
contentPolicyType:
NetworkUtils.stringToCauseType(cause.type) ||
lazy.NetworkUtils.stringToCauseType(cause.type) ||
Ci.nsIContentPolicy.TYPE_OTHER,
});

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

@ -0,0 +1,101 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* The 3 methods here are duplicated from ThreadSafeDevToolsUtils.js
* The ones defined here are used from other sys.mjs files, mostly from the
* NetworkObserver codebase, while the ones remaining in ThreadSafeDevToolsUtils.js
* are used in commonjs modules, including modules which can be loaded in workers.
*
* sys.mjs modules are currently not supported in workers, see Bug 1247687.
*/
/**
* Report that |who| threw an exception, |exception|.
*/
function reportException(who, exception) {
const msg = `${who} threw an exception: ${safeErrorString(exception)}`;
dump(msg + "\n");
if (typeof console !== "undefined" && console && console.error) {
console.error(exception);
}
}
/**
* Given a handler function that may throw, return an infallible handler
* function that calls the fallible handler, and logs any exceptions it
* throws.
*
* @param handler function
* A handler function, which may throw.
* @param aName string
* A name for handler, for use in error messages. If omitted, we use
* handler.name.
*
* (SpiderMonkey does generate good names for anonymous functions, but we
* don't have a way to get at them from JavaScript at the moment.)
*/
function makeInfallible(handler, name = handler.name) {
return function() {
try {
return handler.apply(this, arguments);
} catch (ex) {
let who = "Handler function";
if (name) {
who += " " + name;
}
reportException(who, ex);
return undefined;
}
};
}
/**
* Turn the |error| into a string, without fail.
*
* @param {Error|any} error
*/
function safeErrorString(error) {
try {
let errorString = error.toString();
if (typeof errorString == "string") {
// Attempt to attach a stack to |errorString|. If it throws an error, or
// isn't a string, don't use it.
try {
if (error.stack) {
const stack = error.stack.toString();
if (typeof stack == "string") {
errorString += "\nStack: " + stack;
}
}
} catch (ee) {
// Ignore.
}
// Append additional line and column number information to the output,
// since it might not be part of the stringified error.
if (
typeof error.lineNumber == "number" &&
typeof error.columnNumber == "number"
) {
errorString +=
"Line: " + error.lineNumber + ", column: " + error.columnNumber;
}
return errorString;
}
} catch (ee) {
// Ignore.
}
// We failed to find a good error description, so do the next best thing.
return Object.prototype.toString.call(error);
}
export const DevToolsInfaillibleUtils = {
makeInfallible,
reportException,
safeErrorString,
};

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

@ -17,6 +17,10 @@ var {
const lazy = {};
ChromeUtils.defineModuleGetter(lazy, "OS", "resource://gre/modules/osfile.jsm");
ChromeUtils.defineESModuleGetters(lazy, {
NetworkHelper: "resource://devtools/shared/webconsole/NetworkHelper.sys.mjs",
});
ChromeUtils.defineModuleGetter(
lazy,
"FileUtils",
@ -472,10 +476,6 @@ DevToolsUtils.defineLazyGetter(this, "NetUtil", () => {
return ChromeUtils.import("resource://gre/modules/NetUtil.jsm").NetUtil;
});
DevToolsUtils.defineLazyGetter(this, "NetworkHelper", () => {
return require("resource://devtools/shared/webconsole/network-helper.js");
});
/**
* Performs a request to load the desired URL and returns a promise.
*
@ -618,7 +618,10 @@ function mainThreadFetch(
if (!charset) {
charset = aOptions.charset || "UTF-8";
}
const unicodeSource = NetworkHelper.convertToUnicode(source, charset);
const unicodeSource = lazy.NetworkHelper.convertToUnicode(
source,
charset
);
// Look for any source map URL in the response.
let sourceMapURL;

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

@ -50,6 +50,7 @@ DevToolsModules(
"content-observer.js",
"debounce.js",
"defer.js",
"DevToolsInfaillibleUtils.sys.mjs",
"DevToolsUtils.js",
"dom-helpers.js",
"dom-node-constants.js",

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

@ -2,19 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const lazy = {};
loader.lazyRequireGetter(
this,
"NetworkHelper",
"resource://devtools/shared/webconsole/network-helper.js"
);
ChromeUtils.defineESModuleGetters(lazy, {
NetworkHelper: "resource://devtools/shared/webconsole/NetworkHelper.sys.mjs",
});
/**
* Module to fetch cache objects from CacheStorageService
* and return them as an object.
*/
exports.CacheEntry = {
export const CacheEntry = {
/**
* Flag for cache session being initialized.
*/
@ -31,7 +29,7 @@ exports.CacheEntry = {
try {
const cacheService = Services.cache2;
if (cacheService) {
let loadContext = NetworkHelper.getRequestLoadContext(request);
let loadContext = lazy.NetworkHelper.getRequestLoadContext(request);
if (!loadContext) {
// Get default load context if we can't fetch.
loadContext = Services.loadContextInfo.default;

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

@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
"cache-entry.js",
"CacheEntry.sys.mjs",
"clipboard.js",
"stack.js",
)

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

@ -60,17 +60,20 @@
* Mihai Sucan (Mozilla Corp.)
*/
"use strict";
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
ChromeUtils.defineModuleGetter(
lazy,
"NetUtil",
"resource://gre/modules/NetUtil.jsm"
);
const DevToolsUtils = require("resource://devtools/shared/DevToolsUtils.js");
loader.lazyGetter(this, "certDecoder", () => {
ChromeUtils.defineESModuleGetters(lazy, {
DevToolsInfaillibleUtils:
"resource://devtools/shared/DevToolsInfaillibleUtils.sys.mjs",
});
XPCOMUtils.defineLazyModuleGetters(lazy, {
NetUtil: "resource://gre/modules/NetUtil.jsm",
});
XPCOMUtils.defineLazyGetter(lazy, "certDecoder", () => {
const { asn1js } = ChromeUtils.import(
"chrome://global/content/certviewer/asn1js_bundle.jsm"
);
@ -113,7 +116,7 @@ const COOKIE_SAMESITE = {
* Most of the following functions have been taken from the Firebug source. They
* have been modified to match the Firefox coding rules.
*/
var NetworkHelper = {
export var NetworkHelper = {
/**
* Converts text with a given charset to unicode.
*
@ -670,7 +673,7 @@ var NetworkHelper = {
// validation. Return info as info.state = insecure.
return info;
} else {
DevToolsUtils.reportException(
lazy.DevToolsInfaillibleUtils.reportException(
"NetworkHelper.parseSecurityInfo",
"Security state " + state + " has no known STATE_IS_* flags."
);
@ -718,7 +721,7 @@ var NetworkHelper = {
info.hsts = sss.isSecureURI(uri, originAttributes);
info.hpkp = pkps.hostHasPins(uri);
} else {
DevToolsUtils.reportException(
lazy.DevToolsInfaillibleUtils.reportException(
"NetworkHelper.parseSecurityInfo",
"Could not get HSTS/HPKP status as hostname is not available."
);
@ -766,8 +769,8 @@ var NetworkHelper = {
const certHash = cert.sha256Fingerprint;
let parsedCert = decodedCertificateCache.get(certHash);
if (!parsedCert) {
parsedCert = await certDecoder.parse(
certDecoder.pemToDER(cert.getBase64DERString())
parsedCert = await lazy.certDecoder.parse(
lazy.certDecoder.pemToDER(cert.getBase64DERString())
);
decodedCertificateCache.set(certHash, parsedCert);
}
@ -799,7 +802,7 @@ var NetworkHelper = {
sha256: parsedCert.fingerprint.sha256,
};
} else {
DevToolsUtils.reportException(
lazy.DevToolsInfaillibleUtils.reportException(
"NetworkHelper.parseCertificateInfo",
"Secure connection established without certificate."
);
@ -829,7 +832,7 @@ var NetworkHelper = {
case Ci.nsITransportSecurityInfo.TLS_VERSION_1_3:
return "TLSv1.3";
default:
DevToolsUtils.reportException(
lazy.DevToolsInfaillibleUtils.reportException(
"NetworkHelper.formatSecurityProtocol",
"protocolVersion " + version + " is unknown."
);
@ -864,7 +867,7 @@ var NetworkHelper = {
}
if (!isCipher) {
DevToolsUtils.reportException(
lazy.DevToolsInfaillibleUtils.reportException(
"NetworkHelper.getReasonsForWeakness",
"STATE_IS_BROKEN without a known reason. Full state was: " + state
);
@ -909,7 +912,3 @@ var NetworkHelper = {
return paramsArray;
},
};
for (const prop of Object.getOwnPropertyNames(NetworkHelper)) {
exports[prop] = NetworkHelper[prop];
}

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

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const ArrayBufferInputStream = Components.Constructor(
"@mozilla.org/io/arraybuffer-input-stream;1",
"nsIArrayBufferInputStream"
@ -14,14 +12,20 @@ const BinaryInputStream = Components.Constructor(
"setInputStream"
);
loader.lazyServiceGetter(
this,
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
XPCOMUtils.defineLazyServiceGetter(
lazy,
"gActivityDistributor",
"@mozilla.org/network/http-activity-distributor;1",
"nsIHttpActivityDistributor"
);
const { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
XPCOMUtils.defineLazyModuleGetters(lazy, {
setTimeout: "resource://gre/modules/Timer.jsm",
});
/**
* Construct a new nsIStreamListener that buffers data and provides a
@ -188,7 +192,7 @@ NetworkThrottleListener.prototype = {
if (
activitySubtype ===
gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE
lazy.gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE
) {
this.totalSize = extraSizeData;
}
@ -215,13 +219,19 @@ NetworkThrottleListener.prototype = {
*/
maybeEmitEvents() {
if (this.responseStarted) {
this.maybeEmit(gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_START);
this.maybeEmit(gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_HEADER);
this.maybeEmit(lazy.gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_START);
this.maybeEmit(
lazy.gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_HEADER
);
}
if (this.totalSize !== undefined && this.offset >= this.totalSize) {
this.maybeEmit(gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE);
this.maybeEmit(gActivityDistributor.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE);
this.maybeEmit(
lazy.gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE
);
this.maybeEmit(
lazy.gActivityDistributor.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE
);
}
},
@ -313,7 +323,7 @@ NetworkThrottleQueue.prototype = {
this.pendingRequests.add(throttleListener);
const delay = this.random(this.latencyMean, this.latencyMax);
if (delay > 0) {
setTimeout(() => this.allowDataFrom(throttleListener), delay);
lazy.setTimeout(() => this.allowDataFrom(throttleListener), delay);
} else {
this.allowDataFrom(throttleListener);
}
@ -381,7 +391,7 @@ NetworkThrottleQueue.prototype = {
// one second after the oldest previous read.
if (this.downloadQueue.length) {
const when = this.previousReads[0].when + 1000;
setTimeout(this.pump.bind(this), when - now);
lazy.setTimeout(this.pump.bind(this), when - now);
}
this.pumping = false;
@ -404,36 +414,35 @@ NetworkThrottleQueue.prototype = {
* downloadBPSMax are <= 0. Upload throttling will not be done if
* uploadBPSMean and uploadBPSMax are <= 0.
*/
function NetworkThrottleManager({
latencyMean,
latencyMax,
downloadBPSMean,
downloadBPSMax,
uploadBPSMean,
uploadBPSMax,
}) {
if (downloadBPSMax <= 0 && downloadBPSMean <= 0) {
this.downloadQueue = null;
} else {
this.downloadQueue = new NetworkThrottleQueue(
downloadBPSMean,
downloadBPSMax,
latencyMean,
latencyMax
);
export class NetworkThrottleManager {
constructor({
latencyMean,
latencyMax,
downloadBPSMean,
downloadBPSMax,
uploadBPSMean,
uploadBPSMax,
}) {
if (downloadBPSMax <= 0 && downloadBPSMean <= 0) {
this.downloadQueue = null;
} else {
this.downloadQueue = new NetworkThrottleQueue(
downloadBPSMean,
downloadBPSMax,
latencyMean,
latencyMax
);
}
if (uploadBPSMax <= 0 && uploadBPSMean <= 0) {
this.uploadQueue = null;
} else {
this.uploadQueue = Cc[
"@mozilla.org/network/throttlequeue;1"
].createInstance(Ci.nsIInputChannelThrottleQueue);
this.uploadQueue.init(uploadBPSMean, uploadBPSMax);
}
}
if (uploadBPSMax <= 0 && uploadBPSMean <= 0) {
this.uploadQueue = null;
} else {
this.uploadQueue = Cc[
"@mozilla.org/network/throttlequeue;1"
].createInstance(Ci.nsIInputChannelThrottleQueue);
this.uploadQueue.init(uploadBPSMean, uploadBPSMax);
}
}
exports.NetworkThrottleManager = NetworkThrottleManager;
NetworkThrottleManager.prototype = {
/**
* Create a new NetworkThrottleListener for a given channel and
* install it using |setNewListener|.
@ -450,7 +459,7 @@ NetworkThrottleManager.prototype = {
return listener;
}
return null;
},
}
/**
* Throttle uploads taking place on the given channel.
@ -462,5 +471,5 @@ NetworkThrottleManager.prototype = {
channel = channel.QueryInterface(Ci.nsIThrottledInputChannel);
channel.throttleQueue = this.uploadQueue;
}
},
};
}
}

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

@ -29,7 +29,7 @@ DevToolsModules(
"analyze-input-string.js",
"js-property-provider.js",
"messages.js",
"network-helper.js",
"NetworkHelper.sys.mjs",
"parser-helper.js",
"throttle.js",
"Throttle.sys.mjs",
)

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

@ -8,3 +8,7 @@
var { require } = ChromeUtils.importESModule(
"resource://devtools/shared/loader/Loader.sys.mjs"
);
ChromeUtils.defineESModuleGetters(this, {
NetworkHelper: "resource://devtools/shared/webconsole/NetworkHelper.sys.mjs",
});

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

@ -3,15 +3,6 @@
"use strict";
Object.defineProperty(this, "NetworkHelper", {
get() {
return require("resource://devtools/shared/webconsole/network-helper.js");
},
configurable: true,
writeable: false,
enumerable: true,
});
function run_test() {
test_isTextMimeType();
test_parseCookieHeader();

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

@ -5,15 +5,6 @@
// Tests that NetworkHelper.parseCertificateInfo parses certificate information
// correctly.
Object.defineProperty(this, "NetworkHelper", {
get() {
return require("resource://devtools/shared/webconsole/network-helper.js");
},
configurable: true,
writeable: false,
enumerable: true,
});
const DUMMY_CERT = {
getBase64DERString() {
// This is the base64-encoded contents of the "DigiCert ECC Secure Server CA"

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

@ -4,15 +4,6 @@
// Test that NetworkHelper.parseSecurityInfo returns correctly formatted object.
Object.defineProperty(this, "NetworkHelper", {
get() {
return require("resource://devtools/shared/webconsole/network-helper.js");
},
configurable: true,
writeable: false,
enumerable: true,
});
const wpl = Ci.nsIWebProgressListener;
const MockCertificate = {
getBase64DERString() {

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

@ -5,15 +5,6 @@
// Tests that NetworkHelper.formatSecurityProtocol returns correct
// protocol version strings.
Object.defineProperty(this, "NetworkHelper", {
get() {
return require("resource://devtools/shared/webconsole/network-helper.js");
},
configurable: true,
writeable: false,
enumerable: true,
});
const TEST_CASES = [
{
description: "TLS_VERSION_1",

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

@ -5,15 +5,6 @@
// Tests that security info parser gives correct general security state for
// different cases.
Object.defineProperty(this, "NetworkHelper", {
get() {
return require("resource://devtools/shared/webconsole/network-helper.js");
},
configurable: true,
writeable: false,
enumerable: true,
});
const wpl = Ci.nsIWebProgressListener;
// This *cannot* be used as an nsITransportSecurityInfo (since that interface is

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

@ -4,15 +4,6 @@
// Test that NetworkHelper.parseSecurityInfo correctly detects static hpkp pins
Object.defineProperty(this, "NetworkHelper", {
get() {
return require("resource://devtools/shared/webconsole/network-helper.js");
},
configurable: true,
writeable: false,
enumerable: true,
});
const wpl = Ci.nsIWebProgressListener;
// This *cannot* be used as an nsITransportSecurityInfo (since that interface is

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

@ -5,15 +5,6 @@
// Tests that NetworkHelper.getReasonsForWeakness returns correct reasons for
// weak requests.
Object.defineProperty(this, "NetworkHelper", {
get() {
return require("resource://devtools/shared/webconsole/network-helper.js");
},
configurable: true,
writeable: false,
enumerable: true,
});
const wpl = Ci.nsIWebProgressListener;
const TEST_CASES = [
{

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

@ -5,9 +5,9 @@
/* eslint-disable mozilla/use-chromeutils-generateqi */
const {
NetworkThrottleManager,
} = require("resource://devtools/shared/webconsole/throttle.js");
const { NetworkThrottleManager } = ChromeUtils.importESModule(
"resource://devtools/shared/webconsole/Throttle.sys.mjs"
);
const nsIScriptableInputStream = Ci.nsIScriptableInputStream;
function TestStreamListener() {