Since the dawn of e10s we've had to deal with an architecture where we don't know how to handle a channel's content (whether to hit the Download manager, whether to decompress the content, etc) until we're on the child process. This had lead to some ugly workarounds, such as our (very fragile) channel.divertTo() stuff, and now a lot of IPDL traffic to support content-sniffing webextensions (bug 1255894). I've always been told it would be "hard" to move this logic to the parent, but I'd like us to explore it. bz, it sounds like you may be one of the only people who understands how the current setup works. Can you describe it and/or point us at the code where this logic lives now, so we can look into how we could copy this logic to the parent, or cache it, or something else cleverer than the status quo? Not urgent--I'd be surprised if we can get to this in the 57 time frame.
So this is specifically for loads in a docshell, right? The entrypoint for this is nsDocumentOpenInfo::OnStartRequest in uriloader/base/nsURILoader.cpp. This basically does the following (see nsDocumentOpenInfo::DispatchContent): 1) Get content type and disposition. 2) If disposition disallows inline handling, hand it off to the helper app service. 3) Otherwise, check whether our docshell (or generally our original listener; this is used by various non-docshell things too) wants to handle this load (via the IsPreferred/CanHandleContent calls to nsDSURIContentListener in the docshell case). Note that this will talk to the "parentContentListener" for the docshell, which can be chrome JS (e.g. see toolkit/content/widgets/editor.xml but there are also comm-central uses like suite/browser/nsBrowserContentListener.js and suite/common/helpviewer/help.js and mailnews/base/src/nsMsgWindow.cpp (that's a C++ parentContentListener). 4) If the original listener does not want to handle the load, try the list of listeners registered via nsIURILoader::RegisterContentListener. No in-tree consumers for that, but various addons use it. 5) If nothing found so far, try the contractids registered in the "external-uricontentlisteners" category. Again, unused in our code; extensions dxr says there's only one extension doint this. 6) If nothing found, look for an nsIContentHandler for the type. Note that we have chrome JS doing _this_ too; see browser/components/nsBrowserContentHandler.js, toolkit/mozapps/extensions/amContentHandler.js, and I didn't bother checking comm-central or addons. Pretty sure that amContentHandler thing is what handles addon installs, for example. 7) If still nothing found, look for a stream converter chain from the given type to "*/*" and if so do that, see what type results, and try the whole dispatch chain again. 8) If all that failed, hand to the helper app service. OK. So I suspect that steps 1,2, 6, 7, 8 could all happen in the chrome process. That's assuming we want to do stream converters in an unsandboxed environment; obviously it would be better to run them sandboxed if we can. Step 5 can probably go away. Step 4 can probably go away once there are no more XPCOM-using addons. Step 3 is the interesting one. It relies on state on the actual docshell involved (its parentContentListener, but also other bits like whether plugins are enabled on that docshell) to make decisions about what's OK to load in that docshell. So if we moved this to the chrome process we'd need to figure out how this part should work.