summaryrefslogtreecommitdiffstats
path: root/remote/webdriver-bidi/modules/root/network.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'remote/webdriver-bidi/modules/root/network.sys.mjs')
-rw-r--r--remote/webdriver-bidi/modules/root/network.sys.mjs457
1 files changed, 191 insertions, 266 deletions
diff --git a/remote/webdriver-bidi/modules/root/network.sys.mjs b/remote/webdriver-bidi/modules/root/network.sys.mjs
index 6850e3f372..326fa87a02 100644
--- a/remote/webdriver-bidi/modules/root/network.sys.mjs
+++ b/remote/webdriver-bidi/modules/root/network.sys.mjs
@@ -12,8 +12,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
generateUUID: "chrome://remote/content/shared/UUID.sys.mjs",
matchURLPattern:
"chrome://remote/content/shared/webdriver/URLPattern.sys.mjs",
- notifyNavigationStarted:
- "chrome://remote/content/shared/NavigationManager.sys.mjs",
NetworkListener:
"chrome://remote/content/shared/listeners/NetworkListener.sys.mjs",
parseChallengeHeader:
@@ -309,7 +307,9 @@ class NetworkModule extends Module {
// Set of event names which have active subscriptions
this.#subscribedEvents = new Set();
- this.#networkListener = new lazy.NetworkListener();
+ this.#networkListener = new lazy.NetworkListener(
+ this.messageHandler.navigationManager
+ );
this.#networkListener.on("auth-required", this.#onAuthRequired);
this.#networkListener.on("before-request-sent", this.#onBeforeRequestSent);
this.#networkListener.on("fetch-error", this.#onFetchError);
@@ -549,8 +549,7 @@ class NetworkModule extends Module {
);
}
- const wrapper = ChannelWrapper.get(request);
- wrapper.resume();
+ request.wrappedChannel.resume();
resolveBlockedEvent();
}
@@ -684,8 +683,7 @@ class NetworkModule extends Module {
await authCallbacks.provideAuthCredentials();
}
} else {
- const wrapper = ChannelWrapper.get(request);
- wrapper.resume();
+ request.wrappedChannel.resume();
}
resolveBlockedEvent();
@@ -803,9 +801,8 @@ class NetworkModule extends Module {
);
}
- const wrapper = ChannelWrapper.get(request);
- wrapper.resume();
- wrapper.cancel(
+ request.wrappedChannel.resume();
+ request.wrappedChannel.cancel(
Cr.NS_ERROR_ABORT,
Ci.nsILoadInfo.BLOCKING_REASON_WEBDRIVER_BIDI
);
@@ -933,8 +930,7 @@ class NetworkModule extends Module {
if (phase === InterceptPhase.AuthRequired) {
await authCallbacks.provideAuthCredentials();
} else {
- const wrapper = ChannelWrapper.get(request);
- wrapper.resume();
+ request.wrappedChannel.resume();
}
resolveBlockedEvent();
@@ -987,11 +983,7 @@ class NetworkModule extends Module {
* The response channel.
*/
#addBlockedRequest(requestId, phase, options = {}) {
- const {
- authCallbacks,
- requestChannel: request,
- responseChannel: response,
- } = options;
+ const { authCallbacks, request, response } = options;
const { promise: blockedEventPromise, resolve: resolveBlockedEvent } =
Promise.withResolvers();
@@ -1117,14 +1109,14 @@ class NetworkModule extends Module {
}
}
- #extractChallenges(responseData) {
+ #extractChallenges(response) {
let headerName;
// Using case-insensitive match for header names, so we use the lowercase
// version of the "WWW-Authenticate" / "Proxy-Authenticate" strings.
- if (responseData.status === 401) {
+ if (response.status === 401) {
headerName = "www-authenticate";
- } else if (responseData.status === 407) {
+ } else if (response.status === 407) {
headerName = "proxy-authenticate";
} else {
return null;
@@ -1132,10 +1124,10 @@ class NetworkModule extends Module {
const challenges = [];
- for (const header of responseData.headers) {
- if (header.name.toLowerCase() === headerName) {
+ for (const [name, value] of response.getHeadersList()) {
+ if (name.toLowerCase() === headerName) {
// A single header can contain several challenges.
- const headerChallenges = lazy.parseChallengeHeader(header.value);
+ const headerChallenges = lazy.parseChallengeHeader(value);
for (const headerChallenge of headerChallenges) {
const realmParam = headerChallenge.params.find(
param => param.name == "realm"
@@ -1177,7 +1169,7 @@ class NetworkModule extends Module {
};
}
- #getNetworkIntercepts(event, requestData, contextId) {
+ #getNetworkIntercepts(event, request, topContextId) {
const intercepts = [];
let phase;
@@ -1197,17 +1189,11 @@ class NetworkModule extends Module {
return intercepts;
}
- // Retrieve the top browsing context id for this network event.
- const browsingContext = lazy.TabManager.getBrowsingContextById(contextId);
- const topLevelContextId = lazy.TabManager.getIdForBrowsingContext(
- browsingContext.top
- );
-
- const url = requestData.url;
+ const url = request.serializedURL;
for (const [interceptId, intercept] of this.#interceptMap) {
if (
intercept.contexts !== null &&
- !intercept.contexts.includes(topLevelContextId)
+ !intercept.contexts.includes(topContextId)
) {
// Skip this intercept if the event's context does not match the list
// of contexts for this intercept.
@@ -1228,31 +1214,96 @@ class NetworkModule extends Module {
return intercepts;
}
- #getNavigationId(eventName, isNavigationRequest, browsingContext, url) {
- if (!isNavigationRequest) {
- // Not a navigation request return null.
- return null;
+ #getRequestData(request) {
+ const requestId = request.requestId;
+
+ // "Let url be the result of running the URL serializer with request’s URL"
+ // request.serializedURL is already serialized.
+ const url = request.serializedURL;
+ const method = request.method;
+
+ const bodySize = request.postDataSize;
+ const headersSize = request.headersSize;
+ const headers = [];
+ const cookies = [];
+
+ for (const [name, value] of request.getHeadersList()) {
+ headers.push(this.#serializeHeader(name, value));
+ if (name.toLowerCase() == "cookie") {
+ // TODO: Retrieve the actual cookies from the cookie store.
+ const headerCookies = value.split(";");
+ for (const cookie of headerCookies) {
+ const equal = cookie.indexOf("=");
+ const cookieName = cookie.substr(0, equal);
+ const cookieValue = cookie.substr(equal + 1);
+ const serializedCookie = this.#serializeHeader(
+ unescape(cookieName.trim()),
+ unescape(cookieValue.trim())
+ );
+ cookies.push(serializedCookie);
+ }
+ }
}
- let navigation =
- this.messageHandler.navigationManager.getNavigationForBrowsingContext(
- browsingContext
- );
+ const timings = request.getFetchTimings();
- // `onBeforeRequestSent` might be too early for the NavigationManager.
- // If there is no ongoing navigation, create one ourselves.
- // TODO: Bug 1835704 to detect navigations earlier and avoid this.
- if (
- eventName === "network.beforeRequestSent" &&
- (!navigation || navigation.finished)
- ) {
- navigation = lazy.notifyNavigationStarted({
- contextDetails: { context: browsingContext },
- url,
- });
+ return {
+ request: requestId,
+ url,
+ method,
+ bodySize,
+ headersSize,
+ headers,
+ cookies,
+ timings,
+ };
+ }
+
+ #getResponseContentInfo(response) {
+ return {
+ size: response.decodedBodySize,
+ };
+ }
+
+ #getResponseData(response) {
+ const url = response.serializedURL;
+ const protocol = response.protocol;
+ const status = response.status;
+ const statusText = response.statusMessage;
+ // TODO: Ideally we should have a `isCacheStateLocal` getter
+ // const fromCache = response.isCacheStateLocal();
+ const fromCache = response.fromCache;
+ const mimeType = response.getComputedMimeType();
+ const headers = [];
+ for (const [name, value] of response.getHeadersList()) {
+ headers.push(this.#serializeHeader(name, value));
+ }
+
+ const bytesReceived = response.totalTransmittedSize;
+ const headersSize = response.headersTransmittedSize;
+ const bodySize = response.encodedBodySize;
+ const content = this.#getResponseContentInfo(response);
+ const authChallenges = this.#extractChallenges(response);
+
+ const params = {
+ url,
+ protocol,
+ status,
+ statusText,
+ fromCache,
+ headers,
+ mimeType,
+ bytesReceived,
+ headersSize,
+ bodySize,
+ content,
+ };
+
+ if (authChallenges !== null) {
+ params.authChallenges = authChallenges;
}
- return navigation ? navigation.navigationId : null;
+ return params;
}
#getSuspendMarkerText(requestData, phase) {
@@ -1260,21 +1311,13 @@ class NetworkModule extends Module {
}
#onAuthRequired = (name, data) => {
- const {
- authCallbacks,
- contextId,
- isNavigationRequest,
- redirectCount,
- requestChannel,
- requestData,
- responseChannel,
- responseData,
- timestamp,
- } = data;
+ const { authCallbacks, request, response } = data;
let isBlocked = false;
try {
- const browsingContext = lazy.TabManager.getBrowsingContextById(contextId);
+ const browsingContext = lazy.TabManager.getBrowsingContextById(
+ request.contextId
+ );
if (!browsingContext) {
// Do not emit events if the context id does not match any existing
// browsing context.
@@ -1283,18 +1326,9 @@ class NetworkModule extends Module {
const protocolEventName = "network.authRequired";
- // Process the navigation to create potentially missing navigation ids
- // before the early return below.
- const navigation = this.#getNavigationId(
- protocolEventName,
- isNavigationRequest,
- browsingContext,
- requestData.url
- );
-
const isListening = this.messageHandler.eventsDispatcher.hasListener(
protocolEventName,
- { contextId }
+ { contextId: request.contextId }
);
if (!isListening) {
// If there are no listeners subscribed to this event and this context,
@@ -1302,23 +1336,16 @@ class NetworkModule extends Module {
return;
}
- const baseParameters = this.#processNetworkEvent(protocolEventName, {
- contextId,
- navigation,
- redirectCount,
- requestData,
- timestamp,
- });
+ const baseParameters = this.#processNetworkEvent(
+ protocolEventName,
+ request
+ );
- const authRequiredEvent = this.#serializeNetworkEvent({
+ const responseData = this.#getResponseData(response);
+ const authRequiredEvent = {
...baseParameters,
response: responseData,
- });
-
- const authChallenges = this.#extractChallenges(responseData);
- // authChallenges should never be null for a request which triggered an
- // authRequired event.
- authRequiredEvent.response.authChallenges = authChallenges;
+ };
this.emitEvent(
protocolEventName,
@@ -1337,8 +1364,8 @@ class NetworkModule extends Module {
InterceptPhase.AuthRequired,
{
authCallbacks,
- requestChannel,
- responseChannel,
+ request,
+ response,
}
);
}
@@ -1352,16 +1379,11 @@ class NetworkModule extends Module {
};
#onBeforeRequestSent = (name, data) => {
- const {
- contextId,
- isNavigationRequest,
- redirectCount,
- requestChannel,
- requestData,
- timestamp,
- } = data;
+ const { request } = data;
- const browsingContext = lazy.TabManager.getBrowsingContextById(contextId);
+ const browsingContext = lazy.TabManager.getBrowsingContextById(
+ request.contextId
+ );
if (!browsingContext) {
// Do not emit events if the context id does not match any existing
// browsing context.
@@ -1371,15 +1393,6 @@ class NetworkModule extends Module {
const internalEventName = "network._beforeRequestSent";
const protocolEventName = "network.beforeRequestSent";
- // Process the navigation to create potentially missing navigation ids
- // before the early return below.
- const navigation = this.#getNavigationId(
- protocolEventName,
- isNavigationRequest,
- browsingContext,
- requestData.url
- );
-
// Always emit internal events, they are used to support the browsingContext
// navigate command.
// Bug 1861922: Replace internal events with a Network listener helper
@@ -1387,15 +1400,15 @@ class NetworkModule extends Module {
this.emitEvent(
internalEventName,
{
- navigation,
- url: requestData.url,
+ navigation: request.navigationId,
+ url: request.serializedURL,
},
this.#getContextInfo(browsingContext)
);
const isListening = this.messageHandler.eventsDispatcher.hasListener(
protocolEventName,
- { contextId }
+ { contextId: request.contextId }
);
if (!isListening) {
// If there are no listeners subscribed to this event and this context,
@@ -1403,23 +1416,20 @@ class NetworkModule extends Module {
return;
}
- const baseParameters = this.#processNetworkEvent(protocolEventName, {
- contextId,
- navigation,
- redirectCount,
- requestData,
- timestamp,
- });
+ const baseParameters = this.#processNetworkEvent(
+ protocolEventName,
+ request
+ );
// Bug 1805479: Handle the initiator, including stacktrace details.
const initiator = {
type: InitiatorType.Other,
};
- const beforeRequestSentEvent = this.#serializeNetworkEvent({
+ const beforeRequestSentEvent = {
...baseParameters,
initiator,
- });
+ };
this.emitEvent(
protocolEventName,
@@ -1430,32 +1440,26 @@ class NetworkModule extends Module {
if (beforeRequestSentEvent.isBlocked) {
// TODO: Requests suspended in beforeRequestSent still reach the server at
// the moment. https://bugzilla.mozilla.org/show_bug.cgi?id=1849686
- const wrapper = ChannelWrapper.get(requestChannel);
- wrapper.suspend(
- this.#getSuspendMarkerText(requestData, "beforeRequestSent")
+ request.wrappedChannel.suspend(
+ this.#getSuspendMarkerText(request, "beforeRequestSent")
);
this.#addBlockedRequest(
beforeRequestSentEvent.request.request,
InterceptPhase.BeforeRequestSent,
{
- requestChannel,
+ request,
}
);
}
};
#onFetchError = (name, data) => {
- const {
- contextId,
- errorText,
- isNavigationRequest,
- redirectCount,
- requestData,
- timestamp,
- } = data;
+ const { request } = data;
- const browsingContext = lazy.TabManager.getBrowsingContextById(contextId);
+ const browsingContext = lazy.TabManager.getBrowsingContextById(
+ request.contextId
+ );
if (!browsingContext) {
// Do not emit events if the context id does not match any existing
// browsing context.
@@ -1465,15 +1469,6 @@ class NetworkModule extends Module {
const internalEventName = "network._fetchError";
const protocolEventName = "network.fetchError";
- // Process the navigation to create potentially missing navigation ids
- // before the early return below.
- const navigation = this.#getNavigationId(
- protocolEventName,
- isNavigationRequest,
- browsingContext,
- requestData.url
- );
-
// Always emit internal events, they are used to support the browsingContext
// navigate command.
// Bug 1861922: Replace internal events with a Network listener helper
@@ -1481,15 +1476,15 @@ class NetworkModule extends Module {
this.emitEvent(
internalEventName,
{
- navigation,
- url: requestData.url,
+ navigation: request.navigationId,
+ url: request.serializedURL,
},
this.#getContextInfo(browsingContext)
);
const isListening = this.messageHandler.eventsDispatcher.hasListener(
protocolEventName,
- { contextId }
+ { contextId: request.contextId }
);
if (!isListening) {
// If there are no listeners subscribed to this event and this context,
@@ -1497,18 +1492,15 @@ class NetworkModule extends Module {
return;
}
- const baseParameters = this.#processNetworkEvent(protocolEventName, {
- contextId,
- navigation,
- redirectCount,
- requestData,
- timestamp,
- });
+ const baseParameters = this.#processNetworkEvent(
+ protocolEventName,
+ request
+ );
- const fetchErrorEvent = this.#serializeNetworkEvent({
+ const fetchErrorEvent = {
...baseParameters,
- errorText,
- });
+ errorText: request.errorText,
+ };
this.emitEvent(
protocolEventName,
@@ -1518,18 +1510,11 @@ class NetworkModule extends Module {
};
#onResponseEvent = (name, data) => {
- const {
- contextId,
- isNavigationRequest,
- redirectCount,
- requestChannel,
- requestData,
- responseChannel,
- responseData,
- timestamp,
- } = data;
+ const { request, response } = data;
- const browsingContext = lazy.TabManager.getBrowsingContextById(contextId);
+ const browsingContext = lazy.TabManager.getBrowsingContextById(
+ request.contextId
+ );
if (!browsingContext) {
// Do not emit events if the context id does not match any existing
// browsing context.
@@ -1546,15 +1531,6 @@ class NetworkModule extends Module {
? "network._responseStarted"
: "network._responseCompleted";
- // Process the navigation to create potentially missing navigation ids
- // before the early return below.
- const navigation = this.#getNavigationId(
- protocolEventName,
- isNavigationRequest,
- browsingContext,
- requestData.url
- );
-
// Always emit internal events, they are used to support the browsingContext
// navigate command.
// Bug 1861922: Replace internal events with a Network listener helper
@@ -1562,15 +1538,15 @@ class NetworkModule extends Module {
this.emitEvent(
internalEventName,
{
- navigation,
- url: requestData.url,
+ navigation: request.navigationId,
+ url: request.serializedURL,
},
this.#getContextInfo(browsingContext)
);
const isListening = this.messageHandler.eventsDispatcher.hasListener(
protocolEventName,
- { contextId }
+ { contextId: request.contextId }
);
if (!isListening) {
// If there are no listeners subscribed to this event and this context,
@@ -1578,23 +1554,17 @@ class NetworkModule extends Module {
return;
}
- const baseParameters = this.#processNetworkEvent(protocolEventName, {
- contextId,
- navigation,
- redirectCount,
- requestData,
- timestamp,
- });
+ const baseParameters = this.#processNetworkEvent(
+ protocolEventName,
+ request
+ );
- const responseEvent = this.#serializeNetworkEvent({
+ const responseData = this.#getResponseData(response);
+
+ const responseEvent = {
...baseParameters,
response: responseData,
- });
-
- const authChallenges = this.#extractChallenges(responseData);
- if (authChallenges !== null) {
- responseEvent.response.authChallenges = authChallenges;
- }
+ };
this.emitEvent(
protocolEventName,
@@ -1606,51 +1576,40 @@ class NetworkModule extends Module {
protocolEventName === "network.responseStarted" &&
responseEvent.isBlocked
) {
- const wrapper = ChannelWrapper.get(requestChannel);
- wrapper.suspend(
- this.#getSuspendMarkerText(requestData, "responseStarted")
+ request.wrappedChannel.suspend(
+ this.#getSuspendMarkerText(request, "responseStarted")
);
this.#addBlockedRequest(
responseEvent.request.request,
InterceptPhase.ResponseStarted,
{
- requestChannel,
- responseChannel,
+ request,
+ response,
}
);
}
};
- /**
- * Process the network event data for a given network event name and create
- * the corresponding base parameters.
- *
- * @param {string} eventName
- * One of the supported network event names.
- * @param {object} data
- * @param {string} data.contextId
- * The browsing context id for the network event.
- * @param {string|null} data.navigation
- * The navigation id if this is a network event for a navigation request.
- * @param {number} data.redirectCount
- * The redirect count for the network event.
- * @param {RequestData} data.requestData
- * The network.RequestData information for the network event.
- * @param {number} data.timestamp
- * The timestamp when the network event was created.
- */
- #processNetworkEvent(eventName, data) {
- const { contextId, navigation, redirectCount, requestData, timestamp } =
- data;
- const intercepts = this.#getNetworkIntercepts(
- eventName,
- requestData,
- contextId
- );
- const isBlocked = !!intercepts.length;
+ #processNetworkEvent(event, request) {
+ const requestData = this.#getRequestData(request);
+ const navigation = request.navigationId;
+ let contextId = null;
+ let topContextId = null;
+ if (request.contextId) {
+ // Retrieve the top browsing context id for this network event.
+ contextId = request.contextId;
+ const browsingContext = lazy.TabManager.getBrowsingContextById(contextId);
+ topContextId = lazy.TabManager.getIdForBrowsingContext(
+ browsingContext.top
+ );
+ }
- const baseParameters = {
+ const intercepts = this.#getNetworkIntercepts(event, request, topContextId);
+ const redirectCount = request.redirectCount;
+ const timestamp = Date.now();
+ const isBlocked = !!intercepts.length;
+ const params = {
context: contextId,
isBlocked,
navigation,
@@ -1660,51 +1619,17 @@ class NetworkModule extends Module {
};
if (isBlocked) {
- baseParameters.intercepts = intercepts;
+ params.intercepts = intercepts;
}
- return baseParameters;
- }
-
- #serializeHeadersOrCookies(headersOrCookies) {
- return headersOrCookies.map(item => ({
- name: item.name,
- value: this.#serializeStringAsBytesValue(item.value),
- }));
+ return params;
}
- /**
- * Serialize in-place all cookies and headers arrays found in a given network
- * event payload.
- *
- * @param {object} networkEvent
- * The network event parameters object to serialize.
- * @returns {object}
- * The serialized network event parameters.
- */
- #serializeNetworkEvent(networkEvent) {
- // Make a shallow copy of networkEvent before serializing the headers and
- // cookies arrays in request/response.
- const serialized = { ...networkEvent };
-
- // Make a shallow copy of the request data.
- serialized.request = { ...networkEvent.request };
- serialized.request.cookies = this.#serializeHeadersOrCookies(
- networkEvent.request.cookies
- );
- serialized.request.headers = this.#serializeHeadersOrCookies(
- networkEvent.request.headers
- );
-
- if (networkEvent.response?.headers) {
- // Make a shallow copy of the response data.
- serialized.response = { ...networkEvent.response };
- serialized.response.headers = this.#serializeHeadersOrCookies(
- networkEvent.response.headers
- );
- }
-
- return serialized;
+ #serializeHeader(name, value) {
+ return {
+ name,
+ value: this.#serializeStringAsBytesValue(value),
+ };
}
/**