-
Notifications
You must be signed in to change notification settings - Fork 326
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
Adds "audioworklet" and "paintworklet" as destinations. #527
Conversation
This looks reasonable, apart from the CSP directive as discussed in w3c/webappsec-csp#203. We should probably sort that through first. |
I'm fine with adding these. Do we need to distinguish the worklet types in Fetch? That is, do you anticipate controlling the different types of worklets via distinct policy directives? Or would a single |
They are somewhat distinct in that one can have |
This will need to be rebased now that we removed I'm not quite sure requests for worklets count as non-subresource requests. That would mean they get their own service worker rather than the service worker associated with the document they're loaded from. I suspect you actually want the latter. |
Rebased, with just |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @bfgeek! This looks pretty solid to me, apart from a potentially substantive issue around service worker matching.
fetch.bs
Outdated
or "<code>worker</code>". | ||
whose <a for=request>destination</a> is "<code>audioworklet</code>", "<code>document</code>", | ||
"<code>paintworklet</code>", "<code>report</code>", "<code>serviceworker</code>", | ||
"<code>sharedworker</code>", or "<code>worker</code>". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this what we want for worklets? This influences the way a service worker is selected for them. I'd think that we just want to reuse the service worker of the document for worklets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I thought this required additional input from @jakearchibald & @jungkees I've updated the PR.
You'll need to rebase since again since we modified |
Thanks for heads up @annevk, now filed as bug 1402784, linked to the main AudioWorket bug. |
Each call to If the above is correct, they feel very similar to dedicated workers, so I think they're a client, so they should be added to "non-subresource request". Worklets don't support |
A worklet can have multiple associated WorkletGlobalScopes, right? To my understanding, calls to addModule trigger fetching a script from each of the associated global. A WorkletGlobalScope is its own script execution context, and fetching a script for that sounds a main resource fetch to me. So, matching a SW for that fetch sounds reasonable to me. |
@jakearchibald good questions. https://webaudio.github.io/web-audio-api/ which defines audio worklets also defines |
Ugh yes I mean |
Worklets are loaded as module scripts, so they can make a request by the dynamic import. Worklets can be loaded from a remote origin, so having their own Service Worker sounds reasonable. // On http://example.com/
worklet.addModule("http://example.com/worklet.js"); // Same-origin. OK.
worklet.addModule("http://www.example.com/worklet.js") // Remote-origin, but OK. |
Hmm, loading from a remote origin seems at odds with service workers. I don't think we want to launch a service worker from a different origin for these kind of requests. That might actually be problematic for module workers too. cc @domenic |
Just in case, workers cannot load a script from a remote origin:
https://html.spec.whatwg.org/multipage/workers.html#dom-worker |
@nhiroki module workers have no such restriction. That note is incorrect for them. (Though given how service workers work they probably need to have the same restriction. But that also makes me think that we don't want worklets to be non-subresources.) |
Filed whatwg/html#3109 on the module workers problem. I think the best course of action is for worklets to be subresources, though it wold be good for @mikewest to chime in to say if that would harm CSP in anyway. I think referrer we can work around, whenever worklets start fetching resources on their own. The one invariant this will impose on worklets is that they can only ever have a single owner. I hope that's okay @bfgeek. |
Following from whatwg/html#3109 (comment), could we make worklets properly cross origin? |
Treating worklets as subresources seems reasonable. I agree with @annevk's suggestion above that they should not have a distinct service worker, and that we should generally treat them as being part of the document in which they're embedded for purposes of referrer policy and (eventually) CSP restrictions on requests they might make in the future.
What would that mean? My understanding of worklets is that they're basically scripts executing in the same origin as the document (basically weirdly-behaved |
How about dedicated workers? Should we change them to subresources, too? Note that, in the current Chromium implementation, dedicated workers don't have their own service worker. They are controlled by parent document's service worker (https://crbug.com/731599). AFAICS, Firefox does the same behavior, so it could relatively be easy to change them to subresources in terms of SW interception. |
We could, especially if that matches implementations. I think we should consider that in isolation though; would you mind filing an issue at https://github.com/whatwg/html/issues/new? |
Yeah, it doesn't make sense. Worklets as subresources makes sense to me. |
@annevk Filed whatwg/html#3112 |
Wait, don't worklets create globals? Is there any precedent for a subresource that creates globals? This would seem to make the top level entities to me. |
Your example seems no different from import changesSomething from "./changes-something.js";
// PaintWorkletGlobalScope
registerPaint('ripple', class {
paint(ctx, geom, ...) {
if (geom.width ==12345) {
changesSomething();
}
}
});
// changes-something.js
export default () => {
registerPaint('foo', class {
paint() { /* some valid paint code */);
});
}; What am I missing? (You could also avoid even static import by just inlining the contents of that file into the |
Since the modules are fetched from the owner's Client they will be intercepted if that Client is controlled. So I think it will work offline. (Sorry if this is duplicate. Github is confusing the order of messages or something today.) |
@domenic they're static across all threads. Say you But if one of those globals calls It's kinda the same as: if (Math.round(Math.random()) {
// change behaviour
} |
@jakearchibald as I tried to illustrate above, you don't need |
@domenic a static import will hold back the execution of the worklet (or the addition of that module). Whereas with But yeah, you could create the same problem with |
But |
I think I see. I'm happy to work with you all and TC39 to come up with a way of disabling language features like Math.random() and import() in worklets if you think that's really the best path forward. |
We aren't going to stamp out all non-determinism, but I'm fine with leaving it as is and just saying "don't do that" for the time being. :) |
Another reason treating these as subresource requests fits with our current model: Currently the fetch and service worker spec expect non-subresource requests to target a single destination Client: https://fetch.spec.whatwg.org/#concept-request-target-client-id Worklet scripts are loaded once, but may then be executed in multiple different Client contexts. |
Filed a Chromium issue to track this discussion: https://crbug.com/773778 |
@annevk @wanderview I've changed it to a sub-resource request, and rebased. (And I added the paintworklet and audioworklet destinations to be "script-like"). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, thanks! Is there a testing story for these bits?
Also, to summarize the other issues that are somewhat related:
|
@nhiroki & I will work on some tests. Based on my understanding I think broadly we'll need.
It doesn't appear that anyone implements (and are no tests yet) for |
Why wouldn't cross-origin import be intercepted? (This is different from import(), right?) |
Sorry my bad, they should be... |
I just want to follow-up here to clarify that I don't think
So, at least in firefox, I do not expect |
Note that static |
I don't think that's the case given the initial module graph is imported using the owner's context. We do have an origin in that case. The weirdness happens because the initial static import is performed under one origin and then the dynamic |
A global with an opaque origin can have an Origin header (its value will be null). |
Ah, you are correct. So it can do CORS to a server that allows |
@wanderview yes. You can even do a request with credentials if the server replies with ACAO: null (and also sets the credentials header). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll go ahead and merge this given that I trust tests will be written for the service worker part, which is the most important bit here. And I also don't want this to go stale again.
I'm now writing tests for service worker interception (crbug) and came across questions about dynamic
|
@nhiroki I filed w3c/css-houdini-drafts#506. |
These two are the ones which are being implemented, so starting with
them for now.
Preview | Diff