Title: [292867] trunk
Revision
292867
Author
[email protected]
Date
2022-04-14 07:52:58 -0700 (Thu, 14 Apr 2022)

Log Message

WKWebView: navigator.serviceWorker.register method fails for a new version of an already registered service worker.
https://bugs.webkit.org/show_bug.cgi?id=229554
<rdar://problem/82388593>

Reviewed by Brent Fulgham.

Source/WebCore:

Check to see if a domain has already been registered when validating
a service worker registration domain. In this case, we allow an
updated registration.

There are a couple of other changes that are key for testing this.
First, this adds a way to override the max registration count for
tests. This is because we can only use 127.0.0.1 and localhost in
tests, but would need 3 domains in order to test the max count.
overrideServiceWorkerRegistrationCountTestingValue lets us lower that
number.

Second, we also want a way to override the loopback IP address check
to make sure we don't get a false positive test result for localhost
and 127.0.0.1 in API tests.

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::addRegistrationFromStore):
(WebCore::SWServer::addRegistration):
(WebCore::SWServer::SWServer):
(WebCore::SWServer::maxRegistrationCount):
(WebCore::SWServer::allowLoopbackIPAddress):
(WebCore::SWServer::validateRegistrationDomain):
(WebCore::SWServer::scheduleJob):
(WebCore::SWServer::removeFromScopeToRegistrationMap):
* workers/service/server/SWServer.h:

Source/WebKit:

Plumbing to override the max service worker registration count for
test purposes. See WebCore changelog for details.

* NetworkProcess/NetworkSession.cpp:
(WebKit::NetworkSession::NetworkSession):
(WebKit::NetworkSession::ensureSWServer):
* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::overrideServiceWorkerRegistrationCountTestingValue const):
* NetworkProcess/NetworkSessionCreationParameters.cpp:
(WebKit::NetworkSessionCreationParameters::encode const):
(WebKit::NetworkSessionCreationParameters::decode):
* NetworkProcess/NetworkSessionCreationParameters.h:
* UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
* UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm:
(-[_WKWebsiteDataStoreConfiguration overrideServiceWorkerRegistrationCountTestingValue]):
(-[_WKWebsiteDataStoreConfiguration setOverrideServiceWorkerRegistrationCountTestingValue:]):
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::parameters):
* UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
(WebKit::WebsiteDataStoreConfiguration::copy const):
* UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
(WebKit::WebsiteDataStoreConfiguration::overrideServiceWorkerRegistrationCountTestingValue const):
(WebKit::WebsiteDataStoreConfiguration::setOverrideServiceWorkerRegistrationCountTestingValue):

Tools:

Adds a new test for re-registering and an overdue test for
unregistering now that we have the infrastructure. This also does some
refactoring to reduce duplicate code.

* TestWebKitAPI/Info.plist:
Update the Info.plist to consider localhost an app-bound domain so we
can test the max count when overriding the loopback IP. This requires
replacing an existing domain to stay under the count limit.

* TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (292866 => 292867)


--- trunk/Source/WebCore/ChangeLog	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebCore/ChangeLog	2022-04-14 14:52:58 UTC (rev 292867)
@@ -1,3 +1,37 @@
+2022-04-14  Kate Cheney  <[email protected]>
+
+        WKWebView: navigator.serviceWorker.register method fails for a new version of an already registered service worker.
+        https://bugs.webkit.org/show_bug.cgi?id=229554
+        <rdar://problem/82388593>
+
+        Reviewed by Brent Fulgham.
+
+        Check to see if a domain has already been registered when validating
+        a service worker registration domain. In this case, we allow an
+        updated registration.
+
+        There are a couple of other changes that are key for testing this.
+        First, this adds a way to override the max registration count for
+        tests. This is because we can only use 127.0.0.1 and localhost in
+        tests, but would need 3 domains in order to test the max count.
+        overrideServiceWorkerRegistrationCountTestingValue lets us lower that
+        number.
+
+        Second, we also want a way to override the loopback IP address check
+        to make sure we don't get a false positive test result for localhost
+        and 127.0.0.1 in API tests.
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::addRegistrationFromStore):
+        (WebCore::SWServer::addRegistration):
+        (WebCore::SWServer::SWServer):
+        (WebCore::SWServer::maxRegistrationCount):
+        (WebCore::SWServer::allowLoopbackIPAddress):
+        (WebCore::SWServer::validateRegistrationDomain):
+        (WebCore::SWServer::scheduleJob):
+        (WebCore::SWServer::removeFromScopeToRegistrationMap):
+        * workers/service/server/SWServer.h:
+
 2022-04-14  Zan Dobersek  <[email protected]>
 
         [GTK][WPE] Provide WK2 IPC encoding, decoding methods for the DMABufObject type

Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (292866 => 292867)


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2022-04-14 14:52:58 UTC (rev 292867)
@@ -50,7 +50,7 @@
 
 namespace WebCore {
 
-static const unsigned maxRegistrationCount = 3;
+static const unsigned defaultMaxRegistrationCount = 3;
 
 SWServer::Connection::Connection(SWServer& server, Identifier identifier)
     : m_server(server)
@@ -192,7 +192,7 @@
     LOG(ServiceWorker, "Adding registration from store for %s", data.registration.key.loggingString().utf8().data());
 
     auto registrableDomain = WebCore::RegistrableDomain(data.scriptURL);
-    validateRegistrationDomain(registrableDomain, ServiceWorkerJobType::Register, [this, weakThis = WeakPtr { *this }, data = "" (bool isValid) mutable {
+    validateRegistrationDomain(registrableDomain, ServiceWorkerJobType::Register, m_scopeToRegistrationMap.contains(data.registration.key), [this, weakThis = WeakPtr { *this }, data = "" (bool isValid) mutable {
         if (!weakThis)
             return;
         if (m_hasServiceWorkerEntitlement || isValid) {
@@ -218,7 +218,7 @@
 {
     LOG(ServiceWorker, "Adding registration live for %s", registration->key().loggingString().utf8().data());
 
-    if (!m_scopeToRegistrationMap.contains(registration->key()) && !SecurityOrigin::isLocalHostOrLoopbackIPAddress(registration->key().topOrigin().host))
+    if (!m_scopeToRegistrationMap.contains(registration->key()) && !allowLoopbackIPAddress(registration->key().topOrigin().host))
         m_uniqueRegistrationCount++;
 
     if (registration->serviceWorkerPageIdentifier())
@@ -365,7 +365,7 @@
     m_server.removeClientServiceWorkerRegistration(*this, identifier);
 }
 
-SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID sessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, SoftUpdateCallback&& softUpdateCallback, CreateContextConnectionCallback&& callback, AppBoundDomainsCallback&& appBoundDomainsCallback)
+SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID sessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, std::optional<unsigned> overrideServiceWorkerRegistrationCountTestingValue, SoftUpdateCallback&& softUpdateCallback, CreateContextConnectionCallback&& callback, AppBoundDomainsCallback&& appBoundDomainsCallback)
     : m_originStore(WTFMove(originStore))
     , m_sessionID(sessionID)
     , m_isProcessTerminationDelayEnabled(processTerminationDelayEnabled)
@@ -374,6 +374,7 @@
     , m_appBoundDomainsCallback(WTFMove(appBoundDomainsCallback))
     , m_shouldRunServiceWorkersOnMainThreadForTesting(shouldRunServiceWorkersOnMainThreadForTesting)
     , m_hasServiceWorkerEntitlement(hasServiceWorkerEntitlement)
+    , m_overrideServiceWorkerRegistrationCountTestingValue(overrideServiceWorkerRegistrationCountTestingValue)
 {
     RELEASE_LOG_IF(registrationDatabaseDirectory.isEmpty(), ServiceWorker, "No path to store the service worker registrations");
     if (!m_sessionID.isEphemeral())
@@ -385,19 +386,39 @@
     allServers().add(this);
 }
 
-void SWServer::validateRegistrationDomain(WebCore::RegistrableDomain domain, ServiceWorkerJobType type, CompletionHandler<void(bool)>&& completionHandler)
+unsigned SWServer::maxRegistrationCount()
 {
+    if (m_overrideServiceWorkerRegistrationCountTestingValue)
+        return *m_overrideServiceWorkerRegistrationCountTestingValue;
+
+    return defaultMaxRegistrationCount;
+}
+
+bool SWServer::allowLoopbackIPAddress(const String& domain)
+{
+    if (!SecurityOrigin::isLocalHostOrLoopbackIPAddress(domain))
+        return false;
+
+    if (m_overrideServiceWorkerRegistrationCountTestingValue)
+        return false;
+
+    return true;
+}
+
+void SWServer::validateRegistrationDomain(WebCore::RegistrableDomain domain, ServiceWorkerJobType type, bool isRegisteredDomain, CompletionHandler<void(bool)>&& completionHandler)
+{
+    bool jobTypeAllowed = type != ServiceWorkerJobType::Register || isRegisteredDomain;
     if (m_hasServiceWorkerEntitlement || m_hasReceivedAppBoundDomains) {
-        completionHandler(SecurityOrigin::isLocalHostOrLoopbackIPAddress(domain.string()) || type != ServiceWorkerJobType::Register || (m_appBoundDomains.contains(domain) && m_uniqueRegistrationCount < maxRegistrationCount));
+        completionHandler(allowLoopbackIPAddress(domain.string()) || jobTypeAllowed || (m_appBoundDomains.contains(domain) && m_uniqueRegistrationCount < maxRegistrationCount()));
         return;
     }
 
-    m_appBoundDomainsCallback([this, weakThis = WeakPtr { *this }, domain = WTFMove(domain), type, completionHandler = WTFMove(completionHandler)](auto&& appBoundDomains) mutable {
+    m_appBoundDomainsCallback([this, weakThis = WeakPtr { *this }, domain = WTFMove(domain), jobTypeAllowed, completionHandler = WTFMove(completionHandler)](auto&& appBoundDomains) mutable {
         if (!weakThis)
             return;
         m_hasReceivedAppBoundDomains = true;
         m_appBoundDomains = WTFMove(appBoundDomains);
-        completionHandler(SecurityOrigin::isLocalHostOrLoopbackIPAddress(domain.string()) || type != ServiceWorkerJobType::Register || (m_appBoundDomains.contains(domain) && m_uniqueRegistrationCount < maxRegistrationCount));
+        completionHandler(allowLoopbackIPAddress(domain.string()) || jobTypeAllowed || (m_appBoundDomains.contains(domain) && m_uniqueRegistrationCount < maxRegistrationCount()));
     });
 }
 
@@ -406,7 +427,7 @@
 {
     ASSERT(m_connections.contains(jobData.connectionIdentifier()) || jobData.connectionIdentifier() == Process::identifier());
 
-    validateRegistrationDomain(WebCore::RegistrableDomain(jobData.scriptURL), jobData.type, [this, weakThis = WeakPtr { *this }, jobData = WTFMove(jobData)] (bool isValid) mutable {
+    validateRegistrationDomain(WebCore::RegistrableDomain(jobData.scriptURL), jobData.type, m_scopeToRegistrationMap.contains(jobData.registrationKey()), [this, weakThis = WeakPtr { *this }, jobData = WTFMove(jobData)] (bool isValid) mutable {
         if (!weakThis)
             return;
         if (m_hasServiceWorkerEntitlement || isValid) {
@@ -1131,7 +1152,7 @@
 
 void SWServer::removeFromScopeToRegistrationMap(const ServiceWorkerRegistrationKey& key)
 {
-    if (m_scopeToRegistrationMap.contains(key) && !SecurityOrigin::isLocalHostOrLoopbackIPAddress(key.topOrigin().host))
+    if (m_scopeToRegistrationMap.contains(key) && !allowLoopbackIPAddress(key.topOrigin().host))
         m_uniqueRegistrationCount--;
 
     m_scopeToRegistrationMap.remove(key);

Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (292866 => 292867)


--- trunk/Source/WebCore/workers/service/server/SWServer.h	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h	2022-04-14 14:52:58 UTC (rev 292867)
@@ -132,7 +132,7 @@
     using SoftUpdateCallback = Function<void(ServiceWorkerJobData&& jobData, bool shouldRefreshCache, ResourceRequest&&, CompletionHandler<void(const WorkerFetchResult&)>&&)>;
     using CreateContextConnectionCallback = Function<void(const WebCore::RegistrableDomain&, std::optional<ProcessIdentifier> requestingProcessIdentifier, std::optional<ScriptExecutionContextIdentifier>, CompletionHandler<void()>&&)>;
     using AppBoundDomainsCallback = Function<void(CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&)>;
-    WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, SoftUpdateCallback&&, CreateContextConnectionCallback&&, AppBoundDomainsCallback&&);
+    WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, std::optional<unsigned> overrideServiceWorkerRegistrationCountTestingValue, SoftUpdateCallback&&, CreateContextConnectionCallback&&, AppBoundDomainsCallback&&);
 
     WEBCORE_EXPORT ~SWServer();
 
@@ -246,7 +246,9 @@
     WEBCORE_EXPORT void forEachClientForOrigin(const ClientOrigin&, const Function<void(ServiceWorkerClientData&)>&);
 
 private:
-    void validateRegistrationDomain(WebCore::RegistrableDomain, ServiceWorkerJobType, CompletionHandler<void(bool)>&&);
+    unsigned maxRegistrationCount();
+    bool allowLoopbackIPAddress(const String&);
+    void validateRegistrationDomain(WebCore::RegistrableDomain, ServiceWorkerJobType, bool, CompletionHandler<void(bool)>&&);
 
     void scriptFetchFinished(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationKey&, const WorkerFetchResult&);
 
@@ -313,6 +315,7 @@
     bool m_hasServiceWorkerEntitlement { false };
     bool m_hasReceivedAppBoundDomains { false };
     unsigned m_uniqueRegistrationCount { 0 };
+    std::optional<unsigned> m_overrideServiceWorkerRegistrationCountTestingValue;
     uint64_t m_focusOrder { 0 };
 };
 

Modified: trunk/Source/WebKit/ChangeLog (292866 => 292867)


--- trunk/Source/WebKit/ChangeLog	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/ChangeLog	2022-04-14 14:52:58 UTC (rev 292867)
@@ -1,3 +1,35 @@
+2022-04-14  Kate Cheney  <[email protected]>
+
+        WKWebView: navigator.serviceWorker.register method fails for a new version of an already registered service worker.
+        https://bugs.webkit.org/show_bug.cgi?id=229554
+        <rdar://problem/82388593>
+
+        Reviewed by Brent Fulgham.
+
+        Plumbing to override the max service worker registration count for
+        test purposes. See WebCore changelog for details.
+
+        * NetworkProcess/NetworkSession.cpp:
+        (WebKit::NetworkSession::NetworkSession):
+        (WebKit::NetworkSession::ensureSWServer):
+        * NetworkProcess/NetworkSession.h:
+        (WebKit::NetworkSession::overrideServiceWorkerRegistrationCountTestingValue const):
+        * NetworkProcess/NetworkSessionCreationParameters.cpp:
+        (WebKit::NetworkSessionCreationParameters::encode const):
+        (WebKit::NetworkSessionCreationParameters::decode):
+        * NetworkProcess/NetworkSessionCreationParameters.h:
+        * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
+        * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm:
+        (-[_WKWebsiteDataStoreConfiguration overrideServiceWorkerRegistrationCountTestingValue]):
+        (-[_WKWebsiteDataStoreConfiguration setOverrideServiceWorkerRegistrationCountTestingValue:]):
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::parameters):
+        * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
+        (WebKit::WebsiteDataStoreConfiguration::copy const):
+        * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
+        (WebKit::WebsiteDataStoreConfiguration::overrideServiceWorkerRegistrationCountTestingValue const):
+        (WebKit::WebsiteDataStoreConfiguration::setOverrideServiceWorkerRegistrationCountTestingValue):
+
 2022-04-14  Zan Dobersek  <[email protected]>
 
         [WK2] Enable more efficient encoding of synchronous-message reply arguments

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (292866 => 292867)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2022-04-14 14:52:58 UTC (rev 292867)
@@ -142,6 +142,7 @@
     , m_testSpeedMultiplier(parameters.testSpeedMultiplier)
     , m_allowsServerPreconnect(parameters.allowsServerPreconnect)
     , m_shouldRunServiceWorkersOnMainThreadForTesting(parameters.shouldRunServiceWorkersOnMainThreadForTesting)
+    , m_overrideServiceWorkerRegistrationCountTestingValue(parameters.overrideServiceWorkerRegistrationCountTestingValue)
     , m_storageManager(createNetworkStorageManager(networkProcess.parentProcessConnection(), parameters))
 #if ENABLE(BUILT_IN_NOTIFICATIONS)
     , m_notificationManager(*this, parameters.webPushMachServiceName)
@@ -647,7 +648,7 @@
             completionHandler({ });
         };
 #endif
-        m_swServer = makeUnique<SWServer>(makeUniqueRef<WebSWOriginStore>(), info.processTerminationDelayEnabled, WTFMove(path), m_sessionID, shouldRunServiceWorkersOnMainThreadForTesting(), m_networkProcess->parentProcessHasServiceWorkerEntitlement(), [this](auto&& jobData, bool shouldRefreshCache, auto&& request, auto&& completionHandler) mutable {
+        m_swServer = makeUnique<SWServer>(makeUniqueRef<WebSWOriginStore>(), info.processTerminationDelayEnabled, WTFMove(path), m_sessionID, shouldRunServiceWorkersOnMainThreadForTesting(), m_networkProcess->parentProcessHasServiceWorkerEntitlement(), overrideServiceWorkerRegistrationCountTestingValue(), [this](auto&& jobData, bool shouldRefreshCache, auto&& request, auto&& completionHandler) mutable {
             ServiceWorkerSoftUpdateLoader::start(this, WTFMove(jobData), shouldRefreshCache, WTFMove(request), WTFMove(completionHandler));
         }, [this](auto& registrableDomain, std::optional<ProcessIdentifier> requestingProcessIdentifier, std::optional<ScriptExecutionContextIdentifier> serviceWorkerPageIdentifier, auto&& completionHandler) {
             ASSERT(!registrableDomain.isEmpty());

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (292866 => 292867)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2022-04-14 14:52:58 UTC (rev 292867)
@@ -189,7 +189,7 @@
     unsigned testSpeedMultiplier() const { return m_testSpeedMultiplier; }
     bool allowsServerPreconnect() const { return m_allowsServerPreconnect; }
     bool shouldRunServiceWorkersOnMainThreadForTesting() const { return m_shouldRunServiceWorkersOnMainThreadForTesting; }
-
+    std::optional<unsigned> overrideServiceWorkerRegistrationCountTestingValue() const { return m_overrideServiceWorkerRegistrationCountTestingValue; }
     bool isStaleWhileRevalidateEnabled() const { return m_isStaleWhileRevalidateEnabled; }
 
     void lowMemoryHandler(WTF::Critical);
@@ -302,7 +302,7 @@
     unsigned m_testSpeedMultiplier { 1 };
     bool m_allowsServerPreconnect { true };
     bool m_shouldRunServiceWorkersOnMainThreadForTesting { false };
-
+    std::optional<unsigned> m_overrideServiceWorkerRegistrationCountTestingValue;
 #if ENABLE(SERVICE_WORKER)
     HashSet<std::unique_ptr<ServiceWorkerSoftUpdateLoader>> m_softUpdateLoaders;
     HashMap<WebCore::FetchIdentifier, WeakPtr<ServiceWorkerFetchTask>> m_navigationPreloaders;

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp (292866 => 292867)


--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp	2022-04-14 14:52:58 UTC (rev 292867)
@@ -85,6 +85,7 @@
     encoder << allowsServerPreconnect;
     encoder << requiresSecureHTTPSProxyConnection;
     encoder << shouldRunServiceWorkersOnMainThreadForTesting;
+    encoder << overrideServiceWorkerRegistrationCountTestingValue;
     encoder << preventsSystemHTTPProxyAuthentication;
     encoder << appHasRequestedCrossWebsiteTrackingPermission;
     encoder << useNetworkLoader;
@@ -302,6 +303,11 @@
     if (!shouldRunServiceWorkersOnMainThreadForTesting)
         return std::nullopt;
     
+    std::optional<std::optional<unsigned>> overrideServiceWorkerRegistrationCountTestingValue;
+    decoder >> overrideServiceWorkerRegistrationCountTestingValue;
+    if (!overrideServiceWorkerRegistrationCountTestingValue)
+        return std::nullopt;
+
     std::optional<bool> preventsSystemHTTPProxyAuthentication;
     decoder >> preventsSystemHTTPProxyAuthentication;
     if (!preventsSystemHTTPProxyAuthentication)
@@ -467,6 +473,7 @@
         , WTFMove(*allowsServerPreconnect)
         , WTFMove(*requiresSecureHTTPSProxyConnection)
         , *shouldRunServiceWorkersOnMainThreadForTesting
+        , WTFMove(*overrideServiceWorkerRegistrationCountTestingValue)
         , WTFMove(*preventsSystemHTTPProxyAuthentication)
         , WTFMove(*appHasRequestedCrossWebsiteTrackingPermission)
         , WTFMove(*useNetworkLoader)

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h (292866 => 292867)


--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h	2022-04-14 14:52:58 UTC (rev 292867)
@@ -101,6 +101,7 @@
     bool allowsServerPreconnect { true };
     bool requiresSecureHTTPSProxyConnection { false };
     bool shouldRunServiceWorkersOnMainThreadForTesting { false };
+    std::optional<unsigned> overrideServiceWorkerRegistrationCountTestingValue;
     bool preventsSystemHTTPProxyAuthentication { false };
     bool appHasRequestedCrossWebsiteTrackingPermission { false };
     bool useNetworkLoader { false };

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h (292866 => 292867)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h	2022-04-14 14:52:58 UTC (rev 292867)
@@ -53,6 +53,7 @@
 @property (nonatomic) BOOL preventsSystemHTTPProxyAuthentication WK_API_AVAILABLE(macos(11.0), ios(14.0));
 @property (nonatomic) BOOL requiresSecureHTTPSProxyConnection WK_API_AVAILABLE(macos(11.0), ios(14.0));
 @property (nonatomic) BOOL shouldRunServiceWorkersOnMainThreadForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic) NSUInteger overrideServiceWorkerRegistrationCountTestingValue WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 // FIXME: rdar://86641948 Remove acceptInsecureCertificatesForWebSockets once HAVE(NSURLSESSION_WEBSOCKET) is supported on all Cocoa platforms.
 @property (nonatomic, setter=_setShouldAcceptInsecureCertificatesForWebSockets:) BOOL _shouldAcceptInsecureCertificatesForWebSockets WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm (292866 => 292867)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm	2022-04-14 14:52:58 UTC (rev 292867)
@@ -506,6 +506,16 @@
     _configuration->setShouldRunServiceWorkersOnMainThreadForTesting(shouldRunOnMainThread);
 }
 
+- (NSUInteger)overrideServiceWorkerRegistrationCountTestingValue
+{
+    return _configuration->overrideServiceWorkerRegistrationCountTestingValue().value_or(0);
+}
+
+- (void)setOverrideServiceWorkerRegistrationCountTestingValue:(NSUInteger)count
+{
+    _configuration->setOverrideServiceWorkerRegistrationCountTestingValue(count);
+}
+
 - (BOOL)_shouldAcceptInsecureCertificatesForWebSockets
 {
 #if !HAVE(NSURLSESSION_WEBSOCKET)

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (292866 => 292867)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2022-04-14 14:52:58 UTC (rev 292867)
@@ -1857,6 +1857,7 @@
     networkSessionParameters.resourceLoadStatisticsParameters = WTFMove(resourceLoadStatisticsParameters);
     networkSessionParameters.requiresSecureHTTPSProxyConnection = m_configuration->requiresSecureHTTPSProxyConnection();
     networkSessionParameters.shouldRunServiceWorkersOnMainThreadForTesting = m_configuration->shouldRunServiceWorkersOnMainThreadForTesting();
+    networkSessionParameters.overrideServiceWorkerRegistrationCountTestingValue = m_configuration->overrideServiceWorkerRegistrationCountTestingValue();
     networkSessionParameters.preventsSystemHTTPProxyAuthentication = m_configuration->preventsSystemHTTPProxyAuthentication();
     networkSessionParameters.allowsHSTSWithUntrustedRootCertificate = m_configuration->allowsHSTSWithUntrustedRootCertificate();
     networkSessionParameters.pcmMachServiceName = m_configuration->pcmMachServiceName();

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp (292866 => 292867)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp	2022-04-14 14:52:58 UTC (rev 292867)
@@ -105,6 +105,7 @@
     copy->m_allowsServerPreconnect = this->m_allowsServerPreconnect;
     copy->m_requiresSecureHTTPSProxyConnection = this->m_requiresSecureHTTPSProxyConnection;
     copy->m_shouldRunServiceWorkersOnMainThreadForTesting = this->m_shouldRunServiceWorkersOnMainThreadForTesting;
+    copy->m_overrideServiceWorkerRegistrationCountTestingValue = this->m_overrideServiceWorkerRegistrationCountTestingValue;
     copy->m_preventsSystemHTTPProxyAuthentication = this->m_preventsSystemHTTPProxyAuthentication;
     copy->m_standaloneApplicationURL = this->m_standaloneApplicationURL;
     copy->m_enableInAppBrowserPrivacyForTesting = this->m_enableInAppBrowserPrivacyForTesting;

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h (292866 => 292867)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h	2022-04-14 14:52:58 UTC (rev 292867)
@@ -183,6 +183,8 @@
 
     bool shouldRunServiceWorkersOnMainThreadForTesting() const { return m_shouldRunServiceWorkersOnMainThreadForTesting; }
     void setShouldRunServiceWorkersOnMainThreadForTesting(bool shouldRunOnMainThread) { m_shouldRunServiceWorkersOnMainThreadForTesting = shouldRunOnMainThread; }
+    std::optional<unsigned> overrideServiceWorkerRegistrationCountTestingValue() const { return m_overrideServiceWorkerRegistrationCountTestingValue; }
+    void setOverrideServiceWorkerRegistrationCountTestingValue(unsigned count) { m_overrideServiceWorkerRegistrationCountTestingValue = count; }
 
     const URL& standaloneApplicationURL() const { return m_standaloneApplicationURL; }
     void setStandaloneApplicationURL(URL&& url) { m_standaloneApplicationURL = WTFMove(url); }
@@ -255,6 +257,7 @@
     bool m_preventsSystemHTTPProxyAuthentication { false };
     bool m_requiresSecureHTTPSProxyConnection { false };
     bool m_shouldRunServiceWorkersOnMainThreadForTesting { false };
+    std::optional<unsigned> m_overrideServiceWorkerRegistrationCountTestingValue;
     unsigned m_testSpeedMultiplier { 1 };
     URL m_standaloneApplicationURL;
     bool m_enableInAppBrowserPrivacyForTesting { false };

Modified: trunk/Tools/ChangeLog (292866 => 292867)


--- trunk/Tools/ChangeLog	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Tools/ChangeLog	2022-04-14 14:52:58 UTC (rev 292867)
@@ -1,3 +1,23 @@
+2022-04-14  Kate Cheney  <[email protected]>
+
+        WKWebView: navigator.serviceWorker.register method fails for a new version of an already registered service worker.
+        https://bugs.webkit.org/show_bug.cgi?id=229554
+        <rdar://problem/82388593>
+
+        Reviewed by Brent Fulgham.
+
+        Adds a new test for re-registering and an overdue test for
+        unregistering now that we have the infrastructure. This also does some
+        refactoring to reduce duplicate code.
+
+        * TestWebKitAPI/Info.plist:
+        Update the Info.plist to consider localhost an app-bound domain so we
+        can test the max count when overriding the loopback IP. This requires
+        replacing an existing domain to stay under the count limit.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+        (TEST):
+
 2022-04-13  Chris Dumez  <[email protected]>
 
         Replace calls to substring(0, x) with the more concise left(x)

Modified: trunk/Tools/TestWebKitAPI/Info.plist (292866 => 292867)


--- trunk/Tools/TestWebKitAPI/Info.plist	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Tools/TestWebKitAPI/Info.plist	2022-04-14 14:52:58 UTC (rev 292867)
@@ -20,7 +20,7 @@
 		<string>https://www.apple.com/iphone/</string>
 		<string>http://www.example.com/</string>
 		<string>http://bar.com/</string>
-		<string>http://foo.com/</string>
+		<string>localhost</string>
 		<string>https://searchforlongboards.biz</string>
 		<string>app-bound-custom-scheme:</string>
 		<string>longboardshop.biz</string>

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (292866 => 292867)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2022-04-14 14:36:17 UTC (rev 292866)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2022-04-14 14:52:58 UTC (rev 292867)
@@ -43,6 +43,7 @@
 #import <WebKit/WKWebsiteDataStorePrivate.h>
 #import <WebKit/_WKUserContentWorld.h>
 #import <WebKit/_WKUserStyleSheet.h>
+#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 #import <wtf/RunLoop.h>
 #import <wtf/text/WTFString.h>
 
@@ -270,7 +271,7 @@
     initializeInAppBrowserPrivacyTestSettings();
     isDone = false;
     [[WKWebsiteDataStore defaultDataStore] _appBoundDomains:^(NSArray<NSString *> *domains) {
-        NSArray *domainsToCompare = @[@"apple.com", @"bar.com", @"example.com", @"foo.com", @"longboardshop.biz", @"searchforlongboards.biz", @"testdomain1",  @"webkit.org"];
+        NSArray *domainsToCompare = @[@"apple.com", @"bar.com", @"example.com", @"localhost", @"longboardshop.biz", @"searchforlongboards.biz", @"testdomain1",  @"webkit.org"];
 
         NSArray *sortedDomains = [domains sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
 
@@ -877,6 +878,30 @@
 </script>
 )SWRESOURCE"_s;
 
+static constexpr auto mainReregisterBytes = R"SWRESOURCE(
+<script>
+
+function log(msg)
+{
+    window.webkit.messageHandlers.sw.postMessage(msg);
+}
+
+try {
+navigator.serviceWorker.register('/sw.js?v1').then(function(reg) {
+    navigator.serviceWorker.register('/sw.js?v2')
+    .then(() => log("Reregistration success"))
+    .catch(error => log("Reregistration failed " + error));
+
+}).catch(function(error) {
+    log("Registration failed with: " + error);
+});
+} catch(e) {
+    log("Exception: " + e);
+}
+
+</script>
+)SWRESOURCE"_s;
+
 static constexpr auto scriptBytes = R"SWRESOURCE(
 
 self.addEventListener("message", (event) => {
@@ -885,9 +910,8 @@
 
 )SWRESOURCE"_s;
 
-TEST(InAppBrowserPrivacy, AppBoundDomainAllowsServiceWorkers)
+static RetainPtr<WKWebView> setUpSWTest(WKWebsiteDataStore *dataStore)
 {
-    initializeInAppBrowserPrivacyTestSettings();
     isDone = false;
 
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -895,38 +919,25 @@
     [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
     [configuration preferences]._serviceWorkerEntitlementDisabledForTesting = YES;
     [configuration setLimitsNavigationsToAppBoundDomains:YES];
+    [configuration setWebsiteDataStore:dataStore];
 
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
-
-    TestWebKitAPI::HTTPServer server({
-        { "/main.html"_s, { mainBytes } },
-        { "/sw.js"_s, { { { "Content-Type"_s, "application/_javascript_"_s } }, scriptBytes } },
-    });
-
     [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
 
     // Start with a clean slate data store
-    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+    [dataStore removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
         isDone = true;
     }];
     TestWebKitAPI::Util::run(&isDone);
     isDone = false;
-    
-    // Expect the service worker load to complete successfully.
-    expectedMessage = "Message from worker: ServiceWorker received: Hello from an app-bound domain"_s;
-    [webView loadRequest:server.requestWithLocalhost("/main.html")];
-    TestWebKitAPI::Util::run(&isDone);
-    isDone = false;
 
-    [[WKWebsiteDataStore defaultDataStore] fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeServiceWorkerRegistrations] completionHandler:^(NSArray<WKWebsiteDataRecord *> *websiteDataRecords) {
-        EXPECT_EQ(1u, [websiteDataRecords count]);
-        EXPECT_WK_STREQ(websiteDataRecords[0].displayName, "localhost");
-        isDone = true;
-    }];
+    return webView;
+}
 
-    TestWebKitAPI::Util::run(&isDone);
+
+static void cleanUpSWTest(WKWebView *webView)
+{
     isDone = false;
-
     // Reset service worker entitlement.
     [webView _clearServiceWorkerEntitlementOverride:^(void) {
         cleanUpInAppBrowserPrivacyTestSettings();
@@ -942,31 +953,45 @@
     isDone = false;
 }
 
-TEST(InAppBrowserPrivacy, UnregisterServiceWorker)
+TEST(InAppBrowserPrivacy, AppBoundDomainAllowsServiceWorkers)
 {
     initializeInAppBrowserPrivacyTestSettings();
-    isDone = false;
 
-    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    auto messageHandler = adoptNS([[SWInAppBrowserPrivacyMessageHandler alloc] init]);
-    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
-    [configuration preferences]._serviceWorkerEntitlementDisabledForTesting = YES;
-    [configuration setLimitsNavigationsToAppBoundDomains:YES];
+    auto webView = setUpSWTest([WKWebsiteDataStore defaultDataStore]);
 
-    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
-
     TestWebKitAPI::HTTPServer server({
-        { "/main.html"_s, { mainUnregisterBytes } },
+        { "/main.html"_s, { mainBytes } },
         { "/sw.js"_s, { { { "Content-Type"_s, "application/_javascript_"_s } }, scriptBytes } },
     });
 
-    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
-    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+    // Expect the service worker load to complete successfully.
+    expectedMessage = "Message from worker: ServiceWorker received: Hello from an app-bound domain"_s;
+    [webView loadRequest:server.requestWithLocalhost("/main.html")];
+    TestWebKitAPI::Util::run(&isDone);
+    isDone = false;
+
+    [[WKWebsiteDataStore defaultDataStore] fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeServiceWorkerRegistrations] completionHandler:^(NSArray<WKWebsiteDataRecord *> *websiteDataRecords) {
+        EXPECT_EQ(1u, [websiteDataRecords count]);
+        EXPECT_WK_STREQ(websiteDataRecords[0].displayName, "localhost");
         isDone = true;
     }];
+
     TestWebKitAPI::Util::run(&isDone);
+    cleanUpSWTest(webView.get());
+}
+
+TEST(InAppBrowserPrivacy, UnregisterServiceWorker)
+{
+    initializeInAppBrowserPrivacyTestSettings();
     isDone = false;
 
+    auto webView = setUpSWTest([WKWebsiteDataStore defaultDataStore]);
+
+    TestWebKitAPI::HTTPServer server({
+        { "/main.html"_s, { mainUnregisterBytes } },
+        { "/sw.js"_s, { { { "Content-Type"_s, "application/_javascript_"_s } }, scriptBytes } },
+    });
+
     expectedMessage = "Unregistration success"_s;
     [webView loadRequest:server.requestWithLocalhost("/main.html")];
     TestWebKitAPI::Util::run(&isDone);
@@ -979,21 +1004,64 @@
     }];
 
     TestWebKitAPI::Util::run(&isDone);
+    cleanUpSWTest(webView.get());
+}
+
+TEST(InAppBrowserPrivacy, UnregisterServiceWorkerMaxRegistrationCount)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    auto websiteDataStoreConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] init]);
+    [websiteDataStoreConfiguration setOverrideServiceWorkerRegistrationCountTestingValue:1];
+    auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:websiteDataStoreConfiguration.get()]);
+    auto webView = setUpSWTest(dataStore.get());
+
+    TestWebKitAPI::HTTPServer server({
+        { "/main.html"_s, { mainUnregisterBytes } },
+        { "/sw.js"_s, { { { "Content-Type"_s, "application/_javascript_"_s } }, scriptBytes } },
+    });
+
+    expectedMessage = "Unregistration success"_s;
+    [webView loadRequest:server.requestWithLocalhost("/main.html")];
+    TestWebKitAPI::Util::run(&isDone);
+
     isDone = false;
 
-    // Reset service worker entitlement.
-    [webView _clearServiceWorkerEntitlementOverride:^(void) {
-        cleanUpInAppBrowserPrivacyTestSettings();
+    [dataStore fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeServiceWorkerRegistrations] completionHandler:^(NSArray<WKWebsiteDataRecord *> *websiteDataRecords) {
+        EXPECT_EQ(0u, [websiteDataRecords count]);
         isDone = true;
     }];
+
     TestWebKitAPI::Util::run(&isDone);
+    cleanUpSWTest(webView.get());
+}
+
+TEST(InAppBrowserPrivacy, ReregisterServiceWorkerMaxRegistrationCount)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    auto websiteDataStoreConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] init]);
+    [websiteDataStoreConfiguration setOverrideServiceWorkerRegistrationCountTestingValue:1];
+    auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:websiteDataStoreConfiguration.get()]);
+    auto webView = setUpSWTest(dataStore.get());
+
+    TestWebKitAPI::HTTPServer server({
+        { "/main.html"_s, { mainReregisterBytes } },
+        { "/sw.js?v1"_s, { { { "Content-Type"_s, "application/_javascript_"_s } }, scriptBytes } },
+        { "/sw.js?v2"_s, { { { "Content-Type"_s, "application/_javascript_"_s } }, scriptBytes } },
+    });
+
+    expectedMessage = "Reregistration success"_s;
+    [webView loadRequest:server.requestWithLocalhost("/main.html")];
+    TestWebKitAPI::Util::run(&isDone);
+
     isDone = false;
-    
-    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+
+    [dataStore fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeServiceWorkerRegistrations] completionHandler:^(NSArray<WKWebsiteDataRecord *> *websiteDataRecords) {
+        EXPECT_EQ(1u, [websiteDataRecords count]);
         isDone = true;
     }];
+
     TestWebKitAPI::Util::run(&isDone);
-    isDone = false;
+    cleanUpSWTest(webView.get());
 }
 
 TEST(InAppBrowserPrivacy, NonAppBoundDomainDoesNotAllowServiceWorkers)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to