nsIContentPolicy.shouldLoad not called for web requests

NEW
Unassigned

Status

defect
8 years ago
8 years ago

People

(Reporter: mikeperry.unused, Unassigned)

Tracking

Trunk
x86
Linux

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

(Reporter)

Description

8 years ago
Last night I attempted to port HTTPSEverywhere to Firefox Mobile 4.0b3 (using the Linux version). It appears as though shoudLoad is only called for chrome urls, but not http/https requests.. HTTPSEverywhere relies on shouldLoad for early interception of requests to rewrite them.

Attached is a build of HTTPSEverywhere for fennec. It is built from git://git.torproject.org/mikeperry/https-everywhere.git branch firefox-mobile, and sets the loglevel to verbose. The calls to shouldLoad appear in the standard output (via dump()) and are prefixed by "shouldLoad:". 

It's apparent they stop as soon as all of the fennec chrome is loaded, and do not apply to any subsequent requests. This very same .xpi works fine on Firefox 4.0b10, with all appropriate calls to shouldLoad.
Mike,

chrome urls are loaded in "local" tabs (ie. in the parent process) while http and https urls are loaded in "remote" tabs (in the child process).

This means that you must load your implementation of nsIContentPolicy in the child process, using a content script.
(Reporter)

Comment 2

8 years ago
We are registering the content policy using the new xpcom category registration in chrome.manifest. It was my understanding this was the new way of registering for category events in FF4. For backward-compatibility, we also use the FF3.x mechanism of listing "content-policy" in the _xpcom_categories array.

Both of these are triggered during the component load by Firefox, so which process it happens in seems out of our control..

Is there another way to do this for fennec? If so, is it documented? I didn't see it on any of the fennec dev pages, but maybe I missed it.
The issue here is not fennec vs. firefox. The difference in fennec is that we use e10s to run content tabs in a different process, and that your components are not registered in this process.

Here's how I got a content policy working in a content script :

I defined my policy handler as a JS object in adblockplus:
var PolicyPrivate =
{
  classDescription: "Adblock Plus content policy (remote)",
  classID: Components.ID("de90f1ea-72c6-43f9-a500-133bbef0aedc"),
  contractID: "@adblockplus.org/abp/policy-remote;1",
  xpcom_categories: ["content-policy", "net-channel-event-sinks"],

  QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver,
    Ci.nsIChannelEventSink, Ci.nsIFactory, Ci.nsISupportsWeakReference]),

  ....
}

and then I register it manually :
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
  try
  {
    registrar.registerFactory(PolicyPrivate.classID, PolicyPrivate.classDescription, PolicyPrivate.contractI
D, PolicyPrivate);
  }
  catch (e)
  {
    // Don't stop on errors - the factory might already be registered
    Cu.reportError(e);
  }
  let catMan = Utils.categoryManager;
  for each (let category in PolicyPrivate.xpcom_categories)
    catMan.addCategoryEntry(category, PolicyPrivate.classDescription, PolicyPrivate.contractID, false, true);

For sure it would be better if the category manager did it automatically in content scripts!
(Reporter)

Comment 4

8 years ago
What is the scope here? By content script, do you mean scripts attached to a browser overlay?

In HTTPSEverywhere, we do not have any overlay scripts. We have a preferences window, but in fenec that is not allowed to have script attached..

Do we need to add a browser overlay just for this? Or is there another hack we can use? And should we expect this situation to remain the same by the time the beta is over?
A content script is loaded by the messageManager of the parent process. Look at the doc here :
https://wiki.mozilla.org/Mobile/Fennec/Extensions/Electrolysis

You'll need to have a overlay script just to load this content script, unless your add-on is restartless; in this case you can do it in bootstrap.js
(Reporter)

Comment 6

8 years ago
Two more questions:

1. What about the observer service? Do we also need to register each http observer in the new processes as well?

2. I'm guessing that once we add this e10s support we should not expect to have easy access to our URL rewriting rule sets that are loaded into memory? For best performance, should we perform message passing to actually check our rule sets for each request, or should we try to somehow copy or otherwise transmit the entire ruleset of some 15k rules into each new tab process?

I guess question #2 boils down to: is message passing super fast? Can we expect to be able to do ~3-5 message passing round trips for each request (because of our multiple observers) and expect it to be fast? Or should we take the memory overhead and copy the whole ruleset data structure into each new process?
(In reply to comment #6)
> Two more questions:
> 
> 1. What about the observer service? Do we also need to register each http
> observer in the new processes as well?

I have found that you can create a single observer listener in the parent process, and you will get notified for all tabs in the child process.

> 2. I'm guessing that once we add this e10s support we should not expect to have
> easy access to our URL rewriting rule sets that are loaded into memory? For
> best performance, should we perform message passing to actually check our rule
> sets for each request, or should we try to somehow copy or otherwise transmit
> the entire ruleset of some 15k rules into each new tab process?

Message passing is fast, but some caching might make sense in any case. We try to minimize message passing.
You need to log in before you can comment on or make changes to this bug.