From 1704dc2a726e6c5e04b1826f042cf9e6c8203212 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 11 May 2017 09:26:18 -0400 Subject: [PATCH 1/2] Backed out 14 changesets (bug 1290951) for causing topcrash bug 1364059. a=me Backed out changeset d9cb7e835d4c (bug 1290951) Backed out changeset 2684d41c75e4 (bug 1290951) Backed out changeset 2fdb0ae64a1b (bug 1290951) Backed out changeset 6194a6a0f510 (bug 1290951) Backed out changeset 9a722c9de441 (bug 1290951) Backed out changeset 4e36f20bea04 (bug 1290951) Backed out changeset 7236a196cff0 (bug 1290951) Backed out changeset b6b85669af94 (bug 1290951) Backed out changeset bb76b58e45fc (bug 1290951) Backed out changeset f2b2e0d54e51 (bug 1290951) Backed out changeset 974b55cde2af (bug 1290951) Backed out changeset cda24c8eccc4 (bug 1290951) Backed out changeset fedca2ad4ce6 (bug 1290951) Backed out changeset e40aeb64bdab (bug 1290951) --- dom/workers/ServiceWorkerScriptCache.cpp | 1164 ++++++----------- dom/workers/ServiceWorkerScriptCache.h | 14 +- dom/workers/ServiceWorkerUpdateJob.cpp | 37 +- dom/workers/ServiceWorkerUpdateJob.h | 6 +- .../bug1290951_worker_imported.sjs | 23 - .../serviceworkers/bug1290951_worker_main.sjs | 33 - dom/workers/test/serviceworkers/mochitest.ini | 3 - .../test/serviceworkers/test_bug1290951.html | 68 - testing/web-platform/meta/MANIFEST.json | 28 - .../bytecheck-worker-imported-script.py | 19 - .../resources/bytecheck-worker.py | 28 - .../update-bytecheck.https.html | 127 -- 12 files changed, 444 insertions(+), 1106 deletions(-) delete mode 100644 dom/workers/test/serviceworkers/bug1290951_worker_imported.sjs delete mode 100644 dom/workers/test/serviceworkers/bug1290951_worker_main.sjs delete mode 100644 dom/workers/test/serviceworkers/test_bug1290951.html delete mode 100644 testing/web-platform/tests/service-workers/service-worker/resources/bytecheck-worker-imported-script.py delete mode 100644 testing/web-platform/tests/service-workers/service-worker/resources/bytecheck-worker.py delete mode 100644 testing/web-platform/tests/service-workers/service-worker/update-bytecheck.https.html diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorkerScriptCache.cpp index 2731928bf870..1f235e5e5a93 100644 --- a/dom/workers/ServiceWorkerScriptCache.cpp +++ b/dom/workers/ServiceWorkerScriptCache.cpp @@ -30,7 +30,6 @@ using mozilla::dom::cache::Cache; using mozilla::dom::cache::CacheStorage; -using mozilla::ipc::PrincipalInfo; BEGIN_WORKERS_NAMESPACE @@ -80,11 +79,9 @@ CreateCacheStorage(JSContext* aCx, nsIPrincipal* aPrincipal, ErrorResult& aRv, } class CompareManager; -class CompareCache; -// This class downloads a URL from the network, compare the downloaded script -// with an existing cache if provided, and report to CompareManager via calling -// ComparisonFinished(). +// This class downloads a URL from the network and then it calls +// NetworkFinished() in the CompareManager. class CompareNetwork final : public nsIStreamLoaderObserver, public nsIRequestObserver { @@ -93,34 +90,25 @@ public: NS_DECL_NSISTREAMLOADEROBSERVER NS_DECL_NSIREQUESTOBSERVER - CompareNetwork(CompareManager* aManager, - nsIPrincipal* aPrincipal, - const nsAString& aURL, - bool aIsMainScript, - nsILoadGroup* aLoadGroup, - Cache* const aCache) + explicit CompareNetwork(CompareManager* aManager) : mManager(aManager) - , mIsMainScript(true) - , mInternalHeaders(new InternalHeaders()) - , mState(WaitingForInitialization) - , mNetworkResult(NS_OK) - , mCacheResult(NS_OK) - , mLoadFlags(nsIChannel::LOAD_BYPASS_SERVICE_WORKER) { MOZ_ASSERT(aManager); AssertIsOnMainThread(); - - Initialize(aPrincipal, aURL, aIsMainScript, aLoadGroup, aCache); } - void - Abort(); + nsresult + Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, nsILoadGroup* aLoadGroup); void - NetworkFinished(nsresult aRv); + Abort() + { + AssertIsOnMainThread(); - void - CacheFinished(nsresult aRv); + MOZ_ASSERT(mChannel); + mChannel->Cancel(NS_BINDING_ABORTED); + mChannel = nullptr; + } const nsString& Buffer() const { @@ -128,82 +116,15 @@ public: return mBuffer; } - const nsString& - URL() const - { - AssertIsOnMainThread(); - return mURL; - } - - const ChannelInfo& - GetChannelInfo() const - { - return mChannelInfo; - } - - already_AddRefed - GetInternalHeaders() const - { - RefPtr internalHeaders = mInternalHeaders; - return internalHeaders.forget(); - } - - UniquePtr - TakePrincipalInfo() - { - return Move(mPrincipalInfo); - } - - bool - Succeeded() const - { - return NS_SUCCEEDED(mNetworkResult); - } - private: ~CompareNetwork() { AssertIsOnMainThread(); - MOZ_ASSERT(!mCC); } - void - Initialize(nsIPrincipal* aPrincipal, - const nsAString& aURL, - bool aIsMainScript, - nsILoadGroup* aLoadGroup, - Cache* const aCache); - - void - Finished(); - - nsresult - SetPrincipalInfo(nsIChannel* aChannel); - RefPtr mManager; - RefPtr mCC; nsCOMPtr mChannel; nsString mBuffer; - - nsString mURL; - bool mIsMainScript; - ChannelInfo mChannelInfo; - RefPtr mInternalHeaders; - UniquePtr mPrincipalInfo; - - enum { - WaitingForInitialization, - WaitingForBothFinished, - WaitingForNetworkFinished, - WaitingForCacheFinished, - Redundant - } mState; - - nsresult mNetworkResult; - nsresult mCacheResult; - - nsCString mMaxScope; - nsLoadFlags mLoadFlags; }; NS_IMPL_ISUPPORTS(CompareNetwork, nsIStreamLoaderObserver, @@ -218,24 +139,54 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSISTREAMLOADEROBSERVER - CompareCache(CompareNetwork* aCN, - const nsAString& aURL, - Cache* const aCache) - : mCN(aCN) - , mState(WaitingForInitialization) - , mInCache(false) + explicit CompareCache(CompareManager* aManager) + : mManager(aManager) + , mState(WaitingForCache) + , mAborted(false) { - MOZ_ASSERT(aCN); + MOZ_ASSERT(aManager); AssertIsOnMainThread(); - - Initialize(aURL, aCache); } + nsresult + Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, + const nsAString& aCacheName); + void - Abort(); + Abort() + { + AssertIsOnMainThread(); + + MOZ_ASSERT(!mAborted); + mAborted = true; + + if (mPump) { + mPump->Cancel(NS_BINDING_ABORTED); + mPump = nullptr; + } + } + + // This class manages 2 promises: 1 is to retrieve cache object, and 2 is for + // the value from the cache. For this reason we have mState to know what + // reject/resolve callback we are handling. virtual void - ResolvedCallback(JSContext* aCx, JS::Handle aValue) override; + ResolvedCallback(JSContext* aCx, JS::Handle aValue) override + { + AssertIsOnMainThread(); + + if (mAborted) { + return; + } + + if (mState == WaitingForCache) { + ManageCacheResult(aCx, aValue); + return; + } + + MOZ_ASSERT(mState == WaitingForValue); + ManageValueResult(aCx, aValue); + } virtual void RejectedCallback(JSContext* aCx, JS::Handle aValue) override; @@ -252,12 +203,6 @@ public: return mURL; } - bool - InCache() - { - return mInCache; - } - private: ~CompareCache() { @@ -265,27 +210,23 @@ private: } void - Initialize(const nsAString& aURL, Cache* const aCache); - - void - Finished(nsresult aStatus, bool aInCache = false); + ManageCacheResult(JSContext* aCx, JS::Handle aValue); void ManageValueResult(JSContext* aCx, JS::Handle aValue); - RefPtr mCN; + RefPtr mManager; nsCOMPtr mPump; nsString mURL; nsString mBuffer; enum { - WaitingForInitialization, - WaitingForValue, - Redundant + WaitingForCache, + WaitingForValue } mState; - bool mInCache; + bool mAborted; }; NS_IMPL_ISUPPORTS(CompareCache, nsIStreamLoaderObserver) @@ -295,23 +236,60 @@ class CompareManager final : public PromiseNativeHandler public: NS_DECL_ISUPPORTS - CompareManager(ServiceWorkerRegistrationInfo* aRegistration, - CompareCallback* aCallback, - nsIPrincipal* aPrincipal, - const nsAString& aURL, - const nsAString& aCacheName, - nsILoadGroup* aLoadGroup) + explicit CompareManager(ServiceWorkerRegistrationInfo* aRegistration, + CompareCallback* aCallback) : mRegistration(aRegistration) , mCallback(aCallback) - , mState(WaitingForInitialization) - , mPendingCount(0) - , mAreScriptsEqual(true) - , mLoadFlags(nsIChannel::LOAD_BYPASS_SERVICE_WORKER) + , mInternalHeaders(new InternalHeaders()) + , mState(WaitingForOpen) + , mNetworkFinished(false) + , mCacheFinished(false) + , mInCache(false) { AssertIsOnMainThread(); MOZ_ASSERT(aRegistration); + } - Initialize(aPrincipal, aURL, aCacheName, aLoadGroup); + nsresult + Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, + const nsAString& aCacheName, nsILoadGroup* aLoadGroup) + { + AssertIsOnMainThread(); + MOZ_ASSERT(aPrincipal); + + mURL = aURL; + + // Always create a CacheStorage since we want to write the network entry to + // the cache even if there isn't an existing one. + AutoJSAPI jsapi; + jsapi.Init(); + ErrorResult result; + mSandbox.init(jsapi.cx()); + mCacheStorage = CreateCacheStorage(jsapi.cx(), aPrincipal, result, &mSandbox); + if (NS_WARN_IF(result.Failed())) { + MOZ_ASSERT(!result.IsErrorWithMessage()); + Cleanup(); + return result.StealNSResult(); + } + + mCN = new CompareNetwork(this); + nsresult rv = mCN->Initialize(aPrincipal, aURL, aLoadGroup); + if (NS_WARN_IF(NS_FAILED(rv))) { + Cleanup(); + return rv; + } + + if (!aCacheName.IsEmpty()) { + mCC = new CompareCache(this); + rv = mCC->Initialize(aPrincipal, aURL, aCacheName); + if (NS_WARN_IF(NS_FAILED(rv))) { + mCN->Abort(); + Cleanup(); + return rv; + } + } + + return NS_OK; } const nsString& @@ -321,6 +299,13 @@ public: return mURL; } + void + SetMaxScope(const nsACString& aMaxScope) + { + MOZ_ASSERT(!mNetworkFinished); + mMaxScope = aMaxScope; + } + already_AddRefed GetRegistration() { @@ -329,10 +314,118 @@ public: } void - ResolvedCallback(JSContext* aCx, JS::Handle aValue) override; + SaveLoadFlags(nsLoadFlags aLoadFlags) + { + mCallback->SaveLoadFlags(aLoadFlags); + } void - RejectedCallback(JSContext* aCx, JS::Handle aValue) override; + NetworkFinished(nsresult aStatus) + { + AssertIsOnMainThread(); + + mNetworkFinished = true; + + if (NS_WARN_IF(NS_FAILED(aStatus))) { + if (mCC) { + mCC->Abort(); + } + + ComparisonFinished(aStatus, false); + return; + } + + MaybeCompare(); + } + + void + CacheFinished(nsresult aStatus, bool aInCache) + { + AssertIsOnMainThread(); + + mCacheFinished = true; + mInCache = aInCache; + + if (NS_WARN_IF(NS_FAILED(aStatus))) { + if (mCN) { + mCN->Abort(); + } + + ComparisonFinished(aStatus, false); + return; + } + + MaybeCompare(); + } + + void + MaybeCompare() + { + AssertIsOnMainThread(); + + if (!mNetworkFinished || (mCC && !mCacheFinished)) { + return; + } + + if (!mCC || !mInCache) { + ComparisonFinished(NS_OK, false); + return; + } + + ComparisonFinished(NS_OK, mCC->Buffer().Equals(mCN->Buffer())); + } + + // This class manages 2 promises: 1 is to retrieve Cache object, and 2 is to + // Put the value in the cache. For this reason we have mState to know what + // callback we are handling. + void + ResolvedCallback(JSContext* aCx, JS::Handle aValue) override + { + AssertIsOnMainThread(); + MOZ_ASSERT(mCallback); + + if (mState == WaitingForOpen) { + if (NS_WARN_IF(!aValue.isObject())) { + Fail(NS_ERROR_FAILURE); + return; + } + + JS::Rooted obj(aCx, &aValue.toObject()); + if (NS_WARN_IF(!obj)) { + Fail(NS_ERROR_FAILURE); + return; + } + + Cache* cache = nullptr; + nsresult rv = UNWRAP_OBJECT(Cache, obj, cache); + if (NS_WARN_IF(NS_FAILED(rv))) { + Fail(rv); + return; + } + + // Just to be safe. + RefPtr kungfuDeathGrip = cache; + WriteToCache(cache); + return; + } + + MOZ_ASSERT(mState == WaitingForPut); + mCallback->ComparisonResult(NS_OK, false /* aIsEqual */, + mNewCacheName, mMaxScope); + Cleanup(); + } + + void + RejectedCallback(JSContext* aCx, JS::Handle aValue) override + { + AssertIsOnMainThread(); + if (mState == WaitingForOpen) { + NS_WARNING("Could not open cache."); + } else { + NS_WARNING("Could not write to cache."); + } + Fail(NS_ERROR_FAILURE); + } CacheStorage* CacheStorage_() @@ -342,220 +435,96 @@ public: return mCacheStorage; } - void - ComparisonFinished(nsresult aStatus) + nsresult + OnStartRequest(nsIChannel* aChannel) { - MOZ_ASSERT(NS_FAILED(aStatus)); - ComparisonFinished(aStatus, - false /* aIsEqual */, - false /* aIsMainScript */, - EmptyCString(), - nsIRequest::LOAD_NORMAL); + nsresult rv = SetPrincipalInfo(aChannel); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + mChannelInfo.InitFromChannel(aChannel); + + mInternalHeaders->FillResponseHeaders(aChannel); + + return NS_OK; } - void - ComparisonFinished(nsresult aStatus, - bool aIsEqual, - bool aIsMainScript, - const nsACString& aMaxScope, - nsLoadFlags aLoadFlags) + nsresult + SetPrincipalInfo(nsIChannel* aChannel) { - AssertIsOnMainThread(); + nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); + NS_ASSERTION(ssm, "Should never be null!"); - if (NS_WARN_IF(NS_FAILED(aStatus))) { - NotifyComparisonResult(aStatus); - return; + nsCOMPtr channelPrincipal; + nsresult rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(channelPrincipal)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } - mAreScriptsEqual = mAreScriptsEqual && aIsEqual; - - if (aIsMainScript) { - mMaxScope = aMaxScope; - mLoadFlags = aLoadFlags; + UniquePtr principalInfo(new mozilla::ipc::PrincipalInfo()); + rv = PrincipalToPrincipalInfo(channelPrincipal, principalInfo.get()); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } - // Check whether all CompareNetworks finished their jobs. - MOZ_DIAGNOSTIC_ASSERT(mPendingCount > 0); - if (--mPendingCount) { - return; - } - - if (mAreScriptsEqual) { - NotifyComparisonResult(aStatus, - true /* aSameScripts */, - EmptyString(), - mMaxScope, - mLoadFlags); - return; - } - - // Write to Cache so ScriptLoader reads succeed. - mState = WaitingForOpen; - WriteNetworkBufferToNewCache(); + mPrincipalInfo = Move(principalInfo); + return NS_OK; } private: ~CompareManager() { AssertIsOnMainThread(); - MOZ_ASSERT(mCNs.Length() == 0); + MOZ_ASSERT(!mCC); + MOZ_ASSERT(!mCN); } void - Initialize(nsIPrincipal* aPrincipal, - const nsAString& aURL, - const nsAString& aCacheName, - nsILoadGroup* aLoadGroup); - - - // Only used for notifying falsy results. - void - NotifyComparisonResult(nsresult aStatus); - - void - NotifyComparisonResult(nsresult aStatus, - bool aSameScripts, - const nsAString& aNewCacheName, - const nsACString& aMaxScope, - nsLoadFlags aLoadFlags); - - void - FetchScript(const nsAString& aURL, - bool aIsMainScript, - Cache* const aCache) + Fail(nsresult aStatus) { - RefPtr cn = new CompareNetwork(this, - mPrincipal, - aURL, - aIsMainScript, - mLoadGroup, - aCache); - mCNs.AppendElement(cn.forget()); - mPendingCount += 1; + AssertIsOnMainThread(); + mCallback->ComparisonResult(aStatus, false /* aIsEqual */, + EmptyString(), EmptyCString()); + Cleanup(); } void - ManageOldCache(JSContext* aCx, JS::Handle aValue) + Cleanup() { - MOZ_ASSERT(mState == WaitingForExistingOpen); - - if (NS_WARN_IF(!aValue.isObject())) { - NotifyComparisonResult(NS_ERROR_FAILURE); - return; - } - - MOZ_ASSERT(!mOldCache); - JS::Rooted obj(aCx, &aValue.toObject()); - if (NS_WARN_IF(!obj) || - NS_WARN_IF(NS_FAILED(UNWRAP_OBJECT(Cache, obj, mOldCache)))) { - NotifyComparisonResult(NS_ERROR_FAILURE); - return; - } - - Optional request; - CacheQueryOptions options; - ErrorResult error; - RefPtr promise = mOldCache->Keys(request, options, error); - if (NS_WARN_IF(error.Failed())) { - NotifyComparisonResult(error.StealNSResult()); - return; - } - - mState = WaitingForExistingKeys; - promise->AppendNativeHandler(this); - return; + AssertIsOnMainThread(); + MOZ_ASSERT(mCallback); + mCallback = nullptr; + mCN = nullptr; + mCC = nullptr; } void - ManageOldKeys(JSContext* aCx, JS::Handle aValue) + ComparisonFinished(nsresult aStatus, bool aIsEqual) { - MOZ_ASSERT(mState == WaitingForExistingKeys); + AssertIsOnMainThread(); + MOZ_ASSERT(mCallback); - if (NS_WARN_IF(!aValue.isObject())) { - NotifyComparisonResult(NS_ERROR_FAILURE); + if (NS_WARN_IF(NS_FAILED(aStatus))) { + Fail(aStatus); return; } - JS::Rooted obj(aCx, &aValue.toObject()); - if (NS_WARN_IF(!obj)) { - NotifyComparisonResult(NS_ERROR_FAILURE); + if (aIsEqual) { + mCallback->ComparisonResult(aStatus, aIsEqual, EmptyString(), mMaxScope); + Cleanup(); return; } - uint32_t len = 0; - if (!JS_GetArrayLength(aCx, obj, &len)) { - NotifyComparisonResult(NS_ERROR_FAILURE); - return; - } - - // Fetch the new scripts. - MOZ_ASSERT(mPendingCount == 0); - - mState = WaitingForScriptOrComparisonResult; - for (uint32_t i = 0; i < len; ++i) { - JS::Rooted val(aCx); - if (NS_WARN_IF(!JS_GetElement(aCx, obj, i, &val)) || - NS_WARN_IF(!val.isObject())) { - NotifyComparisonResult(NS_ERROR_FAILURE); - return; - } - - Request* request; - JS::Rooted requestObj(aCx, &val.toObject()); - if (NS_WARN_IF(NS_FAILED(UNWRAP_OBJECT(Request, - requestObj, - request)))) { - NotifyComparisonResult(NS_ERROR_FAILURE); - continue; - }; - - nsString URL; - request->GetUrl(URL); - FetchScript(URL, mURL == URL /* aIsMainScript */, mOldCache); - } - - return; - } - - void - ManageNewCache(JSContext* aCx, JS::Handle aValue) - { - MOZ_ASSERT(mState == WaitingForOpen); - - if (NS_WARN_IF(!aValue.isObject())) { - NotifyComparisonResult(NS_ERROR_FAILURE); - return; - } - - JS::Rooted obj(aCx, &aValue.toObject()); - if (NS_WARN_IF(!obj)) { - NotifyComparisonResult(NS_ERROR_FAILURE); - return; - } - - Cache* cache = nullptr; - nsresult rv = UNWRAP_OBJECT(Cache, obj, cache); - if (NS_WARN_IF(NS_FAILED(rv))) { - NotifyComparisonResult(rv); - return; - } - - // Just to be safe. - RefPtr kungfuDeathGrip = cache; - mState = WaitingForPut; - - MOZ_ASSERT(mPendingCount == 0); - for (uint32_t i = 0; i < mCNs.Length(); ++i) { - WriteToCache(cache, mCNs[i]); - } - return; + // Write to Cache so ScriptLoader reads succeed. + WriteNetworkBufferToNewCache(); } void WriteNetworkBufferToNewCache() { AssertIsOnMainThread(); - MOZ_ASSERT(mCNs.Length() != 0); + MOZ_ASSERT(mCN); MOZ_ASSERT(mCacheStorage); MOZ_ASSERT(mNewCacheName.IsEmpty()); @@ -563,14 +532,14 @@ private: result = serviceWorkerScriptCache::GenerateCacheName(mNewCacheName); if (NS_WARN_IF(result.Failed())) { MOZ_ASSERT(!result.IsErrorWithMessage()); - NotifyComparisonResult(result.StealNSResult()); + Fail(result.StealNSResult()); return; } RefPtr cacheOpenPromise = mCacheStorage->Open(mNewCacheName, result); if (NS_WARN_IF(result.Failed())) { MOZ_ASSERT(!result.IsErrorWithMessage()); - NotifyComparisonResult(result.StealNSResult()); + Fail(result.StealNSResult()); return; } @@ -578,45 +547,38 @@ private: } void - WriteToCache(Cache* aCache, CompareNetwork* aCN) + WriteToCache(Cache* aCache) { AssertIsOnMainThread(); MOZ_ASSERT(aCache); - MOZ_ASSERT(aCN); - MOZ_ASSERT(mState == WaitingForPut); - - if (!aCN->Succeeded()) { - return; - } + MOZ_ASSERT(mState == WaitingForOpen); ErrorResult result; nsCOMPtr body; result = NS_NewCStringInputStream(getter_AddRefs(body), - NS_ConvertUTF16toUTF8(aCN->Buffer())); + NS_ConvertUTF16toUTF8(mCN->Buffer())); if (NS_WARN_IF(result.Failed())) { MOZ_ASSERT(!result.IsErrorWithMessage()); - NotifyComparisonResult(result.StealNSResult()); + Fail(result.StealNSResult()); return; } RefPtr ir = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); - ir->SetBody(body, aCN->Buffer().Length()); + ir->SetBody(body, mCN->Buffer().Length()); - ir->InitChannelInfo(aCN->GetChannelInfo()); - UniquePtr principalInfo = aCN->TakePrincipalInfo(); - if (principalInfo) { - ir->SetPrincipalInfo(Move(principalInfo)); + ir->InitChannelInfo(mChannelInfo); + if (mPrincipalInfo) { + ir->SetPrincipalInfo(Move(mPrincipalInfo)); } IgnoredErrorResult ignored; - RefPtr internalHeaders = aCN->GetInternalHeaders(); - ir->Headers()->Fill(*(internalHeaders.get()), ignored); + ir->Headers()->Fill(*mInternalHeaders, ignored); RefPtr response = new Response(aCache->GetGlobalObject(), ir); RequestOrUSVString request; - request.SetAsUSVString().Rebind(aCN->URL().Data(), URL().Length()); + request.SetAsUSVString().Rebind(URL().Data(), URL().Length()); // For now we have to wait until the Put Promise is fulfilled before we can // continue since Cache does not yet support starting a read that is being @@ -624,11 +586,11 @@ private: RefPtr cachePromise = aCache->Put(request, *response, result); if (NS_WARN_IF(result.Failed())) { MOZ_ASSERT(!result.IsErrorWithMessage()); - NotifyComparisonResult(result.StealNSResult()); + Fail(result.StealNSResult()); return; } - mPendingCount += 1; + mState = WaitingForPut; cachePromise->AppendNativeHandler(this); } @@ -637,79 +599,61 @@ private: JS::PersistentRooted mSandbox; RefPtr mCacheStorage; - nsTArray> mCNs; + RefPtr mCN; + RefPtr mCC; nsString mURL; - RefPtr mPrincipal; - RefPtr mLoadGroup; - - // Used for the old cache where saves the old source scripts. - nsString mOldCacheName; - RefPtr mOldCache; - // Only used if the network script has changed and needs to be cached. nsString mNewCacheName; - enum { - WaitingForInitialization, - WaitingForExistingOpen, - WaitingForExistingKeys, - WaitingForScriptOrComparisonResult, - WaitingForOpen, - WaitingForPut, - Redundant - } mState; + ChannelInfo mChannelInfo; + RefPtr mInternalHeaders; - uint32_t mPendingCount; - bool mAreScriptsEqual; + UniquePtr mPrincipalInfo; nsCString mMaxScope; - nsLoadFlags mLoadFlags; + + enum { + WaitingForOpen, + WaitingForPut + } mState; + + bool mNetworkFinished; + bool mCacheFinished; + bool mInCache; }; NS_IMPL_ISUPPORTS0(CompareManager) -void -CompareNetwork::Initialize(nsIPrincipal* aPrincipal, - const nsAString& aURL, - bool aIsMainScript, - nsILoadGroup* aLoadGroup, - Cache* const aCache) +nsresult +CompareNetwork::Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, nsILoadGroup* aLoadGroup) { - AssertIsOnMainThread(); MOZ_ASSERT(aPrincipal); - MOZ_ASSERT(mState == WaitingForInitialization); - - // RAII error notifier - nsresult rv = NS_ERROR_FAILURE; - auto guard = MakeScopeExit([&] { - NetworkFinished(rv); - }); - - mURL = aURL; + AssertIsOnMainThread(); nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, nullptr); + nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { - return; + return rv; } - mIsMainScript = aIsMainScript; - nsCOMPtr loadGroup; rv = NS_NewLoadGroup(getter_AddRefs(loadGroup), aPrincipal); if (NS_WARN_IF(NS_FAILED(rv))) { - return; + return rv; } - // Update mLoadFlags, which is passed to script loaders later. + nsLoadFlags flags = nsIChannel::LOAD_BYPASS_SERVICE_WORKER; RefPtr registration = mManager->GetRegistration(); - mLoadFlags |= registration->GetLoadFlags(); + flags |= registration->GetLoadFlags(); if (registration->IsLastUpdateCheckTimeOverOneDay()) { - mLoadFlags |= nsIRequest::LOAD_BYPASS_CACHE; + flags |= nsIRequest::LOAD_BYPASS_CACHE; } + // Save the load flags for propagating to ServiceWorkerInfo. + mManager->SaveLoadFlags(flags); + // Note that because there is no "serviceworker" RequestContext type, we can // use the TYPE_INTERNAL_SCRIPT content policy types when loading a service // worker. @@ -719,9 +663,9 @@ CompareNetwork::Initialize(nsIPrincipal* aPrincipal, nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER, loadGroup, nullptr, // aCallbacks - mLoadFlags); + flags); if (NS_WARN_IF(NS_FAILED(rv))) { - return; + return rv; } nsCOMPtr httpChannel = do_QueryInterface(mChannel); @@ -739,112 +683,15 @@ CompareNetwork::Initialize(nsIPrincipal* aPrincipal, nsCOMPtr loader; rv = NS_NewStreamLoader(getter_AddRefs(loader), this, this); if (NS_WARN_IF(NS_FAILED(rv))) { - return; + return rv; } rv = mChannel->AsyncOpen2(loader); if (NS_WARN_IF(NS_FAILED(rv))) { - return; + return rv; } - // If we don't have an existing cache to compare with. - if (!aCache) { - mState = WaitingForNetworkFinished; - - guard.release(); - return; - } - - mCC = new CompareCache(this, aURL, aCache); - mState = WaitingForBothFinished; - - guard.release(); -} - -void -CompareNetwork::Finished() -{ - MOZ_ASSERT(mState != Redundant); - mState = Redundant; - - bool same = true; - nsresult rv = NS_OK; - - // mNetworkResult is prior to mCacheResult, since it's needed for reporting - // various error to the web contenet. - if (NS_FAILED(mNetworkResult)) { - // An imported script could become offline, since it might no longer be - // needed by the new importing script. In that case, the importing script - // must be different, and thus, it's okay to report same script found here. - rv = mIsMainScript ? mNetworkResult : NS_OK; - same = true; - } else if (mCC && NS_FAILED(mCacheResult)) { - rv = mCacheResult; - } else { // Both passed. - same = mCC && - mCC->InCache() && - mCC->Buffer().Equals(mBuffer); - } - - mManager->ComparisonFinished(rv, same, mIsMainScript, mMaxScope, mLoadFlags); - - mCC = nullptr; -} - -void -CompareNetwork::NetworkFinished(nsresult aRv) -{ - mNetworkResult = aRv; - - if (mState == WaitingForBothFinished) { - mState = WaitingForCacheFinished; - return; - } - - if (mState == WaitingForInitialization || - mState == WaitingForNetworkFinished) { - Finished(); - return; - } - - MOZ_CRASH("Unacceptable state."); -} - -void -CompareNetwork::CacheFinished(nsresult aRv) -{ - mCacheResult = aRv; - - if (mState == WaitingForBothFinished) { - mState = WaitingForNetworkFinished; - return; - } - - if (mState == WaitingForCacheFinished) { - Finished(); - return; - } - - MOZ_CRASH("Unacceptable state."); -} - -void -CompareNetwork::Abort() -{ - AssertIsOnMainThread(); - - if (mState != Redundant) { - mState = Redundant; - - MOZ_ASSERT(mChannel); - mChannel->Cancel(NS_BINDING_ABORTED); - mChannel = nullptr; - - if (mCC) { - mCC->Abort(); - mCC = nullptr; - } - } + return NS_OK; } NS_IMETHODIMP @@ -862,39 +709,11 @@ CompareNetwork::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) MOZ_ASSERT(channel == mChannel); #endif - MOZ_ASSERT(!mChannelInfo.IsInitialized()); - mChannelInfo.InitFromChannel(mChannel); - - nsresult rv = SetPrincipalInfo(mChannel); + nsresult rv = mManager->OnStartRequest(mChannel); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - mInternalHeaders->FillResponseHeaders(mChannel); - - return NS_OK; -} - -nsresult -CompareNetwork::SetPrincipalInfo(nsIChannel* aChannel) -{ - nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); - NS_ASSERTION(ssm, "Should never be null!"); - - nsCOMPtr channelPrincipal; - nsresult rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(channelPrincipal)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - UniquePtr principalInfo = MakeUnique(); - rv = PrincipalToPrincipalInfo(channelPrincipal, principalInfo.get()); - - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mPrincipalInfo = Move(principalInfo); return NS_OK; } @@ -920,9 +739,9 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext if (NS_WARN_IF(NS_FAILED(aStatus))) { if (aStatus == NS_ERROR_REDIRECT_LOOP) { - NetworkFinished(NS_ERROR_DOM_SECURITY_ERR); + mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR); } else { - NetworkFinished(aStatus); + mManager->NetworkFinished(aStatus); } return NS_OK; } @@ -930,7 +749,7 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext nsCOMPtr request; nsresult rv = aLoader->GetRequest(getter_AddRefs(request)); if (NS_WARN_IF(NS_FAILED(rv))) { - NetworkFinished(rv); + mManager->NetworkFinished(rv); return NS_OK; } @@ -940,7 +759,7 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext bool requestSucceeded; rv = httpChannel->GetRequestSucceeded(&requestSucceeded); if (NS_WARN_IF(NS_FAILED(rv))) { - NetworkFinished(rv); + mManager->NetworkFinished(rv); return NS_OK; } @@ -957,17 +776,17 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext registration->mScope, "ServiceWorkerRegisterNetworkError", nsTArray { NS_ConvertUTF8toUTF16(registration->mScope), statusAsText, mManager->URL() }); - NetworkFinished(NS_ERROR_FAILURE); + mManager->NetworkFinished(NS_ERROR_FAILURE); return NS_OK; } - if (mIsMainScript) { - // Note: we explicitly don't check for the return value here, because the - // absence of the header is not an error condition. - Unused << httpChannel->GetResponseHeader( - NS_LITERAL_CSTRING("Service-Worker-Allowed"), - mMaxScope); - } + nsAutoCString maxScope; + // Note: we explicitly don't check for the return value here, because the + // absence of the header is not an error condition. + Unused << httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Service-Worker-Allowed"), + maxScope); + + mManager->SetMaxScope(maxScope); bool isFromCache = false; nsCOMPtr cacheChannel(do_QueryInterface(httpChannel)); @@ -990,7 +809,7 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext // were received but no content type was specified, we'll be given // UNKNOWN_CONTENT_TYPE "application/x-unknown-content-type" and so fall // into the next case with its better error message. - NetworkFinished(NS_ERROR_DOM_SECURITY_ERR); + mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR); return rv; } @@ -1002,7 +821,7 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext registration->mScope, "ServiceWorkerRegisterMimeTypeError", nsTArray { NS_ConvertUTF8toUTF16(registration->mScope), NS_ConvertUTF8toUTF16(mimeType), mManager->URL() }); - NetworkFinished(NS_ERROR_DOM_SECURITY_ERR); + mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR); return rv; } @@ -1013,73 +832,35 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext NS_LITERAL_STRING("UTF-8"), nullptr, buffer, len); if (NS_WARN_IF(NS_FAILED(rv))) { - NetworkFinished(rv); + mManager->NetworkFinished(rv); return rv; } mBuffer.Adopt(buffer, len); - NetworkFinished(NS_OK); + mManager->NetworkFinished(NS_OK); return NS_OK; } -void -CompareCache::Initialize(const nsAString& aURL, - Cache* const aCache) +nsresult +CompareCache::Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, + const nsAString& aCacheName) { - MOZ_ASSERT(aCache); - MOZ_ASSERT(mState == WaitingForInitialization); + MOZ_ASSERT(aPrincipal); AssertIsOnMainThread(); - // RAII error notifier - nsresult rv = NS_ERROR_FAILURE; - auto guard = MakeScopeExit([&] { - Finished(rv); - }); - mURL = aURL; - RequestOrUSVString request; - request.SetAsUSVString().Rebind(mURL.Data(), mURL.Length()); - ErrorResult error; - CacheQueryOptions params; - RefPtr promise = aCache->Match(request, params, error); - if (NS_WARN_IF(error.Failed())) { - rv = error.StealNSResult(); - return; + ErrorResult rv; + + RefPtr promise = mManager->CacheStorage_()->Open(aCacheName, rv); + if (NS_WARN_IF(rv.Failed())) { + MOZ_ASSERT(!rv.IsErrorWithMessage()); + return rv.StealNSResult(); } - mState = WaitingForValue; promise->AppendNativeHandler(this); - - guard.release(); -} - -void -CompareCache::Finished(nsresult aStatus, bool aInCache) -{ - if (mState != Redundant) { - mState = Redundant; - mInCache = aInCache; - mCN->CacheFinished(aStatus); - } -} - -void -CompareCache::Abort() -{ - AssertIsOnMainThread(); - - if (mState != Redundant) { - mState = Redundant; - - if (mPump) { - mPump->Cancel(NS_BINDING_ABORTED); - mPump = nullptr; - } - - mCN = nullptr; - } + return NS_OK; } NS_IMETHODIMP @@ -1089,12 +870,12 @@ CompareCache::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext, { AssertIsOnMainThread(); - if (mState == Redundant) { + if (mAborted) { return aStatus; } if (NS_WARN_IF(NS_FAILED(aStatus))) { - Finished(aStatus, false); + mManager->CacheFinished(aStatus, false); return aStatus; } @@ -1105,40 +886,63 @@ CompareCache::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext, NS_LITERAL_STRING("UTF-8"), nullptr, buffer, len); if (NS_WARN_IF(NS_FAILED(rv))) { - Finished(rv, false); + mManager->CacheFinished(rv, false); return rv; } mBuffer.Adopt(buffer, len); - Finished(NS_OK, true); + mManager->CacheFinished(NS_OK, true); return NS_OK; } -// This class manages only 1 promise: For the value from the cache. -void -CompareCache::ResolvedCallback(JSContext* aCx, JS::Handle aValue) -{ - AssertIsOnMainThread(); - - if (mState == Redundant) { - return; - } - - MOZ_ASSERT(mState == WaitingForValue); - ManageValueResult(aCx, aValue); -} - void CompareCache::RejectedCallback(JSContext* aCx, JS::Handle aValue) { AssertIsOnMainThread(); - if (mState == Redundant) { + if (mAborted) { return; } - Finished(NS_ERROR_FAILURE, false); + mManager->CacheFinished(NS_ERROR_FAILURE, false); +} + +void +CompareCache::ManageCacheResult(JSContext* aCx, JS::Handle aValue) +{ + AssertIsOnMainThread(); + + if (NS_WARN_IF(!aValue.isObject())) { + mManager->CacheFinished(NS_ERROR_FAILURE, false); + return; + } + + JS::Rooted obj(aCx, &aValue.toObject()); + if (NS_WARN_IF(!obj)) { + mManager->CacheFinished(NS_ERROR_FAILURE, false); + return; + } + + Cache* cache = nullptr; + nsresult rv = UNWRAP_OBJECT(Cache, obj, cache); + if (NS_WARN_IF(NS_FAILED(rv))) { + mManager->CacheFinished(rv, false); + return; + } + + RequestOrUSVString request; + request.SetAsUSVString().Rebind(mURL.Data(), mURL.Length()); + ErrorResult error; + CacheQueryOptions params; + RefPtr promise = cache->Match(request, params, error); + if (NS_WARN_IF(error.Failed())) { + mManager->CacheFinished(error.StealNSResult(), false); + return; + } + + promise->AppendNativeHandler(this); + mState = WaitingForValue; } void @@ -1148,7 +952,7 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle aValue) // The cache returns undefined if the object is not stored. if (aValue.isUndefined()) { - Finished(NS_OK, false); + mManager->CacheFinished(NS_OK, false); return; } @@ -1156,14 +960,14 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle aValue) JS::Rooted obj(aCx, &aValue.toObject()); if (NS_WARN_IF(!obj)) { - Finished(NS_ERROR_FAILURE, false); + mManager->CacheFinished(NS_ERROR_FAILURE, false); return; } Response* response = nullptr; nsresult rv = UNWRAP_OBJECT(Response, obj, response); if (NS_WARN_IF(NS_FAILED(rv))) { - Finished(rv, false); + mManager->CacheFinished(rv, false); return; } @@ -1176,21 +980,21 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle aValue) MOZ_ASSERT(!mPump); rv = NS_NewInputStreamPump(getter_AddRefs(mPump), inputStream); if (NS_WARN_IF(NS_FAILED(rv))) { - Finished(rv, false); + mManager->CacheFinished(rv, false); return; } nsCOMPtr loader; rv = NS_NewStreamLoader(getter_AddRefs(loader), this); if (NS_WARN_IF(NS_FAILED(rv))) { - Finished(rv, false); + mManager->CacheFinished(rv, false); return; } rv = mPump->AsyncRead(loader, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { mPump = nullptr; - Finished(rv, false); + mManager->CacheFinished(rv, false); return; } @@ -1201,172 +1005,12 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle aValue) rv = rr->RetargetDeliveryTo(sts); if (NS_WARN_IF(NS_FAILED(rv))) { mPump = nullptr; - Finished(rv, false); + mManager->CacheFinished(rv, false); return; } } } -void -CompareManager::Initialize(nsIPrincipal* aPrincipal, - const nsAString& aURL, - const nsAString& aCacheName, - nsILoadGroup* aLoadGroup) -{ - AssertIsOnMainThread(); - MOZ_ASSERT(aPrincipal); - MOZ_ASSERT(mState == WaitingForInitialization); - MOZ_ASSERT(mPendingCount == 0); - - // RAII error notifier - nsresult rv = NS_ERROR_FAILURE; - auto guard = MakeScopeExit([&] { - NotifyComparisonResult(rv); - }); - - mURL = aURL; - mPrincipal = aPrincipal; - mLoadGroup = aLoadGroup; - mOldCacheName = aCacheName; - - // Always create a CacheStorage since we want to write the network entry to - // the cache even if there isn't an existing one. - AutoJSAPI jsapi; - jsapi.Init(); - ErrorResult result; - mSandbox.init(jsapi.cx()); - mCacheStorage = CreateCacheStorage(jsapi.cx(), aPrincipal, result, &mSandbox); - if (NS_WARN_IF(result.Failed())) { - MOZ_ASSERT(!result.IsErrorWithMessage()); - rv = result.StealNSResult(); - return; - } - - // Open the cache saving the old source scripts. - if (!mOldCacheName.IsEmpty()) { - RefPtr promise = mCacheStorage->Open(mOldCacheName, result); - if (NS_WARN_IF(result.Failed())) { - MOZ_ASSERT(!result.IsErrorWithMessage()); - rv = result.StealNSResult(); - return; - } - - mState = WaitingForExistingOpen; - promise->AppendNativeHandler(this); - - guard.release(); - return; - } - - // Go fetch the script directly without comparison. - mState = WaitingForScriptOrComparisonResult; - FetchScript(mURL, true /* aIsMainScript */, nullptr); - - guard.release(); -} - -// This class manages 4 promises if needed: -// 1. Retrieve the Cache object by a given CacheName of OldCache. -// 2. Retrieve the URLs saved in OldCache. -// 3. Retrieve the Cache object of the NewCache for the newly created SW. -// 4. Put the value in the cache. -// For this reason we have mState to know what callback we are handling. -void -CompareManager::ResolvedCallback(JSContext* aCx, JS::Handle aValue) -{ - AssertIsOnMainThread(); - MOZ_ASSERT(mCallback); - - if (mState == WaitingForExistingOpen) { - ManageOldCache(aCx, aValue); - return; - } - - if (mState == WaitingForExistingKeys) { - ManageOldKeys(aCx, aValue); - return; - } - - if (mState == WaitingForOpen) { - ManageNewCache(aCx, aValue); - return; - } - - MOZ_ASSERT(mState == WaitingForPut); - MOZ_DIAGNOSTIC_ASSERT(mPendingCount > 0); - if (--mPendingCount) { - return; - } - - NotifyComparisonResult(NS_OK, - false /* aSameScripts */, - mNewCacheName, - mMaxScope, - mLoadFlags); -} - -void -CompareManager::RejectedCallback(JSContext* aCx, JS::Handle aValue) -{ - AssertIsOnMainThread(); - if (mState == WaitingForExistingKeys) { - NS_WARNING("Could not get the existing URLs."); - } else if (mState == WaitingForExistingKeys){ - NS_WARNING("Could not get the existing URLs."); - } else if (mState == WaitingForOpen) { - NS_WARNING("Could not open cache."); - } else { - NS_WARNING("Could not write to cache."); - } - NotifyComparisonResult(NS_ERROR_FAILURE); -} - -void -CompareManager::NotifyComparisonResult(nsresult aState) -{ - MOZ_ASSERT(NS_FAILED(aState)); - NotifyComparisonResult(aState, - false /* aSameScripts*/, - EmptyString(), - EmptyCString(), - nsIRequest::LOAD_NORMAL); -} - -void -CompareManager::NotifyComparisonResult(nsresult aStatus, - bool aSameScripts, - const nsAString& aNewCacheName, - const nsACString& aMaxScope, - nsLoadFlags aLoadFlags) -{ - AssertIsOnMainThread(); - - // If mState is Redundant, the comparison result is sent out and this - // CompareManager cleaned up before. Thus, there is nothing left to do here. - if (mState == Redundant) { - return; - } - - // Mark this CompareManager is Redundant. - mState = Redundant; - - // Send the result to mCallBack. - MOZ_ASSERT(mCallback); - mCallback->ComparisonResult(aStatus, - aSameScripts, - aNewCacheName, - aMaxScope, - aLoadFlags); - mCallback = nullptr; - - // Abort and release CompareNetworks. - MOZ_ASSERT(mCNs.Length()); - for (uint32_t i = 0; i < mCNs.Length(); ++i) { - mCNs[i]->Abort(); - } - mCNs.Clear(); -} - } // namespace nsresult @@ -1424,7 +1068,7 @@ GenerateCacheName(nsAString& aName) return NS_OK; } -void +nsresult Compare(ServiceWorkerRegistrationInfo* aRegistration, nsIPrincipal* aPrincipal, const nsAString& aCacheName, const nsAString& aURL, CompareCallback* aCallback, @@ -1436,12 +1080,14 @@ Compare(ServiceWorkerRegistrationInfo* aRegistration, MOZ_ASSERT(!aURL.IsEmpty()); MOZ_ASSERT(aCallback); - RefPtr cm = new CompareManager(aRegistration, - aCallback, - aPrincipal, - aURL, - aCacheName, - aLoadGroup); + RefPtr cm = new CompareManager(aRegistration, aCallback); + + nsresult rv = cm->Initialize(aPrincipal, aURL, aCacheName, aLoadGroup); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; } } // namespace serviceWorkerScriptCache diff --git a/dom/workers/ServiceWorkerScriptCache.h b/dom/workers/ServiceWorkerScriptCache.h index 3a0e5bc31910..a2a5b91fde7d 100644 --- a/dom/workers/ServiceWorkerScriptCache.h +++ b/dom/workers/ServiceWorkerScriptCache.h @@ -39,13 +39,21 @@ public: ComparisonResult(nsresult aStatus, bool aInCacheAndEqual, const nsAString& aNewCacheName, - const nsACString& aMaxScope, - nsLoadFlags aLoadFlags) = 0; + const nsACString& aMaxScope) = 0; + + /* + * Right before fetching the main script from the network, we check whether + * the script expiration timer has expired. Via this method, we can save the + * result of the check, and propogate it to the new ServiceWorkerInfo if there + * is one, so the imported scripts can be affected by the result as well. + */ + virtual void + SaveLoadFlags(nsLoadFlags aLoadFlags) = 0; NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING }; -void +nsresult Compare(ServiceWorkerRegistrationInfo* aRegistration, nsIPrincipal* aPrincipal, const nsAString& aCacheName, const nsAString& aURL, CompareCallback* aCallback, nsILoadGroup* aLoadGroup); diff --git a/dom/workers/ServiceWorkerUpdateJob.cpp b/dom/workers/ServiceWorkerUpdateJob.cpp index b0c69c4d2082..aae6be4ec801 100644 --- a/dom/workers/ServiceWorkerUpdateJob.cpp +++ b/dom/workers/ServiceWorkerUpdateJob.cpp @@ -98,14 +98,15 @@ public: ComparisonResult(nsresult aStatus, bool aInCacheAndEqual, const nsAString& aNewCacheName, - const nsACString& aMaxScope, - nsLoadFlags aLoadFlags) override + const nsACString& aMaxScope) override { - mJob->ComparisonResult(aStatus, - aInCacheAndEqual, - aNewCacheName, - aMaxScope, - aLoadFlags); + mJob->ComparisonResult(aStatus, aInCacheAndEqual, aNewCacheName, aMaxScope); + } + + virtual void + SaveLoadFlags(nsLoadFlags aLoadFlags) override + { + mJob->SetLoadFlags(aLoadFlags); } NS_INLINE_DECL_REFCOUNTING(ServiceWorkerUpdateJob::CompareCallback, override) @@ -317,9 +318,14 @@ ServiceWorkerUpdateJob::Update() RefPtr callback = new CompareCallback(this); - serviceWorkerScriptCache::Compare(mRegistration, mPrincipal, cacheName, - NS_ConvertUTF8toUTF16(mScriptSpec), - callback, mLoadGroup); + nsresult rv = + serviceWorkerScriptCache::Compare(mRegistration, mPrincipal, cacheName, + NS_ConvertUTF8toUTF16(mScriptSpec), + callback, mLoadGroup); + if (NS_WARN_IF(NS_FAILED(rv))) { + FailUpdateJob(rv); + return; + } } nsLoadFlags @@ -328,12 +334,17 @@ ServiceWorkerUpdateJob::GetLoadFlags() const return mLoadFlags; } +void +ServiceWorkerUpdateJob::SetLoadFlags(nsLoadFlags aLoadFlags) +{ + mLoadFlags = aLoadFlags; +} + void ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus, bool aInCacheAndEqual, const nsAString& aNewCacheName, - const nsACString& aMaxScope, - nsLoadFlags aLoadFlags) + const nsACString& aMaxScope) { AssertIsOnMainThread(); @@ -428,7 +439,7 @@ ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus, mRegistration->mScope, mScriptSpec, aNewCacheName, - aLoadFlags); + mLoadFlags); mRegistration->SetEvaluating(sw); diff --git a/dom/workers/ServiceWorkerUpdateJob.h b/dom/workers/ServiceWorkerUpdateJob.h index 229118a6e409..ed5067273223 100644 --- a/dom/workers/ServiceWorkerUpdateJob.h +++ b/dom/workers/ServiceWorkerUpdateJob.h @@ -73,6 +73,9 @@ protected: nsLoadFlags GetLoadFlags() const; + void + SetLoadFlags(nsLoadFlags aLoadFlags); + private: class CompareCallback; class ContinueUpdateRunnable; @@ -84,8 +87,7 @@ private: ComparisonResult(nsresult aStatus, bool aInCacheAndEqual, const nsAString& aNewCacheName, - const nsACString& aMaxScope, - nsLoadFlags aLoadFlags); + const nsACString& aMaxScope); // Utility method called after evaluating the worker script. void diff --git a/dom/workers/test/serviceworkers/bug1290951_worker_imported.sjs b/dom/workers/test/serviceworkers/bug1290951_worker_imported.sjs deleted file mode 100644 index a5ada59bf1ba..000000000000 --- a/dom/workers/test/serviceworkers/bug1290951_worker_imported.sjs +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -function handleRequest(request, response) { - let count = getState("count"); - if (count === "") { - count = "1"; - } - - // If this is the first request, return the first source. - if (count === "1") { - response.setHeader("Content-Type", "application/javascript"); - response.write("// Imported."); - setState("count", "2"); - } - // For all subsequent requests, return the second source. - else { - response.setStatusLine(request.httpVersion, 404, "Not found"); - } -} - diff --git a/dom/workers/test/serviceworkers/bug1290951_worker_main.sjs b/dom/workers/test/serviceworkers/bug1290951_worker_main.sjs deleted file mode 100644 index 1e1346571ca6..000000000000 --- a/dom/workers/test/serviceworkers/bug1290951_worker_main.sjs +++ /dev/null @@ -1,33 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const WORKER_1 = ` - importScripts("bug1290951_worker_imported.sjs"); -`; - -const WORKER_2 = ` - // Remove importScripts(...)" for testing purpose. -`; - -function handleRequest(request, response) { - let count = getState("count"); - if (count === "") { - count = "1"; - } - - // This header is necessary for making this script able to be loaded. - response.setHeader("Content-Type", "application/javascript"); - - // If this is the first request, return the first source. - if (count === "1") { - response.write(WORKER_1); - setState("count", "2"); - } - // For all subsequent requests, return the second source. - else { - response.write(WORKER_2); - } -} - diff --git a/dom/workers/test/serviceworkers/mochitest.ini b/dom/workers/test/serviceworkers/mochitest.ini index 604631a43d38..29ab778c66a2 100644 --- a/dom/workers/test/serviceworkers/mochitest.ini +++ b/dom/workers/test/serviceworkers/mochitest.ini @@ -215,11 +215,8 @@ support-files = nofetch_handler_worker.js service_worker.js service_worker_client.html - bug1290951_worker_main.sjs - bug1290951_worker_imported.sjs [test_bug1151916.html] -[test_bug1290951.html] [test_bug1240436.html] [test_claim.html] [test_claim_oninstall.html] diff --git a/dom/workers/test/serviceworkers/test_bug1290951.html b/dom/workers/test/serviceworkers/test_bug1290951.html deleted file mode 100644 index ee240478ea1a..000000000000 --- a/dom/workers/test/serviceworkers/test_bug1290951.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Bug 1290951 - Test update after a new verion of mainscipt that doesn't need an imported script anymore. - - - - - -

-
-

-
-
-
-
-
diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json
index 34c3ad51765d..d15626d6f53e 100644
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -61981,16 +61981,6 @@
      {}
     ]
    ],
-   "service-workers/service-worker/resources/bytecheck-worker-imported-script.py": [
-    [
-     {}
-    ]
-   ],
-   "service-workers/service-worker/resources/bytecheck-worker.py": [
-    [
-     {}
-    ]
-   ],
    "service-workers/service-worker/resources/claim-with-redirect-iframe.html": [
     [
      {}
@@ -122856,12 +122846,6 @@
      {}
     ]
    ],
-   "service-workers/service-worker/update-bytecheck.https.html": [
-    [
-     "/service-workers/service-worker/update-bytecheck.https.html",
-     {}
-    ]
-   ],
    "service-workers/service-worker/update-recovery.https.html": [
     [
      "/service-workers/service-worker/update-recovery.https.html",
@@ -206425,14 +206409,6 @@
    "0ddb4f1cf84729ed673295719ec58a3e5d600a12",
    "support"
   ],
-  "service-workers/service-worker/resources/bytecheck-worker-imported-script.py": [
-   "772d029d4efbe22f62f3473d4afe9e501a792571",
-   "support"
-  ],
-  "service-workers/service-worker/resources/bytecheck-worker.py": [
-   "2693790af1dcd812bc3741db7fa355e23eef0e01",
-   "support"
-  ],
   "service-workers/service-worker/resources/claim-with-redirect-iframe.html": [
    "fdc472f4e9a591f0b471174b2aa1783107731f49",
    "support"
@@ -207101,10 +207077,6 @@
    "7c8c6c3edca83d54f1838eccf3afb0b1223c7a44",
    "testharness"
   ],
-  "service-workers/service-worker/update-bytecheck.https.html": [
-   "6562348b198124822297c6b622c3e63870427672",
-   "testharness"
-  ],
   "service-workers/service-worker/update-recovery.https.html": [
    "aac5705d6844e4a33200418504adb57053a45be2",
    "testharness"
diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/bytecheck-worker-imported-script.py b/testing/web-platform/tests/service-workers/service-worker/resources/bytecheck-worker-imported-script.py
deleted file mode 100644
index e96022026c52..000000000000
--- a/testing/web-platform/tests/service-workers/service-worker/resources/bytecheck-worker-imported-script.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import time
-
-def main(request, response):
-    headers = [('Content-Type', 'application/javascript'),
-               ('Cache-Control', 'max-age=0')]
-
-    imported_content_type = ''
-    if 'imported' in request.GET:
-        imported_content_type = request.GET['imported']
-
-    imported_content = 'default'
-    if imported_content_type == 'time':
-        imported_content = time.time()
-
-    body = '''
-    // %s
-    ''' % (imported_content)
-
-    return headers, body
diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/bytecheck-worker.py b/testing/web-platform/tests/service-workers/service-worker/resources/bytecheck-worker.py
deleted file mode 100644
index 7796c6f1bbe3..000000000000
--- a/testing/web-platform/tests/service-workers/service-worker/resources/bytecheck-worker.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import time
-
-def main(request, response):
-    headers = [('Content-Type', 'application/javascript'),
-               ('Cache-Control', 'max-age=0')]
-
-    main_content_type = ''
-    if 'main' in request.GET:
-        main_content_type = request.GET['main']
-
-    main_content = 'default'
-    if main_content_type == 'time':
-        main_content = time.time()
-
-    imported_request_type = ''
-    if 'imported' in request.GET:
-        imported_request_type = request.GET['imported']
-
-    imported_request = ''
-    if imported_request_type == 'time':
-        imported_request = '?imported=time';
-
-    body = '''
-    // %s
-    importScripts('bytecheck-worker-imported-script.py%s');
-    ''' % (main_content, imported_request)
-
-    return headers, body
diff --git a/testing/web-platform/tests/service-workers/service-worker/update-bytecheck.https.html b/testing/web-platform/tests/service-workers/service-worker/update-bytecheck.https.html
deleted file mode 100644
index b3e3f7ec5826..000000000000
--- a/testing/web-platform/tests/service-workers/service-worker/update-bytecheck.https.html
+++ /dev/null
@@ -1,127 +0,0 @@
-
-
-
-
-
-
-
-

From cd8c561106d804e26bc09389f18f361846d005eb Mon Sep 17 00:00:00 2001
From: Dragana Damjanovic 
Date: Thu, 11 May 2017 05:16:00 -0400
Subject: [PATCH 2/2] Bug 1364046 - Turn off TCP Fast Open. r=bagder, a=RyanVM

---
 modules/libpref/init/all.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 39e8e498c0a3..a7d7aa609829 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4626,7 +4626,7 @@ pref("network.tcp.keepalive.retry_interval", 1); // seconds
 pref("network.tcp.keepalive.probe_count", 4);
 #endif
 
-pref("network.tcp.tcp_fastopen_enable", true);
+pref("network.tcp.tcp_fastopen_enable", false);
 pref("network.tcp.tcp_fastopen_consecutive_failure_limit", 5);
 
 // Whether to disable acceleration for all widgets.