summaryrefslogtreecommitdiffstats
path: root/remote/shared/listeners/NetworkEventRecord.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'remote/shared/listeners/NetworkEventRecord.sys.mjs')
-rw-r--r--remote/shared/listeners/NetworkEventRecord.sys.mjs290
1 files changed, 29 insertions, 261 deletions
diff --git a/remote/shared/listeners/NetworkEventRecord.sys.mjs b/remote/shared/listeners/NetworkEventRecord.sys.mjs
index 72b43e3de1..0f592d62b0 100644
--- a/remote/shared/listeners/NetworkEventRecord.sys.mjs
+++ b/remote/shared/listeners/NetworkEventRecord.sys.mjs
@@ -4,10 +4,8 @@
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
- NetworkUtils:
- "resource://devtools/shared/network-observer/NetworkUtils.sys.mjs",
-
- TabManager: "chrome://remote/content/shared/TabManager.sys.mjs",
+ NetworkRequest: "chrome://remote/content/shared/NetworkRequest.sys.mjs",
+ NetworkResponse: "chrome://remote/content/shared/NetworkResponse.sys.mjs",
});
/**
@@ -18,17 +16,10 @@ ChromeUtils.defineESModuleGetters(lazy, {
* NetworkListener instance which created it.
*/
export class NetworkEventRecord {
- #contextId;
#fromCache;
- #isMainDocumentChannel;
#networkListener;
- #redirectCount;
- #requestChannel;
- #requestData;
- #requestId;
- #responseChannel;
- #responseData;
- #wrappedChannel;
+ #request;
+ #response;
/**
*
@@ -39,56 +30,21 @@ export class NetworkEventRecord {
* The nsIChannel behind this network event.
* @param {NetworkListener} networkListener
* The NetworkListener which created this NetworkEventRecord.
+ * @param {NavigationManager} navigationManager
+ * The NavigationManager which belongs to the same session as this
+ * NetworkEventRecord.
*/
- constructor(networkEvent, channel, networkListener) {
- this.#requestChannel = channel;
- this.#responseChannel = null;
+ constructor(networkEvent, channel, networkListener, navigationManager) {
+ this.#request = new lazy.NetworkRequest(channel, {
+ navigationManager,
+ rawHeaders: networkEvent.rawHeaders,
+ });
+ this.#response = null;
this.#fromCache = networkEvent.fromCache;
- this.#isMainDocumentChannel = channel.isMainDocumentChannel;
-
- this.#wrappedChannel = ChannelWrapper.get(channel);
this.#networkListener = networkListener;
- // The context ids computed by TabManager have the lifecycle of a navigable
- // and can be reused for all the events emitted from this record.
- this.#contextId = this.#getContextId();
-
- // The wrappedChannel id remains identical across redirects, whereas
- // nsIChannel.channelId is different for each and every request.
- this.#requestId = this.#wrappedChannel.id.toString();
-
- const { cookies, headers } =
- lazy.NetworkUtils.fetchRequestHeadersAndCookies(channel);
-
- // See the RequestData type definition for the full list of properties that
- // should be set on this object.
- this.#requestData = {
- bodySize: null,
- cookies,
- headers,
- headersSize: networkEvent.rawHeaders ? networkEvent.rawHeaders.length : 0,
- method: channel.requestMethod,
- request: this.#requestId,
- timings: {},
- url: channel.URI.spec,
- };
-
- // See the ResponseData type definition for the full list of properties that
- // should be set on this object.
- this.#responseData = {
- // encoded size (body)
- bodySize: null,
- content: {
- // decoded size
- size: null,
- },
- // encoded size (headers)
- headersSize: null,
- url: channel.URI.spec,
- };
-
// NetworkObserver creates a network event when request headers have been
// parsed.
// According to the BiDi spec, we should emit beforeRequestSent when adding
@@ -113,8 +69,7 @@ export class NetworkEventRecord {
* The request POST data.
*/
addRequestPostData(postData) {
- // Only the postData size is needed for RemoteAgent consumers.
- this.#requestData.bodySize = postData.size;
+ this.#request.setPostData(postData);
}
/**
@@ -130,25 +85,11 @@ export class NetworkEventRecord {
* @param {string} options.rawHeaders
*/
addResponseStart(options) {
- const { channel, fromCache, rawHeaders = "" } = options;
- this.#responseChannel = channel;
-
- const { headers } =
- lazy.NetworkUtils.fetchResponseHeadersAndCookies(channel);
-
- const headersSize = rawHeaders.length;
- this.#responseData = {
- ...this.#responseData,
- bodySize: 0,
- bytesReceived: headersSize,
+ const { channel, fromCache, rawHeaders } = options;
+ this.#response = new lazy.NetworkResponse(channel, {
+ rawHeaders,
fromCache: this.#fromCache || !!fromCache,
- headers,
- headersSize,
- mimeType: this.#getMimeType(),
- protocol: lazy.NetworkUtils.getProtocol(channel),
- status: channel.responseStatus,
- statusText: channel.responseStatusText,
- };
+ });
// This should be triggered when all headers have been received, matching
// the WebDriverBiDi response started trigger in `4.6. HTTP-network fetch`
@@ -189,25 +130,16 @@ export class NetworkEventRecord {
*
* Required API for a NetworkObserver event owner.
*
- * @param {object} response
+ * @param {object} responseContent
* An object which represents the response content.
* @param {object} responseInfo
* Additional meta data about the response.
*/
- addResponseContent(response, responseInfo) {
- // Update content-related sizes with the latest data from addResponseContent.
- this.#responseData = {
- ...this.#responseData,
- bodySize: response.bodySize,
- bytesReceived: response.transferredSize,
- content: {
- size: response.decodedBodySize,
- },
- };
-
+ addResponseContent(responseContent, responseInfo) {
if (responseInfo.blockedReason) {
this.#emitFetchError();
} else {
+ this.#response.addResponseContent(responseContent);
this.#emitResponseCompleted();
}
}
@@ -234,201 +166,37 @@ export class NetworkEventRecord {
this.#emitAuthRequired(authCallbacks);
}
- /**
- * Convert the provided request timing to a timing relative to the beginning
- * of the request. All timings are numbers representing high definition
- * timestamps.
- *
- * @param {number} timing
- * High definition timestamp for a request timing relative from the time
- * origin.
- * @param {number} requestTime
- * High definition timestamp for the request start time relative from the
- * time origin.
- * @returns {number}
- * High definition timestamp for the request timing relative to the start
- * time of the request, or 0 if the provided timing was 0.
- */
- #convertTimestamp(timing, requestTime) {
- if (timing == 0) {
- return 0;
- }
-
- return timing - requestTime;
- }
-
#emitAuthRequired(authCallbacks) {
- this.#updateDataFromTimedChannel();
-
this.#networkListener.emit("auth-required", {
authCallbacks,
- contextId: this.#contextId,
- isNavigationRequest: this.#isMainDocumentChannel,
- redirectCount: this.#redirectCount,
- requestChannel: this.#requestChannel,
- requestData: this.#requestData,
- responseChannel: this.#responseChannel,
- responseData: this.#responseData,
- timestamp: Date.now(),
+ request: this.#request,
+ response: this.#response,
});
}
#emitBeforeRequestSent() {
- this.#updateDataFromTimedChannel();
-
this.#networkListener.emit("before-request-sent", {
- contextId: this.#contextId,
- isNavigationRequest: this.#isMainDocumentChannel,
- redirectCount: this.#redirectCount,
- requestChannel: this.#requestChannel,
- requestData: this.#requestData,
- timestamp: Date.now(),
+ request: this.#request,
});
}
#emitFetchError() {
- this.#updateDataFromTimedChannel();
-
this.#networkListener.emit("fetch-error", {
- contextId: this.#contextId,
- // TODO: Update with a proper error text. Bug 1873037.
- errorText: ChromeUtils.getXPCOMErrorName(this.#requestChannel.status),
- isNavigationRequest: this.#isMainDocumentChannel,
- redirectCount: this.#redirectCount,
- requestChannel: this.#requestChannel,
- requestData: this.#requestData,
- timestamp: Date.now(),
+ request: this.#request,
});
}
#emitResponseCompleted() {
- this.#updateDataFromTimedChannel();
-
this.#networkListener.emit("response-completed", {
- contextId: this.#contextId,
- isNavigationRequest: this.#isMainDocumentChannel,
- redirectCount: this.#redirectCount,
- requestChannel: this.#requestChannel,
- requestData: this.#requestData,
- responseChannel: this.#responseChannel,
- responseData: this.#responseData,
- timestamp: Date.now(),
+ request: this.#request,
+ response: this.#response,
});
}
#emitResponseStarted() {
- this.#updateDataFromTimedChannel();
-
this.#networkListener.emit("response-started", {
- contextId: this.#contextId,
- isNavigationRequest: this.#isMainDocumentChannel,
- redirectCount: this.#redirectCount,
- requestChannel: this.#requestChannel,
- requestData: this.#requestData,
- responseChannel: this.#responseChannel,
- responseData: this.#responseData,
- timestamp: Date.now(),
+ request: this.#request,
+ response: this.#response,
});
}
-
- #getBrowsingContext() {
- const id = lazy.NetworkUtils.getChannelBrowsingContextID(
- this.#requestChannel
- );
- return BrowsingContext.get(id);
- }
-
- /**
- * Retrieve the navigable id for the current browsing context associated to
- * the requests' channel. Network events are recorded in the parent process
- * so we always expect to be able to use TabManager.getIdForBrowsingContext.
- *
- * @returns {string}
- * The navigable id corresponding to the given browsing context.
- */
- #getContextId() {
- return lazy.TabManager.getIdForBrowsingContext(this.#getBrowsingContext());
- }
-
- #getMimeType() {
- // TODO: DevTools NetworkObserver is computing a similar value in
- // addResponseContent, but uses an inconsistent implementation in
- // addResponseStart. This approach can only be used as early as in
- // addResponseHeaders. We should move this logic to the NetworkObserver and
- // expose mimeType in addResponseStart. Bug 1809670.
- let mimeType = "";
-
- try {
- mimeType = this.#wrappedChannel.contentType;
- const contentCharset = this.#requestChannel.contentCharset;
- if (contentCharset) {
- mimeType += `;charset=${contentCharset}`;
- }
- } catch (e) {
- // Ignore exceptions when reading contentType/contentCharset
- }
-
- return mimeType;
- }
-
- #getTimingsFromTimedChannel(timedChannel) {
- const {
- channelCreationTime,
- redirectStartTime,
- redirectEndTime,
- dispatchFetchEventStartTime,
- cacheReadStartTime,
- domainLookupStartTime,
- domainLookupEndTime,
- connectStartTime,
- connectEndTime,
- secureConnectionStartTime,
- requestStartTime,
- responseStartTime,
- responseEndTime,
- } = timedChannel;
-
- // fetchStart should be the post-redirect start time, which should be the
- // first non-zero timing from: dispatchFetchEventStart, cacheReadStart and
- // domainLookupStart. See https://www.w3.org/TR/navigation-timing-2/#processing-model
- const fetchStartTime =
- dispatchFetchEventStartTime ||
- cacheReadStartTime ||
- domainLookupStartTime;
-
- // Bug 1805478: Per spec, the origin time should match Performance API's
- // timeOrigin for the global which initiated the request. This is not
- // available in the parent process, so for now we will use 0.
- const timeOrigin = 0;
-
- return {
- timeOrigin,
- requestTime: this.#convertTimestamp(channelCreationTime, timeOrigin),
- redirectStart: this.#convertTimestamp(redirectStartTime, timeOrigin),
- redirectEnd: this.#convertTimestamp(redirectEndTime, timeOrigin),
- fetchStart: this.#convertTimestamp(fetchStartTime, timeOrigin),
- dnsStart: this.#convertTimestamp(domainLookupStartTime, timeOrigin),
- dnsEnd: this.#convertTimestamp(domainLookupEndTime, timeOrigin),
- connectStart: this.#convertTimestamp(connectStartTime, timeOrigin),
- connectEnd: this.#convertTimestamp(connectEndTime, timeOrigin),
- tlsStart: this.#convertTimestamp(secureConnectionStartTime, timeOrigin),
- tlsEnd: this.#convertTimestamp(connectEndTime, timeOrigin),
- requestStart: this.#convertTimestamp(requestStartTime, timeOrigin),
- responseStart: this.#convertTimestamp(responseStartTime, timeOrigin),
- responseEnd: this.#convertTimestamp(responseEndTime, timeOrigin),
- };
- }
-
- /**
- * Update the timings and the redirect count from the nsITimedChannel
- * corresponding to the current channel. This should be called before emitting
- * any event from this class.
- */
- #updateDataFromTimedChannel() {
- const timedChannel = this.#requestChannel.QueryInterface(
- Ci.nsITimedChannel
- );
- this.#redirectCount = timedChannel.redirectCount;
- this.#requestData.timings = this.#getTimingsFromTimedChannel(timedChannel);
- }
}