MozillaZine

How to get context/tab/browser from process script (e10s)?

Talk about add-ons and extension development.
pintassilgo
 
Posts: 149
Joined: August 30th, 2013, 3:50 pm

Post Posted November 21st, 2017, 1:31 pm

[Previous subject: Redirect without recording original URL in history]

Most legacy redirection extensions, including the WebExtensions API intended for this (if I'm not mistaken), make redirects in http-on-modify-request. But this way the original URL is recorded in history as well as the redirected URL.

To prevent the original URL from being recorded you need to use [nsIContentPolicy].shouldLoad. In e10s world it needs to be implmented in content process. The code is something like:
Code: Select all
          shouldLoad: function (contentType, contentLocation, requestOrigin, node) {
            let redirectUrl = this.getRedirectUrl(contentLocation.spec);
            if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT && redirectUrl && node) {
              node.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).loadURI(redirectUrl, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, requestOrigin, null, null);
              return Ci.nsIContentPolicy.REJECT_REQUEST;
            }
            return Ci.nsIContentPolicy.ACCEPT;
          }

The original URL request is rejected by Ci.nsIContentPolicy.REJECT_REQUEST, then the loadURI function creates a new request on the same channel with the redirected URL. So far so good.

But because of https://bugzilla.mozilla.org/show_bug.cgi?id=1331740, this doesn't work anymore, fails on node.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation). So now how could I get some reference of the tab/channel where the original request was made to then be able to call loadURI function?
Last edited by pintassilgo on November 21st, 2017, 4:28 pm, edited 1 time in total.

pintassilgo
 
Posts: 149
Joined: August 30th, 2013, 3:50 pm

Post Posted November 21st, 2017, 4:20 pm

A workaround would be to use loadFrameScript instead of loadProcessScript, then content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).loadURI, but this is not recommended:

For example, in multiprocess Firefox, if you need to use nsIContentPolicy to register a content policy, you must do this in the content process. But if you register it in a frame script, and the frame script is loaded more than once, you'll register the content policy more than once, which probably isn't what you intend.

So I would like to continue using loadProcessScript, but I need a way to shouldLoad(context) { context.[what,please?].loadURI }.

pintassilgo
 
Posts: 149
Joined: August 30th, 2013, 3:50 pm

Post Posted November 21st, 2017, 6:17 pm

Solved using

Code: Select all
node.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsITabChild).messageManager.sendAsyncMessage('Redirector', redirectUrl);

in content process, and

Code: Select all
Services.mm.addMessageListener('Redirector', function (m) {
  m.target.loadURI(m.data, null, null, null, null);
});

in chrome process.

I'll use this solution, but I don't know which is best:
(1) comunicate between chrome and content processes (the solution in this post)
(2) inject the content script much more times using loadFrameScript instead of loadProcessScript (the solution in previous post).

I guess I chose it right, but not sure. Nor if there is a better solution than both.

Return to Extension Development


Who is online

Users browsing this forum: No registered users and 1 guest