Diff
Modified: trunk/Source/WebCore/ChangeLog (277836 => 277837)
--- trunk/Source/WebCore/ChangeLog 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/ChangeLog 2021-05-20 23:39:30 UTC (rev 277837)
@@ -1,3 +1,54 @@
+2021-05-20 Kate Cheney <[email protected]>
+
+ Mark ServiceWorkerThreadProxy with a default app-bound value
+ https://bugs.webkit.org/show_bug.cgi?id=223201
+ <rdar://problem/77664416>
+
+ Reviewed by Youenn Fablet.
+
+ Service worker loads have their own document loader, so they don't
+ always get properly marked as app-bound based on the main frame
+ navigation. Prior fixes handled some fetch events, synthetic
+ responses, and soft updates. But we need to set a default value when
+ we install the service worker.
+
+ We had to pick a best-effort heuristic to do this. If any client for
+ the worker is app-bound, then all loads with that worker will be
+ marked app-bound.
+
+ * testing/ServiceWorkerInternals.cpp:
+ (WebCore::ServiceWorkerInternals::lastNavigationWasAppBound):
+ * testing/ServiceWorkerInternals.h:
+ * testing/ServiceWorkerInternals.idl:
+ * workers/WorkerRunLoop.h:
+ To test this, I added a new API to ServiceWorkerInternals to get the
+ worker's app bound value.
+
+ * workers/service/ServiceWorkerClientData.cpp:
+ (WebCore::ServiceWorkerClientData::isolatedCopy const):
+ (WebCore::ServiceWorkerClientData::from):
+ * workers/service/ServiceWorkerClientData.h:
+ (WebCore::ServiceWorkerClientData::encode const):
+ (WebCore::ServiceWorkerClientData::decode):
+ Store the main navigation app-bound value when we register a client.
+
+ * workers/service/ServiceWorkerContextData.cpp:
+ (WebCore::ServiceWorkerContextData::isolatedCopy const):
+ * workers/service/ServiceWorkerContextData.h:
+ (WebCore::ServiceWorkerContextData::encode const):
+ (WebCore::ServiceWorkerContextData::decode):
+ * workers/service/context/ServiceWorkerThreadProxy.cpp:
+ (WebCore::ServiceWorkerThreadProxy::ServiceWorkerThreadProxy):
+ (WebCore::ServiceWorkerThreadProxy::lastNavigationWasAppBound):
+ * workers/service/context/ServiceWorkerThreadProxy.h:
+ * workers/service/server/RegistrationDatabase.cpp:
+ (WebCore::RegistrationDatabase::importRecords):
+ * workers/service/server/SWServer.cpp:
+ (WebCore::SWServer::updateWorker):
+ (WebCore::SWServer::clientIsAppBoundForRegistrableDomain):
+ Best-effort heuristic to mark a load as app bound if any client for
+ that origin was registered as app-bound.
+
2021-05-20 Sam Weinig <[email protected]>
Fix inverted ASSERT in sampleColor.
Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp (277836 => 277837)
--- trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -108,6 +108,23 @@
return getCurrentProcessID();
}
+void ServiceWorkerInternals::lastNavigationWasAppBound(Ref<DeferredPromise>&& promise)
+{
+ ASSERT(!m_lastNavigationWasAppBoundPromise);
+ m_lastNavigationWasAppBoundPromise = WTFMove(promise);
+ callOnMainThread([identifier = m_identifier, weakThis = makeWeakPtr(this)]() mutable {
+ if (auto* proxy = SWContextManager::singleton().workerByID(identifier)) {
+ proxy->thread().runLoop().postTaskForMode([weakThis = WTFMove(weakThis), appBound = proxy->lastNavigationWasAppBound()](auto&) {
+ if (!weakThis || !weakThis->m_lastNavigationWasAppBoundPromise)
+ return;
+
+ weakThis->m_lastNavigationWasAppBoundPromise->resolve<IDLBoolean>(appBound);
+ weakThis->m_lastNavigationWasAppBoundPromise = nullptr;
+ }, WorkerRunLoop::defaultMode());
+ }
+ });
+}
+
} // namespace WebCore
#endif
Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.h (277836 => 277837)
--- trunk/Source/WebCore/testing/ServiceWorkerInternals.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -28,6 +28,7 @@
#if ENABLE(SERVICE_WORKER)
#include "IDLTypes.h"
+#include "JSDOMPromiseDeferred.h"
#include "ServiceWorkerIdentifier.h"
#include <wtf/RefCounted.h>
@@ -39,7 +40,7 @@
template<typename IDLType> class DOMPromiseDeferred;
-class WEBCORE_TESTSUPPORT_EXPORT ServiceWorkerInternals : public RefCounted<ServiceWorkerInternals> {
+class WEBCORE_TESTSUPPORT_EXPORT ServiceWorkerInternals : public RefCounted<ServiceWorkerInternals>, public CanMakeWeakPtr<ServiceWorkerInternals> {
public:
static Ref<ServiceWorkerInternals> create(ServiceWorkerIdentifier identifier) { return adoptRef(*new ServiceWorkerInternals { identifier }); }
~ServiceWorkerInternals();
@@ -57,10 +58,13 @@
int processIdentifier() const;
+ void lastNavigationWasAppBound(Ref<DeferredPromise>&&);
+
private:
explicit ServiceWorkerInternals(ServiceWorkerIdentifier);
ServiceWorkerIdentifier m_identifier;
+ RefPtr<DeferredPromise> m_lastNavigationWasAppBoundPromise;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.idl (277836 => 277837)
--- trunk/Source/WebCore/testing/ServiceWorkerInternals.idl 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.idl 2021-05-20 23:39:30 UTC (rev 277837)
@@ -40,4 +40,6 @@
readonly attribute boolean isThrottleable;
readonly attribute long processIdentifier;
+
+ Promise<boolean> lastNavigationWasAppBound();
};
Modified: trunk/Source/WebCore/workers/WorkerRunLoop.h (277836 => 277837)
--- trunk/Source/WebCore/workers/WorkerRunLoop.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/WorkerRunLoop.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -60,12 +60,12 @@
void postTask(ScriptExecutionContext::Task&&);
void postTaskAndTerminate(ScriptExecutionContext::Task&&);
- void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode);
+ WEBCORE_EXPORT void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode);
void postDebuggerTask(ScriptExecutionContext::Task&&);
unsigned long createUniqueId() { return ++m_uniqueId; }
- static String defaultMode();
+ WEBCORE_EXPORT static String defaultMode();
class Task {
WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED;
public:
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClientData.cpp (277836 => 277837)
--- trunk/Source/WebCore/workers/service/ServiceWorkerClientData.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClientData.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -30,6 +30,7 @@
#include "DOMWindow.h"
#include "Document.h"
+#include "DocumentLoader.h"
#include "Frame.h"
#include "SWClientConnection.h"
@@ -57,7 +58,7 @@
ServiceWorkerClientData ServiceWorkerClientData::isolatedCopy() const
{
- return { identifier, type, frameType, url.isolatedCopy() };
+ return { identifier, type, frameType, url.isolatedCopy(), lastNavigationWasAppBound };
}
ServiceWorkerClientData ServiceWorkerClientData::from(ScriptExecutionContext& context, SWClientConnection& connection)
@@ -65,11 +66,14 @@
bool isDocument = is<Document>(context);
RELEASE_ASSERT(isDocument); // We do not support dedicated workers as clients yet.
+ auto& document = downcast<Document>(context);
+ auto lastNavigationWasAppBound = document.loader() && document.loader()->lastNavigationWasAppBound() ? LastNavigationWasAppBound::Yes : LastNavigationWasAppBound::No;
+
return {
- { connection.serverConnectionIdentifier(), downcast<Document>(context).identifier() },
+ { connection.serverConnectionIdentifier(), document.identifier() },
isDocument ? ServiceWorkerClientType::Window : ServiceWorkerClientType::Worker,
toServiceWorkerClientFrameType(context),
- context.url()
+ context.url(), lastNavigationWasAppBound
};
}
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClientData.h (277836 => 277837)
--- trunk/Source/WebCore/workers/service/ServiceWorkerClientData.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClientData.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -37,11 +37,14 @@
class SWClientConnection;
class ScriptExecutionContext;
+enum class LastNavigationWasAppBound : bool { No, Yes };
+
struct ServiceWorkerClientData {
ServiceWorkerClientIdentifier identifier;
ServiceWorkerClientType type;
ServiceWorkerClientFrameType frameType;
URL url;
+ LastNavigationWasAppBound lastNavigationWasAppBound;
ServiceWorkerClientData isolatedCopy() const;
@@ -54,7 +57,7 @@
template<class Encoder>
void ServiceWorkerClientData::encode(Encoder& encoder) const
{
- encoder << identifier << type << frameType << url;
+ encoder << identifier << type << frameType << url << lastNavigationWasAppBound;
}
template<class Decoder>
@@ -80,7 +83,12 @@
if (!url)
return WTF::nullopt;
- return { { WTFMove(*identifier), WTFMove(*type), WTFMove(*frameType), WTFMove(*url) } };
+ Optional<LastNavigationWasAppBound> lastNavigationWasAppBound;
+ decoder >> lastNavigationWasAppBound;
+ if (!lastNavigationWasAppBound)
+ return WTF::nullopt;
+
+ return { { WTFMove(*identifier), WTFMove(*type), WTFMove(*frameType), WTFMove(*url), WTFMove(*lastNavigationWasAppBound) } };
}
using ServiceWorkerClientsMatchAllCallback = WTF::CompletionHandler<void(Vector<ServiceWorkerClientData>&&)>;
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContextData.cpp (277836 => 277837)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContextData.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContextData.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -44,6 +44,7 @@
scriptURL.isolatedCopy(),
workerType,
loadedFromDisk,
+ lastNavigationWasAppBound,
crossThreadCopy(scriptResourceMap)
};
}
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h (277836 => 277837)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -39,6 +39,8 @@
namespace WebCore {
+enum class LastNavigationWasAppBound : bool;
+
struct ServiceWorkerContextData {
struct ImportedScript {
ScriptBuffer script;
@@ -87,6 +89,7 @@
URL scriptURL;
WorkerType workerType;
bool loadedFromDisk;
+ Optional<LastNavigationWasAppBound> lastNavigationWasAppBound;
HashMap<URL, ImportedScript> scriptResourceMap;
template<class Encoder> void encode(Encoder&) const;
@@ -99,7 +102,7 @@
void ServiceWorkerContextData::encode(Encoder& encoder) const
{
encoder << jobDataIdentifier << registration << serviceWorkerIdentifier << script << contentSecurityPolicy << referrerPolicy
- << scriptURL << workerType << loadedFromDisk << scriptResourceMap << certificateInfo;
+ << scriptURL << workerType << loadedFromDisk << lastNavigationWasAppBound << scriptResourceMap << certificateInfo;
}
template<class Decoder>
@@ -144,6 +147,10 @@
if (!decoder.decode(loadedFromDisk))
return WTF::nullopt;
+ Optional<LastNavigationWasAppBound> lastNavigationWasAppBound;
+ if (!decoder.decode(lastNavigationWasAppBound))
+ return WTF::nullopt;
+
HashMap<URL, ImportedScript> scriptResourceMap;
if (!decoder.decode(scriptResourceMap))
return WTF::nullopt;
@@ -164,6 +171,7 @@
WTFMove(scriptURL),
workerType,
loadedFromDisk,
+ WTFMove(lastNavigationWasAppBound),
WTFMove(scriptResourceMap)
}};
}
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp (277836 => 277837)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -116,6 +116,9 @@
m_remoteDebuggable->setRemoteDebuggingAllowed(true);
m_remoteDebuggable->init();
#endif
+
+ if (data.lastNavigationWasAppBound)
+ setLastNavigationWasAppBound(data.lastNavigationWasAppBound == LastNavigationWasAppBound::Yes);
}
ServiceWorkerThreadProxy::~ServiceWorkerThreadProxy()
@@ -130,6 +133,11 @@
m_document->loader()->setLastNavigationWasAppBound(wasAppBound);
}
+bool ServiceWorkerThreadProxy::lastNavigationWasAppBound()
+{
+ return m_document->loader() ? m_document->loader()->lastNavigationWasAppBound() : false;
+}
+
bool ServiceWorkerThreadProxy::postTaskForModeToWorkerOrWorkletGlobalScope(ScriptExecutionContext::Task&& task, const String& mode)
{
if (m_isTerminatingOrTerminated)
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h (277836 => 277837)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -82,6 +82,7 @@
void didSaveScriptsToDisk(ScriptBuffer&&, HashMap<URL, ScriptBuffer>&& importedScripts);
WEBCORE_EXPORT void setLastNavigationWasAppBound(bool);
+ WEBCORE_EXPORT bool lastNavigationWasAppBound();
private:
WEBCORE_EXPORT ServiceWorkerThreadProxy(PageConfiguration&&, ServiceWorkerContextData&&, String&& userAgent, CacheStorageProvider&, StorageBlockingPolicy);
Modified: trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp (277836 => 277837)
--- trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -569,7 +569,7 @@
auto registrationIdentifier = ServiceWorkerRegistrationIdentifier::generate();
auto serviceWorkerData = ServiceWorkerData { workerIdentifier, scriptURL, ServiceWorkerState::Activated, *workerType, registrationIdentifier };
auto registration = ServiceWorkerRegistrationData { WTFMove(*key), registrationIdentifier, WTFMove(scopeURL), *updateViaCache, lastUpdateCheckTime, WTF::nullopt, WTF::nullopt, WTFMove(serviceWorkerData) };
- auto contextData = ServiceWorkerContextData { WTF::nullopt, WTFMove(registration), workerIdentifier, WTFMove(script), WTFMove(*certificateInfo), WTFMove(*contentSecurityPolicy), WTFMove(referrerPolicy), WTFMove(scriptURL), *workerType, true, WTFMove(scriptResourceMap) };
+ auto contextData = ServiceWorkerContextData { WTF::nullopt, WTFMove(registration), workerIdentifier, WTFMove(script), WTFMove(*certificateInfo), WTFMove(*contentSecurityPolicy), WTFMove(referrerPolicy), WTFMove(scriptURL), *workerType, true, LastNavigationWasAppBound::No, WTFMove(scriptResourceMap) };
callOnMainThread([protectedThis = makeRef(*this), contextData = contextData.isolatedCopy()]() mutable {
protectedThis->addRegistrationToStore(WTFMove(contextData));
Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (277836 => 277837)
--- trunk/Source/WebCore/workers/service/server/SWServer.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -648,9 +648,26 @@
void SWServer::updateWorker(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, SWServerRegistration& registration, const URL& url, const ScriptBuffer& script, const CertificateInfo& certificateInfo, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, const String& referrerPolicy, WorkerType type, HashMap<URL, ServiceWorkerContextData::ImportedScript>&& scriptResourceMap)
{
- tryInstallContextData(ServiceWorkerContextData { jobDataIdentifier, registration.data(), ServiceWorkerIdentifier::generate(), script, certificateInfo, contentSecurityPolicy, referrerPolicy, url, type, false, WTFMove(scriptResourceMap) });
+ tryInstallContextData(ServiceWorkerContextData { jobDataIdentifier, registration.data(), ServiceWorkerIdentifier::generate(), script, certificateInfo, contentSecurityPolicy, referrerPolicy, url, type, false, clientIsAppBoundForRegistrableDomain(RegistrableDomain(url)), WTFMove(scriptResourceMap) });
}
+LastNavigationWasAppBound SWServer::clientIsAppBoundForRegistrableDomain(const RegistrableDomain& domain)
+{
+ auto clientsByRegistrableDomainIterator = m_clientsByRegistrableDomain.find(domain);
+ if (clientsByRegistrableDomainIterator == m_clientsByRegistrableDomain.end())
+ return LastNavigationWasAppBound::No;
+
+ auto& clientsForRegistrableDomain = clientsByRegistrableDomainIterator->value;
+ for (auto& client : clientsForRegistrableDomain) {
+ auto data = ""
+ ASSERT(data != m_clientsById.end());
+ if (data->value.lastNavigationWasAppBound == LastNavigationWasAppBound::Yes)
+ return LastNavigationWasAppBound::Yes;
+ }
+
+ return LastNavigationWasAppBound::No;
+}
+
void SWServer::tryInstallContextData(ServiceWorkerContextData&& data)
{
RegistrableDomain registrableDomain(data.scriptURL);
@@ -869,10 +886,24 @@
return iterator->value->registration();
}
+void SWServer::updateAppBoundValueForWorkers(const ClientOrigin& clientOrigin, LastNavigationWasAppBound lastNavigationWasAppBound)
+{
+ for (auto& worker : m_runningOrTerminatingWorkers.values()) {
+ if (worker->origin().clientRegistrableDomain() == clientOrigin.clientRegistrableDomain())
+ worker->updateAppBoundValue(lastNavigationWasAppBound);
+ }
+}
+
void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceWorkerClientData&& data, const Optional<ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
{
auto clientIdentifier = data.identifier;
+ // Update the app-bound value if the new client is app-bound and the current clients for the origin are not marked app-bound.
+ if (data.lastNavigationWasAppBound == LastNavigationWasAppBound::Yes) {
+ if (clientIsAppBoundForRegistrableDomain(clientOrigin.clientRegistrableDomain()) == LastNavigationWasAppBound::No)
+ updateAppBoundValueForWorkers(clientOrigin, data.lastNavigationWasAppBound);
+ }
+
ASSERT(!m_clientsById.contains(clientIdentifier));
m_clientsById.add(clientIdentifier, WTFMove(data));
@@ -908,6 +939,7 @@
void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, ServiceWorkerClientIdentifier clientIdentifier)
{
auto clientRegistrableDomain = clientOrigin.clientRegistrableDomain();
+ auto appBoundValueBefore = clientIsAppBoundForRegistrableDomain(clientOrigin.clientRegistrableDomain());
bool wasRemoved = m_clientsById.remove(clientIdentifier);
ASSERT_UNUSED(wasRemoved, wasRemoved);
@@ -950,6 +982,12 @@
if (clientsForRegistrableDomain.isEmpty())
m_clientsByRegistrableDomain.remove(clientsByRegistrableDomainIterator);
+ // If the app-bound value changed after this client was removed, we know it was the only app-bound
+ // client for its origin, and we should update all workers to reflect this.
+ auto appBoundValueAfter = clientIsAppBoundForRegistrableDomain(clientOrigin.clientRegistrableDomain());
+ if (appBoundValueBefore != appBoundValueAfter)
+ updateAppBoundValueForWorkers(clientOrigin, appBoundValueAfter);
+
auto registrationIterator = m_clientToControllingRegistration.find(clientIdentifier);
if (registrationIterator == m_clientToControllingRegistration.end())
return;
Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (277836 => 277837)
--- trunk/Source/WebCore/workers/service/server/SWServer.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -217,6 +217,8 @@
static constexpr Seconds defaultTerminationDelay = 10_s;
+ LastNavigationWasAppBound clientIsAppBoundForRegistrableDomain(const RegistrableDomain&);
+
private:
void validateRegistrationDomain(WebCore::RegistrableDomain, CompletionHandler<void(bool)>&&);
@@ -242,6 +244,8 @@
void contextConnectionCreated(SWServerToContextConnection&);
+ void updateAppBoundValueForWorkers(const ClientOrigin&, LastNavigationWasAppBound);
+
HashMap<SWServerConnectionIdentifier, std::unique_ptr<Connection>> m_connections;
HashMap<ServiceWorkerRegistrationKey, WeakPtr<SWServerRegistration>> m_scopeToRegistrationMap;
HashMap<ServiceWorkerRegistrationIdentifier, std::unique_ptr<SWServerRegistration>> m_registrations;
Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h (277836 => 277837)
--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -52,6 +52,7 @@
// Messages to the SW host process
virtual void installServiceWorkerContext(const ServiceWorkerContextData&, const String& userAgent) = 0;
+ virtual void updateAppBoundValue(ServiceWorkerIdentifier, LastNavigationWasAppBound) = 0;
virtual void fireInstallEvent(ServiceWorkerIdentifier) = 0;
virtual void fireActivateEvent(ServiceWorkerIdentifier) = 0;
virtual void terminateWorker(ServiceWorkerIdentifier) = 0;
Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp (277836 => 277837)
--- trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -62,6 +62,7 @@
, m_registrableDomain(m_data.scriptURL)
, m_scriptResourceMap(WTFMove(scriptResourceMap))
, m_terminationTimer(*this, &SWServerWorker::terminationTimerFired)
+ , m_lastNavigationWasAppBound(m_server->clientIsAppBoundForRegistrableDomain(m_registrableDomain))
{
m_data.scriptURL.removeFragmentIdentifier();
@@ -86,9 +87,20 @@
{
ASSERT(m_registration);
- return { WTF::nullopt, m_registration->data(), m_data.identifier, m_script, m_certificateInfo, m_contentSecurityPolicy, m_referrerPolicy, m_data.scriptURL, m_data.type, false, m_scriptResourceMap };
+ return { WTF::nullopt, m_registration->data(), m_data.identifier, m_script, m_certificateInfo, m_contentSecurityPolicy, m_referrerPolicy, m_data.scriptURL, m_data.type, false, m_lastNavigationWasAppBound, m_scriptResourceMap };
}
+void SWServerWorker::updateAppBoundValue(LastNavigationWasAppBound lastNavigationWasAppBound)
+{
+ m_lastNavigationWasAppBound = lastNavigationWasAppBound;
+
+ if (!isRunning())
+ return;
+
+ if (auto* connection = contextConnection())
+ connection->updateAppBoundValue(identifier(), lastNavigationWasAppBound);
+}
+
void SWServerWorker::terminate(CompletionHandler<void()>&& callback)
{
if (!m_server)
Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.h (277836 => 277837)
--- trunk/Source/WebCore/workers/service/server/SWServerWorker.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -127,6 +127,7 @@
void setHasTimedOutAnyFetchTasks() { m_hasTimedOutAnyFetchTasks = true; }
bool hasTimedOutAnyFetchTasks() const { return m_hasTimedOutAnyFetchTasks; }
void didFailHeartBeatCheck();
+ void updateAppBoundValue(LastNavigationWasAppBound);
private:
SWServerWorker(SWServer&, SWServerRegistration&, const URL&, const ScriptBuffer&, const CertificateInfo&, const ContentSecurityPolicyResponseHeaders&, String&& referrerPolicy, WorkerType, ServiceWorkerIdentifier, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&);
@@ -157,6 +158,7 @@
bool m_hasTimedOutAnyFetchTasks { false };
Vector<CompletionHandler<void()>> m_terminationCallbacks;
Timer m_terminationTimer;
+ LastNavigationWasAppBound m_lastNavigationWasAppBound;
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (277836 => 277837)
--- trunk/Source/WebKit/ChangeLog 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/ChangeLog 2021-05-20 23:39:30 UTC (rev 277837)
@@ -1,3 +1,23 @@
+2021-05-20 Kate Cheney <[email protected]>
+
+ Mark ServiceWorkerThreadProxy with a default app-bound value
+ https://bugs.webkit.org/show_bug.cgi?id=223201
+ <rdar://problem/77664416>
+
+ Reviewed by Youenn Fablet.
+
+ * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+ (WebKit::WebSWServerConnection::controlClient):
+ * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+ (WebKit::WebSWServerToContextConnection::updateAppBoundValue):
+ * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+ * Scripts/webkit/messages.py:
+ (headers_for_type):
+ * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+ (WebKit::WebSWContextManagerConnection::updateAppBoundValue):
+ * WebProcess/Storage/WebSWContextManagerConnection.h:
+ * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
2021-05-20 Eric Carlson <[email protected]>
Allow GPU process log channels to be configured
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp (277836 => 277837)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -147,7 +147,7 @@
unregisterServiceWorkerClient(clientIdentifier);
});
- ServiceWorkerClientData data { clientIdentifier, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, request.url() };
+ ServiceWorkerClientData data { clientIdentifier, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, request.url(), request.isAppBound() ? WebCore::LastNavigationWasAppBound::Yes : WebCore::LastNavigationWasAppBound::No };
registerServiceWorkerClient(SecurityOriginData { registration.key().topOrigin() }, WTFMove(data), registration.identifier(), request.httpUserAgent());
}
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (277836 => 277837)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -92,6 +92,11 @@
send(Messages::WebSWContextManagerConnection::InstallServiceWorker { data, userAgent });
}
+void WebSWServerToContextConnection::updateAppBoundValue(ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::LastNavigationWasAppBound lastNavigationWasAppBound)
+{
+ send(Messages::WebSWContextManagerConnection::UpdateAppBoundValue(serviceWorkerIdentifier, lastNavigationWasAppBound));
+}
+
void WebSWServerToContextConnection::fireInstallEvent(ServiceWorkerIdentifier serviceWorkerIdentifier)
{
send(Messages::WebSWContextManagerConnection::FireInstallEvent(serviceWorkerIdentifier));
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (277836 => 277837)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -86,6 +86,7 @@
// Messages to the SW host WebProcess
void installServiceWorkerContext(const WebCore::ServiceWorkerContextData&, const String& userAgent) final;
+ void updateAppBoundValue(WebCore::ServiceWorkerIdentifier, WebCore::LastNavigationWasAppBound) final;
void fireInstallEvent(WebCore::ServiceWorkerIdentifier) final;
void fireActivateEvent(WebCore::ServiceWorkerIdentifier) final;
void terminateWorker(WebCore::ServiceWorkerIdentifier) final;
Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (277836 => 277837)
--- trunk/Source/WebKit/Scripts/webkit/messages.py 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py 2021-05-20 23:39:30 UTC (rev 277837)
@@ -701,6 +701,7 @@
'WebCore::InspectorOverlay::Highlight': ['<WebCore/InspectorOverlay.h>'],
'WebCore::KeyframeValueList': ['<WebCore/GraphicsLayer.h>'],
'WebCore::KeypressCommand': ['<WebCore/KeyboardEvent.h>'],
+ 'WebCore::LastNavigationWasAppBound': ['<WebCore/ServiceWorkerClientData.h>'],
'WebCore::LegacyCDMSessionClient::MediaKeyErrorCode': ['<WebCore/LegacyCDMSession.h>'],
'WebCore::LockBackForwardList': ['<WebCore/FrameLoaderTypes.h>'],
'WebCore::MessagePortChannelProvider::HasActivity': ['<WebCore/MessagePortChannelProvider.h>'],
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (277836 => 277837)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2021-05-20 23:39:30 UTC (rev 277837)
@@ -135,6 +135,12 @@
setShouldUseShortTimeout(store.getBoolValueForKey(WebPreferencesKey::shouldUseServiceWorkerShortTimeoutKey()));
}
+void WebSWContextManagerConnection::updateAppBoundValue(ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::LastNavigationWasAppBound lastNavigationWasAppBound)
+{
+ if (auto* serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(serviceWorkerIdentifier))
+ serviceWorkerThreadProxy->setLastNavigationWasAppBound(lastNavigationWasAppBound == WebCore::LastNavigationWasAppBound::Yes);
+}
+
void WebSWContextManagerConnection::installServiceWorker(ServiceWorkerContextData&& data, String&& userAgent)
{
auto pageConfiguration = pageConfigurationWithEmptyClients(WebProcess::singleton().sessionID());
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (277836 => 277837)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h 2021-05-20 23:39:30 UTC (rev 277837)
@@ -29,6 +29,7 @@
#include "Connection.h"
#include "MessageReceiver.h"
+#include "NavigatingToAppBoundDomain.h"
#include "ShareableResource.h"
#include "UserContentControllerIdentifier.h"
#include "WebPageProxyIdentifier.h"
@@ -85,6 +86,7 @@
void serviceWorkerStarted(Optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, bool doesHandleFetch) final;
void serviceWorkerFailedToStart(Optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
void installServiceWorker(WebCore::ServiceWorkerContextData&&, String&& userAgent);
+ void updateAppBoundValue(WebCore::ServiceWorkerIdentifier, WebCore::LastNavigationWasAppBound);
void startFetch(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&, String&& referrer);
void cancelFetch(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);
void continueDidReceiveFetchResponse(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in (277836 => 277837)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in 2021-05-20 23:39:30 UTC (rev 277837)
@@ -24,6 +24,7 @@
messages -> WebSWContextManagerConnection NotRefCounted {
InstallServiceWorker(struct WebCore::ServiceWorkerContextData contextData, String userAgent)
+ UpdateAppBoundValue(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum:bool WebCore::LastNavigationWasAppBound lastNavigationWasAppBound)
StartFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody, String referrer)
CancelFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier)
ContinueDidReceiveFetchResponse(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier)
Modified: trunk/Tools/ChangeLog (277836 => 277837)
--- trunk/Tools/ChangeLog 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Tools/ChangeLog 2021-05-20 23:39:30 UTC (rev 277837)
@@ -1,3 +1,16 @@
+2021-05-20 Kate Cheney <[email protected]>
+
+ Mark ServiceWorkerThreadProxy with a default app-bound value
+ https://bugs.webkit.org/show_bug.cgi?id=223201
+ <rdar://problem/77664416>
+
+ Reviewed by Youenn Fablet.
+
+ Test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+ (-[SWAppBoundRequestMessageHandler userContentController:didReceiveScriptMessage:]):
+
2021-05-20 Aakash Jain <[email protected]>
Use Python 3 for running various scripts on EWS
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (277836 => 277837)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2021-05-20 23:39:30 UTC (rev 277837)
@@ -1877,4 +1877,149 @@
{
runWebProcessPlugInTest(IsAppBound::No);
}
+
+#if WK_HAVE_C_SPI
+
+static const char* mainSWBytesDefaultValue = R"SWRESOURCE(
+<script>
+
+function log(msg)
+{
+ window.webkit.messageHandlers.sw.postMessage(msg);
+}
+
+navigator.serviceWorker.addEventListener("message", function(event) {
+ log(event.data);
+});
+
+try {
+ navigator.serviceWorker.register('/sw.js').then(function(reg) {
+ if (reg.active) {
+ worker = reg.active;
+ worker.postMessage("SECOND");
+ return;
+ }
+ worker = reg.installing;
+ worker.addEventListener('statechange', function() {
+ if (worker.state == 'activated')
+ worker.postMessage("FIRST");
+ });
+ }).catch(function(error) {
+ log('Registration failed with: ' + error);
+ });
+} catch(e) {
+ log('Exception: ' + e);
+}
+</script>
+)SWRESOURCE";
+
+static const char* scriptBytesDefaultValue = R"SWRESOURCE(
+self.addEventListener('message', async (event) => {
+ if (!self.internals) {
+ event.source.postMessage('No internals');
+ return;
+ }
+
+ queryAppBoundValue(event, false);
+});
+
+async function queryAppBoundValue(event, haveSentInitialMessage)
+{
+ var result = await internals.lastNavigationWasAppBound();
+ if (result) {
+ if (event.data == "FIRST") {
+ event.source.postMessage('app-bound');
+ return;
+ }
+
+ if (!haveSentInitialMessage)
+ event.source.postMessage('starts app-bound');
+
+ queryAppBoundValue(event, true);
+ return;
+ }
+
+ event.source.postMessage('non app-bound');
+}
+
+)SWRESOURCE";
+
+
+static String expectedMessage;
+static bool receivedMessage = false;
+
+@interface SWAppBoundRequestMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation SWAppBoundRequestMessageHandler
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+ EXPECT_WK_STREQ(message.body, expectedMessage);
+ receivedMessage = true;
+}
+@end
+
+TEST(InAppBrowserPrivacy, RegisterServiceWorkerClientUpdatesAppBoundValue)
+{
+ static bool isDone = false;
+
+ [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+ isDone = true;
+ }];
+ TestWebKitAPI::Util::run(&isDone);
+
+ WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+ WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
+ configuration.processPool = (WKProcessPool *)context.get();
+
+ RetainPtr<SWAppBoundRequestMessageHandler> messageHandler = adoptNS([[SWAppBoundRequestMessageHandler alloc] init]);
+ [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+ auto webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
+ auto webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
+
+ auto delegate = adoptNS([TestNavigationDelegate new]);
+ [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+ EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+ callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+ }];
+
+ webView1.get().navigationDelegate = delegate.get();
+ webView2.get().navigationDelegate = delegate.get();
+
+ ServiceWorkerTCPServer server({
+ { "text/html", mainSWBytesDefaultValue },
+ { "application/_javascript_", scriptBytesDefaultValue },
+ }, {
+ { "text/html", mainSWBytesDefaultValue },
+ { "application/_javascript_", scriptBytesDefaultValue },
+ });
+
+ // Load WebView with an app-bound request. We expect the ServiceWorkerThreadProxy to be app-bound.
+ expectedMessage = "app-bound";
+ [webView1 loadRequest:server.request()];
+ TestWebKitAPI::Util::run(&receivedMessage);
+
+ // Load WebView with a non app-bound request. We expect the ServiceWorkerThreadProxy to be app-bound
+ // at first, but then become non app-bound once the second webView is closed and its client is unregistered.
+ expectedMessage = "starts app-bound";
+ receivedMessage = false;
+ NSMutableURLRequest *nonAppBoundRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/main.html", server.port()]]];
+ APP_BOUND_REQUEST_ADDITIONS
+
+ [webView2 loadRequest:nonAppBoundRequest];
+ TestWebKitAPI::Util::run(&receivedMessage);
+
+ // Close the app-bound view. We expect that the existing worker will become non app-bound
+ // now that all app-bound clients have been removed.
+ expectedMessage = "non app-bound";
+ receivedMessage = false;
+ [webView1 _close];
+ webView1 = nullptr;
+
+ TestWebKitAPI::Util::run(&receivedMessage);
+}
+
#endif
+
+#endif