Regression(r257963) didFailProvisionalNavigation delegate no longer gets called when cancelling a cross-site provisional navigation
https://bugs.webkit.org/show_bug.cgi?id=209873
<rdar://problem/61132068>

Reviewed by Alex Christensen.

Source/WebKit:

ProvisionalPageProxy::cancel() was calling didFailProvisionalLoadForFrame() was not passing a valid
FrameInfoData struct as parameter. As a result, FrameInfoData::isMainFrame ended up being false
instead of true. This was an issue because NavigationState::NavigationClient::didFailProvisionalNavigationWithError()
was relying on this flag to decide whether to call webViewDidFailProvisionalNavigationWithError or
webViewNavigationDidFailProvisionalLoadInSubframeWithError, since r257963.

Change is covered by new API tests.

* UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::cancel):

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@259362 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 78eea7f..3307649 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,22 @@
+2020-04-01  Chris Dumez  <cdumez@apple.com>
+
+        Regression(r257963) didFailProvisionalNavigation delegate no longer gets called when cancelling a cross-site provisional navigation
+        https://bugs.webkit.org/show_bug.cgi?id=209873
+        <rdar://problem/61132068>
+
+        Reviewed by Alex Christensen.
+
+        ProvisionalPageProxy::cancel() was calling didFailProvisionalLoadForFrame() was not passing a valid
+        FrameInfoData struct as parameter. As a result, FrameInfoData::isMainFrame ended up being false
+        instead of true. This was an issue because NavigationState::NavigationClient::didFailProvisionalNavigationWithError()
+        was relying on this flag to decide whether to call webViewDidFailProvisionalNavigationWithError or
+        webViewNavigationDidFailProvisionalLoadInSubframeWithError, since r257963.
+
+        Change is covered by new API tests.
+
+        * UIProcess/ProvisionalPageProxy.cpp:
+        (WebKit::ProvisionalPageProxy::cancel):
+
 2020-04-01  Don Olmstead  <don.olmstead@sony.com>
 
         [GPUP][PlayStation] Enable GPU Process
diff --git a/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp b/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
index 39056b6..c86ce81 100644
--- a/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
+++ b/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
@@ -133,7 +133,14 @@
     ASSERT(m_mainFrame);
     auto error = WebKit::cancelledError(m_request);
     error.setType(WebCore::ResourceError::Type::Cancellation);
-    didFailProvisionalLoadForFrame(m_mainFrame->frameID(), { }, { }, m_navigationID, m_provisionalLoadURL, error, WebCore::WillContinueLoading::No, UserData { }); // Will delete |this|.
+    FrameInfoData frameInfo {
+        true, // isMainFrame
+        m_request,
+        SecurityOriginData::fromURL(m_request.url()),
+        m_mainFrame->frameID(),
+        WTF::nullopt,
+    };
+    didFailProvisionalLoadForFrame(m_mainFrame->frameID(), WTFMove(frameInfo), ResourceRequest { m_request }, m_navigationID, m_provisionalLoadURL, error, WebCore::WillContinueLoading::No, UserData { }); // Will delete |this|.
 }
 
 void ProvisionalPageProxy::initializeWebPage(RefPtr<API::WebsitePolicies>&& websitePolicies)
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 7748dd6..1986ceb 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,15 @@
+2020-04-01  Chris Dumez  <cdumez@apple.com>
+
+        Regression(r257963) didFailProvisionalNavigation delegate no longer gets called when cancelling a cross-site provisional navigation
+        https://bugs.webkit.org/show_bug.cgi?id=209873
+        <rdar://problem/61132068>
+
+        Reviewed by Alex Christensen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
 2020-04-01  Don Olmstead  <don.olmstead@sony.com>
 
         [PlayStation] Use OBJECT libraries for WebCore and PAL
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm
index e273256..79eb0cc 100644
--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm
+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm
@@ -3124,6 +3124,50 @@
     EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL] absoluteString]);
 }
 
+static void runCancelCrossSiteProvisionalLoadTest(ShouldEnablePSON shouldEnablePSON)
+{
+    auto processPoolConfiguration = psonProcessPoolConfiguration();
+    processPoolConfiguration.get().processSwapsOnNavigation = shouldEnablePSON == ShouldEnablePSON::Yes;
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+
+    failed = false;
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_FALSE(failed);
+
+    navigationDelegate->didStartProvisionalNavigationHandler = ^{
+        [webView stopLoading];
+    };
+
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.apple.com/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&failed);
+    failed = false;
+}
+
+TEST(ProcessSwap, CancelCrossSiteProvisionalLoadWithoutPSON)
+{
+    runCancelCrossSiteProvisionalLoadTest(ShouldEnablePSON::No);
+}
+
+TEST(ProcessSwap, CancelCrossSiteProvisionalLoadWithPSON)
+{
+    runCancelCrossSiteProvisionalLoadTest(ShouldEnablePSON::Yes);
+}
 
 TEST(ProcessSwap, DoSameSiteNavigationAfterCrossSiteProvisionalLoadStarted)
 {