WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-229465-20210826130815.patch (text/plain), 79.37 KB, created by
Chris Dumez
on 2021-08-26 13:08:16 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2021-08-26 13:08:16 PDT
Size:
79.37 KB
patch
obsolete
>Subversion Revision: 281645 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index cf000afcb2d5169df17894902beeeab9fac90841..e6ae25727a8ccfb6f8bb4d6945af820ed62a7561 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,99 @@ >+2021-08-26 Chris Dumez <cdumez@apple.com> >+ >+ [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 NOBODY (OOPS!). >+ >+ 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-26 Myles C. Maxfield <mmaxfield@apple.com> > > Clean up logging #includes >diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp >index d962a98af5467544fb4087c481aa22ea7ea5f620..5579cdfa78dd14d1f5b7e3bf40bc23e477bae653 100644 >--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp >@@ -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::hasUploadStateChanged(bool hasUpload) > > void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoader& loader) > { >- RELEASE_ASSERT(loader.identifier()); >+ RELEASE_ASSERT(loader.coreIdentifier()); > RELEASE_ASSERT(RunLoop::isMain()); > > if (loader.isKeptAlive()) { >@@ -174,16 +175,16 @@ void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoad > 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) > { > 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,38 @@ std::unique_ptr<ServiceWorkerFetchTask> NetworkConnectionToWebProcess::createFet > } > #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 existingLoader = networkProcess().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"); >+ } >+ > auto& loader = m_networkResourceLoaders.add(identifier, NetworkResourceLoader::create(WTFMove(loadParameters), *this)).iterator->value; > > #if ENABLE(SERVICE_WORKER) >@@ -1269,6 +1281,13 @@ void NetworkConnectionToWebProcess::prioritizeResourceLoads(Vector<ResourceLoadI > session->networkLoadScheduler().prioritizeLoads(loads); > } > >+RefPtr<NetworkResourceLoader> NetworkConnectionToWebProcess::takeNetworkResourceLoader(uint64_t resourceLoadIdentifier) >+{ >+ if (!m_networkResourceLoaders.isValidKey(resourceLoadIdentifier)) >+ return nullptr; >+ return m_networkResourceLoaders.take(resourceLoadIdentifier); >+} >+ > } // namespace WebKit > > #undef CONNECTION_RELEASE_LOG >diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h >index 5e07091e3736de352192cfe78679cb622b23df2f..f4a0ab7193efc6cffac60fefcdcd38fbae9f0950 100644 >--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h >+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h >@@ -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 @@ public: > 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 @@ private: > 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&&); >diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in >index be9244e86fcde35c98c60c704cbaef2402fd0d6a..73f3e891629e223449e47532dd1424735e3d4b0c 100644 >--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in >+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in >@@ -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) >diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp >index 5d6829b2880254bd011310a9fd29d785edb6e055..140b723ee2e0e46fbee216a11e227b2a29c26f0f 100644 >--- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp >@@ -119,6 +119,8 @@ > namespace WebKit { > using namespace WebCore; > >+constexpr Seconds cachedNetworkResourceLoaderLifetime { 30_s }; >+ > static void callExitSoon(IPC::Connection*) > { > // If the connection has been closed and we haven't responded in the main thread for 10 seconds >@@ -2815,6 +2817,48 @@ RTCDataChannelRemoteManagerProxy& NetworkProcess::rtcDataChannelProxy() > } > #endif > >+NetworkProcess::CachedNetworkResourceLoader::CachedNetworkResourceLoader(Ref<NetworkResourceLoader>&& loader) >+ : m_expirationTimer(*this, &CachedNetworkResourceLoader::expirationTimerFired) >+ , m_loader(WTFMove(loader)) >+{ >+ m_expirationTimer.startOneShot(cachedNetworkResourceLoaderLifetime); >+} >+ >+Ref<NetworkResourceLoader> NetworkProcess::CachedNetworkResourceLoader::takeLoader() >+{ >+ return m_loader.releaseNonNull(); >+} >+ >+void NetworkProcess::CachedNetworkResourceLoader::expirationTimerFired() >+{ >+ auto loader = m_loader->connectionToWebProcess().networkProcess().takeLoaderAwaitingWebProcessTransfer(m_loader->identifier()); >+ ASSERT_UNUSED(loader, loader); >+} >+ >+RefPtr<NetworkResourceLoader> NetworkProcess::takeLoaderAwaitingWebProcessTransfer(NetworkResourceLoadIdentifier identifier) >+{ >+ auto cachedResourceLoader = m_loadersAwaitingWebProcessTransfer.take(identifier); >+ if (!cachedResourceLoader) >+ return nullptr; >+ return cachedResourceLoader->takeLoader(); >+} >+ >+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 loader = connection->takeNetworkResourceLoader(resourceLoadIdentifier); >+ if (!loader) >+ return completionHandler(std::nullopt); >+ >+ auto identifier = loader->identifier(); >+ m_loadersAwaitingWebProcessTransfer.add(identifier, makeUnique<CachedNetworkResourceLoader>(loader.releaseNonNull())); >+ completionHandler(identifier); >+} >+ > void NetworkProcess::addWebPageNetworkParameters(PAL::SessionID sessionID, WebPageProxyIdentifier pageID, WebPageNetworkParameters&& parameters) > { > auto session = networkSession(sessionID); >diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h >index ea91ed59403e49fe27da681931671e96ff7bf9a7..42e203c70fc37f43a7783dd79f14fb2d56cc96eb 100644 >--- a/Source/WebKit/NetworkProcess/NetworkProcess.h >+++ b/Source/WebKit/NetworkProcess/NetworkProcess.h >@@ -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" >@@ -389,6 +390,8 @@ public: > RTCDataChannelRemoteManagerProxy& rtcDataChannelProxy(); > #endif > >+ RefPtr<NetworkResourceLoader> takeLoaderAwaitingWebProcessTransfer(NetworkResourceLoadIdentifier); >+ > private: > void platformInitializeNetworkProcess(const NetworkProcessCreationParameters&); > >@@ -422,6 +425,7 @@ private: > 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()>&&); >@@ -609,6 +613,19 @@ private: > > HashMap<WebCore::PageIdentifier, Vector<WebCore::UserContentURLPattern>> m_extensionCORSDisablingPatterns; > >+ class CachedNetworkResourceLoader { >+ WTF_MAKE_FAST_ALLOCATED; >+ public: >+ explicit CachedNetworkResourceLoader(Ref<NetworkResourceLoader>&&); >+ Ref<NetworkResourceLoader> takeLoader(); >+ private: >+ void expirationTimerFired(); >+ WebCore::Timer m_expirationTimer; >+ RefPtr<NetworkResourceLoader> m_loader; >+ }; >+ >+ HashMap<NetworkResourceLoadIdentifier, std::unique_ptr<CachedNetworkResourceLoader>> m_loadersAwaitingWebProcessTransfer; >+ > bool m_privateClickMeasurementEnabled { true }; > bool m_privateClickMeasurementDebugModeEnabled { false }; > }; >diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in >index d7997451c4540cc3d7565348c76a234491382f9a..caeb8d9bb848c6900ae9555d0759f92d59bf2492 100644 >--- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in >+++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in >@@ -195,6 +195,8 @@ messages -> NetworkProcess LegacyReceiver { > 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 >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >index 82f1e530144fa0ff2dab11e644c09b7f6861a000..296d45102bd18d3fefdcf3015437fd8c3fc0e28f 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >@@ -522,6 +522,16 @@ void NetworkResourceLoader::abort() > 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()) >@@ -546,12 +556,12 @@ bool NetworkResourceLoader::shouldInterruptLoadForXFrameOptions(const String& xF > } > 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; > } > } >@@ -578,7 +588,7 @@ bool NetworkResourceLoader::shouldInterruptLoadForCSPFrameAncestorsOrXFrameOptio > 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; > } > } >@@ -595,7 +605,7 @@ bool NetworkResourceLoader::shouldInterruptNavigationForCrossOriginEmbedderPolic > 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; > } > } >@@ -611,7 +621,7 @@ bool NetworkResourceLoader::shouldInterruptWorkerLoadForCrossOriginEmbedderPolic > 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; > } > } >@@ -630,7 +640,7 @@ void NetworkResourceLoader::didReceiveResponse(ResourceResponse&& receivedRespon > 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)); > } > > // For multipart/x-mixed-replace didReceiveResponseAsync gets called multiple times and buffering would require special handling. >@@ -758,7 +768,7 @@ void NetworkResourceLoader::didFinishLoading(const NetworkLoadMetrics& networkLo > 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 >@@ -801,7 +811,7 @@ void NetworkResourceLoader::didFailLoading(const ResourceError& error) > UNUSED_VARIABLE(wasServiceWorkerLoad); > > if (shouldCaptureExtraNetworkLoadMetrics()) >- m_connection->removeNetworkLoadInformation(identifier()); >+ m_connection->removeNetworkLoadInformation(coreIdentifier()); > > ASSERT(!error.isNull()); > >@@ -1202,9 +1212,10 @@ void NetworkResourceLoader::didRetrieveCacheEntry(std::unique_ptr<NetworkCache:: > 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); > } >@@ -1359,7 +1370,7 @@ void NetworkResourceLoader::logCookieInformation() const > 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) >@@ -1463,7 +1474,7 @@ void NetworkResourceLoader::logCookieInformation(NetworkConnectionToWebProcess& > > 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) >@@ -1534,7 +1545,7 @@ void NetworkResourceLoader::serviceWorkerDidNotHandle(ServiceWorkerFetchTask* fe > 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; > } >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.h b/Source/WebKit/NetworkProcess/NetworkResourceLoader.h >index cef65479b7e6bcff25cff01825c2bd3a0c7687ef..d92d3038a1def131b8c04d5dcf45ad1d55583ccf 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.h >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.h >@@ -85,19 +85,23 @@ public: > 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() }; } > >@@ -210,7 +214,7 @@ private: > > ResourceLoadInfo resourceLoadInfo(); > >- const NetworkResourceLoadParameters m_parameters; >+ NetworkResourceLoadParameters m_parameters; > > Ref<NetworkConnectionToWebProcess> m_connection; > >diff --git a/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp b/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp >index af951d5a0b59f69167b704fb42b30f1b8001e287..d455935253f79f5c0431dbaeef9293360704ea26 100644 >--- a/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp >+++ b/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp >@@ -78,7 +78,7 @@ template<typename Message> bool ServiceWorkerFetchTask::sendToServiceWorker(Mess > > 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 @@ void ServiceWorkerFetchTask::didReceiveResponse(ResourceResponse&& response, boo > > 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) >diff --git a/Source/WebKit/Shared/LoadParameters.cpp b/Source/WebKit/Shared/LoadParameters.cpp >index eca11a3a00c23437507e01d96cb0e498101864c4..346f7d8d8450b6fbd0e80661f10dcbe5959852b4 100644 >--- a/Source/WebKit/Shared/LoadParameters.cpp >+++ b/Source/WebKit/Shared/LoadParameters.cpp >@@ -57,6 +57,7 @@ void LoadParameters::encode(IPC::Encoder& encoder) const > encoder << lockBackForwardList; > encoder << clientRedirectSourceForHistory; > encoder << isNavigatingToAppBoundDomain; >+ encoder << existingNetworkResourceLoadIdentifierToResume; > encoder << sessionHistoryVisibility; > > platformEncode(encoder); >@@ -137,6 +138,9 @@ bool LoadParameters::decode(IPC::Decoder& decoder, LoadParameters& data) > > if (!decoder.decode(data.isNavigatingToAppBoundDomain)) > return false; >+ >+ if (!decoder.decode(data.existingNetworkResourceLoadIdentifierToResume)) >+ return false; > > if (!decoder.decode(data.sessionHistoryVisibility)) > return false; >diff --git a/Source/WebKit/Shared/LoadParameters.h b/Source/WebKit/Shared/LoadParameters.h >index e5c57b04049c8b20b6bd611cfc8f6b01f78c07fc..0c0540b046e4a1cc4b1915dea1340f9da066cb13 100644 >--- a/Source/WebKit/Shared/LoadParameters.h >+++ b/Source/WebKit/Shared/LoadParameters.h >@@ -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 @@ struct LoadParameters { > WebCore::SubstituteData::SessionHistoryVisibility sessionHistoryVisibility { WebCore::SubstituteData::SessionHistoryVisibility::Visible }; > String clientRedirectSourceForHistory; > std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain; >+ std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume; > > #if PLATFORM(COCOA) > RetainPtr<NSDictionary> dataDetectionContext; >diff --git a/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp b/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp >index 671add4aa27cd17ebb6790efe16a55a1c14366eb..b1ac3d438a2ea0440cf23caa475d479f699f7b92 100644 >--- a/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp >+++ b/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp >@@ -475,6 +475,17 @@ void NetworkProcessProxy::terminateUnresponsiveServiceWorkerProcesses(WebCore::P > } > } > >+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); >diff --git a/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h b/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h >index 58a8a8e94bf3cfe7bf8c7797985cc12bd3ab68be..4e5bb459a3d72e3d1dd70b2e5ef22bf440817220 100644 >--- a/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h >+++ b/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h >@@ -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 @@ public: > 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(); > >diff --git a/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp b/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp >index 41cd35dbfa8d0e34bd1eb49f5d574f2c3700bd58..75a65c433706547800e620ad05f456c36041eff3 100644 >--- a/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp >+++ b/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp >@@ -171,9 +171,9 @@ void ProvisionalPageProxy::loadData(API::Navigation& navigation, const IPC::Data > 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 @@ void ProvisionalPageProxy::loadRequest(API::Navigation& navigation, WebCore::Res > 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 @@ void ProvisionalPageProxy::decidePolicyForNavigationActionAsync(FrameIdentifier > 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) >diff --git a/Source/WebKit/UIProcess/ProvisionalPageProxy.h b/Source/WebKit/UIProcess/ProvisionalPageProxy.h >index 2714b2a5b547f2667fcb46fcef1b5784fbcf5810..0abea9da6bbd20114ff54c1b8d71cafdbf723762 100644 >--- a/Source/WebKit/UIProcess/ProvisionalPageProxy.h >+++ b/Source/WebKit/UIProcess/ProvisionalPageProxy.h >@@ -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 @@ public: > #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 @@ private: > 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&); >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index 5fb308950156248666153c624f4034ea4a884fdf..7bef9658711c1b6287a37f5e000bb15186f27b7b 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -1381,7 +1381,7 @@ RefPtr<API::Navigation> WebPageProxy::loadRequest(ResourceRequest&& request, Sho > 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 @@ void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& proces > 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); >@@ -3620,7 +3621,7 @@ void WebPageProxy::commitProvisionalPage(FrameIdentifier frameID, FrameInfoData& > 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()); >@@ -3637,7 +3638,7 @@ void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, s > 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()); > >@@ -3660,10 +3661,11 @@ void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, s > > // 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)); >@@ -5617,12 +5619,12 @@ void WebPageProxy::decidePolicyForNewWindowAction(FrameIdentifier frameID, Frame > > 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()); > >@@ -5635,13 +5637,13 @@ void WebPageProxy::decidePolicyForResponseShared(Ref<WebProcessProxy>&& process, > 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); > }); > >@@ -5649,12 +5651,15 @@ void WebPageProxy::decidePolicyForResponseShared(Ref<WebProcessProxy>&& process, > 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; > } > } > >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index ea1c22fb6b11be9689928264d3bf3fc847109b8d..fff85b551af036910e412ead712becc13c91bf26 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -43,6 +43,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 @@ public: > 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) >@@ -2060,7 +2061,7 @@ private: > 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&); > >@@ -2462,7 +2463,7 @@ private: > > 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(); >diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in >index bc37b8fc6adf3ead1872d1155ff0cbd009dc0af9..8196b119a8f02e7a00604085028e91ae23186519 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.messages.in >+++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in >@@ -107,7 +107,7 @@ messages -> WebPageProxy { > #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) >diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >index 6e96907254a4bd155f58df137848b605319f5155..349ea2c63692ab808fc73f5d886a2aa9e5ccf22d 100644 >--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >@@ -412,8 +412,11 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL > > 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. >diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >index ca2349958666a801b0e0a6bd767dbbcccfb716ae..24b69379017d5439bbb1e1b3d1a95c8b792360ef 100644 >--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >@@ -25,6 +25,7 @@ > > #pragma once > >+#include "NetworkResourceLoadIdentifier.h" > #include "WebResourceLoader.h" > #include <WebCore/LoaderStrategy.h> > #include <WebCore/ResourceError.h> >@@ -91,6 +92,8 @@ public: > > static uint64_t generateLoadIdentifier(); > >+ void setExistingNetworkResourceLoadIdentifierToResume(std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume) { m_existingNetworkResourceLoadIdentifierToResume = existingNetworkResourceLoadIdentifierToResume; } >+ > private: > void scheduleLoad(WebCore::ResourceLoader&, WebCore::CachedResource*, bool shouldClearReferrerOnHTTPSToHTTPRedirect); > void scheduleInternallyFailedLoad(WebCore::ResourceLoader&); >@@ -133,6 +136,7 @@ private: > 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 }; > }; > >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >index 72315a5758735ed5ef19666291e610d38cc0e9e1..8bb3ce8910892fdd079bdcd9c9dbfc4004067460 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >@@ -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,12 @@ void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceRespons > auto* coreFrame = m_frame->coreFrame(); > auto* policyDocumentLoader = coreFrame ? coreFrame->loader().provisionalDocumentLoader() : nullptr; > auto navigationID = policyDocumentLoader ? static_cast<WebDocumentLoader&>(*policyDocumentLoader).navigationID() : 0; >+ uint64_t 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, { }, { } }); > } >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >index 04e3ae20143f2f3dbd2064a302f01b84edca9645..fe4f49a645c7f6049141881f28021504ea38fa56 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >@@ -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> >@@ -1689,6 +1690,11 @@ void WebPage::loadRequest(LoadParameters&& loadParameters) > 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; >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h >index 1881a5f366323c7340c008fff8664e395dbc95d3..0efcd5dab95a420d9ba02645114534ee450491d9 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.h >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h >@@ -47,6 +47,7 @@ > #include "LayerTreeContext.h" > #include "MessageReceiver.h" > #include "MessageSender.h" >+#include "NetworkResourceLoadIdentifier.h" > #include "OptionalCallbackID.h" > #include "PDFPluginIdentifier.h" > #include "Plugin.h" >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index ac3bd03f009b87e059dd8ca94608c0ef6c3084cf..9d6bc4cc30aea6afb1174c254af9097be37b3a29 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,18 @@ >+2021-08-26 Chris Dumez <cdumez@apple.com> >+ >+ [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 NOBODY (OOPS!). >+ >+ 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-26 Eric Hutchison <ehutchison@apple.com> > > Update test expectations for webgl tests. >diff --git a/LayoutTests/http/wpt/cross-origin-opener-policy/resources/single-request-to-server-popup.py b/LayoutTests/http/wpt/cross-origin-opener-policy/resources/single-request-to-server-popup.py >new file mode 100644 >index 0000000000000000000000000000000000000000..442b3bdcb29f78a16d045cf30924862e286e8a30 >--- /dev/null >+++ b/LayoutTests/http/wpt/cross-origin-opener-policy/resources/single-request-to-server-popup.py >@@ -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) >diff --git a/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server-expected.txt b/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f6577ece9f5b7bafbaf6d4d229f0f309d66ad040 >--- /dev/null >+++ b/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Make sure we make a single request to the HTTP server when switching browsing context group >+ >diff --git a/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server.html b/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server.html >new file mode 100644 >index 0000000000000000000000000000000000000000..622f0dde68ee17e8550b979b3b2358a1fa5a77c5 >--- /dev/null >+++ b/LayoutTests/http/wpt/cross-origin-opener-policy/single-request-to-server.html >@@ -0,0 +1,22 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset=utf-8> >+<script src=/resources/testharness.js></script> >+<script src=/resources/testharnessreport.js></script> >+<script src="/common/utils.js"></script >+</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>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
ews-feeder
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 229465
:
436334
|
436399
|
436414
|
436417
|
436430
|
436432
|
436436
|
436511
|
436553
|
436556
|
436626
|
436627
|
436638