Title: [293241] branches/safari-613.2.7.1-branch

Diff

Modified: branches/safari-613.2.7.1-branch/Source/WebKit/ChangeLog (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Source/WebKit/ChangeLog	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Source/WebKit/ChangeLog	2022-04-22 20:14:25 UTC (rev 293241)
@@ -1,5 +1,29 @@
 2022-04-22  Russell Epstein  <repst...@apple.com>
 
+        Apply patch. rdar://problem/91288849
+
+    2022-04-21  Youenn Fablet  <you...@apple.com>
+
+            In case of COOP-based process swap, we need to make sure the document gets controlled by its matching service worker registration
+            https://bugs.webkit.org/show_bug.cgi?id=238800
+            <rdar://problem/91288849>
+
+            Reviewed by Chris Dumez.
+
+            Make sure in case loader is transferred to call controlClient in the new WebProcess.
+            To do so, we also update page and frame IDs.
+            Covered by API test.
+
+            * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+            * NetworkProcess/NetworkLoadParameters.h:
+            * NetworkProcess/NetworkResourceLoadParameters.h:
+            * NetworkProcess/NetworkResourceLoader.cpp:
+            * NetworkProcess/NetworkResourceLoader.h:
+            * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+            * NetworkProcess/ServiceWorker/WebSWServerConnection.h:
+
+2022-04-22  Russell Epstein  <repst...@apple.com>
+
         Cherry-pick r291724. rdar://problem/91975589
 
     Expose the AX tree of PDFs loaded via iframes on the Mac

Modified: branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2022-04-22 20:14:25 UTC (rev 293241)
@@ -540,7 +540,7 @@
             if (auto existingLoader = session->takeLoaderAwaitingWebProcessTransfer(*existingLoaderToResume)) {
                 CONNECTION_RELEASE_LOG(Loading, "scheduleResourceLoad: Resuming existing NetworkResourceLoader");
                 m_networkResourceLoaders.add(identifier, *existingLoader);
-                existingLoader->transferToNewWebProcess(*this, identifier);
+                existingLoader->transferToNewWebProcess(*this, loadParameters);
                 return;
             }
             CONNECTION_RELEASE_LOG_ERROR(Loading, "scheduleResourceLoad: Could not find existing NetworkResourceLoader to resume, will do a fresh load");

Modified: branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkLoadParameters.h (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkLoadParameters.h	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkLoadParameters.h	2022-04-22 20:14:25 UTC (rev 293241)
@@ -44,9 +44,9 @@
 
 class NetworkLoadParameters {
 public:
-    WebPageProxyIdentifier webPageProxyID;
-    WebCore::PageIdentifier webPageID;
-    WebCore::FrameIdentifier webFrameID;
+    mutable WebPageProxyIdentifier webPageProxyID;
+    mutable WebCore::PageIdentifier webPageID;
+    mutable WebCore::FrameIdentifier webFrameID;
     RefPtr<WebCore::SecurityOrigin> topOrigin;
     RefPtr<WebCore::SecurityOrigin> sourceOrigin;
     WTF::ProcessID parentPID { 0 };

Modified: branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h	2022-04-22 20:14:25 UTC (rev 293241)
@@ -56,7 +56,7 @@
     Vector<RefPtr<SandboxExtension>> requestBodySandboxExtensions; // Created automatically for the sender.
     RefPtr<SandboxExtension> resourceSandboxExtension; // Created automatically for the sender.
     mutable Seconds maximumBufferingTime;
-    WebCore::FetchOptions options;
+    mutable WebCore::FetchOptions options;
     std::optional<WebCore::ContentSecurityPolicyResponseHeaders> cspResponseHeaders;
     WebCore::CrossOriginEmbedderPolicy parentCrossOriginEmbedderPolicy;
     WebCore::CrossOriginEmbedderPolicy crossOriginEmbedderPolicy;

Modified: branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2022-04-22 20:14:25 UTC (rev 293241)
@@ -537,13 +537,21 @@
     cleanup(LoadResult::Cancel);
 }
 
-void NetworkResourceLoader::transferToNewWebProcess(NetworkConnectionToWebProcess& newConnection, WebCore::ResourceLoaderIdentifier newCoreIdentifier)
+void NetworkResourceLoader::transferToNewWebProcess(NetworkConnectionToWebProcess& newConnection, const NetworkResourceLoadParameters& parameters)
 {
     m_connection = newConnection;
-    m_parameters.identifier = newCoreIdentifier;
+    m_parameters.identifier = parameters.identifier;
+    m_parameters.webPageProxyID = parameters.webPageProxyID;
+    m_parameters.webPageID = parameters.webPageID;
+    m_parameters.webFrameID = parameters.webFrameID;
+    m_parameters.options.clientIdentifier = parameters.options.clientIdentifier;
 
 #if ENABLE(SERVICE_WORKER)
     ASSERT(m_responseCompletionHandler || m_cacheEntryWaitingForContinueDidReceiveResponse || m_serviceWorkerFetchTask);
+    if (m_serviceWorkerRegistration) {
+        if (auto* swConnection = newConnection.swConnection())
+            swConnection->transferServiceWorkerLoadToNewWebProcess(*this, *m_serviceWorkerRegistration);
+    }
 #else
     ASSERT(m_responseCompletionHandler || m_cacheEntryWaitingForContinueDidReceiveResponse);
 #endif
@@ -1140,6 +1148,7 @@
 
 #if ENABLE(SERVICE_WORKER)
     if (parameters().options.mode == FetchOptions::Mode::Navigate) {
+        m_serviceWorkerRegistration = { };
         if (auto serviceWorkerFetchTask = m_connection->createFetchTask(*this, newRequest)) {
             LOADER_RELEASE_LOG("continueWillSendRequest: Created a ServiceWorkerFetchTask to handle the redirect (fetchIdentifier=%" PRIu64 ")", serviceWorkerFetchTask->fetchIdentifier().toUInt64());
             m_networkLoad = nullptr;

Modified: branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.h (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.h	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.h	2022-04-22 20:14:25 UTC (rev 293241)
@@ -38,6 +38,7 @@
 #include <WebCore/CrossOriginAccessControl.h>
 #include <WebCore/PrivateClickMeasurement.h>
 #include <WebCore/ResourceResponse.h>
+#include <WebCore/SWServerRegistration.h>
 #include <WebCore/SecurityPolicyViolationEvent.h>
 #include <WebCore/SharedBuffer.h>
 #include <WebCore/Timer.h>
@@ -87,7 +88,7 @@
     void start();
     void abort();
 
-    void transferToNewWebProcess(NetworkConnectionToWebProcess&, WebCore::ResourceLoaderIdentifier);
+    void transferToNewWebProcess(NetworkConnectionToWebProcess&, const NetworkResourceLoadParameters&);
 
     // Message handlers.
     void didReceiveNetworkResourceLoaderMessage(IPC::Connection&, IPC::Decoder&);
@@ -146,6 +147,7 @@
 #if ENABLE(SERVICE_WORKER)
     void startWithServiceWorker();
     void serviceWorkerDidNotHandle(ServiceWorkerFetchTask*);
+    void setServiceWorkerRegistration(WebCore::SWServerRegistration& serviceWorkerRegistration) { m_serviceWorkerRegistration = serviceWorkerRegistration; }
 #endif
 
     std::optional<WebCore::ResourceError> doCrossOriginOpenerHandlingOfResponse(const WebCore::ResourceResponse&);
@@ -256,6 +258,7 @@
     std::optional<NetworkActivityTracker> m_networkActivityTracker;
 #if ENABLE(SERVICE_WORKER)
     std::unique_ptr<ServiceWorkerFetchTask> m_serviceWorkerFetchTask;
+    WeakPtr<WebCore::SWServerRegistration> m_serviceWorkerRegistration;
 #endif
     NetworkResourceLoadIdentifier m_resourceLoadID;
     WebCore::ResourceResponse m_redirectResponse;

Modified: branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp	2022-04-22 20:14:25 UTC (rev 293241)
@@ -185,6 +185,7 @@
 
         serviceWorkerRegistrationIdentifier = registration->identifier();
         controlClient(*loader.parameters().options.clientIdentifier, *registration, request);
+        loader.setServiceWorkerRegistration(*registration);
     } else {
         if (!loader.parameters().serviceWorkerRegistrationIdentifier)
             return nullptr;
@@ -582,6 +583,11 @@
     callback(registration->navigationPreloadState());
 }
 
+void WebSWServerConnection::transferServiceWorkerLoadToNewWebProcess(NetworkResourceLoader& loader, WebCore::SWServerRegistration& registration)
+{
+    controlClient(*loader.parameters().options.clientIdentifier, registration, loader.originalRequest());
+}
+
 } // namespace WebKit
 
 #undef CONNECTION_MESSAGE_CHECK_COMPLETION

Modified: branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h	2022-04-22 20:14:25 UTC (rev 293241)
@@ -83,6 +83,8 @@
     std::unique_ptr<ServiceWorkerFetchTask> createFetchTask(NetworkResourceLoader&, const WebCore::ResourceRequest&);
     void fetchTaskTimedOut(WebCore::ServiceWorkerIdentifier);
 
+    void transferServiceWorkerLoadToNewWebProcess(NetworkResourceLoader&, WebCore::SWServerRegistration&);
+
 private:
     // Implement SWServer::Connection (Messages to the client WebProcess)
     void rejectJobInClient(WebCore::ServiceWorkerJobIdentifier, const WebCore::ExceptionData&) final;

Modified: branches/safari-613.2.7.1-branch/Tools/ChangeLog (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Tools/ChangeLog	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Tools/ChangeLog	2022-04-22 20:14:25 UTC (rev 293241)
@@ -1,3 +1,17 @@
+2022-04-22  Russell Epstein  <repst...@apple.com>
+
+        Apply patch. rdar://problem/91288849
+
+    2022-04-21  Youenn Fablet  <you...@apple.com>
+
+            In case of COOP-based process swap, we need to make sure the document gets controlled by its matching service worker registration
+            https://bugs.webkit.org/show_bug.cgi?id=238800
+            <rdar://problem/91288849>
+
+            Reviewed by Chris Dumez.
+
+            * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+
 2022-04-19  Alan Coon  <alanc...@apple.com>
 
         Cherry-pick r292680. rdar://problem/91323230

Modified: branches/safari-613.2.7.1-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm (293240 => 293241)


--- branches/safari-613.2.7.1-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2022-04-22 20:14:04 UTC (rev 293240)
+++ branches/safari-613.2.7.1-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2022-04-22 20:14:25 UTC (rev 293241)
@@ -2802,3 +2802,176 @@
     }
     TestWebKitAPI::Util::run(&done);
 }
+
+static constexpr auto ServiceWorkerWindowClientNavigateMain =
+"<div>test page</div>"
+"<script>"
+"let worker;"
+"async function registerServiceWorker() {"
+"    try {"
+"        const registration = await navigator.serviceWorker.register('/sw.js');"
+"        if (registration.active) {"
+"            worker = registration.active;"
+"            alert('already active');"
+"            return;"
+"        }"
+"        worker = registration.installing;"
+"        worker.addEventListener('statechange', () => {"
+"            if (worker.state == 'activated')"
+"                alert('successfully registered');"
+"        });"
+"    } catch(e) {"
+"        alert('Exception: ' + e);"
+"    }"
+"}"
+"window._onload_ = async () => {"
+"   await registerServiceWorker();"
+"   navigator.serviceWorker._onmessage_ = (event) => {"
+"       if (event.data.navigateOtherClientToURL)"
+"           window.location = event.data.navigateOtherClientToURL;"
+"   };"
+"};"
+""
+"function navigateOtherClientToURL(url) {"
+"    worker.postMessage({navigateOtherClientToURL: url});"
+"    navigator.serviceWorker._onmessage_ = (event) => {"
+"        alert(event.data);"
+"    };"
+"}"
+""
+"function countServiceWorkerClients() {"
+"    worker.postMessage('countServiceWorkerClients');"
+"    navigator.serviceWorker._onmessage_ = (event) => {"
+"        alert(event.data);"
+"    };"
+"}"
+""
+"function openWindowToURL(url) {"
+"    worker.postMessage({openWindowToURL: url});"
+"    navigator.serviceWorker._onmessage_ = (event) => {"
+"        alert(event.data);"
+"    };"
+"}"
+"</script>"_s;
+
+static constexpr auto ServiceWorkerWindowClientNavigateJS =
+"async function waitForClientToDisappear(clientId, counter) {"
+"    if (!counter)"
+"        counter = 0;"
+"    else if (counter >= 100)"
+"        return 'fail';"
+"    const currentClients = await self.clients.matchAll();"
+"    for (let client of currentClients) {"
+"       if (client.id == clientId) {"
+"           await new Promise(resolve => setTimeout(resolve, 50));"
+"           return waitForClientToDisappear(clientId, ++counter);"
+"       }"
+"    }"
+"    return 'pass';"
+"}"
+"self.addEventListener('message', async (event) => {"
+"   if (event.data && event.data.navigateOtherClientToURL) {"
+"       let otherClient;"
+"       let currentClients = await self.clients.matchAll();"
+"       for (let client of currentClients) {"
+"           if (client.id !== event.source.id)"
+"               otherClient = client;"
+"       }"
+"       if (!otherClient) {"
+"           event.source.postMessage('failed, no other client, client number = ' + currentClients.length);"
+"           return;"
+"       }"
+"       otherClient.postMessage(event.data);"
+"       event.source.postMessage(await waitForClientToDisappear(otherClient.id));"
+"       return;"
+"   }"
+"   if (event.data ="" 'countServiceWorkerClients') {"
+"       let currentClients = await self.clients.matchAll();"
+"       event.source.postMessage(currentClients.length + ' client(s)');"
+"       return;"
+"   }"
+"});"_s;
+
+static bool shouldServiceWorkerPSONNavigationDelegateAllowNavigation = true;
+static bool shouldServiceWorkerPSONNavigationDelegateAllowNavigationResponse = true;
+@interface ServiceWorkerPSONNavigationDelegate : NSObject <WKNavigationDelegatePrivate> {
+    @public void (^decidePolicyForNavigationAction)(WKNavigationAction *, void (^)(WKNavigationActionPolicy));
+    @public void (^didStartProvisionalNavigationHandler)();
+    @public void (^didCommitNavigationHandler)();
+}
+@end
+
+@implementation ServiceWorkerPSONNavigationDelegate
+
+- (instancetype) init
+{
+    self = [super init];
+    return self;
+}
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
+{
+    decisionHandler(shouldServiceWorkerPSONNavigationDelegateAllowNavigation ? WKNavigationActionPolicyAllow : WKNavigationActionPolicyCancel);
+}
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
+{
+    decisionHandler(shouldServiceWorkerPSONNavigationDelegateAllowNavigationResponse ? WKNavigationResponsePolicyAllow : WKNavigationResponsePolicyCancel);
+}
+
+@end
+
+TEST(ServiceWorker, WindowClientNavigateCOOP)
+{
+    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
+
+    // Start with a clean slate data store
+    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) {
+        if ([feature.key isEqualToString:@"CrossOriginOpenerPolicyEnabled"])
+            [[configuration preferences] _setEnabled:YES forExperimentalFeature:feature];
+        else if ([feature.key isEqualToString:@"CrossOriginEmbedderPolicyEnabled"])
+            [[configuration preferences] _setEnabled:YES forExperimentalFeature:feature];
+    }
+
+    auto webView1 = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+    auto webView2 = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+
+    TestWebKitAPI::HTTPServer server({
+        { "/"_s, { ServiceWorkerWindowClientNavigateMain } },
+        { "/?test"_s, { ServiceWorkerWindowClientNavigateMain } },
+        { "/?fail1"_s, { ServiceWorkerWindowClientNavigateMain } },
+        { "/?fail2"_s, { ServiceWorkerWindowClientNavigateMain } },
+        { "/?swap"_s, { {{ "Content-Type"_s, "application/html"_s }, { "Cross-Origin-Opener-Policy"_s, "same-origin"_s } }, ServiceWorkerWindowClientNavigateMain } },
+        { "/sw.js"_s, { {{ "Content-Type"_s, "application/_javascript_"_s }}, ServiceWorkerWindowClientNavigateJS } }
+    }, TestWebKitAPI::HTTPServer::Protocol::Http, nullptr, nullptr, 8091);
+
+    [webView1 loadRequest:server.request()];
+    EXPECT_WK_STREQ([webView1 _test_waitForAlert], "successfully registered");
+
+    [webView1 evaluateJavaScript:@"countServiceWorkerClients()" completionHandler: nil];
+    EXPECT_WK_STREQ([webView1 _test_waitForAlert], "0 client(s)");
+
+    [webView2 loadRequest:server.request()];
+    EXPECT_WK_STREQ([webView2 _test_waitForAlert], "already active");
+
+    [webView1 evaluateJavaScript:@"countServiceWorkerClients()" completionHandler: nil];
+    EXPECT_WK_STREQ([webView1 _test_waitForAlert], "1 client(s)");
+
+    auto navigationDelegate = adoptNS([[ServiceWorkerPSONNavigationDelegate alloc] init]);
+    [webView2 setNavigationDelegate:navigationDelegate.get()];
+
+    auto *baseURL = [[server.request() URL] absoluteString];
+
+    [webView1 evaluateJavaScript:[NSString stringWithFormat:@"navigateOtherClientToURL('%@?swap')", baseURL] completionHandler: nil];
+    EXPECT_WK_STREQ([webView1 _test_waitForAlert], "pass");
+
+    [webView1 evaluateJavaScript:@"countServiceWorkerClients()" completionHandler: nil];
+    EXPECT_WK_STREQ([webView1 _test_waitForAlert], "1 client(s)");
+}
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to