On 2015-07-17 2:16 PM, Benjamin Kelly wrote:
I thought a little bit more about this after stepping away from my computer.

I think some of our implementation issues for service workers currently
stems from the fact that the fetch spec and necko have modeled the problem
with different primitives:

   - necko provides an object (nsIChannel) to represent the ongoing network
request.  The network request is described as parameters to the creation of
the channel object.  The response is defined as a series of callbacks on
the nsIStreamListener interface.
   - In contrast, fetch defines object primitives for Request and Response,
but has no explicit object to represent the on-going network request.

These are both reasonable ways of doing things, but the impedance mismatch
between the two makes it difficult to accurately translate the new specs
into gecko.  It might be nice to move the DOM code to use the
Request/Response model to align things better with the spec.

One approach we could take would be to add a new internal networking
interface oriented around Request and Response objects.  Internally it
would still use nsIChannel, but would do all the work to translate to and
from Request/Response.  The DOM code would then be modified to create a
Request, call this interface, and then process the returned Response.

We already mostly have this interface in Fetch.h/FetchDriver.h, but we
would probably need to adjust it a bit.  For example, some of the referrer
logic is handled in Fetch.h which requires the use of globals and
Promises.  In theory, though, we should be able to move this into
FetchDriver and provide a clean internal interface to use.

We could then start migrating consumers of NS_NewChannel() to the new
FetchDriver interface.  This would need to be done one-by-one and would
probably run into problems with how to specify internal flags and stuff.
It would be an incremental approach to use a Request/Response oriented
model in the DOM code.

I guess this is probably what you were originally suggesting and I was
jumping to conclusions that you wanted to replace nsIChannel.  Sorry for
that.

Anyway, what do people think?

I think this is a good idea in general, but I'm not sure how well the high level fetch API would map to something internal. Off the top of my head, currently the process of loading something from the network in Gecko (at least for the stuff that we load on behalf of a web page) looks like the following (apologies if I'm forgetting something!):

* Construct an nsIURI. Might need to take things such as the document base URI and charset into account. * Check to see whether the principal of the document or the object requesting the load can load that URL. * Check the content policy implementations to see whether they want to block the load. * Create a new channel. Here we may need to deal with details such as the load flags, setting the right loadgroup/notification callbacks, managing the privacy state of the channel if needed, etc.
* Deal with the referrer.
* Setup an upload stream for POST/etc.
* Setup the priority of the channel, if needed.
* Deal with CORS, if needed.
* Setup the intercept controller if it cannot be obtained through the laodgroup/notification callbacks. * Decide how you would like to consume the content (as in, do you care about individual OnDataAvailable notifications for a streamed load, or do you only care about the final result for a non-streamed one.)
* Open the channel (unless you need to do a CORS preflight!)

There are some concepts here that do not exist in the current fetch spec (for example, load groups) so we would need to add those to our internal APIs. Also, some of the existing concepts (such as streamed Responses) may not be quite fleshed out yet. Therefore, we need to figure out how to design the internal API in a way that gives us the flexibility that we need in some cases, but also be close to the concepts in the fetch spec, and that is tricky. :-) But it seems like what the Necko/Security teams are working on right now is a step in this direction, and that's great!

I should also mention that in addition to the security concerns around fetch interception through service workers, the above steps is *insanely* complex, and almost every time that someone who is not deeply familiar with all of the above steps tries to load something from the network, they're pretty much guaranteed to forget something and as a result potentially open security holes! I look forward to a future where mere mortals can load stuff from the network in Gecko. :-)
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to