Skip to content

Commit c8a64b8

Browse files
authored
browser(firefox): enable document channel (#4065)
In the current tip-of-tree Firefox, document channel is enabled by default, so we have to enable it in order to roll further. This patch: 1. Removes content disposition sniffing from content process since it crashes renderer with document channel. 2. Merges all page-related handlers in a single `PageHandler` and serializes network events wrt the `Page.frameAttached` event. The serialization mentioned in (2) is necessary: frame attachment is reported from the content process, and network events are reported from the browsers process. This is an inherent race, that becomes exposed by the document channel. On a side note, (2) makes it possible to synchronously report all buffered events in `SimpleChannel` (cc offline discussion with @dgozman that highlighted an unsighty approach that we currently employ there: reporting events in a subsequent microtask.) References #3995
1 parent e403fd3 commit c8a64b8

File tree

13 files changed

+216
-353
lines changed

13 files changed

+216
-353
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
1181
2-
Changed: [email protected] Mon, Oct 5, 2020 5:57:35 PM
1+
1182
2+
Changed: [email protected] Mon Oct 5 23:55:54 PDT 2020

browser_patches/firefox/juggler/NetworkObserver.js

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,25 +128,36 @@ class NetworkRequest {
128128
this.httpChannel = httpChannel;
129129
this._networkObserver._channelToRequest.set(this.httpChannel, this);
130130

131+
const loadInfo = this.httpChannel.loadInfo;
132+
let browsingContext = loadInfo?.frameBrowsingContext || loadInfo?.browsingContext;
133+
// TODO: Unfortunately, requests from web workers don't have frameBrowsingContext or
134+
// browsingContext.
135+
//
136+
// We fail to attribute them to the original frames on the browser side, but we
137+
// can use load context top frame to attribute them to the top frame at least.
138+
if (!browsingContext) {
139+
const loadContext = helper.getLoadContext(this.httpChannel);
140+
browsingContext = loadContext?.topFrameElement?.browsingContext;
141+
}
142+
143+
this._frameId = helper.browsingContextToFrameId(browsingContext);
144+
131145
this.requestId = httpChannel.channelId + '';
132146
this.navigationId = httpChannel.isMainDocumentChannel ? this.requestId : undefined;
133147

134148
const internalCauseType = this.httpChannel.loadInfo ? this.httpChannel.loadInfo.internalContentPolicyType : Ci.nsIContentPolicy.TYPE_OTHER;
135-
this.channelKey = this.httpChannel.channelId + ':' + internalCauseType;
136149

137150
this._redirectedIndex = 0;
138151
const ignoredRedirect = redirectedFrom && !redirectedFrom._sentOnResponse;
139152
if (ignoredRedirect) {
140153
// We just ignore redirect that did not hit the network before being redirected.
141154
// This happens, for example, for automatic http->https redirects.
142155
this.navigationId = redirectedFrom.navigationId;
143-
this.channelKey = redirectedFrom.channelKey;
144156
} else if (redirectedFrom) {
145157
this.redirectedFromId = redirectedFrom.requestId;
146158
this._redirectedIndex = redirectedFrom._redirectedIndex + 1;
147159
this.requestId = this.requestId + '-redirect' + this._redirectedIndex;
148160
this.navigationId = redirectedFrom.navigationId;
149-
this.channelKey = redirectedFrom.channelKey;
150161
// Finish previous request now. Since we inherit the listener, we could in theory
151162
// use onStopRequest, but that will only happen after the last redirect has finished.
152163
redirectedFrom._sendOnRequestFinished();
@@ -492,21 +503,9 @@ class NetworkRequest {
492503
const loadInfo = this.httpChannel.loadInfo;
493504
const causeType = loadInfo?.externalContentPolicyType || Ci.nsIContentPolicy.TYPE_OTHER;
494505
const internalCauseType = loadInfo?.internalContentPolicyType || Ci.nsIContentPolicy.TYPE_OTHER;
495-
496-
let browsingContext = loadInfo?.frameBrowsingContext || loadInfo?.browsingContext;
497-
// TODO: Unfortunately, requests from web workers don't have frameBrowsingContext or
498-
// browsingContext.
499-
//
500-
// We fail to attribute them to the original frames on the browser side, but we
501-
// can use load context top frame to attribute them to the top frame at least.
502-
if (!browsingContext) {
503-
const loadContext = helper.getLoadContext(this.httpChannel);
504-
browsingContext = loadContext?.topFrameElement?.browsingContext;
505-
}
506-
507506
pageNetwork.emit(PageNetwork.Events.Request, {
508507
url: this.httpChannel.URI.spec,
509-
frameId: helper.browsingContextToFrameId(browsingContext),
508+
frameId: this._frameId,
510509
isIntercepted,
511510
requestId: this.requestId,
512511
redirectedFrom: this.redirectedFromId,
@@ -516,7 +515,7 @@ class NetworkRequest {
516515
navigationId: this.navigationId,
517516
cause: causeTypeToString(causeType),
518517
internalCause: causeTypeToString(internalCauseType),
519-
}, this.channelKey);
518+
}, this._frameId);
520519
}
521520

522521
_sendOnResponse(fromCache) {
@@ -563,7 +562,7 @@ class NetworkRequest {
563562
remotePort,
564563
status,
565564
statusText,
566-
});
565+
}, this._frameId);
567566
}
568567

569568
_sendOnRequestFailed(error) {
@@ -572,7 +571,7 @@ class NetworkRequest {
572571
pageNetwork.emit(PageNetwork.Events.RequestFailed, {
573572
requestId: this.requestId,
574573
errorCode: helper.getNetworkErrorStatusText(error),
575-
});
574+
}, this._frameId);
576575
}
577576
this._networkObserver._channelToRequest.delete(this.httpChannel);
578577
}
@@ -582,7 +581,7 @@ class NetworkRequest {
582581
if (pageNetwork) {
583582
pageNetwork.emit(PageNetwork.Events.RequestFinished, {
584583
requestId: this.requestId,
585-
});
584+
}, this._frameId);
586585
}
587586
this._networkObserver._channelToRequest.delete(this.httpChannel);
588587
}

browser_patches/firefox/juggler/TargetRegistry.js

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,16 @@ class DownloadInterceptor {
2626
constructor(registry) {
2727
this._registry = registry
2828
this._handlerToUuid = new Map();
29-
helper.addObserver(this._onRequest.bind(this), 'http-on-modify-request');
30-
}
31-
32-
_onRequest(httpChannel, topic) {
33-
let loadContext = helper.getLoadContext(httpChannel);
34-
if (!loadContext)
35-
return;
36-
if (!loadContext.topFrameElement)
37-
return;
38-
const target = this._registry.targetForBrowser(loadContext.topFrameElement);
39-
if (!target)
40-
return;
41-
target._channelIds.add(httpChannel.channelId);
4229
}
4330

4431
//
4532
// nsIDownloadInterceptor implementation.
4633
//
4734
interceptDownloadRequest(externalAppHandler, request, browsingContext, outFile) {
48-
let pageTarget = this._registry._browserBrowsingContextToTarget.get(browsingContext);
49-
// New page downloads won't have browsing contex.
50-
if (!pageTarget)
51-
pageTarget = this._registry._targetForChannel(request);
35+
if (!(request instanceof Ci.nsIChannel))
36+
return false;
37+
const channel = request.QueryInterface(Ci.nsIChannel);
38+
let pageTarget = this._registry._browserBrowsingContextToTarget.get(channel.loadInfo.browsingContext);
5239
if (!pageTarget)
5340
return false;
5441

@@ -324,15 +311,6 @@ class TargetRegistry {
324311
targetForBrowser(browser) {
325312
return this._browserToTarget.get(browser);
326313
}
327-
328-
_targetForChannel(channel) {
329-
const channelId = channel.channelId;
330-
for (const target of this._browserToTarget.values()) {
331-
if (target._channelIds.has(channelId))
332-
return target;
333-
}
334-
return null;
335-
}
336314
}
337315

338316
class PageTarget {
@@ -350,7 +328,6 @@ class PageTarget {
350328
this._url = 'about:blank';
351329
this._openerId = opener ? opener.id() : undefined;
352330
this._channel = SimpleChannel.createForMessageManager(`browser::page[${this._targetId}]`, this._linkedBrowser.messageManager);
353-
this._channelIds = new Set();
354331
this._screencastInfo = undefined;
355332

356333
const navigationListener = {

browser_patches/firefox/juggler/components/juggler.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ CommandLineHandler.prototype = {
7373
if (silent)
7474
Services.startup.exitLastWindowClosingSurvivalArea();
7575
});
76-
dispatcher.rootSession().registerHandler('Browser', browserHandler);
76+
dispatcher.rootSession().setHandler(browserHandler);
7777
}
7878
});
7979
loadFrameScript();
@@ -101,9 +101,9 @@ CommandLineHandler.prototype = {
101101
pipe.stop();
102102
});
103103
});
104-
dispatcher.rootSession().registerHandler('Browser', browserHandler);
104+
dispatcher.rootSession().setHandler(browserHandler);
105105
loadFrameScript();
106-
dump(`Juggler listening to the pipe\n`);
106+
dump(`\nJuggler listening to the pipe\n`);
107107
}
108108
},
109109

browser_patches/firefox/juggler/content/FrameTree.js

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -197,19 +197,12 @@ class FrameTree {
197197
const isTransferring = flag & Ci.nsIWebProgressListener.STATE_TRANSFERRING;
198198
const isStop = flag & Ci.nsIWebProgressListener.STATE_STOP;
199199

200-
let isDownload = false;
201-
try {
202-
isDownload = (channel.contentDisposition === Ci.nsIChannel.DISPOSITION_ATTACHMENT);
203-
} catch(e) {
204-
// The method is expected to throw if it's not an attachment.
205-
}
206-
207200
if (isStart) {
208201
// Starting a new navigation.
209202
frame._pendingNavigationId = this._channelId(channel);
210203
frame._pendingNavigationURL = channel.URI.spec;
211204
this.emit(FrameTree.Events.NavigationStarted, frame);
212-
} else if (isTransferring || (isStop && frame._pendingNavigationId && !status && !isDownload)) {
205+
} else if (isTransferring || (isStop && frame._pendingNavigationId && !status)) {
213206
// Navigation is committed.
214207
for (const subframe of frame._children)
215208
this._detachFrame(subframe);
@@ -221,15 +214,15 @@ class FrameTree {
221214
this.emit(FrameTree.Events.NavigationCommitted, frame);
222215
if (frame === this._mainFrame)
223216
this.forcePageReady();
224-
} else if (isStop && frame._pendingNavigationId && (status || isDownload)) {
217+
} else if (isStop && frame._pendingNavigationId && status) {
225218
// Navigation is aborted.
226219
const navigationId = frame._pendingNavigationId;
227220
frame._pendingNavigationId = null;
228221
frame._pendingNavigationURL = null;
229222
// Always report download navigation as failure to match other browsers.
230-
const errorText = isDownload ? 'Will download to file' : helper.getNetworkErrorStatusText(status);
223+
const errorText = helper.getNetworkErrorStatusText(status);
231224
this.emit(FrameTree.Events.NavigationAborted, frame, navigationId, errorText);
232-
if (frame === this._mainFrame && status !== Cr.NS_BINDING_ABORTED && !isDownload)
225+
if (frame === this._mainFrame && status !== Cr.NS_BINDING_ABORTED)
233226
this.forcePageReady();
234227
}
235228
}
@@ -245,9 +238,9 @@ class FrameTree {
245238
}
246239

247240
_channelId(channel) {
248-
if (channel instanceof Ci.nsIHttpChannel) {
249-
const httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
250-
return String(httpChannel.channelId);
241+
if (channel instanceof Ci.nsIIdentChannel) {
242+
const identChannel = channel.QueryInterface(Ci.nsIIdentChannel);
243+
return String(identChannel.channelId);
251244
}
252245
return helper.generateId();
253246
}

browser_patches/firefox/juggler/jar.mn

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ juggler.jar:
1212
content/protocol/Protocol.js (protocol/Protocol.js)
1313
content/protocol/Dispatcher.js (protocol/Dispatcher.js)
1414
content/protocol/PageHandler.js (protocol/PageHandler.js)
15-
content/protocol/RuntimeHandler.js (protocol/RuntimeHandler.js)
16-
content/protocol/NetworkHandler.js (protocol/NetworkHandler.js)
1715
content/protocol/BrowserHandler.js (protocol/BrowserHandler.js)
18-
content/protocol/AccessibilityHandler.js (protocol/AccessibilityHandler.js)
1916
content/content/main.js (content/main.js)
2017
content/content/FrameTree.js (content/FrameTree.js)
2118
content/content/PageAgent.js (content/PageAgent.js)

browser_patches/firefox/juggler/protocol/AccessibilityHandler.js

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)