Now we have ControllerServiceWorkerInfo (crrev.com/c/742961). So I think we can implement S13nServiceWorker for SharedWorker like this:
1. Add the logic of finding matching Service Worker registration in SharedWorkerServiceImpl::CreateWorker()
2. Create ControllerServiceWorkerInfo and send it via SharedWorkerFactory::CreateSharedWorker() Mojo IPC from in SharedWorkerHost::Start().
3. Change ServiceWorkerNetworkProvider::CreateForSharedWorker():
- Use the ControllerServiceWorkerInfo which was passed from the browser process via the Mojo IPC.
- Call RendererBlinkPlatformImpl::CreateDefaultURLLoaderFactoryGetter() to get the default_loader_factory_getter.
I think a couple things might require more work here to be complete:
- Redirects. If we decide the controller in SharedWorkerServiceImpl::CreateWorker, we'd only use the initial request URL. But the current non-S13nSW code lookups the matching service worker at each redirect URL.
- Races between the controller service worker and newly registered service workers. Ignoring redirects, if we decide the controller in SharedWorkerServiceImpl::CreateWorker, it's possible a new worker becomes active in that time and kicks out the worker that's handling this request. We basically need this worker to be set as having a controllee before the provider host for the shared worker is created. So I think we'll need to precreate a provider host similar to what PlzNavigate does on navigations.
I also don't know how to handle both service worker and AppCache.
I have a basic test site about redirects at https://sw-shared-worker.glitch.me/
Looking into requirements and implementation convenience.
Is it possible to make the URLLoaderClient passed to URLLoaderFactory::CreateLoaderAndStart() be associated with another interface?
Rough design I'm playing with now:
1. (Browser IO thread) SharedWorkerHost precreates a ServiceWorkerProviderHost and creates a SharedWorkerScriptURLLoaderFactory hooked up to the host. Passes the provider id and url loader factory to the renderer.
2. (Renderer main thread) Creates the ServiceWorkerNetworkProvider which connects the renderer to the browser ServiceWorkerProviderHost.
3. (Renderer main thread) Makes the URL request via the url loader factory.
4. (Browser IO thread) SharedWorkerScriptURLLoaderFactory creates a URLLoader for fetching the script. On each request it looks up if there's a service worker and if so calls ServiceWorkerProviderHost::AssociateRegistration to set the controller before returning the response. Redirects are reported to Blink so it can decide whether to follow or not since it's doing some security checks there currently (however, it's probably not needed due to same-origin restriction of workers). Any redirects are expected to be followed, and the URLLoader looks up the service worker registration again.
On the renderer-side, I need to somehow make URLLoaderClient for the script load and ServiceWorkerContainer/ServiceWorkerProviderContext for the shared worker be associated to ensure the SetController messages get received before the script response arrives. I'm not sure that's possible.
Comment 1 by kinuko@chromium.org
, Dec 21 2017