Re: [w3c/ServiceWorker] A way to specify a pattern of destination URLs to hit/skip SW (#1454)

Thanks, all good feedback.  I felt that following might need more discussions among others:

* feature detection
* potential race with Service Worker state
* potential undesirable policy application with cached headers

More comments inline:

> I assume that URLs are resolved relative to the page?

Yes that's my current thinking.
 
> Since the value can be a url or a 'special value' like "none", we need a way of differentiating between the two. We could probably use the same rules are module specifiers. As in, we treat it as a URL if it's one of the following:
> 
> * A full non-relative URL. As in, it doesn't throw an error when put through `new URL(url)`.
> * Starts with `/`.
> * Starts with `./`.
> * Starts with `../`.
> 
> Otherwise we treat it as an enum, eg "none".
> 
> What happens with:
> 
> ```
> Service-Worker-Fetch-Scope: foo
> ```
> 
> Is this discarded as an unknown value, or does it activate the feature with no matching URLs (same as 'none')?

I'd vote for discarding but can be cool with either.

> Is this allowed?
> 
> ```
> Service-Worker-Fetch-Scope: /imgs/, /script/
> ```
>
> …and will fire fetch events for subresources starting `/imgs/` or `/script/`, or will it treat the whole thing as one URL `/imgs/, /script/`?

Didn't mention this in the initial post as I didn't have strong opinion. (Could be open to either)
 
> We probably need to think of a name that doesn't include 'scope', as it may be confused with service worker scope. But meh bikeshedding.
> 
> We need to make sure this header is processed before any headers that trigger subresource fetches, eg `Link`.
> 
> I assume that this would only work as a genuine header, not some `<meta>` equivalent.
> 
> I guess this will work for other client types like workers?
> 
> It's difficult to express "bypass the service worker for urls starting `/video/`". I guess you could support `Ignore-Fetch` and `Fetch-Scope`, but if both headers are used in the same request it could get pretty complicated.

Error out and ignore if both are given?

> In cases where we inherit the controller of the parent document (eg about:blank, srcdoc etc) does it also inherit the fetch scope rules?

That sounds reasonable.

> Can this be feature detected in any way?

Good question. Maybe add some special request header to indicate that?

> The ergonomics of adding a header to a response from the cache or network aren't totally friendly:
> 
> ```js
> addEventListener('fetch', event => {
>   event.respondWith((async function() {
>     if (event.request.mode === 'navigate') {
>       const response = await fetch(event.request);
>       const responseCopy = new Response(response.body, response);
>       responseCopy.headers.set('Service-Worker-Fetch-Scope', '/profile/');
>       return responseCopy;
>     }
>     
>     return fetch(event.request);
>   })());
> });
> ```
> 
> With the declarative routes proposal, I tied the state to the service worker. This means the same thing that specifies the routes, also specifies the handling:
> 
> ```js
> addEventListener('install', event => {
>   event.router.add({ url: { startsWith: '/video/' } }, 'network');
> });
> 
> addEventListener('fetch', event => {
>   // You will never see a request for /video/* here
> });
> ```
> 
> The header-based proposal doesn't give the same guarantees, and I'm worried this will create some unexpected gotchas:
> 
> ```js
> addEventListener('fetch', event => {
>   event.respondWith((async function() {
>     if (event.request.mode === 'navigate') {
>       const response = await fetch(event.request);
>       const responseCopy = new Response(response.body, response);
>       responseCopy.headers.set('Service-Worker-Fetch-Scope', '/profile/');
>       return responseCopy;
>     }
>     
>     // Will you see subresource requests for /profile/* here?
>   })());
> });
> ```
> 
> In this example it looks like I'm forcing all controlled pages to have a fetch scope of `/profile/`, and I can imagine developers assuming they won't have to handle subresource requests to anywhere else. However, this isn't the case.
> 
> The controlled page may have been served by an earlier version of the service worker (due to `skipWaiting`), no service worker, or another registration (due to `clients.claim`). So there's no certainty around the rules the client is following.

Yep, you're right that there could be a race.  My impression around skipWaiting has been that it inherently adds some race, and therefore it could be probably okay to have the race like this, but maybe not.  I'm interested in learning how concerning/critical does this race look to you (and everyone)!

> If you end up with items in the cache with the `Service-Worker-Fetch-Scope` header, you might end up applying rules unintentionally.

I'm wondering if making this header always stripped away when cached could introduce more or less confusion.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/ServiceWorker/issues/1454#issuecomment-520766264

Received on Tuesday, 13 August 2019 09:43:35 UTC