[slightlyoff/ServiceWorker] Is it possible to serve service worker from CDN/remote origin? (#940)

Hey all,

I want to serve a service worker from a CDN, but I can't figure out how to get that to work.

I expected this to work:

```
// The header `Service-Worker-Allowed: www.example.com` is set in the response
var swURL = "cdn.example.com/sw.js";
var options = {scope: 'www.example.com'};
navigator.serviceWorker.register(swURL, options);
```

But it throws the following error in Chrome:

```
Uncaught (in promise) DOMException: Failed to register a ServiceWorker:
The origin of the provided scriptURL ('https://cdn.example.com/sw.js')
does not match the current origin ('https://www.example.com').
```

With the current wording, it seems like Service-Worker-Allowed allows loading the service worker from a remote origin.

> `Service-Worker-Allowed`
> Indicates the user agent will override the path restriction, which limits the maximum allowed scope url that the script can control, to the given value.
> The value is a URL. If a relative URL is given, it is parsed against the script’s URL.

https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-allowed

However, all of the examples and discussion only use Service-Worker-Allowed with relative URLs.

Digging through the Chromium code, I'm pretty sure the error is thrown before the request is made to the url, which means it's made before we can check the header on the sw response:

```
void ServiceWorkerContainer::registerServiceWorkerImpl(/* ... */)
{
    // ...
    if (!documentOrigin->canRequest(scriptURL)) {
        RefPtr<SecurityOrigin> scriptOrigin = SecurityOrigin::create(scriptURL);
        callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTypeSecurity, String("Failed to register a ServiceWorker: The origin of the provided scriptURL ('" + scriptOrigin->toString() + "') does not match the current origin ('" + documentOrigin->toString() + "').")));
        return;
    }
    // ...
    m_provider->registerServiceWorker(patternURL, scriptURL, callbacks.release());
}
```

https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp?q=%22does+not+match+the+current+origin%22&sq=package:chromium&dr=C&l=224

You can follow the rabbit hole down 'canRequest', but I'm pretty sure nothing in that function allows you to allow remote scripts dynamically (e.g. with a header).

Questions:
 - Is it possible to serve a service worker from a remote origin through some other means?
 - The spec is currently ambiguous about remote origins -- it doesn't say they aren't allowed, but it doesn't say they are either. Should Service-Worker-Allowed let you serve from a remote origin?

Thanks for your time! BTW, you all have done excellent work with the spec.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/slightlyoff/ServiceWorker/issues/940

Received on Thursday, 4 August 2016 01:27:27 UTC