commit 63760f73c8971618240cbd485304f21bc01f1fe0
parent 4aafd5370851211ca68948717799a3b0c8037614
Author: Hubert Boma Manilla <hmanilla@mozilla.com>
Date: Fri, 19 Dec 2025 17:14:37 +0000
Bug 2004329 - [devtools] Display webTransport session request in the netmonitor r=devtools-reviewers,nchevobbe
This is the initial patch to displays a webtransport request in the netmonitor
when a new webtransport connection is created.
A good demo project for manual testing is https://github.com/BiagioFesta/wtransport
Differential Revision: https://phabricator.services.mozilla.com/D275196
Diffstat:
6 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/devtools/client/netmonitor/src/connector/index.js b/devtools/client/netmonitor/src/connector/index.js
@@ -66,6 +66,16 @@ class Connector {
TYPES.SERVER_SENT_EVENT,
];
+ get networkResources() {
+ const networkResources = Array.from(Connector.NETWORK_RESOURCES);
+ if (
+ Services.prefs.getBoolPref("devtools.netmonitor.features.webtransport")
+ ) {
+ networkResources.push(TYPES.WEBTRANSPORT);
+ }
+ return networkResources;
+ }
+
get currentTarget() {
return this.commands.targetCommand.targetFront;
}
@@ -161,7 +171,7 @@ class Connector {
if (isExplicitClear) {
// Only clear the resources if the clear was initiated explicitly by the
// UI, in other cases (eg navigation) the server handles the cleanup.
- this.commands.resourceCommand.clearResources(Connector.NETWORK_RESOURCES);
+ this.commands.resourceCommand.clearResources(this.networkResources);
this.emitForTests("clear-network-resources");
}
@@ -171,7 +181,7 @@ class Connector {
pause() {
return this.commands.resourceCommand.unwatchResources(
- Connector.NETWORK_RESOURCES,
+ this.networkResources,
{
onAvailable: this.onResourceAvailable,
onUpdated: this.onResourceUpdated,
@@ -180,14 +190,11 @@ class Connector {
}
resume(ignoreExistingResources = true) {
- return this.commands.resourceCommand.watchResources(
- Connector.NETWORK_RESOURCES,
- {
- onAvailable: this.onResourceAvailable,
- onUpdated: this.onResourceUpdated,
- ignoreExistingResources,
- }
- );
+ return this.commands.resourceCommand.watchResources(this.networkResources, {
+ onAvailable: this.onResourceAvailable,
+ onUpdated: this.onResourceUpdated,
+ ignoreExistingResources,
+ });
}
async onResourceAvailable(resources, { areExistingResources }) {
diff --git a/devtools/server/actors/resources/index.js b/devtools/server/actors/resources/index.js
@@ -25,6 +25,7 @@ const TYPES = {
JSTRACER_TRACE: "jstracer-trace",
JSTRACER_STATE: "jstracer-state",
WEBSOCKET: "websocket",
+ WEBTRANSPORT: "webtransport",
// storage types
CACHE_STORAGE: "Cache",
@@ -116,6 +117,9 @@ const FrameTargetResources = augmentResourceDictionary({
[TYPES.WEBSOCKET]: {
path: "devtools/server/actors/resources/websockets",
},
+ [TYPES.WEBTRANSPORT]: {
+ path: "devtools/server/actors/resources/webtransport",
+ },
});
// Process target resources are spawned via a Process Target Actor.
diff --git a/devtools/server/actors/resources/webtransport.js b/devtools/server/actors/resources/webtransport.js
@@ -10,12 +10,19 @@ const webTransportEventService = Cc[
class WebTransportWatcher {
constructor() {
- this.windowIds = new Set();
+ this.windowIds = new Map();
this.abortController = new AbortController();
this.onWindowReady = this.onWindowReady.bind(this);
this.onWindowDestroy = this.onWindowDestroy.bind(this);
}
+ static createResource(wtMessageType, eventParams) {
+ return {
+ wtMessageType,
+ ...eventParams,
+ };
+ }
+
watch(targetActor, { onAvailable }) {
this.targetActor = targetActor;
this.onAvailable = onAvailable;
@@ -47,14 +54,18 @@ class WebTransportWatcher {
startListening(innerWindowId) {
if (!this.windowIds.has(innerWindowId)) {
- this.windowIds.add(innerWindowId);
- webTransportEventService.addListener(innerWindowId, this);
+ const listener = {
+ // methods for the webTransportEventService
+ webTransportSessionCreated: () => {},
+ webTransportSessionClosed: () => {},
+ };
+ this.windowIds.set(innerWindowId, listener);
+ webTransportEventService.addListener(innerWindowId, listener);
}
}
stopListening(innerWindowId) {
if (this.windowIds.has(innerWindowId)) {
- this.windowIds.delete(innerWindowId);
if (!webTransportEventService.hasListenerFor(innerWindowId)) {
// The listener might have already been cleaned up on `window-destroy`.
console.warn(
@@ -62,7 +73,11 @@ class WebTransportWatcher {
);
return;
}
- webTransportEventService.removeListener(innerWindowId, this);
+ webTransportEventService.removeListener(
+ innerWindowId,
+ this.windowIds.get(innerWindowId)
+ );
+ this.windowIds.delete(innerWindowId);
}
}
@@ -72,8 +87,6 @@ class WebTransportWatcher {
this.stopListening(id);
}
}
-
- // TODO: methods for the webTransportEventService
}
module.exports = WebTransportWatcher;
diff --git a/devtools/server/actors/watcher/session-context.js b/devtools/server/actors/watcher/session-context.js
@@ -201,6 +201,7 @@ function getWatcherSupportedResources(_type) {
[Resources.TYPES.THREAD_STATE]: true,
[Resources.TYPES.SERVER_SENT_EVENT]: true,
[Resources.TYPES.WEBSOCKET]: true,
+ [Resources.TYPES.WEBTRANSPORT]: true,
[Resources.TYPES.JSTRACER_TRACE]: true,
[Resources.TYPES.JSTRACER_STATE]: true,
[Resources.TYPES.LAST_PRIVATE_CONTEXT_EXIT]: true,
diff --git a/devtools/shared/commands/resource/resource-command.js b/devtools/shared/commands/resource/resource-command.js
@@ -1287,6 +1287,7 @@ ResourceCommand.TYPES = ResourceCommand.prototype.TYPES = {
STYLESHEET: "stylesheet",
NETWORK_EVENT: "network-event",
WEBSOCKET: "websocket",
+ WEBTRANSPORT: "webtransport",
COOKIE: "cookies",
LOCAL_STORAGE: "local-storage",
SESSION_STORAGE: "session-storage",
diff --git a/devtools/shared/network-observer/NetworkUtils.sys.mjs b/devtools/shared/network-observer/NetworkUtils.sys.mjs
@@ -76,6 +76,7 @@ const LOAD_CAUSE_STRINGS = {
[Ci.nsIContentPolicy.TYPE_FONT]: "font",
[Ci.nsIContentPolicy.TYPE_MEDIA]: "media",
[Ci.nsIContentPolicy.TYPE_WEBSOCKET]: "websocket",
+ [Ci.nsIContentPolicy.TYPE_WEB_TRANSPORT]: "webtransport",
[Ci.nsIContentPolicy.TYPE_CSP_REPORT]: "csp",
[Ci.nsIContentPolicy.TYPE_XSLT]: "xslt",
[Ci.nsIContentPolicy.TYPE_BEACON]: "beacon",