Title: [283908] branches/safari-612-branch
Revision
283908
Author
[email protected]
Date
2021-10-11 10:41:58 -0700 (Mon, 11 Oct 2021)

Log Message

Cherry-pick r281706. <rdar://83955085>

Modified Paths

Added Paths

Diff

Modified: branches/safari-612-branch/LayoutTests/ChangeLog (283907 => 283908)


--- branches/safari-612-branch/LayoutTests/ChangeLog	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/LayoutTests/ChangeLog	2021-10-11 17:41:58 UTC (rev 283908)
@@ -1,3 +1,18 @@
+2021-08-27  Chris Dumez  <[email protected]>
+
+        [WK2] Reuse the same network load when process-swapping on resource response due to COOP
+        https://bugs.webkit.org/show_bug.cgi?id=229465
+        <rdar://problem/82307611>
+
+        Reviewed by Alex Christensen.
+
+        Add layout test coverage.
+
+        * http/wpt/cross-origin-opener-policy/resources/single-request-to-server-popup.py: Added.
+        (main):
+        * http/wpt/cross-origin-opener-policy/single-request-to-server-expected.txt: Added.
+        * http/wpt/cross-origin-opener-policy/single-request-to-server.html: Added.
+
 2021-08-24  Chris Dumez  <[email protected]>
 
         [WK2] Implement process-swapping based on Cross-Origin-Opener-Policy HTTP header

Added: branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/resources/single-request-to-server-popup.py (0 => 283908)


--- branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/resources/single-request-to-server-popup.py	                        (rev 0)
+++ branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/resources/single-request-to-server-popup.py	2021-10-11 17:41:58 UTC (rev 283908)
@@ -0,0 +1,13 @@
+def main(request, response):
+    token = request.GET[b'token']
+    value = request.server.stash.take(token)
+    already_loaded_string = "not_already_loaded"
+    if value is not None:
+        already_loaded_string = "already_loaded"
+    else:
+        request.server.stash.put(token, True)
+    return ([
+        (b'Cache-Control', b'no-store'),
+        (b'Cross-Origin-Opener-Policy', b'same-origin'),
+        (b'Content-Type', b'text/html')],
+        u'<script>var bc = new BroadcastChannel("single-request-to-server"); bc.postMessage("%s");</script>\n' % already_loaded_string)

Added: branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server-expected.txt (0 => 283908)


--- branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server-expected.txt	                        (rev 0)
+++ branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server-expected.txt	2021-10-11 17:41:58 UTC (rev 283908)
@@ -0,0 +1,3 @@
+
+PASS Make sure we make a single request to the HTTP server when switching browsing context group
+

Added: branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server.html (0 => 283908)


--- branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server.html	                        (rev 0)
+++ branches/safari-612-branch/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server.html	2021-10-11 17:41:58 UTC (rev 283908)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+async_test((t) => {
+    var bc = new BroadcastChannel('single-request-to-server');
+    let w = open("resources/single-request-to-server-popup.py?token=" + token());
+    bc._onmessage_ = t.step_func((event) => {
+        assert_equals(event.data, "not_already_loaded");
+        assert_true(w.closed, "Should switch browsing context group");
+        t.done();
+    });
+}, "Make sure we make a single request to the HTTP server when switching browsing context group");
+</script>
+</body>
+</html>

Modified: branches/safari-612-branch/Source/WebKit/ChangeLog (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/ChangeLog	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/ChangeLog	2021-10-11 17:41:58 UTC (rev 283908)
@@ -1,3 +1,99 @@
+2021-08-27  Chris Dumez  <[email protected]>
+
+        [WK2] Reuse the same network load when process-swapping on resource response due to COOP
+        https://bugs.webkit.org/show_bug.cgi?id=229465
+        <rdar://problem/82307611>
+
+        Reviewed by Alex Christensen.
+
+        r281516 added support for process-swapping based on Cross-Origin-Opener-Policy header
+        in HTTP responses. However, on process-swap, we would abort the existing network load
+        that was started by the original WebProcess and start a fresh network load in the new
+        WebProcess. This was suboptimal and could lead to issues with resources that provide
+        one-time behaviors. This patch addresses the issue by transferring the network load
+        in the network process from the old WebProcess to the new WebProcess when process
+        swapping.
+
+        When the UIProcess decides to process-swap on response policy decision, it first
+        sends IPC to the network process to ask it to prepare the NetworkResourceLoader
+        for ownership transfer. The network process takes the NetworkResourceLoader
+        from its NetworkConnectionToWebProcess and stores it in a temporary cache, then
+        responds to the UIProcess with the NetworkResourceLoadIdentifier of the loader.
+        Upon receiving the response, the UIProcess proceeds with the process-swap, it
+        rejects response processing in the old process and does a loadRequest in a new
+        WebProcess. When starting sending the LoadRequest IPC to the new WebProcess, it
+        passes along the NetworkResourceLoadIdentifier of the cached loader in the network
+        process. When the WebProcess ends up scheduling the load with the network process,
+        it passes again the NetworkResourceLoadIdentifier. Upon receiving the load request,
+        the network process checks if a NetworkResourceLoadIdentifier is provided for
+        continuing a load. If none is provided, we use the regular code path and actually
+        construct a new NetworkResourceLoader. However, if a NetworkResourceLoadIdentifier
+        is provided, we take the corresponding NetworkResourceLoader from the cache,
+        transfer it to the new NetworkConnectionToWebProcess and have it send the
+        DidReceiveResponse IPC to the WebProcess to continue the load with the new
+        WebProcess.
+
+        Test: http/wpt/cross-origin-opener-policy/single-request-to-server.html
+
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        (WebKit::NetworkConnectionToWebProcess::didCleanupResourceLoader):
+        (WebKit::NetworkConnectionToWebProcess::transferKeptAliveLoad):
+        (WebKit::NetworkConnectionToWebProcess::scheduleResourceLoad):
+        (WebKit::NetworkConnectionToWebProcess::takeNetworkResourceLoader):
+        * NetworkProcess/NetworkConnectionToWebProcess.h:
+        * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::CachedNetworkResourceLoader::CachedNetworkResourceLoader):
+        (WebKit::NetworkProcess::CachedNetworkResourceLoader::takeLoader):
+        (WebKit::NetworkProcess::CachedNetworkResourceLoader::expirationTimerFired):
+        (WebKit::NetworkProcess::takeLoaderAwaitingWebProcessTransfer):
+        (WebKit::NetworkProcess::prepareLoadForWebProcessTransfer):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::transferToNewWebProcess):
+        (WebKit::NetworkResourceLoader::shouldInterruptLoadForXFrameOptions):
+        (WebKit::NetworkResourceLoader::shouldInterruptLoadForCSPFrameAncestorsOrXFrameOptions):
+        (WebKit::NetworkResourceLoader::shouldInterruptNavigationForCrossOriginEmbedderPolicy):
+        (WebKit::NetworkResourceLoader::shouldInterruptWorkerLoadForCrossOriginEmbedderPolicy):
+        (WebKit::NetworkResourceLoader::didReceiveResponse):
+        (WebKit::NetworkResourceLoader::didFinishLoading):
+        (WebKit::NetworkResourceLoader::didFailLoading):
+        (WebKit::NetworkResourceLoader::didRetrieveCacheEntry):
+        (WebKit::NetworkResourceLoader::logCookieInformation const):
+        (WebKit::NetworkResourceLoader::addConsoleMessage):
+        (WebKit::NetworkResourceLoader::serviceWorkerDidNotHandle):
+        * NetworkProcess/NetworkResourceLoader.h:
+        * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
+        (WebKit::ServiceWorkerFetchTask::sendToClient):
+        (WebKit::ServiceWorkerFetchTask::didReceiveResponse):
+        * Shared/LoadParameters.cpp:
+        (WebKit::LoadParameters::encode const):
+        (WebKit::LoadParameters::decode):
+        * Shared/LoadParameters.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::prepareLoadForWebProcessTransfer):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/ProvisionalPageProxy.cpp:
+        (WebKit::ProvisionalPageProxy::loadRequest):
+        (WebKit::ProvisionalPageProxy::decidePolicyForResponse):
+        * UIProcess/ProvisionalPageProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::loadRequestWithNavigationShared):
+        (WebKit::WebPageProxy::continueNavigationInNewProcess):
+        (WebKit::WebPageProxy::decidePolicyForResponse):
+        (WebKit::WebPageProxy::decidePolicyForResponseShared):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/Network/WebLoaderStrategy.cpp:
+        (WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess):
+        * WebProcess/Network/WebLoaderStrategy.h:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::loadRequest):
+        * WebProcess/WebPage/WebPage.h:
+
 2021-08-24  Chris Dumez  <[email protected]>
 
         [WK2] Implement process-swapping based on Cross-Origin-Opener-Policy HTTP header

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -85,6 +85,7 @@
 #endif
 
 #define CONNECTION_RELEASE_LOG(channel, fmt, ...) RELEASE_LOG(channel, "%p - [webProcessIdentifier=%" PRIu64 "] NetworkConnectionToWebProcess::" fmt, this, webProcessIdentifier().toUInt64(), ##__VA_ARGS__)
+#define CONNECTION_RELEASE_LOG_ERROR(channel, fmt, ...) RELEASE_LOG_ERROR(channel, "%p - [webProcessIdentifier=%" PRIu64 "] NetworkConnectionToWebProcess::" fmt, this, webProcessIdentifier().toUInt64(), ##__VA_ARGS__)
 
 #define NETWORK_PROCESS_MESSAGE_CHECK(assertion) NETWORK_PROCESS_MESSAGE_CHECK_COMPLETION(assertion, (void)0)
 #define NETWORK_PROCESS_MESSAGE_CHECK_COMPLETION(assertion, completion) do { \
@@ -166,7 +167,7 @@
 
 void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoader& loader)
 {
-    RELEASE_ASSERT(loader.identifier());
+    RELEASE_ASSERT(loader.coreIdentifier());
     RELEASE_ASSERT(RunLoop::isMain());
 
     if (loader.isKeptAlive()) {
@@ -174,8 +175,8 @@
         return;
     }
 
-    ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
-    m_networkResourceLoaders.remove(loader.identifier());
+    ASSERT(m_networkResourceLoaders.get(loader.coreIdentifier()) == &loader);
+    m_networkResourceLoaders.remove(loader.coreIdentifier());
 }
 
 void NetworkConnectionToWebProcess::transferKeptAliveLoad(NetworkResourceLoader& loader)
@@ -182,8 +183,8 @@
 {
     RELEASE_ASSERT(RunLoop::isMain());
     ASSERT(loader.isKeptAlive());
-    ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
-    if (auto takenLoader = m_networkResourceLoaders.take(loader.identifier()))
+    ASSERT(m_networkResourceLoaders.get(loader.coreIdentifier()) == &loader);
+    if (auto takenLoader = m_networkResourceLoaders.take(loader.coreIdentifier()))
         m_networkProcess->addKeptAliveLoad(takenLoader.releaseNonNull());
 }
 
@@ -486,27 +487,41 @@
 }
 #endif
 
-void NetworkConnectionToWebProcess::scheduleResourceLoad(NetworkResourceLoadParameters&& loadParameters)
+void NetworkConnectionToWebProcess::scheduleResourceLoad(NetworkResourceLoadParameters&& loadParameters, std::optional<NetworkResourceLoadIdentifier> existingLoaderToResume)
 {
-    CONNECTION_RELEASE_LOG(Loading, "scheduleResourceLoad: (parentPID=%d, pageProxyID=%" PRIu64 ", webPageID=%" PRIu64 ", frameID=%" PRIu64 ", resourceID=%" PRIu64 ")", loadParameters.parentPID, loadParameters.webPageProxyID.toUInt64(), loadParameters.webPageID.toUInt64(), loadParameters.webFrameID.toUInt64(), loadParameters.identifier);
+    CONNECTION_RELEASE_LOG(Loading, "scheduleResourceLoad: (parentPID=%d, pageProxyID=%" PRIu64 ", webPageID=%" PRIu64 ", frameID=%" PRIu64 ", resourceID=%" PRIu64 ", existingLoaderToResume=%" PRIu64 ")", loadParameters.parentPID, loadParameters.webPageProxyID.toUInt64(), loadParameters.webPageID.toUInt64(), loadParameters.webFrameID.toUInt64(), loadParameters.identifier, existingLoaderToResume.value_or(NetworkResourceLoadIdentifier { }).toUInt64());
 
 #if ENABLE(SERVICE_WORKER)
     auto& server = m_networkProcess->swServerForSession(m_sessionID);
     if (!server.isImportCompleted()) {
-        server.whenImportIsCompleted([this, protectedThis = makeRef(*this), loadParameters = WTFMove(loadParameters)]() mutable {
+        server.whenImportIsCompleted([this, protectedThis = makeRef(*this), loadParameters = WTFMove(loadParameters), existingLoaderToResume]() mutable {
             if (!m_networkProcess->webProcessConnection(webProcessIdentifier()))
                 return;
             ASSERT(m_networkProcess->swServerForSession(m_sessionID).isImportCompleted());
-            scheduleResourceLoad(WTFMove(loadParameters));
+            scheduleResourceLoad(WTFMove(loadParameters), existingLoaderToResume);
         });
         return;
     }
 #endif
+
     auto identifier = loadParameters.identifier;
     RELEASE_ASSERT(identifier);
     RELEASE_ASSERT(RunLoop::isMain());
     ASSERT(!m_networkResourceLoaders.contains(identifier));
 
+    if (existingLoaderToResume) {
+        if (auto session = networkSession()) {
+            if (auto existingLoader = session->takeLoaderAwaitingWebProcessTransfer(*existingLoaderToResume)) {
+                CONNECTION_RELEASE_LOG(Loading, "scheduleResourceLoad: Resuming existing NetworkResourceLoader");
+                m_networkResourceLoaders.add(identifier, *existingLoader);
+                existingLoader->transferToNewWebProcess(*this, identifier);
+                return;
+            }
+            CONNECTION_RELEASE_LOG_ERROR(Loading, "scheduleResourceLoad: Could not find existing NetworkResourceLoader to resume, will do a fresh load");
+        } else
+            CONNECTION_RELEASE_LOG_ERROR(Loading, "scheduleResourceLoad: Could not find network session of existing NetworkResourceLoader to resume, will do a fresh load");
+    }
+
     auto& loader = m_networkResourceLoaders.add(identifier, NetworkResourceLoader::create(WTFMove(loadParameters), *this)).iterator->value;
 
 #if ENABLE(SERVICE_WORKER)
@@ -1271,6 +1286,13 @@
     session->networkLoadScheduler().prioritizeLoads(loads);
 }
 
+RefPtr<NetworkResourceLoader> NetworkConnectionToWebProcess::takeNetworkResourceLoader(uint64_t resourceLoadIdentifier)
+{
+    if (!NetworkResourceLoadMap::MapType::isValidKey(resourceLoadIdentifier))
+        return nullptr;
+    return m_networkResourceLoaders.take(resourceLoadIdentifier);
+}
+
 } // namespace WebKit
 
 #undef CONNECTION_RELEASE_LOG

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -32,6 +32,7 @@
 #include "NetworkConnectionToWebProcessMessagesReplies.h"
 #include "NetworkMDNSRegister.h"
 #include "NetworkRTCProvider.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "NetworkResourceLoadMap.h"
 #include "PolicyDecision.h"
 #include "SandboxExtension.h"
@@ -186,6 +187,7 @@
     void cookieAcceptPolicyChanged(WebCore::HTTPCookieAcceptPolicy);
 
     void broadcastConsoleMessage(JSC::MessageSource, JSC::MessageLevel, const String& message);
+    RefPtr<NetworkResourceLoader> takeNetworkResourceLoader(uint64_t resourceLoadIdentifier);
 
 private:
     NetworkConnectionToWebProcess(NetworkProcess&, WebCore::ProcessIdentifier, PAL::SessionID, IPC::Connection::Identifier);
@@ -203,7 +205,7 @@
     void didReceiveNetworkConnectionToWebProcessMessage(IPC::Connection&, IPC::Decoder&);
     bool didReceiveSyncNetworkConnectionToWebProcessMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
 
-    void scheduleResourceLoad(NetworkResourceLoadParameters&&);
+    void scheduleResourceLoad(NetworkResourceLoadParameters&&, std::optional<NetworkResourceLoadIdentifier> existingLoaderToResume);
     void performSynchronousLoad(NetworkResourceLoadParameters&&, Messages::NetworkConnectionToWebProcess::PerformSynchronousLoadDelayedReply&&);
     void testProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebPageProxyIdentifier, Messages::NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReplyDelayedReply&&);
     void loadPing(NetworkResourceLoadParameters&&);

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in	2021-10-11 17:41:58 UTC (rev 283908)
@@ -22,7 +22,7 @@
 
 messages -> NetworkConnectionToWebProcess LegacyReceiver {
 
-    ScheduleResourceLoad(WebKit::NetworkResourceLoadParameters resourceLoadParameters)
+    ScheduleResourceLoad(WebKit::NetworkResourceLoadParameters resourceLoadParameters, std::optional<WebKit::NetworkResourceLoadIdentifier> existingLoaderToResume)
     PerformSynchronousLoad(WebKit::NetworkResourceLoadParameters resourceLoadParameters) -> (WebCore::ResourceError error, WebCore::ResourceResponse response, Vector<uint8_t> data) Synchronous
     TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebKit::WebPageProxyIdentifier pageID) -> (bool handled) Synchronous
     LoadPing(WebKit::NetworkResourceLoadParameters resourceLoadParameters)

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -2825,6 +2825,26 @@
 }
 #endif
 
+void NetworkProcess::prepareLoadForWebProcessTransfer(WebCore::ProcessIdentifier sourceProcessIdentifier, uint64_t resourceLoadIdentifier, CompletionHandler<void(std::optional<NetworkResourceLoadIdentifier>)>&& completionHandler)
+{
+    ASSERT(resourceLoadIdentifier);
+    auto* connection = webProcessConnection(sourceProcessIdentifier);
+    if (!connection)
+        return completionHandler(std::nullopt);
+
+    auto session = connection->networkSession();
+    if (!session)
+        return completionHandler(std::nullopt);
+
+    auto loader = connection->takeNetworkResourceLoader(resourceLoadIdentifier);
+    if (!loader)
+        return completionHandler(std::nullopt);
+
+    auto identifier = loader->identifier();
+    session->addLoaderAwaitingWebProcessTransfer(loader.releaseNonNull());
+    completionHandler(identifier);
+}
+
 void NetworkProcess::addWebPageNetworkParameters(PAL::SessionID sessionID, WebPageProxyIdentifier pageID, WebPageNetworkParameters&& parameters)
 {
     auto session = networkSession(sessionID);

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -33,6 +33,7 @@
 #include "DownloadManager.h"
 #include "LocalStorageDatabaseTracker.h"
 #include "NetworkContentRuleListManager.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "RTCDataChannelRemoteManagerProxy.h"
 #include "SandboxExtension.h"
 #include "WebIDBServer.h"
@@ -424,6 +425,7 @@
     bool didReceiveSyncNetworkProcessMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
     void initializeNetworkProcess(NetworkProcessCreationParameters&&);
     void createNetworkConnectionToWebProcess(WebCore::ProcessIdentifier, PAL::SessionID, CompletionHandler<void(std::optional<IPC::Attachment>&&, WebCore::HTTPCookieAcceptPolicy)>&&);
+    void prepareLoadForWebProcessTransfer(WebCore::ProcessIdentifier sourceProcessIdentifier, uint64_t resourceLoadIdentifier, CompletionHandler<void(std::optional<NetworkResourceLoadIdentifier>)>&&);
 
     void fetchWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, CompletionHandler<void(WebsiteData&&)>&&);
     void deleteWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, WallTime modifiedSince, CompletionHandler<void()>&&);

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2021-10-11 17:41:58 UTC (rev 283908)
@@ -195,6 +195,8 @@
     ClearAppPrivacyReportTestingData(PAL::SessionID sessionID) -> () Async
 #endif
 
+    PrepareLoadForWebProcessTransfer(WebCore::ProcessIdentifier sourceProcessIdentifier, uint64_t resourceLoadIdentifier) -> (std::optional<WebKit::NetworkResourceLoadIdentifier> networkResourceLoadIdentifier) Async
+
     AddWebPageNetworkParameters(PAL::SessionID sessionID, WebKit::WebPageProxyIdentifier pageID, WebKit::WebPageNetworkParameters parameters)
     RemoveWebPageNetworkParameters(PAL::SessionID sessionID, WebKit::WebPageProxyIdentifier pageID)
     CountNonDefaultSessionSets(PAL::SessionID sessionID) -> (size_t count) Async

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -51,7 +51,7 @@
 
     RefPtr<WebCore::SecurityOrigin> parentOrigin() const;
 
-    ResourceLoadIdentifier identifier { 0 };
+    mutable ResourceLoadIdentifier identifier { 0 };
     Vector<RefPtr<SandboxExtension>> requestBodySandboxExtensions; // Created automatically for the sender.
     RefPtr<SandboxExtension> resourceSandboxExtension; // Created automatically for the sender.
     mutable Seconds maximumBufferingTime;

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -525,6 +525,16 @@
     cleanup(LoadResult::Cancel);
 }
 
+void NetworkResourceLoader::transferToNewWebProcess(NetworkConnectionToWebProcess& newConnection, ResourceLoadIdentifier newCoreIdentifier)
+{
+    m_connection = newConnection;
+    m_parameters.identifier = newCoreIdentifier;
+
+    ASSERT(m_responseCompletionHandler || m_cacheEntryWaitingForContinueDidReceiveResponse || m_serviceWorkerFetchTask);
+    bool willWaitForContinueDidReceiveResponse = true;
+    send(Messages::WebResourceLoader::DidReceiveResponse { m_response, willWaitForContinueDidReceiveResponse });
+}
+
 bool NetworkResourceLoader::shouldInterruptLoadForXFrameOptions(const String& xFrameOptions, const URL& url)
 {
     if (isMainFrameLoad())
@@ -549,12 +559,12 @@
     }
     case XFrameOptionsDisposition::Conflict: {
         String errorMessage = "Multiple 'X-Frame-Options' headers with conflicting values ('" + xFrameOptions + "') encountered when loading '" + url.stringCenterEllipsizedToLength() + "'. Falling back to 'DENY'.";
-        send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::JS, MessageLevel::Error, errorMessage, identifier() }, m_parameters.webPageID);
+        send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::JS, MessageLevel::Error, errorMessage, coreIdentifier() }, m_parameters.webPageID);
         return true;
     }
     case XFrameOptionsDisposition::Invalid: {
         String errorMessage = "Invalid 'X-Frame-Options' header encountered when loading '" + url.stringCenterEllipsizedToLength() + "': '" + xFrameOptions + "' is not a recognized directive. The header will be ignored.";
-        send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::JS, MessageLevel::Error, errorMessage, identifier() }, m_parameters.webPageID);
+        send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::JS, MessageLevel::Error, errorMessage, coreIdentifier() }, m_parameters.webPageID);
         return false;
     }
     }
@@ -581,7 +591,7 @@
         String xFrameOptions = m_response.httpHeaderField(HTTPHeaderName::XFrameOptions);
         if (!xFrameOptions.isNull() && shouldInterruptLoadForXFrameOptions(xFrameOptions, response.url())) {
             String errorMessage = makeString("Refused to display '", response.url().stringCenterEllipsizedToLength(), "' in a frame because it set 'X-Frame-Options' to '", xFrameOptions, "'.");
-            send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::Security, MessageLevel::Error, errorMessage, identifier() }, m_parameters.webPageID);
+            send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::Security, MessageLevel::Error, errorMessage, coreIdentifier() }, m_parameters.webPageID);
             return true;
         }
     }
@@ -598,7 +608,7 @@
         auto responseCOEP = WebCore::obtainCrossOriginEmbedderPolicy(response, m_parameters.sourceOrigin->isPotentiallyTrustworthy() ? IsSecureContext::Yes : IsSecureContext::No);
         if (responseCOEP.value != WebCore::CrossOriginEmbedderPolicyValue::RequireCORP) {
             String errorMessage = makeString("Refused to display '", response.url().stringCenterEllipsizedToLength(), "' in a frame because of Cross-Origin-Embedder-Policy.");
-            send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::Security, MessageLevel::Error, errorMessage, identifier() }, m_parameters.webPageID);
+            send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::Security, MessageLevel::Error, errorMessage, coreIdentifier() }, m_parameters.webPageID);
             return true;
         }
     }
@@ -614,7 +624,7 @@
         auto responseCOEP = WebCore::obtainCrossOriginEmbedderPolicy(response, m_parameters.sourceOrigin->isPotentiallyTrustworthy() ? IsSecureContext::Yes : IsSecureContext::No);
         if (responseCOEP.value != WebCore::CrossOriginEmbedderPolicyValue::RequireCORP) {
             String errorMessage = makeString("Refused to load '", response.url().stringCenterEllipsizedToLength(), "' worker because of Cross-Origin-Embedder-Policy.");
-            send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::Security, MessageLevel::Error, errorMessage, identifier() }, m_parameters.webPageID);
+            send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  MessageSource::Security, MessageLevel::Error, errorMessage, coreIdentifier() }, m_parameters.webPageID);
             return true;
         }
     }
@@ -633,7 +643,7 @@
     if (shouldCaptureExtraNetworkLoadMetrics() && m_networkLoadChecker) {
         auto information = m_networkLoadChecker->takeNetworkLoadInformation();
         information.response = m_response;
-        m_connection->addNetworkLoadInformation(identifier(), WTFMove(information));
+        m_connection->addNetworkLoadInformation(coreIdentifier(), WTFMove(information));
     }
 
     auto resourceLoadInfo = this->resourceLoadInfo();
@@ -782,7 +792,7 @@
     LOADER_RELEASE_LOG("didFinishLoading: (numBytesReceived=%zd, hasCacheEntryForValidation=%d)", m_numBytesReceived, !!m_cacheEntryForValidation);
 
     if (shouldCaptureExtraNetworkLoadMetrics())
-        m_connection->addNetworkLoadInformationMetrics(identifier(), networkLoadMetrics);
+        m_connection->addNetworkLoadInformationMetrics(coreIdentifier(), networkLoadMetrics);
 
     if (m_cacheEntryForValidation) {
         // 304 Not Modified
@@ -825,7 +835,7 @@
     UNUSED_VARIABLE(wasServiceWorkerLoad);
 
     if (shouldCaptureExtraNetworkLoadMetrics())
-        m_connection->removeNetworkLoadInformation(identifier());
+        m_connection->removeNetworkLoadInformation(coreIdentifier());
 
     ASSERT(!error.isNull());
 
@@ -1226,9 +1236,10 @@
     LOADER_RELEASE_LOG("didRetrieveCacheEntry: Sending WebResourceLoader::DidReceiveResponse IPC (needsContinueDidReceiveResponseMessage=%d)", needsContinueDidReceiveResponseMessage);
     send(Messages::WebResourceLoader::DidReceiveResponse { response, needsContinueDidReceiveResponseMessage });
 
-    if (needsContinueDidReceiveResponseMessage)
+    if (needsContinueDidReceiveResponseMessage) {
+        m_response = WTFMove(response);
         m_cacheEntryWaitingForContinueDidReceiveResponse = WTFMove(entry);
-    else {
+    } else {
         sendResultForCacheEntry(WTFMove(entry));
         cleanup(LoadResult::Success);
     }
@@ -1383,7 +1394,7 @@
     auto* networkStorageSession = m_connection->networkProcess().storageSession(sessionID());
     ASSERT(networkStorageSession);
 
-    logCookieInformation(m_connection, "NetworkResourceLoader", reinterpret_cast<const void*>(this), *networkStorageSession, originalRequest().firstPartyForCookies(), SameSiteInfo::create(originalRequest()), originalRequest().url(), originalRequest().httpReferrer(), frameID(), pageID(), identifier());
+    logCookieInformation(m_connection, "NetworkResourceLoader", reinterpret_cast<const void*>(this), *networkStorageSession, originalRequest().firstPartyForCookies(), SameSiteInfo::create(originalRequest()), originalRequest().url(), originalRequest().httpReferrer(), frameID(), pageID(), coreIdentifier());
 }
 
 static void logBlockedCookieInformation(NetworkConnectionToWebProcess& connection, const String& label, const void* loggedObject, const WebCore::NetworkStorageSession& networkStorageSession, const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, const String& referrer, std::optional<FrameIdentifier> frameID, std::optional<PageIdentifier> pageID, std::optional<uint64_t> identifier)
@@ -1487,7 +1498,7 @@
 
 void NetworkResourceLoader::addConsoleMessage(MessageSource messageSource, MessageLevel messageLevel, const String& message, unsigned long)
 {
-    send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  messageSource, messageLevel, message, identifier() }, m_parameters.webPageID);
+    send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID,  messageSource, messageLevel, message, coreIdentifier() }, m_parameters.webPageID);
 }
 
 void NetworkResourceLoader::sendCSPViolationReport(URL&& reportURL, Ref<FormData>&& report)
@@ -1558,7 +1569,7 @@
     RELEASE_ASSERT(m_serviceWorkerFetchTask.get() == fetchTask);
     if (m_parameters.serviceWorkersMode == ServiceWorkersMode::Only) {
         LOADER_RELEASE_LOG_ERROR("serviceWorkerDidNotHandle: Aborting load because the service worker did not handle the load and serviceWorkerMode only allows service workers");
-        send(Messages::WebResourceLoader::ServiceWorkerDidNotHandle { }, identifier());
+        send(Messages::WebResourceLoader::ServiceWorkerDidNotHandle { }, coreIdentifier());
         abort();
         return;
     }

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkResourceLoader.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -85,19 +85,23 @@
     void start();
     void abort();
 
+    void transferToNewWebProcess(NetworkConnectionToWebProcess&, ResourceLoadIdentifier);
+
     // Message handlers.
     void didReceiveNetworkResourceLoaderMessage(IPC::Connection&, IPC::Decoder&);
 
     void continueWillSendRequest(WebCore::ResourceRequest&& newRequest, bool isAllowedToAskUserForCredentials);
 
+    void setResponse(WebCore::ResourceResponse&& response) { m_response = WTFMove(response); }
     const WebCore::ResourceResponse& response() const { return m_response; }
 
     NetworkConnectionToWebProcess& connectionToWebProcess() const { return m_connection; }
     PAL::SessionID sessionID() const { return m_connection->sessionID(); }
-    ResourceLoadIdentifier identifier() const { return m_parameters.identifier; }
+    ResourceLoadIdentifier coreIdentifier() const { return m_parameters.identifier; }
     WebCore::FrameIdentifier frameID() const { return m_parameters.webFrameID; }
     WebCore::PageIdentifier pageID() const { return m_parameters.webPageID; }
     const NetworkResourceLoadParameters& parameters() const { return m_parameters; }
+    NetworkResourceLoadIdentifier identifier() const { return m_resourceLoadID; }
 
     NetworkCache::GlobalFrameID globalFrameID() { return { m_parameters.webPageProxyID, pageID(), frameID() }; }
 

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkSession.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkSession.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkSession.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -56,6 +56,8 @@
 namespace WebKit {
 using namespace WebCore;
 
+constexpr Seconds cachedNetworkResourceLoaderLifetime { 30_s };
+
 std::unique_ptr<NetworkSession> NetworkSession::create(NetworkProcess& networkProcess, NetworkSessionCreationParameters&& parameters)
 {
 #if PLATFORM(COCOA)
@@ -394,6 +396,43 @@
     m_keptAliveLoads.remove(loader);
 }
 
+NetworkSession::CachedNetworkResourceLoader::CachedNetworkResourceLoader(Ref<NetworkResourceLoader>&& loader)
+    : m_expirationTimer(*this, &CachedNetworkResourceLoader::expirationTimerFired)
+    , m_loader(WTFMove(loader))
+{
+    m_expirationTimer.startOneShot(cachedNetworkResourceLoaderLifetime);
+}
+
+RefPtr<NetworkResourceLoader> NetworkSession::CachedNetworkResourceLoader::takeLoader()
+{
+    return std::exchange(m_loader, nullptr);
+}
+
+void NetworkSession::CachedNetworkResourceLoader::expirationTimerFired()
+{
+    auto session = m_loader->connectionToWebProcess().networkSession();
+    ASSERT(session);
+    if (!session)
+        return;
+
+    auto loader = session->takeLoaderAwaitingWebProcessTransfer(m_loader->identifier());
+    ASSERT_UNUSED(loader, loader);
+}
+
+void NetworkSession::addLoaderAwaitingWebProcessTransfer(Ref<NetworkResourceLoader>&& loader)
+{
+    ASSERT(m_sessionID == loader->sessionID());
+    auto identifier = loader->identifier();
+    ASSERT(!m_loadersAwaitingWebProcessTransfer.contains(identifier));
+    m_loadersAwaitingWebProcessTransfer.add(identifier, makeUnique<CachedNetworkResourceLoader>(WTFMove(loader)));
+}
+
+RefPtr<NetworkResourceLoader> NetworkSession::takeLoaderAwaitingWebProcessTransfer(NetworkResourceLoadIdentifier identifier)
+{
+    auto cachedResourceLoader = m_loadersAwaitingWebProcessTransfer.take(identifier);
+    return cachedResourceLoader ? cachedResourceLoader->takeLoader() : nullptr;
+}
+
 std::unique_ptr<WebSocketTask> NetworkSession::createWebSocketTask(WebPageProxyIdentifier, NetworkSocketChannel&, const WebCore::ResourceRequest&, const String& protocol)
 {
     return nullptr;

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkSession.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkSession.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/NetworkSession.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -27,6 +27,7 @@
 
 #include "AppPrivacyReport.h"
 #include "NavigatingToAppBoundDomain.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "PrefetchCache.h"
 #include "PrivateClickMeasurementNetworkLoader.h"
 #include "SandboxExtension.h"
@@ -140,6 +141,9 @@
     void addKeptAliveLoad(Ref<NetworkResourceLoader>&&);
     void removeKeptAliveLoad(NetworkResourceLoader&);
 
+    void addLoaderAwaitingWebProcessTransfer(Ref<NetworkResourceLoader>&&);
+    RefPtr<NetworkResourceLoader> takeLoaderAwaitingWebProcessTransfer(NetworkResourceLoadIdentifier);
+
     NetworkCache::Cache* cache() { return m_cache.get(); }
 
     PrefetchCache& prefetchCache() { return m_prefetchCache; }
@@ -211,6 +215,18 @@
 
     HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
 
+    class CachedNetworkResourceLoader {
+        WTF_MAKE_FAST_ALLOCATED;
+    public:
+        explicit CachedNetworkResourceLoader(Ref<NetworkResourceLoader>&&);
+        RefPtr<NetworkResourceLoader> takeLoader();
+    private:
+        void expirationTimerFired();
+        WebCore::Timer m_expirationTimer;
+        RefPtr<NetworkResourceLoader> m_loader;
+    };
+    HashMap<NetworkResourceLoadIdentifier, std::unique_ptr<CachedNetworkResourceLoader>> m_loadersAwaitingWebProcessTransfer;
+
     PrefetchCache m_prefetchCache;
 
 #if ASSERT_ENABLED

Modified: branches/safari-612-branch/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -78,7 +78,7 @@
 
 template<typename Message> bool ServiceWorkerFetchTask::sendToClient(Message&& message)
 {
-    return m_loader.connectionToWebProcess().connection().send(std::forward<Message>(message), m_loader.identifier());
+    return m_loader.connectionToWebProcess().connection().send(std::forward<Message>(message), m_loader.coreIdentifier());
 }
 
 void ServiceWorkerFetchTask::start(WebSWServerToContextConnection& serviceWorkerConnection)
@@ -162,6 +162,8 @@
 
     response.setSource(ResourceResponse::Source::ServiceWorker);
     sendToClient(Messages::WebResourceLoader::DidReceiveResponse { response, needsContinueDidReceiveResponseMessage });
+    if (needsContinueDidReceiveResponseMessage)
+        m_loader.setResponse(WTFMove(response));
 }
 
 void ServiceWorkerFetchTask::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength)

Modified: branches/safari-612-branch/Source/WebKit/Shared/LoadParameters.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/Shared/LoadParameters.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/Shared/LoadParameters.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -57,6 +57,7 @@
     encoder << lockBackForwardList;
     encoder << clientRedirectSourceForHistory;
     encoder << isNavigatingToAppBoundDomain;
+    encoder << existingNetworkResourceLoadIdentifierToResume;
     encoder << sessionHistoryVisibility;
 
     platformEncode(encoder);
@@ -137,6 +138,9 @@
     
     if (!decoder.decode(data.isNavigatingToAppBoundDomain))
         return false;
+
+    if (!decoder.decode(data.existingNetworkResourceLoadIdentifierToResume))
+        return false;
     
     if (!decoder.decode(data.sessionHistoryVisibility))
         return false;

Modified: branches/safari-612-branch/Source/WebKit/Shared/LoadParameters.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/Shared/LoadParameters.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/Shared/LoadParameters.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "DataReference.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "PolicyDecision.h"
 #include "SandboxExtension.h"
 #include "UserData.h"
@@ -74,6 +75,7 @@
     WebCore::SubstituteData::SessionHistoryVisibility sessionHistoryVisibility { WebCore::SubstituteData::SessionHistoryVisibility::Visible };
     String clientRedirectSourceForHistory;
     std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain;
+    std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume;
 
 #if PLATFORM(COCOA)
     RetainPtr<NSDictionary> dataDetectionContext;

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -476,6 +476,17 @@
     }
 }
 
+void NetworkProcessProxy::prepareLoadForWebProcessTransfer(WebCore::ProcessIdentifier sourceProcessIdentifier, uint64_t resourceLoadIdentifier, CompletionHandler<void(std::optional<NetworkResourceLoadIdentifier>)>&& completionHandler)
+{
+    RELEASE_LOG(ProcessSwapping, "%p - NetworkProcessProxy::prepareLoadForWebProcessTransfer: sourceProcessIdentifier: %" PRIu64 ", resourceLoadIdentifier: %" PRIu64, this, sourceProcessIdentifier.toUInt64(), resourceLoadIdentifier);
+    if (!resourceLoadIdentifier) {
+        completionHandler({ });
+        return;
+    }
+
+    sendWithAsyncReply(Messages::NetworkProcess::PrepareLoadForWebProcessTransfer(sourceProcessIdentifier, resourceLoadIdentifier), WTFMove(completionHandler));
+}
+
 void NetworkProcessProxy::logDiagnosticMessageWithResult(WebPageProxyIdentifier pageID, const String& message, const String& description, uint32_t result, WebCore::ShouldSample shouldSample)
 {
     WebPageProxy* page = WebProcessProxy::webPage(pageID);

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -29,6 +29,7 @@
 #include "AuxiliaryProcessProxy.h"
 #include "CallbackID.h"
 #include "NetworkProcessProxyMessagesReplies.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "ProcessLauncher.h"
 #include "ProcessThrottler.h"
 #include "ProcessThrottlerClient.h"
@@ -214,6 +215,8 @@
     void testProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebPageProxyIdentifier, Messages::NetworkProcessProxy::TestProcessIncomingSyncMessagesWhenWaitingForSyncReplyDelayedReply&&);
     void terminateUnresponsiveServiceWorkerProcesses(WebCore::ProcessIdentifier);
 
+    void prepareLoadForWebProcessTransfer(WebCore::ProcessIdentifier sourceProcessIdentifier, uint64_t resourceLoadIdentifier, CompletionHandler<void(std::optional<NetworkResourceLoadIdentifier>)>&&);
+
     ProcessThrottler& throttler() final { return m_throttler; }
     void updateProcessAssertion();
 

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -171,9 +171,9 @@
     m_page.loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, mimeType, encoding, baseURL, userData, shouldTreatAsContinuingLoad, isNavigatingToAppBoundDomain, WTFMove(websitePolicies), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy, sessionHistoryVisibility);
 }
 
-void ProvisionalPageProxy::loadRequest(API::Navigation& navigation, WebCore::ResourceRequest&& request, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, std::optional<WebsitePoliciesData>&& websitePolicies)
+void ProvisionalPageProxy::loadRequest(API::Navigation& navigation, WebCore::ResourceRequest&& request, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, std::optional<WebsitePoliciesData>&& websitePolicies, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume)
 {
-    PROVISIONALPAGEPROXY_RELEASE_LOG(ProcessSwapping, "loadRequest:");
+    PROVISIONALPAGEPROXY_RELEASE_LOG(ProcessSwapping, "loadRequest: existingNetworkResourceLoadIdentifierToResume=%" PRIu64, existingNetworkResourceLoadIdentifierToResume.value_or(NetworkResourceLoadIdentifier { }).toUInt64());
     ASSERT(shouldTreatAsContinuingLoad != WebCore::ShouldTreatAsContinuingLoad::No);
 
     // If this is a client-side redirect continuing in a new process, then the new process will overwrite the fromItem's URL. In this case,
@@ -182,7 +182,7 @@
     if (navigation.fromItem() && navigation.lockBackForwardList() == WebCore::LockBackForwardList::Yes)
         navigation.fromItem()->setLastProcessIdentifier(m_process->coreProcessIdentifier());
 
-    m_page.loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, WTFMove(request), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy, userData, shouldTreatAsContinuingLoad, isNavigatingToAppBoundDomain, WTFMove(websitePolicies));
+    m_page.loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, WTFMove(request), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy, userData, shouldTreatAsContinuingLoad, isNavigatingToAppBoundDomain, WTFMove(websitePolicies), existingNetworkResourceLoadIdentifierToResume);
 }
 
 void ProvisionalPageProxy::goToBackForwardItem(API::Navigation& navigation, WebBackForwardListItem& item, RefPtr<API::WebsitePolicies>&& websitePolicies)
@@ -330,12 +330,12 @@
     m_page.decidePolicyForNavigationActionAsyncShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, listenerID);
 }
 
-void ProvisionalPageProxy::decidePolicyForResponse(FrameIdentifier frameID, FrameInfoData&& frameInfo, WebCore::PolicyCheckIdentifier identifier, uint64_t navigationID, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t listenerID, const UserData& userData)
+void ProvisionalPageProxy::decidePolicyForResponse(FrameIdentifier frameID, FrameInfoData&& frameInfo, WebCore::PolicyCheckIdentifier identifier, uint64_t navigationID, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t mainResourceLoadIdentifier, uint64_t listenerID, const UserData& userData)
 {
     if (!validateInput(frameID, navigationID))
         return;
 
-    m_page.decidePolicyForResponseShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, response, request, canShowMIMEType, downloadAttribute, wasAllowedByInjectedBundle, needsBrowsingContextGroupSwitch, listenerID, userData);
+    m_page.decidePolicyForResponseShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, response, request, canShowMIMEType, downloadAttribute, wasAllowedByInjectedBundle, needsBrowsingContextGroupSwitch, mainResourceLoadIdentifier, listenerID, userData);
 }
 
 void ProvisionalPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, FrameIdentifier frameID)

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -28,6 +28,7 @@
 #include "DataReference.h"
 #include "MessageReceiver.h"
 #include "MessageSender.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "PolicyDecision.h"
 #include "ProcessThrottler.h"
 #include "SandboxExtension.h"
@@ -105,7 +106,7 @@
 #endif
 
     void loadData(API::Navigation&, const IPC::DataReference&, const String& mimeType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain>, std::optional<WebsitePoliciesData>&&, WebCore::SubstituteData::SessionHistoryVisibility);
-    void loadRequest(API::Navigation&, WebCore::ResourceRequest&&, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain>, std::optional<WebsitePoliciesData>&& = std::nullopt);
+    void loadRequest(API::Navigation&, WebCore::ResourceRequest&&, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain>, std::optional<WebsitePoliciesData>&& = std::nullopt, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume = std::nullopt);
     void goToBackForwardItem(API::Navigation&, WebBackForwardListItem&, RefPtr<API::WebsitePolicies>&&);
     void cancel();
 
@@ -124,7 +125,7 @@
     bool sendMessage(UniqueRef<IPC::Encoder>&&, OptionSet<IPC::SendOption>, std::optional<std::pair<CompletionHandler<void(IPC::Decoder*)>, uint64_t>>&&) final;
 
     void decidePolicyForNavigationActionAsync(WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, NavigationActionData&&, FrameInfoData&& originatingFrameInfo, std::optional<WebPageProxyIdentifier> originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData&, uint64_t listenerID);
-    void decidePolicyForResponse(WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t listenerID, const UserData&);
+    void decidePolicyForResponse(WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t listenerID, uint64_t mainResourceLoadIdentifier, const UserData&);
     void didChangeProvisionalURLForFrame(WebCore::FrameIdentifier, uint64_t navigationID, URL&&);
     void didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, WebCore::FrameIdentifier);
     void didReceiveServerRedirectForProvisionalLoadForFrame(WebCore::FrameIdentifier, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -1381,7 +1381,7 @@
     return navigation;
 }
 
-void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& process, WebCore::PageIdentifier webPageID, API::Navigation& navigation, ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, std::optional<WebsitePoliciesData>&& websitePolicies)
+void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& process, WebCore::PageIdentifier webPageID, API::Navigation& navigation, ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, std::optional<WebsitePoliciesData>&& websitePolicies, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume)
 {
     ASSERT(!m_isClosed);
 
@@ -1404,6 +1404,7 @@
     loadParameters.lockBackForwardList = navigation.lockBackForwardList();
     loadParameters.clientRedirectSourceForHistory = navigation.clientRedirectSourceForHistory();
     loadParameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
+    loadParameters.existingNetworkResourceLoadIdentifierToResume = existingNetworkResourceLoadIdentifierToResume;
     maybeInitializeSandboxExtensionHandle(process, url, m_pageLoadState.resourceDirectoryURL(), loadParameters.sandboxExtensionHandle);
 
     addPlatformLoadParameters(process, loadParameters);
@@ -3629,7 +3630,7 @@
     m_inspectorController->didCommitProvisionalPage(oldWebPageID, m_webPageID);
 }
 
-void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, std::unique_ptr<SuspendedPageProxy>&& suspendedPage, Ref<WebProcessProxy>&& newProcess, ProcessSwapRequestedByClient processSwapRequestedByClient, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, RefPtr<API::WebsitePolicies>&& websitePolicies)
+void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, std::unique_ptr<SuspendedPageProxy>&& suspendedPage, Ref<WebProcessProxy>&& newProcess, ProcessSwapRequestedByClient processSwapRequestedByClient, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, RefPtr<API::WebsitePolicies>&& websitePolicies, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume)
 {
     WEBPAGEPROXY_RELEASE_LOG(Loading, "continueNavigationInNewProcess: newProcessPID=%i, hasSuspendedPage=%i", newProcess->processIdentifier(), !!suspendedPage);
     LOG(Loading, "Continuing navigation %" PRIu64 " '%s' in a new web process", navigation.navigationID(), navigation.loggingString());
@@ -3646,7 +3647,7 @@
     bool isServerSideRedirect = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::YesAfterNavigationPolicyDecision && navigation.currentRequestIsRedirect();
     bool shouldClosePreviousPageAfterCommit = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::YesAfterResponsePolicyDecision;
     m_provisionalPage = makeUnique<ProvisionalPageProxy>(*this, WTFMove(newProcess), WTFMove(suspendedPage), navigation.navigationID(), isServerSideRedirect, navigation.currentRequest(), processSwapRequestedByClient, shouldClosePreviousPageAfterCommit, websitePolicies.get());
-    auto continuation = [this, protectedThis = makeRef(*this), navigation = makeRef(navigation), shouldTreatAsContinuingLoad, websitePolicies = WTFMove(websitePolicies)]() mutable {
+    auto continuation = [this, protectedThis = makeRef(*this), navigation = makeRef(navigation), shouldTreatAsContinuingLoad, websitePolicies = WTFMove(websitePolicies), existingNetworkResourceLoadIdentifierToResume]() mutable {
         if (auto* item = navigation->targetItem()) {
             LOG(Loading, "WebPageProxy %p continueNavigationInNewProcess to back item URL %s", this, item->url().utf8().data());
 
@@ -3669,10 +3670,11 @@
 
         // FIXME: Work out timing of responding with the last policy delegate, etc
         ASSERT(!navigation->currentRequest().isEmpty());
+        ASSERT(!existingNetworkResourceLoadIdentifierToResume || !navigation->substituteData());
         if (auto& substituteData = navigation->substituteData())
             m_provisionalPage->loadData(navigation, { substituteData->content.data(), substituteData->content.size() }, substituteData->MIMEType, substituteData->encoding, substituteData->baseURL, substituteData->userData.get(), shouldTreatAsContinuingLoad, isNavigatingToAppBoundDomain(), WTFMove(websitePoliciesData), substituteData->sessionHistoryVisibility);
         else
-            m_provisionalPage->loadRequest(navigation, ResourceRequest { navigation->currentRequest() }, nullptr, shouldTreatAsContinuingLoad, isNavigatingToAppBoundDomain(), WTFMove(websitePoliciesData));
+            m_provisionalPage->loadRequest(navigation, ResourceRequest { navigation->currentRequest() }, nullptr, shouldTreatAsContinuingLoad, isNavigatingToAppBoundDomain(), WTFMove(websitePoliciesData), existingNetworkResourceLoadIdentifierToResume);
     };
     if (m_inspectorController->shouldPauseLoading(*m_provisionalPage))
         m_inspectorController->setContinueLoadingCallback(*m_provisionalPage, WTFMove(continuation));
@@ -5628,12 +5630,12 @@
 
 void WebPageProxy::decidePolicyForResponse(FrameIdentifier frameID, FrameInfoData&& frameInfo, PolicyCheckIdentifier identifier,
     uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, const String& downloadAttribute,
-    bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t listenerID, const UserData& userData)
+    bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t mainResourceLoadIdentifier, uint64_t listenerID, const UserData& userData)
 {
-    decidePolicyForResponseShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, response, request, canShowMIMEType, downloadAttribute, wasAllowedByInjectedBundle, needsBrowsingContextGroupSwitch, listenerID, userData);
+    decidePolicyForResponseShared(m_process.copyRef(), m_webPageID, frameID, WTFMove(frameInfo), identifier, navigationID, response, request, canShowMIMEType, downloadAttribute, wasAllowedByInjectedBundle, needsBrowsingContextGroupSwitch, mainResourceLoadIdentifier, listenerID, userData);
 }
 
-void WebPageProxy::decidePolicyForResponseShared(Ref<WebProcessProxy>&& process, PageIdentifier webPageID, FrameIdentifier frameID, FrameInfoData&& frameInfo, PolicyCheckIdentifier identifier, uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t listenerID, const UserData& userData)
+void WebPageProxy::decidePolicyForResponseShared(Ref<WebProcessProxy>&& process, PageIdentifier webPageID, FrameIdentifier frameID, FrameInfoData&& frameInfo, PolicyCheckIdentifier identifier, uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t mainResourceLoadIdentifier, uint64_t listenerID, const UserData& userData)
 {
     PageClientProtector protector(pageClient());
 
@@ -5646,13 +5648,13 @@
     RefPtr<API::Navigation> navigation = navigationID ? m_navigationState->navigation(navigationID) : nullptr;
     auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(WTFMove(frameInfo), this).get(), request, response, canShowMIMEType, downloadAttribute);
 
-    auto listener = makeRef(frame->setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), webPageID, frameID, needsBrowsingContextGroupSwitch, identifier, listenerID, navigation = WTFMove(navigation),
+    auto listener = makeRef(frame->setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), webPageID, frameID, needsBrowsingContextGroupSwitch, mainResourceLoadIdentifier, identifier, listenerID, navigation = WTFMove(navigation),
         process, navigationResponse] (PolicyAction policyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain) mutable {
         // FIXME: Assert the API::WebsitePolicies* is nullptr here once clients of WKFramePolicyListenerUseWithPolicies go away.
         RELEASE_ASSERT(processSwapRequestedByClient == ProcessSwapRequestedByClient::No);
         ASSERT_UNUSED(safeBrowsingWarning, !safeBrowsingWarning);
 
-        auto sender = PolicyDecisionSender::create(identifier, [webPageID, frameID, listenerID, process = WTFMove(process)] (const auto& policyDecision) {
+        auto sender = PolicyDecisionSender::create(identifier, [webPageID, frameID, listenerID, process] (const auto& policyDecision) {
             process->send(Messages::WebPage::DidReceivePolicyDecision(frameID, listenerID, policyDecision, createNetworkExtensionsSandboxExtensions(process)), webPageID);
         });
 
@@ -5660,12 +5662,15 @@
         if (policyAction == PolicyAction::Use && needsBrowsingContextGroupSwitch && navigation) {
             RegistrableDomain responseDomain { navigationResponse->response().url() };
             // Avoid process-swapping in cases where the process only contains a single page and is origin-clean.
-            if (this->process().pageCount() > 1 || (this->process().optionalRegistrableDomain() && *this->process().optionalRegistrableDomain() != responseDomain)) {
+            if (process->pageCount() > 1 || (process->optionalRegistrableDomain() && *process->optionalRegistrableDomain() != responseDomain)) {
                 WEBPAGEPROXY_RELEASE_LOG(ProcessSwapping, "decidePolicyForResponseShared: Process-swapping due to Cross-Origin-Opener-Policy");
-                policyAction = PolicyAction::Ignore;
-                auto processForNavigation = m_process->processPool().processForRegistrableDomain(websiteDataStore(), this, responseDomain);
-                continueNavigationInNewProcess(*navigation, nullptr, WTFMove(processForNavigation), ProcessSwapRequestedByClient::No, ShouldTreatAsContinuingLoad::YesAfterResponsePolicyDecision, nullptr);
-                willContinueLoadInNewProcess = WillContinueLoadInNewProcess::Yes;
+                websiteDataStore().networkProcess().prepareLoadForWebProcessTransfer(process->coreProcessIdentifier(), mainResourceLoadIdentifier, [this, protectedThis = WTFMove(protectedThis), responseDomain = WTFMove(responseDomain), navigation, navigationResponse = WTFMove(navigationResponse), sender = WTFMove(sender)](auto existingNetworkResourceLoadIdentifierToResume) mutable {
+                    auto processForNavigation = m_process->processPool().processForRegistrableDomain(websiteDataStore(), this, responseDomain);
+                    continueNavigationInNewProcess(*navigation, nullptr, WTFMove(processForNavigation), ProcessSwapRequestedByClient::No, ShouldTreatAsContinuingLoad::YesAfterResponsePolicyDecision, nullptr, existingNetworkResourceLoadIdentifierToResume);
+
+                    receivedPolicyDecision(PolicyAction::Ignore, navigation.get(), nullptr, WTFMove(navigationResponse), WTFMove(sender), { }, WillContinueLoadInNewProcess::Yes);
+                });
+                return;
             }
         }
         

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -42,6 +42,7 @@
 #include "MediaKeySystemPermissionRequestManagerProxy.h"
 #include "MediaPlaybackState.h"
 #include "MessageSender.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "PDFPluginIdentifier.h"
 #include "PageLoadState.h"
 #include "PasteboardAccessIntent.h"
@@ -1741,10 +1742,10 @@
     void didNavigateWithNavigationDataShared(Ref<WebProcessProxy>&&, const WebNavigationDataStore&, WebCore::FrameIdentifier);
     void didChangeProvisionalURLForFrameShared(Ref<WebProcessProxy>&&, WebCore::FrameIdentifier, uint64_t navigationID, URL&&);
     void decidePolicyForNavigationActionAsyncShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, NavigationActionData&&, FrameInfoData&& originatingFrameInfo, std::optional<WebPageProxyIdentifier> originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData&, uint64_t listenerID);
-    void decidePolicyForResponseShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t listenerID, const UserData&);
+    void decidePolicyForResponseShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t mainResourceLoadIdentifier, uint64_t listenerID, const UserData&);
     void startURLSchemeTaskShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, URLSchemeTaskParameters&&);
     void loadDataWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain>, std::optional<WebsitePoliciesData>&&, WebCore::ShouldOpenExternalURLsPolicy, WebCore::SubstituteData::SessionHistoryVisibility);
-    void loadRequestWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain>, std::optional<WebsitePoliciesData>&& = std::nullopt);
+    void loadRequestWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, std::optional<NavigatingToAppBoundDomain>, std::optional<WebsitePoliciesData>&& = std::nullopt, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume = std::nullopt);
     void backForwardGoToItemShared(Ref<WebProcessProxy>&&, const WebCore::BackForwardItemIdentifier&, CompletionHandler<void(const WebBackForwardListCounts&)>&&);
     void decidePolicyForNavigationActionSyncShared(Ref<WebProcessProxy>&&, WebCore::FrameIdentifier, bool isMainFrame, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, NavigationActionData&&, FrameInfoData&& originatingFrameInfo, std::optional<WebPageProxyIdentifier> originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData&, Messages::WebPageProxy::DecidePolicyForNavigationActionSyncDelayedReply&&);
 #if USE(QUICK_LOOK)
@@ -2062,7 +2063,7 @@
     void decidePolicyForNewWindowAction(WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, NavigationActionData&&,
         WebCore::ResourceRequest&&, const String& frameName, uint64_t listenerID, const UserData&);
     void decidePolicyForResponse(WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID,
-        const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t listenerID, const UserData&);
+        const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t mainResourceLoadIdentifier, uint64_t listenerID, const UserData&);
     void unableToImplementPolicy(WebCore::FrameIdentifier, const WebCore::ResourceError&, const UserData&);
     void beginSafeBrowsingCheck(const URL&, bool, WebFramePolicyListenerProxy&);
 
@@ -2464,7 +2465,7 @@
 
     void reportPageLoadResult(const WebCore::ResourceError& = { });
 
-    void continueNavigationInNewProcess(API::Navigation&, std::unique_ptr<SuspendedPageProxy>&&, Ref<WebProcessProxy>&&, ProcessSwapRequestedByClient, WebCore::ShouldTreatAsContinuingLoad, RefPtr<API::WebsitePolicies>&&);
+    void continueNavigationInNewProcess(API::Navigation&, std::unique_ptr<SuspendedPageProxy>&&, Ref<WebProcessProxy>&&, ProcessSwapRequestedByClient, WebCore::ShouldTreatAsContinuingLoad, RefPtr<API::WebsitePolicies>&&, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume = std::nullopt);
 
     void setNeedsFontAttributes(bool);
     void updateFontAttributesAfterEditorStateChange();

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in	2021-10-11 17:41:58 UTC (rev 283908)
@@ -107,7 +107,7 @@
 #endif
 
     # Policy messages
-    DecidePolicyForResponse(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, WebCore::PolicyCheckIdentifier policyCheckIdentifier, uint64_t navigationID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, String downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t listenerID, WebKit::UserData userData)
+    DecidePolicyForResponse(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, WebCore::PolicyCheckIdentifier policyCheckIdentifier, uint64_t navigationID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, String downloadAttribute, bool wasAllowedByInjectedBundle, bool needsBrowsingContextGroupSwitch, uint64_t mainResourceLoadIdentifier, uint64_t listenerID, WebKit::UserData userData)
     DecidePolicyForNavigationActionAsync(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, WebCore::PolicyCheckIdentifier policyCheckIdentifier, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, std::optional<WebKit::WebPageProxyIdentifier> originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, IPC::FormDataReference requestBody, WebCore::ResourceResponse redirectResponse, WebKit::UserData userData, uint64_t listenerID)
     DecidePolicyForNavigationActionSync(WebCore::FrameIdentifier frameID, bool isMainFrame, struct WebKit::FrameInfoData frameInfo, WebCore::PolicyCheckIdentifier policyCheckIdentifier, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, std::optional<WebKit::WebPageProxyIdentifier> originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, IPC::FormDataReference requestBody, WebCore::ResourceResponse redirectResponse, WebKit::UserData userData) -> (struct WebKit::PolicyDecision PolicyDecision) Synchronous
     DecidePolicyForNewWindowAction(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, WebCore::PolicyCheckIdentifier policyCheckIdentifier, struct WebKit::NavigationActionData navigationActionData, WebCore::ResourceRequest request, String frameName, uint64_t listenerID, WebKit::UserData userData)

Modified: branches/safari-612-branch/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -412,8 +412,11 @@
 
     ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials);
 
-    WEBLOADERSTRATEGY_RELEASE_LOG("scheduleLoad: Resource is being scheduled with the NetworkProcess (priority=%d)", static_cast<int>(resourceLoader.request().priority()));
-    if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::ScheduleResourceLoad(loadParameters), 0)) {
+    std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume;
+    if (loadParameters.isMainFrameNavigation)
+        existingNetworkResourceLoadIdentifierToResume = std::exchange(m_existingNetworkResourceLoadIdentifierToResume, std::nullopt);
+    WEBLOADERSTRATEGY_RELEASE_LOG("scheduleLoad: Resource is being scheduled with the NetworkProcess (priority=%d, existingNetworkResourceLoadIdentifierToResume=%" PRIu64 ")", static_cast<int>(resourceLoader.request().priority()), existingNetworkResourceLoadIdentifierToResume.value_or(NetworkResourceLoadIdentifier { }).toUInt64());
+    if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::ScheduleResourceLoad(loadParameters, existingNetworkResourceLoadIdentifierToResume), 0)) {
         WEBLOADERSTRATEGY_RELEASE_LOG_ERROR("scheduleLoad: Unable to schedule resource with the NetworkProcess (priority=%d)", static_cast<int>(resourceLoader.request().priority()));
         // We probably failed to schedule this load with the NetworkProcess because it had crashed.
         // This load will never succeed so we will schedule it to fail asynchronously.

Modified: branches/safari-612-branch/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "NetworkResourceLoadIdentifier.h"
 #include "WebResourceLoader.h"
 #include <WebCore/LoaderStrategy.h>
 #include <WebCore/ResourceError.h>
@@ -93,6 +94,8 @@
 
     static constexpr Seconds mediaMaximumBufferingTime { 50_ms };
 
+    void setExistingNetworkResourceLoadIdentifierToResume(std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume) { m_existingNetworkResourceLoadIdentifierToResume = existingNetworkResourceLoadIdentifierToResume; }
+
 private:
     void scheduleLoad(WebCore::ResourceLoader&, WebCore::CachedResource*, bool shouldClearReferrerOnHTTPSToHTTPRedirect);
     void scheduleInternallyFailedLoad(WebCore::ResourceLoader&);
@@ -135,6 +138,7 @@
     HashMap<unsigned long, PingLoadCompletionHandler> m_pingLoadCompletionHandlers;
     HashMap<unsigned long, PreconnectCompletionHandler> m_preconnectCompletionHandlers;
     Vector<Function<void(bool)>> m_onlineStateChangeListeners;
+    std::optional<NetworkResourceLoadIdentifier> m_existingNetworkResourceLoadIdentifierToResume;
     bool m_isOnLine { true };
 };
 

Modified: branches/safari-612-branch/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -91,6 +91,7 @@
 #include <WebCore/ScriptController.h>
 #include <WebCore/SecurityOriginData.h>
 #include <WebCore/Settings.h>
+#include <WebCore/SubresourceLoader.h>
 #include <WebCore/UIEventWithKeyState.h>
 #include <WebCore/Widget.h>
 #include <WebCore/WindowFeatures.h>
@@ -848,11 +849,13 @@
     auto* coreFrame = m_frame->coreFrame();
     auto* policyDocumentLoader = coreFrame ? coreFrame->loader().provisionalDocumentLoader() : nullptr;
     auto navigationID = policyDocumentLoader ? static_cast<WebDocumentLoader&>(*policyDocumentLoader).navigationID() : 0;
+    // FIXME: We should be using a strongly-typed identifier for mainResourceLoadIdentifier.
+    auto mainResourceLoadIdentifier = policyDocumentLoader && policyDocumentLoader->mainResourceLoader() ? policyDocumentLoader->mainResourceLoader()->identifier() : 0;
 
     bool wasAllowedByInjectedBundle = policy == WKBundlePagePolicyActionUse;
     auto protector = m_frame.copyRef();
     uint64_t listenerID = m_frame->setUpPolicyListener(identifier, WTFMove(function), WebFrame::ForNavigationAction::No);
-    if (!webPage->send(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), m_frame->info(), identifier, navigationID, response, request, canShowResponse, downloadAttribute, wasAllowedByInjectedBundle, needsBrowsingContextGroupSwitch, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())))) {
+    if (!webPage->send(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), m_frame->info(), identifier, navigationID, response, request, canShowResponse, downloadAttribute, wasAllowedByInjectedBundle, needsBrowsingContextGroupSwitch, mainResourceLoadIdentifier, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())))) {
         WEBFRAMELOADERCLIENT_RELEASE_LOG(Network, "dispatchDecidePolicyForResponse: ignoring because WebPageProxy::DecidePolicyForResponse failed");
         m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { identifier, std::nullopt, PolicyAction::Ignore, 0, { }, { } });
     }

Modified: branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-10-11 17:41:58 UTC (rev 283908)
@@ -262,6 +262,7 @@
 #include <pal/SessionID.h>
 #include <wtf/ProcessID.h>
 #include <wtf/RunLoop.h>
+#include <wtf/Scope.h>
 #include <wtf/SetForScope.h>
 #include <wtf/SystemTracing.h>
 #include <wtf/text/TextStream.h>
@@ -1703,6 +1704,11 @@
     setIsNavigatingToAppBoundDomain(loadParameters.isNavigatingToAppBoundDomain, &m_mainFrame.get());
 #endif
 
+    WebProcess::singleton().webLoaderStrategy().setExistingNetworkResourceLoadIdentifierToResume(loadParameters.existingNetworkResourceLoadIdentifierToResume);
+    auto resumingLoadScope = makeScopeExit([] {
+        WebProcess::singleton().webLoaderStrategy().setExistingNetworkResourceLoadIdentifierToResume(std::nullopt);
+    });
+
     SendStopResponsivenessTimer stopper;
 
     m_pendingNavigationID = loadParameters.navigationID;

Modified: branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/WebPage.h (283907 => 283908)


--- branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-10-11 17:34:25 UTC (rev 283907)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-10-11 17:41:58 UTC (rev 283908)
@@ -46,6 +46,7 @@
 #include "LayerTreeContext.h"
 #include "MessageReceiver.h"
 #include "MessageSender.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "OptionalCallbackID.h"
 #include "PDFPluginIdentifier.h"
 #include "Plugin.h"
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to