Changeset 241752 in webkit


Ignore:
Timestamp:
Feb 18, 2019 6:29:02 PM (5 years ago)
Author:
Chris Dumez
Message:

REGRESSION (PSON): Can't access optumbank.com from myuhc.com
https://bugs.webkit.org/show_bug.cgi?id=194797
<rdar://problem/48055151>

Reviewed by Geoffrey Garen.

Source/WebKit:

The issue was caused by us mistakenly process-swapping for a same-site server side redirect.
The reason we were getting it wrong is because the logic in
WebProcessPool::processForNavigationInternal() was expecting page.process() to be the source
process and page.pageLoadState().url() to be the source URL. Those assumptions are incorrect
when a server-side redirect occurs in a provisional process. In such case, the source process
is the ProvisionalPageProxy's process and the source URL is the provisional URL, not the
committed one.

  • UIProcess/ProvisionalPageProxy.cpp:

(WebKit::ProvisionalPageProxy::didPerformServerRedirect):
(WebKit::ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame):
(WebKit::ProvisionalPageProxy::didReceiveMessage):

  • UIProcess/ProvisionalPageProxy.h:

Make sure the provisional page forwards IPC related to server-side redirects to the page so
that the client gets informed.

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::receivedNavigationPolicyDecision):
(WebKit::WebPageProxy::didPerformServerRedirect):
(WebKit::WebPageProxy::didPerformServerRedirectShared):

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::processForNavigation):
(WebKit::WebProcessPool::processForNavigationInternal):

  • UIProcess/WebProcessPool.h:

Tools:

Add API test coverage.

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

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r241751 r241752  
     12019-02-18  Chris Dumez  <cdumez@apple.com>
     2
     3        REGRESSION (PSON): Can't access optumbank.com from myuhc.com
     4        https://bugs.webkit.org/show_bug.cgi?id=194797
     5        <rdar://problem/48055151>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        The issue was caused by us mistakenly process-swapping for a same-site server side redirect.
     10        The reason we were getting it wrong is because the logic in
     11        WebProcessPool::processForNavigationInternal() was expecting page.process() to be the source
     12        process and page.pageLoadState().url() to be the source URL. Those assumptions are incorrect
     13        when a server-side redirect occurs in a provisional process. In such case, the source process
     14        is the ProvisionalPageProxy's process and the source URL is the provisional URL, not the
     15        committed one.
     16
     17        * UIProcess/ProvisionalPageProxy.cpp:
     18        (WebKit::ProvisionalPageProxy::didPerformServerRedirect):
     19        (WebKit::ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame):
     20        (WebKit::ProvisionalPageProxy::didReceiveMessage):
     21        * UIProcess/ProvisionalPageProxy.h:
     22        Make sure the provisional page forwards IPC related to server-side redirects to the page so
     23        that the client gets informed.
     24
     25        * UIProcess/WebPageProxy.cpp:
     26        (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
     27        (WebKit::WebPageProxy::didPerformServerRedirect):
     28        (WebKit::WebPageProxy::didPerformServerRedirectShared):
     29        * UIProcess/WebPageProxy.h:
     30        * UIProcess/WebProcessPool.cpp:
     31        (WebKit::WebProcessPool::processForNavigation):
     32        (WebKit::WebProcessPool::processForNavigationInternal):
     33        * UIProcess/WebProcessPool.h:
     34
    1352019-02-16  Darin Adler  <darin@apple.com>
    236
  • trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp

    r241556 r241752  
    285285}
    286286
     287void ProvisionalPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
     288{
     289    m_page.didPerformServerRedirectShared(m_process.copyRef(), sourceURLString, destinationURLString, frameID);
     290}
     291
     292void ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&& request, const UserData& userData)
     293{
     294    m_page.didReceiveServerRedirectForProvisionalLoadForFrameShared(m_process.copyRef(), frameID, navigationID, WTFMove(request), userData);
     295}
     296
    287297void ProvisionalPageProxy::startURLSchemeTask(URLSchemeTaskParameters&& parameters)
    288298{
     
    375385    }
    376386
     387    if (decoder.messageName() == Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame::name()) {
     388        IPC::handleMessage<Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame>(decoder, this, &ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame);
     389        return;
     390    }
     391
     392    if (decoder.messageName() == Messages::WebPageProxy::DidPerformServerRedirect::name()) {
     393        IPC::handleMessage<Messages::WebPageProxy::DidPerformServerRedirect>(decoder, this, &ProvisionalPageProxy::didPerformServerRedirect);
     394        return;
     395    }
     396
    377397    LOG(ProcessSwapping, "Unhandled message %s::%s from provisional process", decoder.messageReceiverName().toString().data(), decoder.messageName().toString().data());
    378398}
  • trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h

    r241337 r241752  
    6565    ProcessSwapRequestedByClient processSwapRequestedByClient() const { return m_processSwapRequestedByClient; }
    6666    uint64_t navigationID() const { return m_navigationID; }
     67    const URL& provisionalURL() const { return m_provisionalLoadURL; }
    6768
    6869    DrawingAreaProxy* drawingArea() const { return m_drawingArea.get(); }
     
    9293        const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&);
    9394    void didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t navigationID, URL&&);
     95    void didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
     96    void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);
    9497    void didNavigateWithNavigationData(const WebNavigationDataStore&, uint64_t frameID);
    9598    void didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r241735 r241752  
    27492749    }
    27502750
    2751     process().processPool().processForNavigation(*this, *navigation, processSwapRequestedByClient, [this, protectedThis = makeRef(*this), policyAction, navigation = makeRef(*navigation),
     2751    Ref<WebProcessProxy> sourceProcess = process();
     2752    URL sourceURL = URL { URL(), pageLoadState().url() };
     2753    if (auto* provisionalPage = provisionalPageProxy()) {
     2754        if (provisionalPage->navigationID() == navigation->navigationID()) {
     2755            ASSERT(navigation->currentRequestIsRedirect());
     2756            sourceProcess = provisionalPage->process();
     2757            sourceURL = provisionalPage->provisionalURL();
     2758        }
     2759    }
     2760
     2761    process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, [this, protectedThis = makeRef(*this), policyAction, navigation = makeRef(*navigation), sourceProcess = sourceProcess.copyRef(),
    27522762        data = WTFMove(data), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {
    27532763        // If the navigation has been destroyed, then no need to proceed.
     
    27572767        }
    27582768
    2759         if (processForNavigation.ptr() != &process()) {
     2769        bool shouldProcessSwap = processForNavigation.ptr() != sourceProcess.ptr();
     2770        if (shouldProcessSwap) {
    27602771            policyAction = PolicyAction::StopAllLoads;
    27612772            RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "decidePolicyForNavigationAction, swapping process %i with process %i for navigation, reason: %{public}s", processIdentifier(), processForNavigation->processIdentifier(), reason.utf8().data());
     
    27642775            RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "decidePolicyForNavigationAction: keep using process %i for navigation, reason: %{public}s", processIdentifier(), reason.utf8().data());
    27652776
    2766         bool shouldProcessSwap = processForNavigation.ptr() != &process();
    27672777        receivedPolicyDecision(policyAction, navigation.ptr(), shouldProcessSwap ? WTF::nullopt : WTFMove(data), WTFMove(sender), shouldProcessSwap ? WillContinueLoadInNewProcess::Yes : WillContinueLoadInNewProcess::No);
    27682778
     
    47994809void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
    48004810{
    4801     RELEASE_LOG_IF_ALLOWED(Loading, "didPerformServerRedirect: webPID = %i, pageID = %" PRIu64, m_process->processIdentifier(), m_pageID);
     4811    didPerformServerRedirectShared(m_process.copyRef(), sourceURLString, destinationURLString, frameID);
     4812}
     4813
     4814void WebPageProxy::didPerformServerRedirectShared(Ref<WebProcessProxy>&& process, const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
     4815{
     4816    RELEASE_LOG_IF_ALLOWED(Loading, "didPerformServerRedirect: webPID = %i, pageID = %" PRIu64, process->processIdentifier(), m_pageID);
    48024817
    48034818    PageClientProtector protector(pageClient());
     
    48064821        return;
    48074822   
    4808     WebFrameProxy* frame = m_process->webFrame(frameID);
    4809     MESSAGE_CHECK(m_process, frame);
    4810     MESSAGE_CHECK(m_process, frame->page() == this);
    4811 
    4812     MESSAGE_CHECK_URL(m_process, sourceURLString);
    4813     MESSAGE_CHECK_URL(m_process, destinationURLString);
     4823    WebFrameProxy* frame = process->webFrame(frameID);
     4824    MESSAGE_CHECK(process, frame);
     4825    MESSAGE_CHECK(process, frame->page() == this);
     4826
     4827    MESSAGE_CHECK_URL(process, sourceURLString);
     4828    MESSAGE_CHECK_URL(process, destinationURLString);
    48144829
    48154830    if (frame->isMainFrame())
    48164831        m_historyClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString);
    4817     process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
     4832    process->processPool().historyClient().didPerformServerRedirect(process->processPool(), *this, sourceURLString, destinationURLString, *frame);
    48184833}
    48194834
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r241451 r241752  
    14431443    void didFailProvisionalLoadForFrameShared(Ref<WebProcessProxy>&&, uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, const UserData&);
    14441444    void didReceiveServerRedirectForProvisionalLoadForFrameShared(Ref<WebProcessProxy>&&, uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);
     1445    void didPerformServerRedirectShared(Ref<WebProcessProxy>&&, const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
    14451446    void didPerformClientRedirectShared(Ref<WebProcessProxy>&&, const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
    14461447    void didNavigateWithNavigationDataShared(Ref<WebProcessProxy>&&, const WebNavigationDataStore&, uint64_t frameID);
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r241556 r241752  
    21162116#endif
    21172117
    2118 void WebProcessPool::addProcessToOriginCacheSet(WebPageProxy& page)
    2119 {
    2120     auto registrableDomain = toRegistrableDomain({ { }, page.pageLoadState().url() });
    2121     auto result = m_swappedProcessesPerRegistrableDomain.add(registrableDomain, &page.process());
     2118void WebProcessPool::addProcessToOriginCacheSet(WebProcessProxy& process, const URL& url)
     2119{
     2120    auto registrableDomain = toRegistrableDomain(url);
     2121    auto result = m_swappedProcessesPerRegistrableDomain.add(registrableDomain, &process);
    21222122    if (!result.isNewEntry)
    2123         result.iterator->value = &page.process();
    2124 
    2125     LOG(ProcessSwapping, "(ProcessSwapping) Registrable domain %s just saved a cached process with pid %i", registrableDomain.utf8().data(), page.process().processIdentifier());
     2123        result.iterator->value = &process;
     2124
     2125    LOG(ProcessSwapping, "(ProcessSwapping) Registrable domain %s just saved a cached process with pid %i", registrableDomain.utf8().data(), process.processIdentifier());
    21262126    if (!result.isNewEntry)
    21272127        LOG(ProcessSwapping, "(ProcessSwapping) Note: It already had one saved");
     
    21432143}
    21442144
    2145 void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, ProcessSwapRequestedByClient processSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
    2146 {
    2147     processForNavigationInternal(page, navigation, processSwapRequestedByClient, [this, page = makeRefPtr(page), navigation = makeRef(navigation), processSwapRequestedByClient, completionHandler = WTFMove(completionHandler)](Ref<WebProcessProxy>&& process, SuspendedPageProxy* suspendedPage, const String& reason) mutable {
     2145void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
     2146{
     2147    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 {
    21482148        // We are process-swapping so automatic process prewarming would be beneficial if the client has not explicitly enabled / disabled it.
    2149         bool doingAnAutomaticProcessSwap = processSwapRequestedByClient == ProcessSwapRequestedByClient::No && process.ptr() != &page->process();
     2149        bool doingAnAutomaticProcessSwap = processSwapRequestedByClient == ProcessSwapRequestedByClient::No && process.ptr() != sourceProcess.ptr();
    21502150        if (doingAnAutomaticProcessSwap && !configuration().wasAutomaticProcessWarmingSetByClient() && !configuration().clientWouldBenefitFromAutomaticProcessPrewarming()) {
    21512151            RELEASE_LOG(PerformanceLogging, "Automatically turning on process prewarming because the client would benefit from it");
     
    21532153        }
    21542154
    2155         if (m_configuration->alwaysKeepAndReuseSwappedProcesses() && process.ptr() != &page->process()) {
     2155        if (m_configuration->alwaysKeepAndReuseSwappedProcesses() && process.ptr() != sourceProcess.ptr()) {
    21562156            static std::once_flag onceFlag;
    21572157            std::call_once(onceFlag, [] {
     
    21592159            });
    21602160
    2161             addProcessToOriginCacheSet(*page);
    2162 
    2163             LOG(ProcessSwapping, "(ProcessSwapping) Navigating from %s to %s, keeping around old process. Now holding on to old processes for %u origins.", page->currentURL().utf8().data(), navigation->currentRequest().url().string().utf8().data(), m_swappedProcessesPerRegistrableDomain.size());
     2161            addProcessToOriginCacheSet(sourceProcess, sourceURL);
     2162
     2163            LOG(ProcessSwapping, "(ProcessSwapping) Navigating from %s to %s, keeping around old process. Now holding on to old processes for %u origins.", sourceURL.string().utf8().data(), navigation->currentRequest().url().string().utf8().data(), m_swappedProcessesPerRegistrableDomain.size());
    21642164        }
    21652165
     
    21682168}
    21692169
    2170 void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, ProcessSwapRequestedByClient processSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
     2170void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& pageSourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
    21712171{
    21722172    auto& targetURL = navigation.currentRequest().url();
     
    21942194
    21952195    if (usesSingleWebProcess())
    2196         return completionHandler(page.process(), nullptr, "Single WebProcess mode is enabled"_s);
     2196        return completionHandler(WTFMove(sourceProcess), nullptr, "Single WebProcess mode is enabled"_s);
    21972197
    21982198    if (processSwapRequestedByClient == ProcessSwapRequestedByClient::Yes)
     
    22002200
    22012201    if (!m_configuration->processSwapsOnNavigation())
    2202         return completionHandler(page.process(), nullptr, "Feature is disabled"_s);
     2202        return completionHandler(WTFMove(sourceProcess), nullptr, "Feature is disabled"_s);
    22032203
    22042204    if (m_automationSession)
    2205         return completionHandler(page.process(), nullptr, "An automation session is active"_s);
    2206 
    2207     if (!page.process().hasCommittedAnyProvisionalLoads()) {
    2208         tryPrewarmWithDomainInformation(page.process(), targetURL);
    2209         return completionHandler(page.process(), nullptr, "Process has not yet committed any provisional loads"_s);
     2205        return completionHandler(WTFMove(sourceProcess), nullptr, "An automation session is active"_s);
     2206
     2207    if (!sourceProcess->hasCommittedAnyProvisionalLoads()) {
     2208        tryPrewarmWithDomainInformation(sourceProcess, targetURL);
     2209        return completionHandler(WTFMove(sourceProcess), nullptr, "Process has not yet committed any provisional loads"_s);
    22102210    }
    22112211
     
    22132213    // The issue is that the opener has a handle to the WindowProxy.
    22142214    if (navigation.openedByDOMWithOpener() && !m_configuration->processSwapsOnWindowOpenWithOpener())
    2215         return completionHandler(page.process(), nullptr, "Browsing context been opened by DOM without 'noopener'"_s);
     2215        return completionHandler(WTFMove(sourceProcess), nullptr, "Browsing context been opened by DOM without 'noopener'"_s);
    22162216
    22172217    // FIXME: We should support process swap when a window has opened other windows via window.open.
    22182218    if (navigation.hasOpenedFrames())
    2219         return completionHandler(page.process(), nullptr, "Browsing context has opened other windows"_s);
     2219        return completionHandler(WTFMove(sourceProcess), nullptr, "Browsing context has opened other windows"_s);
    22202220
    22212221    if (auto* targetItem = navigation.targetItem()) {
     
    22462246
    22472247    if (navigation.treatAsSameOriginNavigation())
    2248         return completionHandler(page.process(), nullptr, "The treatAsSameOriginNavigation flag is set"_s);
     2248        return completionHandler(WTFMove(sourceProcess), nullptr, "The treatAsSameOriginNavigation flag is set"_s);
    22492249
    22502250    URL sourceURL;
     
    22522252        sourceURL = URL { URL(), navigation.requesterOrigin().toString() };
    22532253    else
    2254         sourceURL = URL { { }, page.pageLoadState().url() };
     2254        sourceURL = pageSourceURL;
    22552255
    22562256    if (sourceURL.isEmpty() && page.configuration().relatedPage()) {
     
    22602260
    22612261    if (!sourceURL.isValid() || !targetURL.isValid() || sourceURL.isEmpty() || sourceURL.protocolIsAbout() || registrableDomainsAreEqual(sourceURL, targetURL))
    2262         return completionHandler(page.process(), nullptr, "Navigation is same-site"_s);
     2262        return completionHandler(WTFMove(sourceProcess), nullptr, "Navigation is same-site"_s);
    22632263
    22642264    String reason = "Navigation is cross-site"_s;
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r241556 r241752  
    458458#endif
    459459
    460     void processForNavigation(WebPageProxy&, const API::Navigation&, ProcessSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
     460    void processForNavigation(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
    461461
    462462    // SuspendedPageProxy management.
     
    500500    void platformInvalidateContext();
    501501
    502     void processForNavigationInternal(WebPageProxy&, const API::Navigation&, ProcessSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
     502    void processForNavigationInternal(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
    503503
    504504    RefPtr<WebProcessProxy> tryTakePrewarmedProcess(WebsiteDataStore&);
     
    563563    void platformResolvePathsForSandboxExtensions();
    564564
    565     void addProcessToOriginCacheSet(WebPageProxy&);
     565    void addProcessToOriginCacheSet(WebProcessProxy&, const URL&);
    566566    void removeProcessFromOriginCacheSet(WebProcessProxy&);
    567567
  • trunk/Tools/ChangeLog

    r241749 r241752  
     12019-02-18  Chris Dumez  <cdumez@apple.com>
     2
     3        REGRESSION (PSON): Can't access optumbank.com from myuhc.com
     4        https://bugs.webkit.org/show_bug.cgi?id=194797
     5        <rdar://problem/48055151>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add API test coverage.
     10
     11        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
     12
    1132019-02-18  Wenson Hsieh  <wenson_hsieh@apple.com>
    214
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm

    r241728 r241752  
    14071407
    14081408    seenPIDs.add([webView _webProcessIdentifier]);
     1409    if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1410        seenPIDs.add(provisionalPID);
    14091411
    14101412    TestWebKitAPI::Util::run(&done);
     
    14121414
    14131415    seenPIDs.add([webView _webProcessIdentifier]);
     1416    if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1417        seenPIDs.add(provisionalPID);
    14141418
    14151419    EXPECT_FALSE(serverRedirected);
     
    14561460
    14571461    seenPIDs.add([webView _webProcessIdentifier]);
     1462    if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1463        seenPIDs.add(provisionalPID);
    14581464
    14591465    TestWebKitAPI::Util::run(&done);
     
    14611467
    14621468    seenPIDs.add([webView _webProcessIdentifier]);
     1469    if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1470        seenPIDs.add(provisionalPID);
    14631471
    14641472    EXPECT_FALSE(serverRedirected);
     
    14741482
    14751483    EXPECT_WK_STREQ(@"pson://www.webkit.org/main1.html", [[webView URL] absoluteString]);
     1484}
     1485
     1486enum class ShouldCacheProcessFirst { No, Yes };
     1487static void runSameOriginServerRedirectTest(ShouldCacheProcessFirst shouldCacheProcessFirst)
     1488{
     1489    auto processPoolConfiguration = psonProcessPoolConfiguration();
     1490    processPoolConfiguration.get().processSwapsOnNavigation = YES;
     1491    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
     1492
     1493    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     1494    [webViewConfiguration setProcessPool:processPool.get()];
     1495    auto handler = adoptNS([[PSONScheme alloc] init]);
     1496    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:crossSiteClientSideRedirectBytes];
     1497    [handler addRedirectFromURLString:@"pson://www.apple.com/main.html" toURLString:@"pson://www.apple.com/main2.html"];
     1498    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"pson"];
     1499
     1500    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
     1501    auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
     1502    [webView setNavigationDelegate:delegate.get()];
     1503
     1504    NSURLRequest *request;
     1505
     1506    if (shouldCacheProcessFirst == ShouldCacheProcessFirst::Yes) {
     1507        request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.apple.com/main3.html"]];
     1508        [webView loadRequest:request];
     1509
     1510        TestWebKitAPI::Util::run(&done);
     1511        done = false;
     1512    }
     1513
     1514    delegate->didStartProvisionalNavigationHandler = ^{
     1515        seenPIDs.add([webView _webProcessIdentifier]);
     1516        if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1517            seenPIDs.add(provisionalPID);
     1518    };
     1519
     1520    willPerformClientRedirect = false;
     1521    didPerformClientRedirect = false;
     1522    serverRedirected = false;
     1523    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
     1524    [webView loadRequest:request];
     1525
     1526    TestWebKitAPI::Util::run(&willPerformClientRedirect);
     1527
     1528    seenPIDs.add([webView _webProcessIdentifier]);
     1529    if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1530        seenPIDs.add(provisionalPID);
     1531
     1532    TestWebKitAPI::Util::run(&didPerformClientRedirect);
     1533    didPerformClientRedirect = false;
     1534    willPerformClientRedirect = false;
     1535
     1536    seenPIDs.add([webView _webProcessIdentifier]);
     1537    if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1538        seenPIDs.add(provisionalPID);
     1539
     1540    TestWebKitAPI::Util::run(&serverRedirected);
     1541    serverRedirected = false;
     1542
     1543    seenPIDs.add([webView _webProcessIdentifier]);
     1544    if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1545        seenPIDs.add(provisionalPID);
     1546
     1547    TestWebKitAPI::Util::run(&done);
     1548    done = false;
     1549
     1550    seenPIDs.add([webView _webProcessIdentifier]);
     1551    if (auto provisionalPID = [webView _provisionalWebProcessIdentifier])
     1552        seenPIDs.add(provisionalPID);
     1553
     1554    EXPECT_EQ(2u, seenPIDs.size());
     1555}
     1556
     1557TEST(ProcessSwap, SameOriginServerRedirect)
     1558{
     1559    runSameOriginServerRedirectTest(ShouldCacheProcessFirst::No);
     1560}
     1561
     1562TEST(ProcessSwap, SameOriginServerRedirectFromCachedProcess)
     1563{
     1564    runSameOriginServerRedirectTest(ShouldCacheProcessFirst::Yes);
    14761565}
    14771566
Note: See TracChangeset for help on using the changeset viewer.