зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1856090 - Improve ServiceWorker state propagation. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D190245
This commit is contained in:
Родитель
f36c2e9caa
Коммит
49058aa9d5
|
@ -616,8 +616,22 @@ already_AddRefed<ScriptLoadRequest> WorkerScriptLoader::CreateScriptLoadRequest(
|
|||
|
||||
Maybe<ClientInfo> clientInfo = GetGlobal()->GetClientInfo();
|
||||
|
||||
RefPtr<WorkerLoadContext> loadContext =
|
||||
new WorkerLoadContext(kind, clientInfo, this);
|
||||
// (For non-serviceworkers, this variable does not matter, but false best
|
||||
// captures their behavior.)
|
||||
bool onlyExistingCachedResourcesAllowed = false;
|
||||
if (mWorkerRef->Private()->IsServiceWorker()) {
|
||||
// https://w3c.github.io/ServiceWorker/#importscripts step 4:
|
||||
// > 4. If serviceWorker’s state is not "parsed" or "installing":
|
||||
// > 1. Return map[url] if it exists and a network error otherwise.
|
||||
//
|
||||
// So if our state is beyond installing, it's too late to make a request
|
||||
// that would perform a new fetch which would be cached.
|
||||
onlyExistingCachedResourcesAllowed =
|
||||
mWorkerRef->Private()->GetServiceWorkerDescriptor().State() >
|
||||
ServiceWorkerState::Installing;
|
||||
}
|
||||
RefPtr<WorkerLoadContext> loadContext = new WorkerLoadContext(
|
||||
kind, clientInfo, this, onlyExistingCachedResourcesAllowed);
|
||||
|
||||
// Create ScriptLoadRequests for this WorkerScriptLoader
|
||||
ReferrerPolicy referrerPolicy = mWorkerRef->Private()->GetReferrerPolicy();
|
||||
|
@ -1429,7 +1443,8 @@ nsresult ScriptLoaderRunnable::Run() {
|
|||
handle->mRunnable = this;
|
||||
WorkerLoadContext* loadContext = handle->GetContext();
|
||||
mCacheCreator->AddLoader(MakeNotNull<RefPtr<CacheLoadHandler>>(
|
||||
mWorkerRef, handle, loadContext->IsTopLevel(), mScriptLoader));
|
||||
mWorkerRef, handle, loadContext->IsTopLevel(),
|
||||
loadContext->mOnlyExistingCachedResourcesAllowed, mScriptLoader));
|
||||
}
|
||||
|
||||
// The worker may have a null principal on first load, but in that case its
|
||||
|
|
|
@ -237,13 +237,14 @@ void CacheCreator::DeleteCache(nsresult aReason) {
|
|||
CacheLoadHandler::CacheLoadHandler(ThreadSafeWorkerRef* aWorkerRef,
|
||||
ThreadSafeRequestHandle* aRequestHandle,
|
||||
bool aIsWorkerScript,
|
||||
bool aOnlyExistingCachedResourcesAllowed,
|
||||
WorkerScriptLoader* aLoader)
|
||||
: mRequestHandle(aRequestHandle),
|
||||
mLoader(aLoader),
|
||||
mWorkerRef(aWorkerRef),
|
||||
mIsWorkerScript(aIsWorkerScript),
|
||||
mFailed(false),
|
||||
mState(aWorkerRef->Private()->GetServiceWorkerDescriptor().State()) {
|
||||
mOnlyExistingCachedResourcesAllowed(aOnlyExistingCachedResourcesAllowed) {
|
||||
MOZ_ASSERT(aWorkerRef);
|
||||
MOZ_ASSERT(aWorkerRef->Private()->IsServiceWorker());
|
||||
mMainThreadEventTarget = aWorkerRef->Private()->MainThreadEventTarget();
|
||||
|
@ -373,9 +374,7 @@ void CacheLoadHandler::ResolvedCallback(JSContext* aCx,
|
|||
// storage was probably wiped without removing the service worker
|
||||
// registration. It can also happen for exposed reasons like the
|
||||
// service worker script calling importScripts() after install.
|
||||
if (NS_WARN_IF(mIsWorkerScript ||
|
||||
(mState != ServiceWorkerState::Parsed &&
|
||||
mState != ServiceWorkerState::Installing))) {
|
||||
if (NS_WARN_IF(mIsWorkerScript || mOnlyExistingCachedResourcesAllowed)) {
|
||||
Fail(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,9 @@ class CacheLoadHandler final : public PromiseNativeHandler,
|
|||
|
||||
CacheLoadHandler(ThreadSafeWorkerRef* aWorkerRef,
|
||||
ThreadSafeRequestHandle* aRequestHandle,
|
||||
bool aIsWorkerScript, WorkerScriptLoader* aLoader);
|
||||
bool aIsWorkerScript,
|
||||
bool aOnlyExistingCachedResourcesAllowed,
|
||||
WorkerScriptLoader* aLoader);
|
||||
|
||||
void Fail(nsresult aRv);
|
||||
|
||||
|
@ -110,7 +112,7 @@ class CacheLoadHandler final : public PromiseNativeHandler,
|
|||
RefPtr<ThreadSafeWorkerRef> mWorkerRef;
|
||||
const bool mIsWorkerScript;
|
||||
bool mFailed;
|
||||
const ServiceWorkerState mState;
|
||||
bool mOnlyExistingCachedResourcesAllowed;
|
||||
nsCOMPtr<nsIInputStreamPump> mPump;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
mozilla::dom::ChannelInfo mChannelInfo;
|
||||
|
|
|
@ -13,11 +13,14 @@ namespace dom {
|
|||
|
||||
WorkerLoadContext::WorkerLoadContext(
|
||||
Kind aKind, const Maybe<ClientInfo>& aClientInfo,
|
||||
workerinternals::loader::WorkerScriptLoader* aScriptLoader)
|
||||
workerinternals::loader::WorkerScriptLoader* aScriptLoader,
|
||||
bool aOnlyExistingCachedResourcesAllowed)
|
||||
: JS::loader::LoadContextBase(JS::loader::ContextKind::Worker),
|
||||
mKind(aKind),
|
||||
mClientInfo(aClientInfo),
|
||||
mScriptLoader(aScriptLoader){};
|
||||
mScriptLoader(aScriptLoader),
|
||||
mOnlyExistingCachedResourcesAllowed(
|
||||
aOnlyExistingCachedResourcesAllowed){};
|
||||
|
||||
ThreadSafeRequestHandle::ThreadSafeRequestHandle(
|
||||
JS::loader::ScriptLoadRequest* aRequest, nsISerialEventTarget* aSyncTarget)
|
||||
|
|
|
@ -98,7 +98,8 @@ class WorkerLoadContext : public JS::loader::LoadContextBase {
|
|||
};
|
||||
|
||||
WorkerLoadContext(Kind aKind, const Maybe<ClientInfo>& aClientInfo,
|
||||
workerinternals::loader::WorkerScriptLoader* aScriptLoader);
|
||||
workerinternals::loader::WorkerScriptLoader* aScriptLoader,
|
||||
bool aOnlyExistingCachedResourcesAllowed);
|
||||
|
||||
// Used to detect if the `is top-level` bit is set on a given module.
|
||||
bool IsTopLevel() {
|
||||
|
@ -163,6 +164,11 @@ class WorkerLoadContext : public JS::loader::LoadContextBase {
|
|||
|
||||
CacheStatus mCacheStatus = Uncached;
|
||||
|
||||
// If the requested script is not currently in the cache, should we initiate
|
||||
// a request to fetch and cache it? Only ServiceWorkers that are being
|
||||
// installed are allowed to go to the network (and then cache the result).
|
||||
bool mOnlyExistingCachedResourcesAllowed = false;
|
||||
|
||||
bool IsAwaitingPromise() const { return bool(mCachePromise); }
|
||||
};
|
||||
|
||||
|
|
|
@ -50,9 +50,10 @@ already_AddRefed<ModuleLoadRequest> WorkerModuleLoader::CreateStaticImport(
|
|||
// See Discussion in https://github.com/w3c/webappsec-csp/issues/336
|
||||
Maybe<ClientInfo> clientInfo = GetGlobalObject()->GetClientInfo();
|
||||
|
||||
RefPtr<WorkerLoadContext> loadContext =
|
||||
new WorkerLoadContext(WorkerLoadContext::Kind::StaticImport, clientInfo,
|
||||
aParent->GetWorkerLoadContext()->mScriptLoader);
|
||||
RefPtr<WorkerLoadContext> loadContext = new WorkerLoadContext(
|
||||
WorkerLoadContext::Kind::StaticImport, clientInfo,
|
||||
aParent->GetWorkerLoadContext()->mScriptLoader,
|
||||
aParent->GetWorkerLoadContext()->mOnlyExistingCachedResourcesAllowed);
|
||||
RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest(
|
||||
aURI, aParent->ReferrerPolicy(), aParent->mFetchOptions, SRIMetadata(),
|
||||
aParent->mURI, loadContext, false, /* is top level */
|
||||
|
@ -91,6 +92,8 @@ already_AddRefed<ModuleLoadRequest> WorkerModuleLoader::CreateDynamicImport(
|
|||
}
|
||||
|
||||
// Not supported for Service Workers.
|
||||
// https://github.com/w3c/ServiceWorker/issues/1585 covers existing discussion
|
||||
// about potentially supporting use of import().
|
||||
if (workerPrivate->IsServiceWorker()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -123,9 +126,16 @@ already_AddRefed<ModuleLoadRequest> WorkerModuleLoader::CreateDynamicImport(
|
|||
|
||||
Maybe<ClientInfo> clientInfo = GetGlobalObject()->GetClientInfo();
|
||||
|
||||
RefPtr<WorkerLoadContext> context =
|
||||
new WorkerLoadContext(WorkerLoadContext::Kind::DynamicImport, clientInfo,
|
||||
GetCurrentScriptLoader());
|
||||
RefPtr<WorkerLoadContext> context = new WorkerLoadContext(
|
||||
WorkerLoadContext::Kind::DynamicImport, clientInfo,
|
||||
GetCurrentScriptLoader(),
|
||||
// When dynamic import is supported in ServiceWorkers,
|
||||
// the current plan in onlyExistingCachedResourcesAllowed
|
||||
// is that only existing cached resources will be
|
||||
// allowed. (`import()` will not be used for caching
|
||||
// side effects, but instead a specific method will be
|
||||
// used during installation.)
|
||||
true);
|
||||
|
||||
ReferrerPolicy referrerPolicy = workerPrivate->GetReferrerPolicy();
|
||||
RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest(
|
||||
|
|
Загрузка…
Ссылка в новой задаче