⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 242371 in webkit


Ignore:
Timestamp:
Mar 4, 2019, 12:26:06 PM (7 years ago)
Author:
Chris Dumez
Message:

Do not share WebProcesses between private and regular sessions
https://bugs.webkit.org/show_bug.cgi?id=195189
<rdar://problem/48421064>

Reviewed by Alex Christensen.

Source/WebKit:

Do not share WebProcesses between private and regular sessions. There are some privacy concerns.
Also, some of the WebsiteDataStore informations are passed via WebProcessCreationParameters (e.g.
ApplicationCache path) and cannot be updated later.

There were 2 cases where this could happen and that are fixed in the patch:

  • A process may be prewarmed with a given website data store and then later on used for a page associated with a different data store. We now prevent this. While this is not necessary for privacy reasons, it is still useful because our code currently does not support well uses different sessions inside a single WebProcess, as mentioned above.
  • The client can force a WebsiteDataStore swap when responding to the decidePolicyForNavigationAction, via the WebsitePolicies. To address the issue, we now force a process swap whenever the client makes such a change.

As a result, WebProcessProxy::websiteDataStore() now makes sense and is always correct. It can
also only contains pages whose WebPageProxy::websiteDataStore() returns the same store.

  • UIProcess/API/C/WKContext.cpp:

(WKContextWarmInitialProcess):

  • UIProcess/API/Cocoa/WKProcessPool.mm:

(-[WKProcessPool _warmInitialProcess]):

  • UIProcess/ProvisionalPageProxy.cpp:

(WebKit::ProvisionalPageProxy::ProvisionalPageProxy):
(WebKit::ProvisionalPageProxy::~ProvisionalPageProxy):

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::notifyProcessPoolToPrewarm):
(WebKit::WebPageProxy::reattachToWebProcess):
(WebKit::WebPageProxy::swapToWebProcess):
(WebKit::WebPageProxy::close):
(WebKit::WebPageProxy::receivedNavigationPolicyDecision):
(WebKit::WebPageProxy::commitProvisionalPage):
(WebKit::WebPageProxy::creationParameters):

  • UIProcess/WebPageProxy.h:

(WebKit::WebPageProxy::websiteDataStore):

  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::ensureNetworkProcess):
(WebKit::WebProcessPool::tryTakePrewarmedProcess):
(WebKit::WebProcessPool::prewarmProcess):
(WebKit::WebProcessPool::createWebPage):
(WebKit::WebProcessPool::pageBeginUsingWebsiteDataStore):
(WebKit::WebProcessPool::pageEndUsingWebsiteDataStore):
(WebKit::WebProcessPool::didReachGoodTimeToPrewarm):
(WebKit::WebProcessPool::processForNavigation):
(WebKit::WebProcessPool::processForNavigationInternal):
(WebKit::WebProcessPool::findReusableSuspendedPageProcess):

  • UIProcess/WebProcessPool.h:

(WebKit::WebProcessPool::sendToOneProcess):

  • UIProcess/WebProcessProxy.cpp:

(WebKit::WebProcessProxy::createWebPage):
(WebKit::WebProcessProxy::addExistingWebPage):
(WebKit::WebProcessProxy::removeWebPage):

  • UIProcess/WebProcessProxy.h:

Tools:

Add API test coverage.

  • TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
  • TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r242369 r242371  
     12019-03-04  Chris Dumez  <cdumez@apple.com>
     2
     3        Do not share WebProcesses between private and regular sessions
     4        https://bugs.webkit.org/show_bug.cgi?id=195189
     5        <rdar://problem/48421064>
     6
     7        Reviewed by Alex Christensen.
     8
     9        Do not share WebProcesses between private and regular sessions. There are some privacy concerns.
     10        Also, some of the WebsiteDataStore informations are passed via WebProcessCreationParameters (e.g.
     11        ApplicationCache path) and cannot be updated later.
     12
     13        There were 2 cases where this could happen and that are fixed in the patch:
     14        - A process may be prewarmed with a given website data store and then later on used for a page
     15          associated with a different data store. We now prevent this. While this is not necessary for
     16          privacy reasons, it is still useful because our code currently does not support well uses
     17          different sessions inside a single WebProcess, as mentioned above.
     18        - The client can force a WebsiteDataStore swap when responding to the decidePolicyForNavigationAction,
     19          via the WebsitePolicies. To address the issue, we now force a process swap whenever the client
     20          makes such a change.
     21
     22        As a result, WebProcessProxy::websiteDataStore() now makes sense and is always correct. It can
     23        also only contains pages whose WebPageProxy::websiteDataStore() returns the same store.
     24
     25        * UIProcess/API/C/WKContext.cpp:
     26        (WKContextWarmInitialProcess):
     27        * UIProcess/API/Cocoa/WKProcessPool.mm:
     28        (-[WKProcessPool _warmInitialProcess]):
     29        * UIProcess/ProvisionalPageProxy.cpp:
     30        (WebKit::ProvisionalPageProxy::ProvisionalPageProxy):
     31        (WebKit::ProvisionalPageProxy::~ProvisionalPageProxy):
     32        * UIProcess/WebPageProxy.cpp:
     33        (WebKit::WebPageProxy::notifyProcessPoolToPrewarm):
     34        (WebKit::WebPageProxy::reattachToWebProcess):
     35        (WebKit::WebPageProxy::swapToWebProcess):
     36        (WebKit::WebPageProxy::close):
     37        (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
     38        (WebKit::WebPageProxy::commitProvisionalPage):
     39        (WebKit::WebPageProxy::creationParameters):
     40        * UIProcess/WebPageProxy.h:
     41        (WebKit::WebPageProxy::websiteDataStore):
     42        * UIProcess/WebProcessPool.cpp:
     43        (WebKit::WebProcessPool::ensureNetworkProcess):
     44        (WebKit::WebProcessPool::tryTakePrewarmedProcess):
     45        (WebKit::WebProcessPool::prewarmProcess):
     46        (WebKit::WebProcessPool::createWebPage):
     47        (WebKit::WebProcessPool::pageBeginUsingWebsiteDataStore):
     48        (WebKit::WebProcessPool::pageEndUsingWebsiteDataStore):
     49        (WebKit::WebProcessPool::didReachGoodTimeToPrewarm):
     50        (WebKit::WebProcessPool::processForNavigation):
     51        (WebKit::WebProcessPool::processForNavigationInternal):
     52        (WebKit::WebProcessPool::findReusableSuspendedPageProcess):
     53        * UIProcess/WebProcessPool.h:
     54        (WebKit::WebProcessPool::sendToOneProcess):
     55        * UIProcess/WebProcessProxy.cpp:
     56        (WebKit::WebProcessProxy::createWebPage):
     57        (WebKit::WebProcessProxy::addExistingWebPage):
     58        (WebKit::WebProcessProxy::removeWebPage):
     59        * UIProcess/WebProcessProxy.h:
     60
    1612019-03-04  Chris Dumez  <cdumez@apple.com>
    262
  • trunk/Source/WebKit/UIProcess/API/C/WKContext.cpp

    r240363 r242371  
    525525void WKContextWarmInitialProcess(WKContextRef contextRef)
    526526{
    527     WebKit::toImpl(contextRef)->prewarmProcess(WebKit::WebProcessPool::MayCreateDefaultDataStore::Yes);
     527    WebKit::toImpl(contextRef)->prewarmProcess(nullptr, WebKit::WebProcessPool::MayCreateDefaultDataStore::Yes);
    528528}
    529529
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm

    r242339 r242371  
    390390- (void)_warmInitialProcess
    391391{
    392     _processPool->prewarmProcess(WebKit::WebProcessPool::MayCreateDefaultDataStore::Yes);
     392    _processPool->prewarmProcess(nullptr, WebKit::WebProcessPool::MayCreateDefaultDataStore::Yes);
    393393}
    394394
  • trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp

    r242182 r242371  
    4242#include "WebPageProxyMessages.h"
    4343#include "WebProcessMessages.h"
     44#include "WebProcessPool.h"
    4445#include "WebProcessProxy.h"
    4546#include <WebCore/ShouldTreatAsContinuingLoad.h>
     
    6768        m_page.webProcessLifetimeTracker().webPageEnteringWebProcess(m_process);
    6869
     70    if (&m_process->websiteDataStore() != &m_page.websiteDataStore())
     71        m_process->processPool().pageBeginUsingWebsiteDataStore(m_page.pageID(), m_process->websiteDataStore());
     72
    6973    // If we are reattaching to a SuspendedPage, then the WebProcess' WebPage already exists and
    7074    // WebPageProxy::didCreateMainFrame() will not be called to initialize m_mainFrame. In such
     
    9094    if (m_process->state() == AuxiliaryProcessProxy::State::Running)
    9195        m_page.webProcessLifetimeTracker().webPageLeavingWebProcess(m_process);
     96
     97    if (&m_process->websiteDataStore() != &m_page.websiteDataStore())
     98        m_process->processPool().pageEndUsingWebsiteDataStore(m_page.pageID(), m_process->websiteDataStore());
    9299
    93100    m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID());
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r242336 r242371  
    563563}
    564564
    565 void WebPageProxy::changeWebsiteDataStore(WebsiteDataStore& websiteDataStore)
    566 {
    567     m_process->processPool().pageEndUsingWebsiteDataStore(*this);
    568     m_websiteDataStore = websiteDataStore;
    569     m_process->processPool().pageBeginUsingWebsiteDataStore(*this);
    570 }
    571 
    572565const API::PageConfiguration& WebPageProxy::configuration() const
    573566{
     
    594587void WebPageProxy::notifyProcessPoolToPrewarm()
    595588{
    596     m_process->processPool().didReachGoodTimeToPrewarm();
     589    m_process->processPool().didReachGoodTimeToPrewarm(m_websiteDataStore);
    597590}
    598591
     
    747740    RELEASE_LOG_IF_ALLOWED(Loading, "reattachToWebProcess: webPID = %i, pageID = %" PRIu64, m_process->processIdentifier(), m_pageID);
    748741
    749     m_process->removeWebPage(*this, m_pageID, WebProcessProxy::EndsUsingDataStore::Yes);
     742    m_process->removeWebPage(*this, WebProcessProxy::EndsUsingDataStore::Yes);
    750743    m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
    751744
     
    754747    m_isValid = true;
    755748
    756     m_process->addExistingWebPage(*this, m_pageID, WebProcessProxy::BeginsUsingDataStore::Yes);
     749    m_process->addExistingWebPage(*this, WebProcessProxy::BeginsUsingDataStore::Yes);
    757750    m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
    758751
     
    815808
    816809    m_process = WTFMove(process);
     810    m_websiteDataStore = m_process->websiteDataStore();
     811
    817812    ASSERT(!m_drawingArea);
    818813    setDrawingArea(WTFMove(drawingArea));
     
    821816    m_isValid = true;
    822817
    823     m_process->addExistingWebPage(*this, m_pageID, WebProcessProxy::BeginsUsingDataStore::No);
     818    m_process->addExistingWebPage(*this, WebProcessProxy::BeginsUsingDataStore::No);
    824819    m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
    825820
     
    10331028
    10341029    m_process->send(Messages::WebPage::Close(), m_pageID);
    1035     m_process->removeWebPage(*this, m_pageID, WebProcessProxy::EndsUsingDataStore::Yes);
     1030    m_process->removeWebPage(*this, WebProcessProxy::EndsUsingDataStore::Yes);
    10361031    m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
    10371032    m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
     
    27462741void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, API::Navigation* navigation, ProcessSwapRequestedByClient processSwapRequestedByClient, WebFrameProxy& frame, API::WebsitePolicies* policies, Ref<PolicyDecisionSender>&& sender)
    27472742{
     2743    Ref<WebsiteDataStore> websiteDataStore = m_websiteDataStore.copyRef();
    27482744    Optional<WebsitePoliciesData> data;
    27492745    if (policies) {
    27502746        data = policies->data();
    2751         if (policies->websiteDataStore())
    2752             changeWebsiteDataStore(policies->websiteDataStore()->websiteDataStore());
     2747        if (policies->websiteDataStore() && &policies->websiteDataStore()->websiteDataStore() != websiteDataStore.ptr()) {
     2748            websiteDataStore = policies->websiteDataStore()->websiteDataStore();
     2749            processSwapRequestedByClient = ProcessSwapRequestedByClient::Yes;
     2750        }
    27532751    }
    27542752
     
    27772775    }
    27782776
    2779     process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, [this, protectedThis = makeRef(*this), policyAction, navigation = makeRef(*navigation), sourceProcess = sourceProcess.copyRef(),
     2777    process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, WTFMove(websiteDataStore), [this, protectedThis = makeRef(*this), policyAction, navigation = makeRef(*navigation), sourceProcess = sourceProcess.copyRef(),
    27802778        data = WTFMove(data), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {
    27812779        // If the navigation has been destroyed, then no need to proceed.
     
    28542852    auto* navigation = navigationState().navigation(m_provisionalPage->navigationID());
    28552853    bool didSuspendPreviousPage = navigation ? suspendCurrentPageIfPossible(*navigation, mainFrameIDInPreviousProcess, m_provisionalPage->processSwapRequestedByClient()) : false;
    2856     m_process->removeWebPage(*this, m_pageID, WebProcessProxy::EndsUsingDataStore::No);
     2854    m_process->removeWebPage(*this, m_websiteDataStore.ptr() == &m_provisionalPage->process().websiteDataStore() ? WebProcessProxy::EndsUsingDataStore::No : WebProcessProxy::EndsUsingDataStore::Yes);
    28572855
    28582856    // There is no way we'll be able to return to the page in the previous page so close it.
     
    69056903    parameters.userAgent = userAgent();
    69066904    parameters.itemStates = m_backForwardList->itemStates();
    6907     parameters.sessionID = sessionID();
     6905    parameters.sessionID = process.websiteDataStore().sessionID();
    69086906    parameters.userContentControllerID = m_userContentController->identifier();
    69096907    parameters.visitedLinkTableID = m_visitedLinkStore->identifier();
    6910     parameters.websiteDataStoreID = m_websiteDataStore->identifier();
     6908    parameters.websiteDataStoreID = process.websiteDataStore().identifier();
    69116909    parameters.canRunBeforeUnloadConfirmPanel = m_uiClient->canRunBeforeUnloadConfirmPanel();
    69126910    parameters.canRunModal = m_canRunModal;
     
    69906988
    69916989#if ENABLE(SERVICE_WORKER)
    6992     parameters.hasRegisteredServiceWorkers = process.processPool().mayHaveRegisteredServiceWorkers(m_websiteDataStore);
     6990    parameters.hasRegisteredServiceWorkers = process.processPool().mayHaveRegisteredServiceWorkers(process.websiteDataStore());
    69936991#endif
    69946992
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r242339 r242371  
    378378
    379379    WebsiteDataStore& websiteDataStore() { return m_websiteDataStore; }
    380     void changeWebsiteDataStore(WebsiteDataStore&);
    381380
    382381    void addPreviouslyVisitedPath(const String&);
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r242305 r242371  
    605605
    606606    // Make sure the network process knows about all the sessions that have been registered before it started.
    607     for (auto& sessionID : m_sessionToPagesMap.keys()) {
     607    for (auto& sessionID : m_sessionToPageIDsMap.keys()) {
    608608        if (auto* websiteDataStore = WebsiteDataStore::existingNonDefaultDataStoreForSessionID(sessionID))
    609609            m_networkProcess->addSession(*websiteDataStore);
     
    783783{
    784784    if (!m_prewarmedProcess)
     785        return nullptr;
     786
     787    if (&m_prewarmedProcess->websiteDataStore() != &websiteDataStore)
    785788        return nullptr;
    786789
     
    981984}
    982985
    983 void WebProcessPool::prewarmProcess(MayCreateDefaultDataStore mayCreateDefaultDataStore)
    984 {
     986void WebProcessPool::prewarmProcess(WebsiteDataStore* websiteDataStore, MayCreateDefaultDataStore mayCreateDefaultDataStore)
     987{
     988    if (m_prewarmedProcess && websiteDataStore && &m_prewarmedProcess->websiteDataStore() != websiteDataStore) {
     989        RELEASE_LOG(PerformanceLogging, "Shutting down prewarmed process %i because we needed a prewarmed process with a different data store", m_prewarmedProcess->processIdentifier());
     990        m_prewarmedProcess->shutDown();
     991        ASSERT(!m_prewarmedProcess);
     992    }
     993
    985994    if (m_prewarmedProcess)
    986995        return;
    987996
    988     auto* websiteDataStore = m_websiteDataStore ? &m_websiteDataStore->websiteDataStore() : nullptr;
    989997    if (!websiteDataStore) {
    990         if (!m_processes.isEmpty())
    991             websiteDataStore = &m_processes.last()->websiteDataStore();
    992         else if (mayCreateDefaultDataStore == MayCreateDefaultDataStore::Yes || API::WebsiteDataStore::defaultDataStoreExists())
    993             websiteDataStore = &API::WebsiteDataStore::defaultDataStore()->websiteDataStore();
    994         else {
    995             RELEASE_LOG(PerformanceLogging, "Unable to prewarming a WebProcess because we could not find a usable data store");
    996             return;
     998        websiteDataStore = m_websiteDataStore ? &m_websiteDataStore->websiteDataStore() : nullptr;
     999        if (!websiteDataStore) {
     1000            if (!m_processes.isEmpty())
     1001                websiteDataStore = &m_processes.last()->websiteDataStore();
     1002            else if (mayCreateDefaultDataStore == MayCreateDefaultDataStore::Yes || API::WebsiteDataStore::defaultDataStoreExists())
     1003                websiteDataStore = &API::WebsiteDataStore::defaultDataStore()->websiteDataStore();
     1004            else {
     1005                RELEASE_LOG(PerformanceLogging, "Unable to prewarming a WebProcess because we could not find a usable data store");
     1006                return;
     1007            }
    9971008        }
    9981009    }
     1010
    9991011    ASSERT(websiteDataStore);
    10001012
     
    11581170    }
    11591171
     1172    auto page = process->createWebPage(pageClient, WTFMove(pageConfiguration));
     1173
    11601174#if ENABLE(SERVICE_WORKER)
    11611175    ASSERT(!is<ServiceWorkerProcessProxy>(*process));
    1162 #endif
    1163 
    1164     auto page = process->createWebPage(pageClient, WTFMove(pageConfiguration));
     1176
     1177    if (!m_serviceWorkerPreferences) {
     1178        m_serviceWorkerPreferences = page->preferencesStore();
     1179        for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values())
     1180            serviceWorkerProcess->updatePreferencesStore(*m_serviceWorkerPreferences);
     1181    }
     1182#endif
    11651183
    11661184    bool enableProcessSwapOnCrossSiteNavigation = page->preferences().processSwapOnCrossSiteNavigationEnabled();
     
    12071225#endif
    12081226
    1209 void WebProcessPool::pageBeginUsingWebsiteDataStore(WebPageProxy& page)
    1210 {
    1211     auto result = m_sessionToPagesMap.add(page.sessionID(), HashSet<WebPageProxy*>()).iterator->value.add(&page);
     1227void WebProcessPool::pageBeginUsingWebsiteDataStore(uint64_t pageID, WebsiteDataStore& dataStore)
     1228{
     1229    auto result = m_sessionToPageIDsMap.add(dataStore.sessionID(), HashSet<uint64_t>()).iterator->value.add(pageID);
    12121230    ASSERT_UNUSED(result, result.isNewEntry);
    12131231
    1214     auto sessionID = page.sessionID();
     1232    auto sessionID = dataStore.sessionID();
    12151233    if (sessionID.isEphemeral()) {
    1216         ASSERT(page.websiteDataStore().parameters().networkSessionParameters.sessionID == sessionID);
     1234        ASSERT(dataStore.parameters().networkSessionParameters.sessionID == sessionID);
    12171235        if (m_networkProcess)
    1218             m_networkProcess->addSession(makeRef(page.websiteDataStore()));
    1219         page.websiteDataStore().clearPendingCookies();
     1236            m_networkProcess->addSession(makeRef(dataStore));
     1237        dataStore.clearPendingCookies();
    12201238    } else if (sessionID != PAL::SessionID::defaultSessionID()) {
    12211239        if (m_networkProcess)
    1222             m_networkProcess->addSession(makeRef(page.websiteDataStore()));
    1223         page.websiteDataStore().clearPendingCookies();
    1224     }
    1225 
    1226 #if ENABLE(SERVICE_WORKER)
    1227     if (!m_serviceWorkerPreferences) {
    1228         m_serviceWorkerPreferences = page.preferencesStore();
    1229         for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values())
    1230             serviceWorkerProcess->updatePreferencesStore(*m_serviceWorkerPreferences);
    1231     }
    1232 #endif
    1233 }
    1234 
    1235 void WebProcessPool::pageEndUsingWebsiteDataStore(WebPageProxy& page)
    1236 {
    1237     auto sessionID = page.sessionID();
    1238     auto iterator = m_sessionToPagesMap.find(sessionID);
    1239     ASSERT(iterator != m_sessionToPagesMap.end());
    1240 
    1241     auto takenPage = iterator->value.take(&page);
    1242     ASSERT_UNUSED(takenPage, takenPage == &page);
     1240            m_networkProcess->addSession(makeRef(dataStore));
     1241        dataStore.clearPendingCookies();
     1242    }
     1243}
     1244
     1245void WebProcessPool::pageEndUsingWebsiteDataStore(uint64_t pageID, WebsiteDataStore& dataStore)
     1246{
     1247    auto sessionID = dataStore.sessionID();
     1248    auto iterator = m_sessionToPageIDsMap.find(sessionID);
     1249    ASSERT(iterator != m_sessionToPageIDsMap.end());
     1250
     1251    auto takenPageID = iterator->value.take(pageID);
     1252    ASSERT_UNUSED(takenPageID, takenPageID == pageID);
    12431253
    12441254    if (iterator->value.isEmpty()) {
    1245         m_sessionToPagesMap.remove(iterator);
     1255        m_sessionToPageIDsMap.remove(iterator);
    12461256
    12471257        if (sessionID == PAL::SessionID::defaultSessionID())
     
    13111321}
    13121322
    1313 void WebProcessPool::didReachGoodTimeToPrewarm()
     1323void WebProcessPool::didReachGoodTimeToPrewarm(WebsiteDataStore& dataStore)
    13141324{
    13151325    if (!configuration().isAutomaticProcessWarmingEnabled() || !configuration().processSwapsOnNavigation() || usesSingleWebProcess())
     
    13221332    }
    13231333
    1324     prewarmProcess(MayCreateDefaultDataStore::No);
     1334    prewarmProcess(&dataStore, MayCreateDefaultDataStore::No);
    13251335}
    13261336
     
    21402150}
    21412151
    2142 void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
    2143 {
    2144     processForNavigationInternal(page, navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, [this, page = makeRefPtr(page), navigation = makeRef(navigation), sourceProcess = sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, completionHandler = WTFMove(completionHandler)](Ref<WebProcessProxy>&& process, SuspendedPageProxy* suspendedPage, const String& reason) mutable {
     2152void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
     2153{
     2154    processForNavigationInternal(page, navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, WTFMove(dataStore), [this, page = makeRefPtr(page), navigation = makeRef(navigation), sourceProcess = sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, completionHandler = WTFMove(completionHandler)](Ref<WebProcessProxy>&& process, SuspendedPageProxy* suspendedPage, const String& reason) mutable {
    21452155        // We are process-swapping so automatic process prewarming would be beneficial if the client has not explicitly enabled / disabled it.
    21462156        bool doingAnAutomaticProcessSwap = processSwapRequestedByClient == ProcessSwapRequestedByClient::No && process.ptr() != sourceProcess.ptr();
     
    21652175}
    21662176
    2167 void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& pageSourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
     2177void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& pageSourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
    21682178{
    21692179    auto& targetURL = navigation.currentRequest().url();
    21702180    auto registrableDomain = toRegistrableDomain(targetURL);
    21712181
    2172     auto createNewProcess = [this, protectedThis = makeRef(*this), page = makeRef(page), targetURL, registrableDomain] () -> Ref<WebProcessProxy> {
    2173         if (auto process = webProcessCache().takeProcess(registrableDomain, page->websiteDataStore()))
     2182    auto createNewProcess = [this, protectedThis = makeRef(*this), page = makeRef(page), targetURL, registrableDomain, dataStore = dataStore.copyRef()] () -> Ref<WebProcessProxy> {
     2183        if (auto process = webProcessCache().takeProcess(registrableDomain, dataStore))
    21742184            return process.releaseNonNull();
    21752185
    21762186        // Check if we have a suspended page for the given registrable domain and use its process if we do, for performance reasons.
    2177         if (auto process = findReusableSuspendedPageProcess(registrableDomain, page)) {
     2187        if (auto process = findReusableSuspendedPageProcess(registrableDomain, page, dataStore)) {
    21782188            RELEASE_LOG(ProcessSwapping, "Using WebProcess %i from a SuspendedPage", process->processIdentifier());
    21792189            return process.releaseNonNull();
    21802190        }
    21812191
    2182         if (auto process = tryTakePrewarmedProcess(page->websiteDataStore())) {
     2192        if (auto process = tryTakePrewarmedProcess(dataStore)) {
    21832193            RELEASE_LOG(ProcessSwapping, "Using prewarmed process %i", process->processIdentifier());
    21842194            tryPrewarmWithDomainInformation(*process, targetURL);
     
    21872197
    21882198        RELEASE_LOG(ProcessSwapping, "Launching a new process");
    2189         return createNewWebProcess(page->websiteDataStore());
     2199        return createNewWebProcess(dataStore);
    21902200    };
    21912201
     
    22652275
    22662276        if (auto* process = m_swappedProcessesPerRegistrableDomain.get(registrableDomain)) {
    2267             if (&process->websiteDataStore() == &page.websiteDataStore()) {
     2277            if (&process->websiteDataStore() == dataStore.ptr()) {
    22682278                LOG(ProcessSwapping, "(ProcessSwapping) Reusing a previously cached process with pid %i to continue navigation to URL %s", process->processIdentifier(), targetURL.string().utf8().data());
    22692279
     
    22822292}
    22832293
    2284 RefPtr<WebProcessProxy> WebProcessPool::findReusableSuspendedPageProcess(const String& registrableDomain, WebPageProxy& page)
     2294RefPtr<WebProcessProxy> WebProcessPool::findReusableSuspendedPageProcess(const String& registrableDomain, WebPageProxy& page, WebsiteDataStore& dataStore)
    22852295{
    22862296    auto it = m_suspendedPages.findIf([&](auto& suspendedPage) {
    2287         return suspendedPage->registrableDomain() == registrableDomain && &suspendedPage->process().websiteDataStore() == &page.websiteDataStore();
     2297        return suspendedPage->registrableDomain() == registrableDomain && &suspendedPage->process().websiteDataStore() == &dataStore;
    22882298    });
    22892299    if (it == m_suspendedPages.end())
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r242303 r242371  
    188188    Ref<WebPageProxy> createWebPage(PageClient&, Ref<API::PageConfiguration>&&);
    189189
    190     void pageBeginUsingWebsiteDataStore(WebPageProxy&);
    191     void pageEndUsingWebsiteDataStore(WebPageProxy&);
     190    void pageBeginUsingWebsiteDataStore(uint64_t pageID, WebsiteDataStore&);
     191    void pageEndUsingWebsiteDataStore(uint64_t pageID, WebsiteDataStore&);
    192192
    193193    const String& injectedBundlePath() const { return m_configuration->injectedBundlePath(); }
     
    307307
    308308    enum class MayCreateDefaultDataStore { No, Yes };
    309     void prewarmProcess(MayCreateDefaultDataStore);
     309    void prewarmProcess(WebsiteDataStore*, MayCreateDefaultDataStore);
    310310
    311311    bool shouldTerminate(WebProcessProxy*);
     
    456456#endif
    457457
    458     void processForNavigation(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
     458    void processForNavigation(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
    459459
    460460    // SuspendedPageProxy management.
     
    466466    bool hasSuspendedPageFor(WebProcessProxy&, WebPageProxy&) const;
    467467    unsigned maxSuspendedPageCount() const { return m_maxSuspendedPageCount; }
    468     RefPtr<WebProcessProxy> findReusableSuspendedPageProcess(const String&, WebPageProxy&);
     468    RefPtr<WebProcessProxy> findReusableSuspendedPageProcess(const String&, WebPageProxy&, WebsiteDataStore&);
    469469
    470470    void clearSuspendedPages(AllowProcessCaching);
    471471
    472     void didReachGoodTimeToPrewarm();
     472    void didReachGoodTimeToPrewarm(WebsiteDataStore&);
    473473
    474474    void didCollectPrewarmInformation(const String& registrableDomain, const WebCore::PrewarmInformation&);
     
    500500    void platformInvalidateContext();
    501501
    502     void processForNavigationInternal(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
     502    void processForNavigationInternal(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
    503503
    504504    RefPtr<WebProcessProxy> tryTakePrewarmedProcess(WebsiteDataStore&);
     
    731731    Paths m_resolvedPaths;
    732732
    733     HashMap<PAL::SessionID, HashSet<WebPageProxy*>> m_sessionToPagesMap;
     733    HashMap<PAL::SessionID, HashSet<uint64_t>> m_sessionToPageIDsMap;
    734734    RunLoop::Timer<WebProcessPool> m_serviceWorkerProcessesTerminationTimer;
    735735
     
    810810
    811811    if (!messageSent) {
    812         prewarmProcess(MayCreateDefaultDataStore::No);
     812        prewarmProcess(nullptr, MayCreateDefaultDataStore::No);
    813813        RefPtr<WebProcessProxy> process = m_processes.last();
    814814        if (process->canSendMessage())
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r242182 r242371  
    350350    Ref<WebPageProxy> webPage = WebPageProxy::create(pageClient, *this, pageID, WTFMove(pageConfiguration));
    351351
    352     addExistingWebPage(webPage.get(), pageID, BeginsUsingDataStore::Yes);
     352    addExistingWebPage(webPage.get(), BeginsUsingDataStore::Yes);
    353353
    354354    return webPage;
    355355}
    356356
    357 void WebProcessProxy::addExistingWebPage(WebPageProxy& webPage, uint64_t pageID, BeginsUsingDataStore beginsUsingDataStore)
    358 {
    359     ASSERT(!m_pageMap.contains(pageID));
    360     ASSERT(!globalPageMap().contains(pageID));
     357void WebProcessProxy::addExistingWebPage(WebPageProxy& webPage, BeginsUsingDataStore beginsUsingDataStore)
     358{
     359    ASSERT(!m_pageMap.contains(webPage.pageID()));
     360    ASSERT(!globalPageMap().contains(webPage.pageID()));
    361361    ASSERT(!m_isInProcessCache);
     362    ASSERT(m_websiteDataStore.ptr() == &webPage.websiteDataStore());
    362363
    363364    if (beginsUsingDataStore == BeginsUsingDataStore::Yes)
    364         m_processPool->pageBeginUsingWebsiteDataStore(webPage);
    365 
    366     m_pageMap.set(pageID, &webPage);
    367     globalPageMap().set(pageID, &webPage);
     365        m_processPool->pageBeginUsingWebsiteDataStore(webPage.pageID(), webPage.websiteDataStore());
     366
     367    m_pageMap.set(webPage.pageID(), &webPage);
     368    globalPageMap().set(webPage.pageID(), &webPage);
    368369
    369370    updateBackgroundResponsivenessTimer();
     
    381382}
    382383
    383 void WebProcessProxy::removeWebPage(WebPageProxy& webPage, uint64_t pageID, EndsUsingDataStore endsUsingDataStore)
    384 {
    385     auto* removedPage = m_pageMap.take(pageID);
     384void WebProcessProxy::removeWebPage(WebPageProxy& webPage, EndsUsingDataStore endsUsingDataStore)
     385{
     386    auto* removedPage = m_pageMap.take(webPage.pageID());
    386387    ASSERT_UNUSED(removedPage, removedPage == &webPage);
    387     removedPage = globalPageMap().take(pageID);
     388    removedPage = globalPageMap().take(webPage.pageID());
    388389    ASSERT_UNUSED(removedPage, removedPage == &webPage);
    389390
    390391    if (endsUsingDataStore == EndsUsingDataStore::Yes)
    391         m_processPool->pageEndUsingWebsiteDataStore(webPage);
     392        m_processPool->pageEndUsingWebsiteDataStore(webPage.pageID(), webPage.websiteDataStore());
    392393
    393394    updateBackgroundResponsivenessTimer();
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.h

    r242222 r242371  
    127127
    128128    enum class BeginsUsingDataStore : bool { No, Yes };
    129     void addExistingWebPage(WebPageProxy&, uint64_t pageID, BeginsUsingDataStore);
     129    void addExistingWebPage(WebPageProxy&, BeginsUsingDataStore);
    130130
    131131    enum class EndsUsingDataStore : bool { No, Yes };
    132     void removeWebPage(WebPageProxy&, uint64_t pageID, EndsUsingDataStore);
     132    void removeWebPage(WebPageProxy&, EndsUsingDataStore);
    133133
    134134    void addProvisionalPageProxy(ProvisionalPageProxy& provisionalPage) { ASSERT(!m_provisionalPages.contains(&provisionalPage)); m_provisionalPages.add(&provisionalPage); }
  • trunk/Tools/ChangeLog

    r242354 r242371  
     12019-03-04  Chris Dumez  <cdumez@apple.com>
     2
     3        Do not share WebProcesses between private and regular sessions
     4        https://bugs.webkit.org/show_bug.cgi?id=195189
     5        <rdar://problem/48421064>
     6
     7        Reviewed by Alex Christensen.
     8
     9        Add API test coverage.
     10
     11        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
     12        * TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
     13
    1142019-03-04  Michael Catanzaro  <mcatanzaro@igalia.com>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessPreWarming.mm

    r242339 r242371  
    6363    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    6464    configuration.get().processPool = pool.get();
    65     configuration.get().websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
    6665
    6766    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm

    r242339 r242371  
    26262626}
    26272627
     2628TEST(ProcessSwap, PrivateAndRegularSessionsShouldGetDifferentProcesses)
     2629{
     2630    auto processPoolConfiguration = psonProcessPoolConfiguration();
     2631    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
     2632
     2633    auto privateWebViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     2634    [privateWebViewConfiguration setProcessPool:processPool.get()];
     2635    [privateWebViewConfiguration setWebsiteDataStore:[WKWebsiteDataStore nonPersistentDataStore]];
     2636    auto handler = adoptNS([[PSONScheme alloc] init]);
     2637    [privateWebViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
     2638    auto regularWebViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     2639    [regularWebViewConfiguration setProcessPool:processPool.get()];
     2640    [regularWebViewConfiguration setWebsiteDataStore:[WKWebsiteDataStore defaultDataStore]];
     2641    [regularWebViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
     2642
     2643    auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
     2644
     2645    auto regularWebView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:regularWebViewConfiguration.get()]);
     2646    [regularWebView1 setNavigationDelegate:delegate.get()];
     2647
     2648    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.google.com/main.html"]];
     2649    [regularWebView1 loadRequest:request];
     2650
     2651    TestWebKitAPI::Util::run(&done);
     2652    done = false;
     2653
     2654    [regularWebView1 _close];
     2655    regularWebView1 = nil;
     2656
     2657    auto privateWebView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:privateWebViewConfiguration.get()]);
     2658    [privateWebView setNavigationDelegate:delegate.get()];
     2659
     2660    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
     2661    [privateWebView loadRequest:request];
     2662
     2663    TestWebKitAPI::Util::run(&done);
     2664    done = false;
     2665
     2666    auto privateSessionWebkitPID = [privateWebView _webProcessIdentifier];
     2667
     2668    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.apple.com/main.html"]];
     2669    [privateWebView loadRequest:request];
     2670
     2671    TestWebKitAPI::Util::run(&done);
     2672    done = false;
     2673
     2674    auto privateSessionApplePID = [privateWebView _webProcessIdentifier];
     2675    EXPECT_NE(privateSessionWebkitPID, privateSessionApplePID);
     2676
     2677    [privateWebView _close];
     2678    privateWebView = nil;
     2679
     2680    auto regularWebView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:regularWebViewConfiguration.get()]);
     2681    [regularWebView2 setNavigationDelegate:delegate.get()];
     2682
     2683    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.google.com/main.html"]];
     2684    [regularWebView2 loadRequest:request];
     2685
     2686    TestWebKitAPI::Util::run(&done);
     2687    done = false;
     2688
     2689    auto regularSessionGooglePID = [regularWebView2 _webProcessIdentifier];
     2690
     2691    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
     2692    [regularWebView2 loadRequest:request];
     2693
     2694    TestWebKitAPI::Util::run(&done);
     2695    done = false;
     2696
     2697    auto regularSessionWebkitPID = [regularWebView2 _webProcessIdentifier];
     2698    EXPECT_NE(regularSessionGooglePID, regularSessionWebkitPID);
     2699    EXPECT_NE(privateSessionWebkitPID, regularSessionWebkitPID);
     2700}
     2701
    26282702static const char* keepNavigatingFrameBytes = R"PSONRESOURCE(
    26292703<body>
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm

    r242339 r242371  
    14871487    TestWebKitAPI::Util::run(&done);
    14881488    done = false;
     1489
     1490    auto pid1 = [cookieWebView _webProcessIdentifier];
     1491
    14891492    [cookieWebView loadHTMLString:alertOldCookie baseURL:[NSURL URLWithString:@"http://example.com/checkCookies"]];
    14901493    TestWebKitAPI::Util::run(&done);
    1491 }
     1494
     1495    EXPECT_NE(pid1, [cookieWebView _webProcessIdentifier]);
     1496}
Note: See TracChangeset for help on using the changeset viewer.