Message from discussion New Content Policy API
Received: by 10.68.0.33 with SMTP id 1mr1970563pbb.4.1316214443649;
Fri, 16 Sep 2011 16:07:23 -0700 (PDT)
NNTP-Posting-Date: Fri, 16 Sep 2011 18:07:22 -0500
X-Virus-Scanned: amavisd-new at mozilla.org
Received-SPF: none (sicking.cc: No applicable sender policy available)
From: Jonas Sicking <jo...@sicking.cc>
Date: Fri, 16 Sep 2011 16:06:44 -0700
Subject: Re: New Content Policy API
To: Jorge Villalobos <jo...@mozilla.com>,
Benjamin Smedberg <bsmedb...@mozilla.com>
Cc: dev-platform <dev-platf...@lists.mozilla.org>
List-Id: "The Mozilla platform \(XULRunner\)" <dev-platform.lists.mozilla.org>
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
Content-Type: text/plain; charset=ISO-8859-1
On Fri, Sep 16, 2011 at 3:54 PM, Jorge Villalobos <jo...@mozilla.com> wrote:
> On 9/16/11 2:14 PM, Jonas Sicking wrote:
>> Hi All,
>> We had a impromptu meeting today discussing what a new Content Policy
>> API would look like. We have for a long time been suffering from an
>> API which provides very little convenience for code needing to do
>> security checks before opening a network connection, while also
>> providing very little support for people implementing the Content
>> Policy API in order to block certain network loads.
>> Additionally the existing API works very poorly in e10s since it's
>> fully synchronous and uses XPCOM component registration.
>> So below is what we are thinking. There's not a lot of detail yet,
>> more higher-level ideas. Please do ask questions if you have concerns
>> or ideas!
>> Here's how things would work from the point of view of someone
>> implementing a content policy:
>> First off, we want to use normal (but chrome-only) DOM events to
>> deliver the notifications. This works better with e10s as have been
>> discussed at . Each content policy would then register to be an
>> event handler for this event.
>> When the event fires, a event handler can either do nothing if it
>> wants to let the load proceed as normal, or it can call a function on
>> the Event indicating that the load should be blocked. There should
>> also be a function to indicate "I don't have an answer yet, but I'll
>> call you back asynchronously to let you know my answer". We won't
>> start any network traffic until everyone that requested to reply
>> asynchronously has responded.
>> As a performance saving measure we can make the call to synchronously
>> block the load also call Event.stopImmediatePropagation, which would
>> prevent more of the content-policy-event-handlers from getting called.
>> When the event fires, we make the following information available:
>> * Load type. I.e. stylesheet, document, XHR, etc.  is the list of
>> types that we currently have
>> * URI. The uri we're about to load
>> * Node. The note initiating the load. In some cases when we can't
>> figure out the exact node it'll be the document where the load
>> * Channel. The channel we're about to start loading.
>> A big change here is that we provide the channel. This will make it
>> much easier to track a single load through the rest of necko. Another
>> thing to note is that since we provide a reference to the node the
>> event has to be fired in the e10s content process. This shouldn't be
>> too hard to deal with for addons though as we have good mechanisms for
>> registering event handlers in all e10s content processes as detailed
>> in . The principal of the loader will be trivially accessible from
>> the Node.
>> If a redirect occurs we'll again fire an event looking exactly like
>> the first event which provides the same data and additionally the old
>> channel and old URI. This makes handling redirects *a lot* easier
>> compared to how things work today. Again the
>> content-policy-event-handler has the ability to respond synchronously
>> or asynchronously and we won't hit the network for the new URI until
>> everyone has responded.
>> We'll also provide a explicit API on the event to allow a content
>> policy to redirect a load to a new URI. When that happens we'll treat
>> this like a "normal" redirect and fire a new event on all content
>> policy just like for a http redirect. If multiple policies want to
>> redirect to different URIs we'll have to handle that somehow.
>> Once we have downloaded enough of the resource that we have things
>> like header data we fire a second, in place of the current
>> nsIContentPolicy.shouldProcess callback. Again content policies will
>> have the ability to respond synchronously or asynchronously. Not until
>> we have responses from all event handlers will we hand the result of
>> the network request to the client.
>> For someone wanting to call into the content policy API before
>> starting a network load here's what things would look like:
>> First the caller creates a channel for the load. The caller then calls
>> into the content policy API and provide the load type, the loading
>> node and the channel (the URI can be derived from the channel) and
>> flags. The flags are for things like:
>> * Do same-origin check
>> * Is data: considered same-origin
>> * Are loads from chrome: allowed
>> * Other checkloaduri flags 
>> The API takes care of doing the same-origin check if requested,
>> including on redirects. It also performs the CheckLoadURI check
>> according to flags. If those checks pass it'll notify the content
>> policy implementations by firing the above described event. Once all
>> the checks have passed, which could happen asynchronously, it'll fire
>> off the network load.
>> Even if the API doesn't synchronously know if it's safe to hit the
>> network it'll still have to call AsyncOpen on the channel
>> synchronously. Or at least it'll have make the channel act as if
>> AsyncOpen had been called. This is important as to allow the channel
>> to be canceled and to prevent SetRequestHeader and similar APIs from
>> being called.
>> Another important aspect is that the API has to fire the event off of
>> a scriptrunner. This to ensure that content-policy-event-handlers
>> doesn't take any actions that we're not prepared for due to being in
>> an inconsistent state.
>> Once we get the OnStartRequest notification from necko we'll fire the
>> second event. While waiting for the response to this event (which
>> could come asynchronously) we'll have to pause the channel to prevent
>> OnDataAvailable calls from coming in. We also don't call
>> OnStartRequest on the streamlistener.
>> Is the above list of information enough to provide to the content
>> policy consumers? I.e. is channel, node, uri and load type enough? We
>> currently have some additional properties, but they seem mostly
>> useless. The reason we want to drop them is to have to carry around
>> less information in case a redirect happens.
>> Is the current list of load types that we have good? This is pretty
>> orthogonal to the other changes proposed here, but since we're
>> changing the API in backwards incompatible ways anyway, we have a good
>> opportunity to make improvements.
>> / Jonas
> A couple of notes:
> 1) It is unclear to me how registration would look for consumers (would it
> be a service you register to, would you need to implement an interface,
> etc.). I guess that is still undefined.
I'm not sure if this mechanism exists yet or not. I thought it did
though I could be wrong. The intent is that it'll use the same event
registration mechanism that we have for many types of events in e10s
as defined by  above.
> 2) Several add-on have a need to block a page load (for various reasons) and
> display their UI instead. Since this new Content Policy API will support
> redirects, it would be nice that it is also possible to redirect to a
> chrome:, resource: or file: URL.
That should be doable. Though don't we already have mechanisms for
intercepting page navigation?
> 3) Remember the addon-compat flag! :)