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)");
+}