WebKit Bugzilla
Attachment 341771 Details for
Bug 182444
: ServiceWorker registration should store any script fetched through importScripts
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-182444-20180601104035.patch (text/plain), 51.90 KB, created by
youenn fablet
on 2018-06-01 10:40:35 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
youenn fablet
Created:
2018-06-01 10:40:35 PDT
Size:
51.90 KB
patch
obsolete
>Subversion Revision: 232334 >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index e20f70f5ea8f5d2e13c279095e2a096524c297b6..6b2441bbcae84d59c27f342c8720a8f1d5998357 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,13 @@ >+2018-06-01 Youenn Fablet <youenn@apple.com> >+ >+ ServiceWorker registration should store any script fetched through importScripts >+ https://bugs.webkit.org/show_bug.cgi?id=182444 >+ <rdar://problem/37164835> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * wtf/persistence/PersistentCoders.h: >+ > 2018-05-30 Keith Miller <keith_miller@apple.com> > > LLInt get_by_id prototype caching doesn't properly handle changes >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 8090e224971d9a5e80b9e73aa109a7f7177d0a56..5235b548e3020c2b1830629a743080fc92195fbc 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,61 @@ >+2018-05-31 Youenn Fablet <youenn@apple.com> >+ >+ ServiceWorker registration should store any script fetched through importScripts >+ https://bugs.webkit.org/show_bug.cgi?id=182444 >+ <rdar://problem/37164835> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Covered by added test http/wpt/service-workers/persistent-importScripts.html. >+ >+ Update importScripts implementation to look for/update the resource map in case of service worker scope. >+ This resource map is stored persistently and sent when running the service worker. >+ Add support to persistent storage of this resource map. >+ >+ When updating the service worker, the resource map is currently flushed so that all scripts will be retrieved from the network. >+ >+ Did some limited refactoring to put more loading handling in WorkerScriptLoader. >+ >+ * workers/WorkerGlobalScope.cpp: >+ (WebCore::WorkerGlobalScope::importScripts): >+ * workers/WorkerScriptLoader.cpp: >+ (WebCore::WorkerScriptLoader::loadSynchronously): >+ (WebCore::WorkerScriptLoader::script): >+ * workers/WorkerScriptLoader.h: >+ * workers/service/ServiceWorkerContextData.cpp: >+ (WebCore::ServiceWorkerContextData::isolatedCopy const): >+ * workers/service/ServiceWorkerContextData.h: >+ (WebCore::ServiceWorkerContextData::ImportedScript::isolatedCopy const): >+ (WebCore::ServiceWorkerContextData::ImportedScript::encode const): >+ (WebCore::ServiceWorkerContextData::ImportedScript::decode): >+ (WebCore::ServiceWorkerContextData::encode const): >+ (WebCore::ServiceWorkerContextData::decode): >+ * workers/service/ServiceWorkerGlobalScope.cpp: >+ (WebCore::ServiceWorkerGlobalScope::scriptResource const): >+ (WebCore::ServiceWorkerGlobalScope::setScriptResource): >+ * workers/service/ServiceWorkerGlobalScope.h: >+ * workers/service/context/SWContextManager.h: >+ * workers/service/server/RegistrationDatabase.cpp: >+ (WebCore::v1RecordsTableSchema): >+ (WebCore::RegistrationDatabase::doPushChanges): >+ (WebCore::RegistrationDatabase::importRecords): >+ * workers/service/server/SWServer.cpp: >+ (WebCore::SWServer::addRegistrationFromStore): >+ (WebCore::SWServer::updateWorker): >+ (WebCore::SWServer::installContextData): >+ * workers/service/server/SWServer.h: >+ * workers/service/server/SWServerJobQueue.cpp: >+ (WebCore::SWServerJobQueue::scriptFetchFinished): >+ * workers/service/server/SWServerToContextConnection.cpp: >+ (WebCore::SWServerToContextConnection::setScriptResource): >+ * workers/service/server/SWServerToContextConnection.h: >+ * workers/service/server/SWServerWorker.cpp: >+ (WebCore::SWServerWorker::SWServerWorker): >+ (WebCore::m_scriptResourceMap): >+ (WebCore::SWServerWorker::contextData const): >+ (WebCore::SWServerWorker::setScriptResource): >+ * workers/service/server/SWServerWorker.h: >+ > 2018-05-30 Nan Wang <n_wang@apple.com> > > AX: VoiceOver on macOS does not announce fieldset description from aria-describedby when focussing inputs >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 4ec6e2f86b158dab1e3d9c41680ce2fa2231024c..b21b5ea0cc20b0b2eca6720f278b795fc72f0a59 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,16 @@ >+2018-05-31 Youenn Fablet <youenn@apple.com> >+ >+ ServiceWorker registration should store any script fetched through importScripts >+ https://bugs.webkit.org/show_bug.cgi?id=182444 >+ <rdar://problem/37164835> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in: >+ * WebProcess/Storage/WebSWContextManagerConnection.cpp: >+ (WebKit::WebSWContextManagerConnection::setScriptResource): >+ * WebProcess/Storage/WebSWContextManagerConnection.h: >+ > 2018-05-30 Brent Fulgham <bfulgham@apple.com> > > [macOS] WebProcess needs TCC entitlements for media capture (Take 2) >diff --git a/Source/WTF/wtf/persistence/PersistentCoders.h b/Source/WTF/wtf/persistence/PersistentCoders.h >index 741e21dafa958388499d4b07a64fea702f8d7b48..1bd4d6f7cd41ba4ed52f28c084dd81afc7184f70 100644 >--- a/Source/WTF/wtf/persistence/PersistentCoders.h >+++ b/Source/WTF/wtf/persistence/PersistentCoders.h >@@ -155,10 +155,12 @@ template<typename T, size_t inlineCapacity> struct VectorCoder<true, T, inlineCa > > static bool decode(Decoder& decoder, Vector<T, inlineCapacity>& vector) > { >- uint64_t size; >- if (!decoder.decode(size)) >+ uint64_t decodedSize; >+ if (!decoder.decode(decodedSize)) > return false; > >+ auto size = safeCast<size_t>(decodedSize); >+ > // Since we know the total size of the elements, we can allocate the vector in > // one fell swoop. Before allocating we must however make sure that the decoder buffer > // is big enough. >diff --git a/Source/WebCore/workers/WorkerGlobalScope.cpp b/Source/WebCore/workers/WorkerGlobalScope.cpp >index f32ef2e2d7254b9e7d3255abff310e4116e2133c..a5b1b36eda2d68114806aaaed45c5b89796fa1fb 100644 >--- a/Source/WebCore/workers/WorkerGlobalScope.cpp >+++ b/Source/WebCore/workers/WorkerGlobalScope.cpp >@@ -33,7 +33,6 @@ > #include "IDBConnectionProxy.h" > #include "ImageBitmapOptions.h" > #include "InspectorInstrumentation.h" >-#include "MIMETypeRegistry.h" > #include "Performance.h" > #include "ScheduledAction.h" > #include "ScriptSourceCode.h" >@@ -285,16 +284,9 @@ ExceptionOr<void> WorkerGlobalScope::importScripts(const Vector<String>& urls) > return Exception { NetworkError }; > > auto scriptLoader = WorkerScriptLoader::create(); >- scriptLoader->loadSynchronously(this, url, FetchOptions::Mode::NoCors, cachePolicy, shouldBypassMainWorldContentSecurityPolicy ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceScriptSrcDirective, resourceRequestIdentifier()); >- >- // If the fetching attempt failed, throw a NetworkError exception and abort all these steps. >- if (scriptLoader->failed()) >- return Exception { NetworkError, scriptLoader->error().localizedDescription() }; >- >-#if ENABLE(SERVICE_WORKER) >- if (isServiceWorkerGlobalScope && !MIMETypeRegistry::isSupportedJavaScriptMIMEType(scriptLoader->responseMIMEType())) >- return Exception { NetworkError }; >-#endif >+ auto cspEnforcement = shouldBypassMainWorldContentSecurityPolicy ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceScriptSrcDirective; >+ if (auto exception = scriptLoader->loadSynchronously(this, url, FetchOptions::Mode::NoCors, cachePolicy, cspEnforcement, resourceRequestIdentifier())) >+ return WTFMove(*exception); > > InspectorInstrumentation::scriptImported(*this, scriptLoader->identifier(), scriptLoader->script()); > >diff --git a/Source/WebCore/workers/WorkerScriptLoader.cpp b/Source/WebCore/workers/WorkerScriptLoader.cpp >index 1f91cd5dcaf91ae854e80ab3cb4ffd7cc607d378..a173e224b109c48f0c6d1674fa83d34f7e89873a 100644 >--- a/Source/WebCore/workers/WorkerScriptLoader.cpp >+++ b/Source/WebCore/workers/WorkerScriptLoader.cpp >@@ -29,9 +29,11 @@ > > #include "ContentSecurityPolicy.h" > #include "FetchIdioms.h" >+#include "MIMETypeRegistry.h" > #include "ResourceResponse.h" > #include "ScriptExecutionContext.h" > #include "ServiceWorker.h" >+#include "ServiceWorkerGlobalScope.h" > #include "TextResourceDecoder.h" > #include "WorkerGlobalScope.h" > #include "WorkerScriptLoaderClient.h" >@@ -44,7 +46,7 @@ WorkerScriptLoader::WorkerScriptLoader() = default; > > WorkerScriptLoader::~WorkerScriptLoader() = default; > >-void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecutionContext, const URL& url, FetchOptions::Mode mode, FetchOptions::Cache cachePolicy, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, const String& initiatorIdentifier) >+std::optional<Exception> WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecutionContext, const URL& url, FetchOptions::Mode mode, FetchOptions::Cache cachePolicy, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, const String& initiatorIdentifier) > { > ASSERT(scriptExecutionContext); > auto& workerGlobalScope = downcast<WorkerGlobalScope>(*scriptExecutionContext); >@@ -52,9 +54,22 @@ void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecuti > m_url = url; > m_destination = FetchOptions::Destination::Script; > >+ bool isServiceWorkerGlobalScope = workerGlobalScope.isServiceWorkerGlobalScope(); >+ >+#if ENABLE(SERVICE_WORKER) >+ if (isServiceWorkerGlobalScope) { >+ if (auto scriptResource = downcast<ServiceWorkerGlobalScope>(workerGlobalScope).scriptResource(url)) { >+ m_cachedScript = WTFMove(scriptResource->script); >+ m_responseURL = URL { URL { }, scriptResource->responseURL }; >+ m_responseMIMEType = WTFMove(scriptResource->mimeType); >+ return std::nullopt; >+ } >+ } >+#endif >+ > std::unique_ptr<ResourceRequest> request(createResourceRequest(initiatorIdentifier)); > if (!request) >- return; >+ return std::nullopt; > > ASSERT_WITH_SECURITY_IMPLICATION(is<WorkerGlobalScope>(scriptExecutionContext)); > >@@ -75,6 +90,20 @@ void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecuti > options.serviceWorkerRegistrationIdentifier = activeServiceWorker->registrationIdentifier(); > #endif > WorkerThreadableLoader::loadResourceSynchronously(workerGlobalScope, WTFMove(*request), *this, options); >+ >+ // If the fetching attempt failed, throw a NetworkError exception and abort all these steps. >+ if (failed()) >+ return Exception { NetworkError, error().localizedDescription() }; >+ >+#if ENABLE(SERVICE_WORKER) >+ if (isServiceWorkerGlobalScope) { >+ if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(responseMIMEType())) >+ return Exception { NetworkError, ASCIILiteral("mime type is not a supported JavaScript mime type") }; >+ >+ downcast<ServiceWorkerGlobalScope>(workerGlobalScope).setScriptResource(url, ServiceWorkerContextData::ImportedScript { script(), m_responseURL, m_responseMIMEType }); >+ } >+#endif >+ return std::nullopt; > } > > void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext& scriptExecutionContext, ResourceRequest&& scriptRequest, FetchOptions&& fetchOptions, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, ServiceWorkersMode serviceWorkerMode, WorkerScriptLoaderClient& client) >@@ -203,7 +232,7 @@ void WorkerScriptLoader::notifyError() > > String WorkerScriptLoader::script() > { >- return m_script.toString(); >+ return !m_cachedScript.isNull() ? m_cachedScript : m_script.toString(); > } > > void WorkerScriptLoader::notifyFinished() >diff --git a/Source/WebCore/workers/WorkerScriptLoader.h b/Source/WebCore/workers/WorkerScriptLoader.h >index 6f1d852c8870c12eaa6a7e3140b5541e58919473..e408a6cbcd1269fe018970b2bde8b53a0d940131 100644 >--- a/Source/WebCore/workers/WorkerScriptLoader.h >+++ b/Source/WebCore/workers/WorkerScriptLoader.h >@@ -54,7 +54,7 @@ public: > return adoptRef(*new WorkerScriptLoader); > } > >- void loadSynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, FetchOptions::Cache, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier); >+ std::optional<Exception> loadSynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, FetchOptions::Cache, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier); > void loadAsynchronously(ScriptExecutionContext&, ResourceRequest&&, FetchOptions&&, ContentSecurityPolicyEnforcement, ServiceWorkersMode, WorkerScriptLoaderClient&); > > void notifyError(); >@@ -89,6 +89,7 @@ private: > String m_responseEncoding; > RefPtr<TextResourceDecoder> m_decoder; > StringBuilder m_script; >+ String m_cachedScript; > URL m_url; > URL m_responseURL; > String m_responseMIMEType; >diff --git a/Source/WebCore/workers/service/ServiceWorkerContextData.cpp b/Source/WebCore/workers/service/ServiceWorkerContextData.cpp >index cd09a97c947977f33f87e7d96f9865dba40eb01c..d92d98d7d6ff1877aaa73f9306f1fc7bc1e847c5 100644 >--- a/Source/WebCore/workers/service/ServiceWorkerContextData.cpp >+++ b/Source/WebCore/workers/service/ServiceWorkerContextData.cpp >@@ -32,7 +32,11 @@ namespace WebCore { > > ServiceWorkerContextData ServiceWorkerContextData::isolatedCopy() const > { >- return { jobDataIdentifier, registration.isolatedCopy(), serviceWorkerIdentifier, script.isolatedCopy(), contentSecurityPolicy.isolatedCopy(), scriptURL.isolatedCopy(), workerType, sessionID, loadedFromDisk }; >+ HashMap<URL, ImportedScript> map; >+ for (auto& keyValue : scriptResourceMap) >+ map.add(keyValue.key.isolatedCopy(), keyValue.value.isolatedCopy()); >+ >+ return { jobDataIdentifier, registration.isolatedCopy(), serviceWorkerIdentifier, script.isolatedCopy(), contentSecurityPolicy.isolatedCopy(), scriptURL.isolatedCopy(), workerType, sessionID, loadedFromDisk, WTFMove(map) }; > } > > } // namespace WebCore >diff --git a/Source/WebCore/workers/service/ServiceWorkerContextData.h b/Source/WebCore/workers/service/ServiceWorkerContextData.h >index b93d922162e0ac794a1e752bb9abe4c1aa31b9d6..eee8c6e1e8877de3e7e9500a3c9888ab259e9b6f 100644 >--- a/Source/WebCore/workers/service/ServiceWorkerContextData.h >+++ b/Source/WebCore/workers/service/ServiceWorkerContextData.h >@@ -30,14 +30,44 @@ > #include "ServiceWorkerJobDataIdentifier.h" > #include "ServiceWorkerRegistrationData.h" > #include "URL.h" >+#include "URLHash.h" > #include "WorkerType.h" > #include <pal/SessionID.h> >+#include <wtf/HashMap.h> > > #if ENABLE(SERVICE_WORKER) > > namespace WebCore { > > struct ServiceWorkerContextData { >+ >+ struct ImportedScript { >+ String script; >+ String responseURL; >+ String mimeType; >+ >+ ImportedScript isolatedCopy() const { return { script.isolatedCopy(), responseURL.isolatedCopy(), mimeType.isolatedCopy() }; } >+ >+ template<class Encoder> void encode(Encoder& encoder) const >+ { >+ encoder << script << responseURL << mimeType; >+ } >+ >+ template<class Decoder> static std::optional<ImportedScript> decode(Decoder& decoder) >+ { >+ String script; >+ if (!decoder.decode(script)) >+ return std::nullopt; >+ String responseURL; >+ if (!decoder.decode(responseURL)) >+ return std::nullopt; >+ String mimeType; >+ if (!decoder.decode(mimeType)) >+ return std::nullopt; >+ return ImportedScript { WTFMove(script), WTFMove(responseURL), WTFMove(mimeType) }; >+ } >+ }; >+ > std::optional<ServiceWorkerJobDataIdentifier> jobDataIdentifier; > ServiceWorkerRegistrationData registration; > ServiceWorkerIdentifier serviceWorkerIdentifier; >@@ -47,10 +77,11 @@ struct ServiceWorkerContextData { > WorkerType workerType; > PAL::SessionID sessionID; > bool loadedFromDisk; >+ HashMap<WebCore::URL, ImportedScript> scriptResourceMap; > > template<class Encoder> void encode(Encoder&) const; > template<class Decoder> static std::optional<ServiceWorkerContextData> decode(Decoder&); >- >+ > ServiceWorkerContextData isolatedCopy() const; > }; > >@@ -58,6 +89,11 @@ template<class Encoder> > void ServiceWorkerContextData::encode(Encoder& encoder) const > { > encoder << jobDataIdentifier << registration << serviceWorkerIdentifier << script << contentSecurityPolicy << scriptURL << workerType << sessionID << loadedFromDisk; >+ encoder << static_cast<uint64_t>(scriptResourceMap.size()); >+ for (auto keyValue : scriptResourceMap) { >+ encoder << keyValue.key; >+ encoder << keyValue.value; >+ } > } > > template<class Decoder> >@@ -101,7 +137,27 @@ std::optional<ServiceWorkerContextData> ServiceWorkerContextData::decode(Decoder > if (!decoder.decode(loadedFromDisk)) > return std::nullopt; > >- return {{ WTFMove(*jobDataIdentifier), WTFMove(*registration), WTFMove(*serviceWorkerIdentifier), WTFMove(script), WTFMove(contentSecurityPolicy), WTFMove(scriptURL), workerType, sessionID, loadedFromDisk }}; >+ HashMap<URL, ImportedScript> scriptResourceMap; >+ uint64_t scriptResourceMapSize; >+ if (!decoder.decode(scriptResourceMapSize)) >+ return std::nullopt; >+ >+ // FIXME: Add a templated version of HashMap encode/decode >+ for (uint64_t i = 0; i < scriptResourceMapSize; ++i) { >+ URL key; >+ if (!decoder.decode(key)) >+ return std::nullopt; >+ >+ std::optional<ImportedScript> value; >+ decoder >> value; >+ if (!value) >+ return std::nullopt; >+ >+ if (!scriptResourceMap.add(WTFMove(key), WTFMove(*value)).isNewEntry) >+ return std::nullopt; >+ } >+ >+ return {{ WTFMove(*jobDataIdentifier), WTFMove(*registration), WTFMove(*serviceWorkerIdentifier), WTFMove(script), WTFMove(contentSecurityPolicy), WTFMove(scriptURL), workerType, sessionID, loadedFromDisk, WTFMove(scriptResourceMap) }}; > } > > } // namespace WebCore >diff --git a/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp b/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp >index 628151149ef0cff12fa82b0bfbe9849f443e60b2..97b477b3abd94567887c378d222e7b107c73b07a 100644 >--- a/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp >+++ b/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp >@@ -130,6 +130,24 @@ void ServiceWorkerGlobalScope::updateExtendedEventsSet(ExtendableEvent* newEvent > }); > } > >+std::optional<ServiceWorkerContextData::ImportedScript> ServiceWorkerGlobalScope::scriptResource(const URL& url) const >+{ >+ auto iterator = m_contextData.scriptResourceMap.find(url); >+ if (iterator == m_contextData.scriptResourceMap.end()) >+ return std::nullopt; >+ return ServiceWorkerContextData::ImportedScript { iterator->value }; >+} >+ >+void ServiceWorkerGlobalScope::setScriptResource(const URL& url, ServiceWorkerContextData::ImportedScript&& script) >+{ >+ callOnMainThread([threadIdentifier = thread().identifier(), url = url.isolatedCopy(), script = script.isolatedCopy()] { >+ if (auto* connection = SWContextManager::singleton().connection()) >+ connection->setScriptResource(threadIdentifier, url, script); >+ }); >+ >+ m_contextData.scriptResourceMap.set(url, WTFMove(script)); >+} >+ > } // namespace WebCore > > #endif // ENABLE(SERVICE_WORKER) >diff --git a/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h b/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h >index 1369499e74fa65b717077d14c1271c481ef90230..ae5a3fcf63dfd4dd4b94678256cb11458887413e 100644 >--- a/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h >+++ b/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h >@@ -64,6 +64,9 @@ public: > > void updateExtendedEventsSet(ExtendableEvent* newEvent = nullptr); > >+ std::optional<ServiceWorkerContextData::ImportedScript> scriptResource(const URL&) const; >+ void setScriptResource(const URL&, ServiceWorkerContextData::ImportedScript&&); >+ > private: > ServiceWorkerGlobalScope(const ServiceWorkerContextData&, const URL&, Ref<SecurityOrigin>&&, const String& identifier, const String& userAgent, bool isOnline, ServiceWorkerThread&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, MonotonicTime timeOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*, PAL::SessionID); > >diff --git a/Source/WebCore/workers/service/context/SWContextManager.h b/Source/WebCore/workers/service/context/SWContextManager.h >index 453c6fe962733b90c56b5be03595cfe73b07dab9..b7b52e6b4e5ab66c334fb321b6aa430473d3347c 100644 >--- a/Source/WebCore/workers/service/context/SWContextManager.h >+++ b/Source/WebCore/workers/service/context/SWContextManager.h >@@ -54,12 +54,13 @@ public: > virtual void didFinishActivation(ServiceWorkerIdentifier) = 0; > virtual void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool) = 0; > virtual void workerTerminated(ServiceWorkerIdentifier) = 0; >- virtual void skipWaiting(ServiceWorkerIdentifier, WTF::Function<void()>&& callback) = 0; >+ virtual void skipWaiting(ServiceWorkerIdentifier, Function<void()>&&) = 0; >+ virtual void setScriptResource(ServiceWorkerIdentifier, const URL&, const ServiceWorkerContextData::ImportedScript&) = 0; > >- using FindClientByIdentifierCallback = WTF::CompletionHandler<void(ExceptionOr<std::optional<ServiceWorkerClientData>>&&)>; >+ using FindClientByIdentifierCallback = CompletionHandler<void(ExceptionOr<std::optional<ServiceWorkerClientData>>&&)>; > virtual void findClientByIdentifier(ServiceWorkerIdentifier, ServiceWorkerClientIdentifier, FindClientByIdentifierCallback&&) = 0; > virtual void matchAll(ServiceWorkerIdentifier, const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&) = 0; >- virtual void claim(ServiceWorkerIdentifier, WTF::CompletionHandler<void()>&&) = 0; >+ virtual void claim(ServiceWorkerIdentifier, CompletionHandler<void()>&&) = 0; > }; > > WEBCORE_EXPORT void setConnection(std::unique_ptr<Connection>&&); >diff --git a/Source/WebCore/workers/service/server/RegistrationDatabase.cpp b/Source/WebCore/workers/service/server/RegistrationDatabase.cpp >index eb1aaf21e6cd28b984a27369679a4646db05ffa3..ddda435918d40fd2b5b5cea29f3f05cecd17db8e 100644 >--- a/Source/WebCore/workers/service/server/RegistrationDatabase.cpp >+++ b/Source/WebCore/workers/service/server/RegistrationDatabase.cpp >@@ -47,11 +47,11 @@ > > namespace WebCore { > >-static const int schemaVersion = 1; >+static const int schemaVersion = 2; > > static const String v1RecordsTableSchema(const String& tableName) > { >- return makeString("CREATE TABLE ", tableName, " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, origin TEXT NOT NULL ON CONFLICT FAIL, scopeURL TEXT NOT NULL ON CONFLICT FAIL, topOrigin TEXT NOT NULL ON CONFLICT FAIL, lastUpdateCheckTime DOUBLE NOT NULL ON CONFLICT FAIL, updateViaCache TEXT NOT NULL ON CONFLICT FAIL, scriptURL TEXT NOT NULL ON CONFLICT FAIL, script TEXT NOT NULL ON CONFLICT FAIL, workerType TEXT NOT NULL ON CONFLICT FAIL, contentSecurityPolicy BLOB NOT NULL ON CONFLICT FAIL)"); >+ return makeString("CREATE TABLE ", tableName, " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, origin TEXT NOT NULL ON CONFLICT FAIL, scopeURL TEXT NOT NULL ON CONFLICT FAIL, topOrigin TEXT NOT NULL ON CONFLICT FAIL, lastUpdateCheckTime DOUBLE NOT NULL ON CONFLICT FAIL, updateViaCache TEXT NOT NULL ON CONFLICT FAIL, scriptURL TEXT NOT NULL ON CONFLICT FAIL, script TEXT NOT NULL ON CONFLICT FAIL, workerType TEXT NOT NULL ON CONFLICT FAIL, contentSecurityPolicy BLOB NOT NULL ON CONFLICT FAIL, scriptResourceMap BLOB NOT NULL ON CONFLICT FAIL)"); > } > > static const String v1RecordsTableSchema() >@@ -275,7 +275,7 @@ void RegistrationDatabase::doPushChanges(Vector<ServiceWorkerContextData>&& data > SQLiteTransaction transaction(*m_database); > transaction.begin(); > >- SQLiteStatement sql(*m_database, ASCIILiteral("INSERT INTO Records VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); >+ SQLiteStatement sql(*m_database, ASCIILiteral("INSERT INTO Records VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); > if (sql.prepare() != SQLITE_OK) { > RELEASE_LOG_ERROR(ServiceWorker, "Failed to prepare statement to store registration data into records table (%i) - %s", m_database->lastError(), m_database->lastErrorMsg()); > return; >@@ -294,8 +294,11 @@ void RegistrationDatabase::doPushChanges(Vector<ServiceWorkerContextData>&& data > continue; > } > >- WTF::Persistence::Encoder encoder; >- data.contentSecurityPolicy.encode(encoder); >+ WTF::Persistence::Encoder cspEncoder; >+ data.contentSecurityPolicy.encode(cspEncoder); >+ >+ WTF::Persistence::Encoder scriptResourceMapEncoder; >+ scriptResourceMapEncoder.encode(data.scriptResourceMap); > > if (sql.bindText(1, data.registration.key.toDatabaseKey()) != SQLITE_OK > || sql.bindText(2, data.registration.scopeURL.protocolHostAndPort()) != SQLITE_OK >@@ -306,7 +309,8 @@ void RegistrationDatabase::doPushChanges(Vector<ServiceWorkerContextData>&& data > || sql.bindText(7, data.scriptURL.string()) != SQLITE_OK > || sql.bindText(8, data.script) != SQLITE_OK > || sql.bindText(9, workerTypeToString(data.workerType)) != SQLITE_OK >- || sql.bindBlob(10, encoder.buffer(), encoder.bufferSize()) != SQLITE_OK >+ || sql.bindBlob(10, cspEncoder.buffer(), cspEncoder.bufferSize()) != SQLITE_OK >+ || sql.bindBlob(11, scriptResourceMapEncoder.buffer(), scriptResourceMapEncoder.bufferSize()) != SQLITE_OK > || sql.step() != SQLITE_DONE) { > RELEASE_LOG_ERROR(ServiceWorker, "Failed to store registration data into records table (%i) - %s", m_database->lastError(), m_database->lastErrorMsg()); > return; >@@ -341,11 +345,21 @@ String RegistrationDatabase::importRecords() > > Vector<uint8_t> contentSecurityPolicyData; > sql.getColumnBlobAsVector(9, contentSecurityPolicyData); >- WTF::Persistence::Decoder decoder(contentSecurityPolicyData.data(), contentSecurityPolicyData.size()); >+ WTF::Persistence::Decoder cspDecoder(contentSecurityPolicyData.data(), contentSecurityPolicyData.size()); > ContentSecurityPolicyResponseHeaders contentSecurityPolicy; >- if (contentSecurityPolicyData.size() && !ContentSecurityPolicyResponseHeaders::decode(decoder, contentSecurityPolicy)) >+ if (contentSecurityPolicyData.size() && !ContentSecurityPolicyResponseHeaders::decode(cspDecoder, contentSecurityPolicy)) > continue; > >+ Vector<uint8_t> scriptResourceMapData; >+ sql.getColumnBlobAsVector(10, scriptResourceMapData); >+ HashMap<URL, ServiceWorkerContextData::ImportedScript> scriptResourceMap; >+ if (scriptResourceMapData.size()) { >+ WTF::Persistence::Decoder scriptResourceMapDecoder(scriptResourceMapData.data(), scriptResourceMapData.size()); >+ if (!scriptResourceMapDecoder.decode(scriptResourceMapData)) >+ continue; >+ >+ } >+ > // Validate the input for this registration. > // If any part of this input is invalid, let's skip this registration. > // FIXME: Should we return an error skipping *all* registrations? >@@ -356,7 +370,7 @@ String RegistrationDatabase::importRecords() > auto registrationIdentifier = generateObjectIdentifier<ServiceWorkerRegistrationIdentifierType>(); > auto serviceWorkerData = ServiceWorkerData { workerIdentifier, scriptURL, ServiceWorkerState::Activated, *workerType, registrationIdentifier }; > auto registration = ServiceWorkerRegistrationData { WTFMove(*key), registrationIdentifier, URL(originURL, scopePath), *updateViaCache, lastUpdateCheckTime, std::nullopt, std::nullopt, WTFMove(serviceWorkerData) }; >- auto contextData = ServiceWorkerContextData { std::nullopt, WTFMove(registration), workerIdentifier, WTFMove(script), WTFMove(contentSecurityPolicy), WTFMove(scriptURL), *workerType, m_store.server().sessionID(), true }; >+ auto contextData = ServiceWorkerContextData { std::nullopt, WTFMove(registration), workerIdentifier, WTFMove(script), WTFMove(contentSecurityPolicy), WTFMove(scriptURL), *workerType, m_store.server().sessionID(), true, WTFMove(scriptResourceMap) }; > > postTaskReply(createCrossThreadTask(*this, &RegistrationDatabase::addRegistrationToStore, WTFMove(contextData))); > } >diff --git a/Source/WebCore/workers/service/server/SWServer.cpp b/Source/WebCore/workers/service/server/SWServer.cpp >index dc325ddd9c6ea5db67766abaa843e63fc37d4390..7dd5cc31ac29b607515e6d9c6ba72b5033d46212 100644 >--- a/Source/WebCore/workers/service/server/SWServer.cpp >+++ b/Source/WebCore/workers/service/server/SWServer.cpp >@@ -138,7 +138,7 @@ void SWServer::addRegistrationFromStore(ServiceWorkerContextData&& data) > auto registrationPtr = registration.get(); > addRegistration(WTFMove(registration)); > >- auto worker = SWServerWorker::create(*this, *registrationPtr, data.scriptURL, data.script, data.contentSecurityPolicy, data.workerType, data.serviceWorkerIdentifier); >+ auto worker = SWServerWorker::create(*this, *registrationPtr, data.scriptURL, data.script, data.contentSecurityPolicy, data.workerType, data.serviceWorkerIdentifier, HashMap<URL, ServiceWorkerContextData::ImportedScript> { data.scriptResourceMap }); > registrationPtr->updateRegistrationState(ServiceWorkerRegistrationState::Active, worker.ptr()); > worker->setState(ServiceWorkerState::Activated); > } >@@ -500,9 +500,9 @@ void SWServer::removeClientServiceWorkerRegistration(Connection& connection, Ser > registration->removeClientServiceWorkerRegistration(connection.identifier()); > } > >-void SWServer::updateWorker(Connection&, const ServiceWorkerJobDataIdentifier& jobDataIdentifier, SWServerRegistration& registration, const URL& url, const String& script, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, WorkerType type) >+void SWServer::updateWorker(Connection&, const ServiceWorkerJobDataIdentifier& jobDataIdentifier, SWServerRegistration& registration, const URL& url, const String& script, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, WorkerType type, HashMap<URL, ServiceWorkerContextData::ImportedScript>&& scriptResourceMap) > { >- tryInstallContextData({ jobDataIdentifier, registration.data(), generateObjectIdentifier<ServiceWorkerIdentifierType>(), script, contentSecurityPolicy, url, type, sessionID(), false }); >+ tryInstallContextData({ jobDataIdentifier, registration.data(), generateObjectIdentifier<ServiceWorkerIdentifierType>(), script, contentSecurityPolicy, url, type, sessionID(), false, WTFMove(scriptResourceMap) }); > } > > void SWServer::tryInstallContextData(ServiceWorkerContextData&& data) >@@ -547,7 +547,7 @@ void SWServer::installContextData(const ServiceWorkerContextData& data) > auto* registration = m_registrations.get(data.registration.key); > RELEASE_ASSERT(registration); > >- auto worker = SWServerWorker::create(*this, *registration, data.scriptURL, data.script, data.contentSecurityPolicy, data.workerType, data.serviceWorkerIdentifier); >+ auto worker = SWServerWorker::create(*this, *registration, data.scriptURL, data.script, data.contentSecurityPolicy, data.workerType, data.serviceWorkerIdentifier, HashMap<URL, ServiceWorkerContextData::ImportedScript> { data.scriptResourceMap }); > > auto* connection = worker->contextConnection(); > ASSERT(connection); >diff --git a/Source/WebCore/workers/service/server/SWServer.h b/Source/WebCore/workers/service/server/SWServer.h >index da8f8f84271095c02ac26b64e742b4ae25f1ad7d..cf5ecc165e48b327a02b24a03ff4c534c68387ca 100644 >--- a/Source/WebCore/workers/service/server/SWServer.h >+++ b/Source/WebCore/workers/service/server/SWServer.h >@@ -135,7 +135,7 @@ public: > void resolveUnregistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationKey&, bool unregistrationResult); > void startScriptFetch(const ServiceWorkerJobData&, FetchOptions::Cache); > >- void updateWorker(Connection&, const ServiceWorkerJobDataIdentifier&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&, WorkerType); >+ void updateWorker(Connection&, const ServiceWorkerJobDataIdentifier&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&, WorkerType, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&); > void terminateWorker(SWServerWorker&); > void syncTerminateWorker(SWServerWorker&); > void fireInstallEvent(SWServerWorker&); >diff --git a/Source/WebCore/workers/service/server/SWServerJobQueue.cpp b/Source/WebCore/workers/service/server/SWServerJobQueue.cpp >index dc36e5f2c439ec593d7f97626d24efb9d6ac632b..5cab0c8e9be6eccce97da17600d64ce9c7fb2878 100644 >--- a/Source/WebCore/workers/service/server/SWServerJobQueue.cpp >+++ b/Source/WebCore/workers/service/server/SWServerJobQueue.cpp >@@ -97,8 +97,10 @@ void SWServerJobQueue::scriptFetchFinished(SWServer::Connection& connection, con > return; > } > >+ // FIXME: Update all the imported scripts as per spec. For now, we just do as if there is none. >+ > // FIXME: Support the proper worker type (classic vs module) >- m_server.updateWorker(connection, job.identifier(), *registration, job.scriptURL, result.script, result.contentSecurityPolicy, WorkerType::Classic); >+ m_server.updateWorker(connection, job.identifier(), *registration, job.scriptURL, result.script, result.contentSecurityPolicy, WorkerType::Classic, { }); > } > > // https://w3c.github.io/ServiceWorker/#update-algorithm >diff --git a/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp b/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp >index 3c26172f32f5b1019181b77e1e9688c19002f40a..1d704ef5087a1a77b181e831d3edc707aa529bbc 100644 >--- a/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp >+++ b/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp >@@ -131,6 +131,12 @@ void SWServerToContextConnection::skipWaiting(ServiceWorkerIdentifier serviceWor > didFinishSkipWaiting(callbackID); > } > >+void SWServerToContextConnection::setScriptResource(ServiceWorkerIdentifier serviceWorkerIdentifier, URL&& url, String&& script, String&& responseURL, String&& mimeType) >+{ >+ if (auto* worker = SWServerWorker::existingWorkerForIdentifier(serviceWorkerIdentifier)) >+ worker->setScriptResource(WTFMove(url), ServiceWorkerContextData::ImportedScript { WTFMove(script), WTFMove(responseURL), WTFMove(mimeType) }); >+} >+ > } // namespace WebCore > > #endif // ENABLE(SERVICE_WORKER) >diff --git a/Source/WebCore/workers/service/server/SWServerToContextConnection.h b/Source/WebCore/workers/service/server/SWServerToContextConnection.h >index 2e604ef2cb547c15d538cdd87f85d89ec82eb570..997216235dd06867a916ae73da77591a4ddd281c 100644 >--- a/Source/WebCore/workers/service/server/SWServerToContextConnection.h >+++ b/Source/WebCore/workers/service/server/SWServerToContextConnection.h >@@ -29,6 +29,7 @@ > > #include "SecurityOriginData.h" > #include "ServiceWorkerClientQueryOptions.h" >+#include "ServiceWorkerContextData.h" > #include "ServiceWorkerIdentifier.h" > #include "ServiceWorkerTypes.h" > #include <wtf/RefCounted.h> >@@ -73,6 +74,7 @@ public: > WEBCORE_EXPORT void findClientByIdentifier(uint64_t clientIdRequestIdentifier, ServiceWorkerIdentifier, ServiceWorkerClientIdentifier); > WEBCORE_EXPORT void matchAll(uint64_t requestIdentifier, ServiceWorkerIdentifier, const ServiceWorkerClientQueryOptions&); > WEBCORE_EXPORT void claim(uint64_t requestIdentifier, ServiceWorkerIdentifier); >+ WEBCORE_EXPORT void setScriptResource(ServiceWorkerIdentifier, URL&&, String&& script, String&& responseURL, String&& mimeType); > > static SWServerToContextConnection* connectionForOrigin(const SecurityOriginData&); > >diff --git a/Source/WebCore/workers/service/server/SWServerWorker.cpp b/Source/WebCore/workers/service/server/SWServerWorker.cpp >index 159bce669f1cb9b2e6b94f39c6cd2612712e6c11..7f525cbb616103c0da51f4ac64d221d8174548d7 100644 >--- a/Source/WebCore/workers/service/server/SWServerWorker.cpp >+++ b/Source/WebCore/workers/service/server/SWServerWorker.cpp >@@ -45,12 +45,13 @@ SWServerWorker* SWServerWorker::existingWorkerForIdentifier(ServiceWorkerIdentif > } > > // FIXME: Use r-value references for script and contentSecurityPolicy >-SWServerWorker::SWServerWorker(SWServer& server, SWServerRegistration& registration, const URL& scriptURL, const String& script, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, WorkerType type, ServiceWorkerIdentifier identifier) >+SWServerWorker::SWServerWorker(SWServer& server, SWServerRegistration& registration, const URL& scriptURL, const String& script, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, WorkerType type, ServiceWorkerIdentifier identifier, HashMap<URL, ServiceWorkerContextData::ImportedScript>&& scriptResourceMap) > : m_server(server) > , m_registrationKey(registration.key()) > , m_data { identifier, scriptURL, ServiceWorkerState::Redundant, type, registration.identifier() } > , m_script(script) > , m_contentSecurityPolicy(contentSecurityPolicy) >+ , m_scriptResourceMap(WTFMove(scriptResourceMap)) > { > m_data.scriptURL.removeFragmentIdentifier(); > >@@ -73,7 +74,7 @@ ServiceWorkerContextData SWServerWorker::contextData() const > auto* registration = m_server.getRegistration(m_registrationKey); > ASSERT(registration); > >- return { std::nullopt, registration->data(), m_data.identifier, m_script, m_contentSecurityPolicy, m_data.scriptURL, m_data.type, m_server.sessionID(), false }; >+ return { std::nullopt, registration->data(), m_data.identifier, m_script, m_contentSecurityPolicy, m_data.scriptURL, m_data.type, m_server.sessionID(), false, m_scriptResourceMap }; > } > > void SWServerWorker::terminate() >@@ -140,6 +141,11 @@ void SWServerWorker::claim() > return m_server.claim(*this); > } > >+void SWServerWorker::setScriptResource(URL&& url, ServiceWorkerContextData::ImportedScript&& script) >+{ >+ m_scriptResourceMap.set(WTFMove(url), WTFMove(script)); >+} >+ > void SWServerWorker::skipWaiting() > { > m_isSkipWaitingFlagSet = true; >diff --git a/Source/WebCore/workers/service/server/SWServerWorker.h b/Source/WebCore/workers/service/server/SWServerWorker.h >index 85b8b0f142a7b3acdb58bbee4c38bab60481cbc8..2fb9dc12ebc6694228375cb74fa9d219fbd19e07 100644 >--- a/Source/WebCore/workers/service/server/SWServerWorker.h >+++ b/Source/WebCore/workers/service/server/SWServerWorker.h >@@ -29,11 +29,11 @@ > > #include "ContentSecurityPolicyResponseHeaders.h" > #include "ServiceWorkerClientData.h" >+#include "ServiceWorkerContextData.h" > #include "ServiceWorkerData.h" > #include "ServiceWorkerIdentifier.h" > #include "ServiceWorkerRegistrationKey.h" > #include "ServiceWorkerTypes.h" >-#include "URL.h" > #include <wtf/RefCounted.h> > > namespace WebCore { >@@ -94,6 +94,7 @@ public: > WEBCORE_EXPORT std::optional<ServiceWorkerClientData> findClientByIdentifier(const ServiceWorkerClientIdentifier&) const; > void matchAll(const ServiceWorkerClientQueryOptions&, const ServiceWorkerClientsMatchAllCallback&); > void claim(); >+ void setScriptResource(URL&&, ServiceWorkerContextData::ImportedScript&&); > > void skipWaiting(); > bool isSkipWaitingFlagSet() const { return m_isSkipWaitingFlagSet; } >@@ -110,7 +111,7 @@ public: > WEBCORE_EXPORT SWServerToContextConnection* contextConnection(); > > private: >- SWServerWorker(SWServer&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&, WorkerType, ServiceWorkerIdentifier); >+ SWServerWorker(SWServer&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&, WorkerType, ServiceWorkerIdentifier, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&); > > void callWhenActivatedHandler(bool success); > >@@ -123,7 +124,8 @@ private: > State m_state { State::NotRunning }; > mutable std::optional<ClientOrigin> m_origin; > bool m_isSkipWaitingFlagSet { false }; >- Vector<WTF::Function<void(bool)>> m_whenActivatedHandlers; >+ Vector<Function<void(bool)>> m_whenActivatedHandlers; >+ HashMap<URL, ServiceWorkerContextData::ImportedScript> m_scriptResourceMap; > }; > > } // namespace WebCore >diff --git a/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in b/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in >index 3405a5a7dad5ad8b233dc548b659f2bbb1413333..50062a3b7ce0933e75c155770d6d93c59cafccff 100644 >--- a/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in >+++ b/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in >@@ -35,6 +35,7 @@ messages -> WebSWServerToContextConnection { > FindClientByIdentifier(uint64_t requestIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, struct WebCore::ServiceWorkerClientIdentifier clientIdentifier); > MatchAll(uint64_t matchAllRequestIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, struct WebCore::ServiceWorkerClientQueryOptions options); > Claim(uint64_t claimRequestIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier); >+ SetScriptResource(WebCore::ServiceWorkerIdentifier identifier, WebCore::URL url, String script, String responseURL, String mimeType); > } > > #endif // ENABLE(SERVICE_WORKER) >diff --git a/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp b/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp >index 5bde3d0e2bf4cf23e8f68222f57cebc996693da5..faa7e39da36de366341045457d1e056eba4708fe 100644 >--- a/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp >+++ b/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp >@@ -278,6 +278,11 @@ void WebSWContextManagerConnection::skipWaiting(ServiceWorkerIdentifier serviceW > m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::SkipWaiting(serviceWorkerIdentifier, callbackID), 0); > } > >+void WebSWContextManagerConnection::setScriptResource(ServiceWorkerIdentifier serviceWorkerIdentifier, const URL& url, const ServiceWorkerContextData::ImportedScript& script) >+{ >+ m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::SetScriptResource { serviceWorkerIdentifier, url, script.script, script.responseURL, script.mimeType }, 0); >+} >+ > void WebSWContextManagerConnection::workerTerminated(ServiceWorkerIdentifier serviceWorkerIdentifier) > { > m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::WorkerTerminated(serviceWorkerIdentifier), 0); >diff --git a/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h b/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h >index 491cbda776535d1fbdbaa99fa7d52a8e25b09996..d0421ae73c08d01e143c12e1aad8877f9c9ef132 100644 >--- a/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h >+++ b/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h >@@ -70,8 +70,9 @@ private: > void workerTerminated(WebCore::ServiceWorkerIdentifier) final; > void findClientByIdentifier(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerClientIdentifier, FindClientByIdentifierCallback&&) final; > void matchAll(WebCore::ServiceWorkerIdentifier, const WebCore::ServiceWorkerClientQueryOptions&, WebCore::ServiceWorkerClientsMatchAllCallback&&) final; >- void claim(WebCore::ServiceWorkerIdentifier, WTF::CompletionHandler<void()>&&) final; >- void skipWaiting(WebCore::ServiceWorkerIdentifier, WTF::Function<void()>&& callback) final; >+ void claim(WebCore::ServiceWorkerIdentifier, CompletionHandler<void()>&&) final; >+ void skipWaiting(WebCore::ServiceWorkerIdentifier, Function<void()>&&) final; >+ void setScriptResource(WebCore::ServiceWorkerIdentifier, const WebCore::URL&, const WebCore::ServiceWorkerContextData::ImportedScript&) final; > > // IPC messages. > void serviceWorkerStartedWithMessage(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final; >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index cbe4272527565b6b427f6e5e854a462ddb48a164..76df72c79d3bda78f28aee0f47ae2078fdee8999 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,17 @@ >+2018-05-31 Youenn Fablet <youenn@apple.com> >+ >+ ServiceWorker registration should store any script fetched through importScripts >+ https://bugs.webkit.org/show_bug.cgi?id=182444 >+ <rdar://problem/37164835> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * http/wpt/service-workers/persistent-importScripts-expected.txt: Added. >+ * http/wpt/service-workers/persistent-importScripts.html: Added. >+ * http/wpt/service-workers/resources/persistent-importScripts-script.py: Added. >+ * http/wpt/service-workers/resources/persistent-importScripts-worker.js: Added. >+ * http/wpt/service-workers/resources/routines.js: Added. >+ > 2018-05-30 Nan Wang <n_wang@apple.com> > > AX: VoiceOver on macOS does not announce fieldset description from aria-describedby when focussing inputs >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index fae4de4aa17d96a7e2f1d674a8065a0a4bbf7b33..ed0f91e2fa86911e6b8005cd444d369a63b6a89e 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,13 @@ >+2018-06-01 Youenn Fablet <youenn@apple.com> >+ >+ ServiceWorker registration should store any script fetched through importScripts >+ https://bugs.webkit.org/show_bug.cgi?id=182444 >+ <rdar://problem/37164835> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * web-platform-tests/service-workers/service-worker/registration-mime-types.https-expected.txt: >+ > 2018-05-30 Chris Dumez <cdumez@apple.com> > > Referrer-Policy response header is ignored >diff --git a/LayoutTests/http/wpt/service-workers/persistent-importScripts-expected.txt b/LayoutTests/http/wpt/service-workers/persistent-importScripts-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..fede0a39250bf7416218874adece0bf74e9fbb42 >--- /dev/null >+++ b/LayoutTests/http/wpt/service-workers/persistent-importScripts-expected.txt >@@ -0,0 +1,4 @@ >+ >+ >+PASS Test persistency of imported scripts >+ >diff --git a/LayoutTests/http/wpt/service-workers/persistent-importScripts.html b/LayoutTests/http/wpt/service-workers/persistent-importScripts.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4df302e564febdd185b7e0f00142caeccf2bfa37 >--- /dev/null >+++ b/LayoutTests/http/wpt/service-workers/persistent-importScripts.html >@@ -0,0 +1,39 @@ >+<html> >+<head> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="resources/routines.js"></script> >+</head> >+<body> >+<script> >+function getRandomIdFromWorker(worker) >+{ >+ worker.postMessage("getRandomId"); >+ return new Promise(function(resolve) { >+ navigator.serviceWorker.addEventListener('message', function(e) { >+ resolve(e.data); >+ }); >+ }); >+} >+ >+promise_test(async (test) => { >+ if (!window.testRunner) >+ return Promise.reject('Internals API needed for this test'); >+ >+ let registration = await navigator.serviceWorker.register("resources/persistent-importScripts-worker.js"); >+ let worker = registration.installing; >+ await waitForState(worker, "activated"); >+ >+ let frame = await withIframe("resources"); >+ let randomId1 = await getRandomIdFromWorker(worker); >+ >+ testRunner.terminateServiceWorkerProcess(); >+ >+ await waitFor(100); >+ let randomId2 = await getRandomIdFromWorker(worker); >+ >+ assert_equals(randomId1, randomId2); >+}, "Test persistency of imported scripts"); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/http/wpt/service-workers/resources/persistent-importScripts-script.py b/LayoutTests/http/wpt/service-workers/resources/persistent-importScripts-script.py >new file mode 100644 >index 0000000000000000000000000000000000000000..a9bb2dd98b4f95a4dfe6cfa73849f5f5ea78dce4 >--- /dev/null >+++ b/LayoutTests/http/wpt/service-workers/resources/persistent-importScripts-script.py >@@ -0,0 +1,7 @@ >+import random >+ >+def main(request, response): >+ headers = [("Content-type", "text/javascript"), >+ ("Cache-Control", "no-store") >+ ] >+ return headers, "self.addEventListener('message', function(e) { e.source.postMessage('" + str(random.random()) +"'); });" >diff --git a/LayoutTests/http/wpt/service-workers/resources/persistent-importScripts-worker.js b/LayoutTests/http/wpt/service-workers/resources/persistent-importScripts-worker.js >new file mode 100644 >index 0000000000000000000000000000000000000000..7eb9dd62057f545aff5aa45a175ec0a0f1e68e71 >--- /dev/null >+++ b/LayoutTests/http/wpt/service-workers/resources/persistent-importScripts-worker.js >@@ -0,0 +1,2 @@ >+importScripts("persistent-importScripts-script.py"); >+ >diff --git a/LayoutTests/http/wpt/service-workers/resources/routines.js b/LayoutTests/http/wpt/service-workers/resources/routines.js >new file mode 100644 >index 0000000000000000000000000000000000000000..df2392558422206fad617a5eec7cc596ed4b4152 >--- /dev/null >+++ b/LayoutTests/http/wpt/service-workers/resources/routines.js >@@ -0,0 +1,29 @@ >+function waitFor(duration) >+{ >+ return new Promise((resolve) => setTimeout(resolve, duration)); >+} >+ >+function withIframe(url) { >+ return new Promise(function(resolve) { >+ var frame = document.createElement('iframe'); >+ frame.src = url; >+ frame.onload = function() { resolve(frame); }; >+ document.body.appendChild(frame); >+ }); >+} >+ >+function waitForState(worker, state) >+{ >+ if (!worker || worker.state == undefined) >+ return Promise.reject(new Error('wait_for_state must be passed a ServiceWorker')); >+ >+ if (worker.state === state) >+ return Promise.resolve(state); >+ >+ return new Promise(function(resolve) { >+ worker.addEventListener('statechange', function() { >+ if (worker.state === state) >+ resolve(state); >+ }); >+ }); >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-mime-types.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-mime-types.https-expected.txt >index 1d98128f119ffc694c61fee4f44e664be203ace9..537a2f7bd62124ca491bef1a6f86aeb9f88251ff 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-mime-types.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/registration-mime-types.https-expected.txt >@@ -1,8 +1,8 @@ > > PASS Registering script with no MIME type > PASS Registering script with bad MIME type >-FAIL Registering script that imports script with no MIME type assert_throws: Registration of no MIME type imported script should fail. function "function () { throw e }" threw object "TypeError: NetworkError: A network error occurred." that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18 >-FAIL Registering script that imports script with bad MIME type assert_throws: Registration of plain text imported script should fail. function "function () { throw e }" threw object "TypeError: NetworkError: A network error occurred." that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18 >+FAIL Registering script that imports script with no MIME type assert_throws: Registration of no MIME type imported script should fail. function "function () { throw e }" threw object "TypeError: NetworkError: mime type is not a supported JavaScript mime type" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18 >+FAIL Registering script that imports script with bad MIME type assert_throws: Registration of plain text imported script should fail. function "function () { throw e }" threw object "TypeError: NetworkError: mime type is not a supported JavaScript mime type" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18 > PASS Registering script with good MIME type application/ecmascript > PASS Registering script that imports script with good MIME type application/ecmascript > PASS Registering script with good MIME type application/javascript
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 182444
:
341102
|
341764
|
341770
|
341771
|
341942
|
341952
|
341966