Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interception of the fallback requests initiated from a SW for cross-origin resources #684

Closed
jungkees opened this issue Apr 22, 2015 · 14 comments

Comments

@jungkees
Copy link
Collaborator

While discussing use cases for navigator.connect(), we've encountered a case where interception of the fallback requests to a third-party resources and serving them through a cross-origin SW would greatly help the overall resource management. Here's the use case and the proposed extension API that enables the communication between a client SW and a service SW:
https://github.com/mkruisselbrink/navigator-connect/blob/gh-pages/explainer.md#solving-the-fonts-problem

A service opts in to handle clients' fallback requests by calling e.handleFallThroughRequests from within its oninstall event listener. Then, the requests initiated from a client SW are intercepted, and fetch events tagged with e.isFallThrough set to true are dispatched to the service SW instead of going out to the network.

It was originally discussed as part of the navigator.connect() spec, but agreed to be proposed as an extension to the SW API (v2): mkruisselbrink/navigator-connect#28

Comments would be appreciated.

@benfrancis
Copy link
Member

I'd be interested to hear peoples' thoughts on whether another use case for this could be for a cross-origin Service Worker to provide an HTTP web service which works even when offline mkruisselbrink/navigator-connect#23

This has been discussed as a use case on Mozilla's dev-webapi mailing list https://groups.google.com/forum/#!msg/mozilla.dev.webapi/2NWlXa9SlqY/mQ0zBI1SChUJ

This could provide an avenue to replace many of Gecko's current proprietary APIs with potentially more webby solutions.

@jakearchibald
Copy link
Contributor

You could have:

// https://foo/sw.js
self.oninstall = event => {
  event.waitUntil(
    event.registerExternal('//font-service/sw.js')
  );
};

//font-service/sw.js would require a Service-Worker-Scope header, which would be the scope on //font-service that it would be registered to.

// https://font-service/sw.js
self.oninstall = event => {
  event.handleFallThroughRequests(['/resources', '/font']);
  // …
};

URLs passed to handleFallThroughRequests must be within the SW's scope.

My questions/concerns about this model:

  • The number of workers that may be needed to handle requests to a single page - is this a problem?
  • How/when will //font-service/sw.js be checked for updates?

@mkruisselbrink
Copy link
Collaborator

@jakearchibald is your proposal that https://font-service/sw.js would only be allowed to intercept requests from service workers (and their controlled pages) that explicitly called registerExternal for that service?

I don't think either way that this will significantly increase the number of workers that may be needed to display a single page. After all there already is a problem with things like social network "like" buttons, ads, and probably many more things that are typically implemented with iframes, which all potentially can have their own service workers.

The update thing is a good question. I haven't really thought about that. On one hand I'm tempted to say to just leave this up to user agents (after all, a user agent is already allowed to call the Soft Update algorithm as often as it wants), but then on the other hand this does feel like something that should somehow be specced.

@jakearchibald
Copy link
Contributor

is your proposal that https://font-service/sw.js would only be allowed to intercept requests from service workers (and their controlled pages) that explicitly called registerExternal for that service?

That was my thinking. But at a minimum (if we have this feature) I should be able to specify another service as an install dependency.

there already is a problem with things like social network "like" buttons, ads, and probably many more things that are typically implemented with iframes, which all potentially can have their own service workers.

Should we be adding to that problem?

@slightlyoff
Copy link
Contributor

Per conversations in SF today, a few points that seem relevant:

  • Moving the registration (e.handleFallThroughRequests(['/resources', '/font']);) to onactivate is non-controversial. Registrations overwrite each other and last-one-wins semantics prevail.
  • We need an API for examining the fall-through registrations
  • The fall-through handler (e.g., b.com's handler for a fetch that a.com generates) should probably have a different event name, e.g. onfallthroughfetch to prevent naive reuse of onfetch logic that isn't suited to dealing with requests from third parties
  • CORS is hard. Logically, any fetch() from a.com, either from it's documents or Service Workers, that reach a fallthrough event handler should allow b.com's onfallthroughfetch to see CORS preflights and respond appropriately. Logically speaking, b.com's SW is executing across the network from a.com's perspective
  • To prevent abuse, responses from onfallthroughfetch should probably be made opaque by default and explicit action, perhaps in the form of a different Response object type or an argument to respondWith should be necessary to make a response non-opaque.

@jakearchibald
Copy link
Contributor

Registrations overwrite each other and last-one-wins semantics prevail.

Furthermore, if a new version fails to call handleFallThroughRequests (or whatever we call it), then another SW won't be used for fall-through requests.

should allow b.com's onfallthroughfetch to see CORS preflights

I still don't think this is necessary. The fall-through worker will be able to inspect the request and should be given details on the origin that will get access to the response. It'll be able to make a call without preflight access.

responses from onfallthroughfetch should probably be made opaque by default

I'm not convinced opaque responses from a third party services are useful. One of the key usecases we have is fonts, and they require CORS. Isn't the new event name enough of an explicit action?

@annevk
Copy link
Member

annevk commented Jun 9, 2015

CORS preflight is about protecting servers. In the case of a service worker that opts in there is nothing to protect so they should certainly not go there.

@annevk
Copy link
Member

annevk commented Jul 20, 2015

https://wiki.whatwg.org/wiki/Foreign_Fetch is Mozilla's proposal, for the record.

@benfrancis
Copy link
Member

Was there any discussion on this in the face to face meeting this week? Any conclusions/meeting notes?

@wanderview
Copy link
Member

I believe we had consensus that implementing a fallback- or foreign-fetch API was preferred to a postMessage-like API for the initial use cases.

We just need to work through differences in our proposal and get it spec'd. I didn't get the sense that there were any major sticking points, but I guess we will see.

I guess my personal hope is that this could be spec'd in Q3 and maybe first implementations could start showing up in Q4.

@mkruisselbrink
Copy link
Collaborator

Yes, that's pretty much what I think the consensus was as well. Both proposals are pretty similar so it's just a matter of working out details and speccing it out (and hope that the various security teams etc are happy with such an API).

@mkruisselbrink
Copy link
Collaborator

I started putting together a bit more of a concrete proposal in https://gist.github.com/mkruisselbrink/f6957bece64740926b84 although as I was doing so I realized I should probably just put this in a fork/pull request for the actual service worker spec, so unless somebody objects I'll start doing that and making the proposal even more concrete sometime next week.

@annevk
Copy link
Member

annevk commented Aug 21, 2015

Can we call it foreign fetch? I find that much more clear. The service worker is already doing fetch interception.

@mkruisselbrink
Copy link
Collaborator

Pull request #749 (also visible at http://mkruisselbrink.github.io/ServiceWorker/spec/service_worker/) is my initial attempt at spec-ing this feature. I'm sure many refinements are still needed, so any comments are welcome.

mkruisselbrink added a commit to mkruisselbrink/ServiceWorker that referenced this issue Feb 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants