WebPageProxy::loadData should accept ShouldOpenExternalURLsPolicy
authorjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Jun 2019 22:47:17 +0000 (22:47 +0000)
committerjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Jun 2019 22:47:17 +0000 (22:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199114
<rdar://problem/51671674>

Reviewed by Youenn Fablet.

Source/WebCore:

Covered by new test content within existing tests.

* loader/FrameLoaderTypes.h:
Adds an EnumTraits for ShouldOpenExternalURLsPolicy.

Source/WebKit:

This patch teaches WebPageProxy::loadData to accept ShouldOpenExternalURLsPolicy policy,
and then utilize it in RedirectSOAuthorizationSession. Therefore, the response loaded after
successful interceptions will be able to propagate the same policy from the last navigation
as it were continuous loading.

Besides the above, this patch also fixes some minor issues.

* Shared/LoadParameters.h:
* UIProcess/Cocoa/SOAuthorization/NavigationSOAuthorizationSession.mm:
(WebKit::NavigationSOAuthorizationSession::shouldStartInternal):
(WebKit::NavigationSOAuthorizationSession::webViewDidMoveToWindow):
* UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h:
* UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm:
(WebKit::PopUpSOAuthorizationSession::completeInternal):
* UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.h:
* UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.mm:
(WebKit::shouldOpenExternalURLsPolicy):
(WebKit::RedirectSOAuthorizationSession::completeInternal):
* UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.h:
* UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.mm:
(WebKit::SOAuthorizationSession::complete):
* UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.h:
* UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.mm:
(WebKit::SubFrameSOAuthorizationSession::fallBackToWebPathInternal):
(WebKit::SubFrameSOAuthorizationSession::completeInternal):
(WebKit::SubFrameSOAuthorizationSession::loadDataToFrame):
(WebKit::SubFrameSOAuthorizationSession::postDidCancelMessageToParent):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::loadRequestWithNavigationShared):
(WebKit::WebPageProxy::loadFile):
(WebKit::WebPageProxy::loadData):
(WebKit::WebPageProxy::loadDataWithNavigationShared):
* UIProcess/WebPageProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::loadDataImpl):
(WebKit::WebPage::loadData):
* WebProcess/WebPage/WebPage.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/TestSOAuthorization.mm:
(-[TestSOAuthorizationNavigationDelegate init]):
(-[TestSOAuthorizationNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(configureSOAuthorizationWebView):
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246701 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
Source/WebCore/ChangeLog
Source/WebCore/loader/FrameLoaderTypes.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/LoadParameters.h
Source/WebKit/UIProcess/API/APINavigationAction.h
Source/WebKit/UIProcess/Cocoa/SOAuthorization/NavigationSOAuthorizationSession.mm
Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h
Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm
Source/WebKit/UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.h
Source/WebKit/UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.mm
Source/WebKit/UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.h
Source/WebKit/UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.mm
Source/WebKit/UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.h
Source/WebKit/UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.mm
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/TestSOAuthorization.mm

index 2e9b173..7e5dde3 100644 (file)
@@ -1,3 +1,16 @@
+2019-06-21  Jiewen Tan  <jiewen_tan@apple.com>
+
+        WebPageProxy::loadData should accept ShouldOpenExternalURLsPolicy
+        https://bugs.webkit.org/show_bug.cgi?id=199114
+        <rdar://problem/51671674>
+
+        Reviewed by Youenn Fablet.
+
+        Covered by new test content within existing tests.
+
+        * loader/FrameLoaderTypes.h:
+        Adds an EnumTraits for ShouldOpenExternalURLsPolicy.
+
 2019-06-21  Saam Barati  <sbarati@apple.com>
 
         [WHLSL] Code that accesses an undefined variable crashes
index 596ad7d..7a48bc6 100644 (file)
@@ -219,4 +219,13 @@ template<> struct EnumTraits<WebCore::FrameLoadType> {
     >;
 };
 
+template<> struct EnumTraits<WebCore::ShouldOpenExternalURLsPolicy> {
+    using values = EnumValues<
+        WebCore::ShouldOpenExternalURLsPolicy,
+        WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow,
+        WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes,
+        WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow
+    >;
+};
+
 } // namespace WTF
index 1d1176c..e07e4dd 100644 (file)
@@ -1,3 +1,49 @@
+2019-06-21  Jiewen Tan  <jiewen_tan@apple.com>
+
+        WebPageProxy::loadData should accept ShouldOpenExternalURLsPolicy
+        https://bugs.webkit.org/show_bug.cgi?id=199114
+        <rdar://problem/51671674>
+
+        Reviewed by Youenn Fablet.
+
+        This patch teaches WebPageProxy::loadData to accept ShouldOpenExternalURLsPolicy policy,
+        and then utilize it in RedirectSOAuthorizationSession. Therefore, the response loaded after
+        successful interceptions will be able to propagate the same policy from the last navigation
+        as it were continuous loading.
+
+        Besides the above, this patch also fixes some minor issues.
+
+        * Shared/LoadParameters.h:
+        * UIProcess/Cocoa/SOAuthorization/NavigationSOAuthorizationSession.mm:
+        (WebKit::NavigationSOAuthorizationSession::shouldStartInternal):
+        (WebKit::NavigationSOAuthorizationSession::webViewDidMoveToWindow):
+        * UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.h:
+        * UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm:
+        (WebKit::PopUpSOAuthorizationSession::completeInternal):
+        * UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.h:
+        * UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.mm:
+        (WebKit::shouldOpenExternalURLsPolicy):
+        (WebKit::RedirectSOAuthorizationSession::completeInternal):
+        * UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.h:
+        * UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.mm:
+        (WebKit::SOAuthorizationSession::complete):
+        * UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.h:
+        * UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.mm:
+        (WebKit::SubFrameSOAuthorizationSession::fallBackToWebPathInternal):
+        (WebKit::SubFrameSOAuthorizationSession::completeInternal):
+        (WebKit::SubFrameSOAuthorizationSession::loadDataToFrame):
+        (WebKit::SubFrameSOAuthorizationSession::postDidCancelMessageToParent):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::loadRequestWithNavigationShared):
+        (WebKit::WebPageProxy::loadFile):
+        (WebKit::WebPageProxy::loadData):
+        (WebKit::WebPageProxy::loadDataWithNavigationShared):
+        * UIProcess/WebPageProxy.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::loadDataImpl):
+        (WebKit::WebPage::loadData):
+        * WebProcess/WebPage/WebPage.h:
+
 2019-06-21  Tim Horton  <timothy_horton@apple.com>
 
         WebKit context menu highlights include extra padding
index 108b191..33a3c93 100644 (file)
@@ -63,7 +63,7 @@ struct LoadParameters {
 
     Optional<WebsitePoliciesData> websitePolicies;
 
-    uint64_t shouldOpenExternalURLsPolicy;
+    WebCore::ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy;
     bool shouldTreatAsContinuingLoad { false };
     UserData userData;
     WebCore::LockHistory lockHistory { WebCore::LockHistory::No };
index cfb0089..3554438 100644 (file)
@@ -59,6 +59,7 @@ public:
     bool shouldOpenAppLinks() const { return m_shouldOpenAppLinks && m_navigationActionData.shouldOpenExternalURLsPolicy == WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow; }
     bool shouldPerformDownload() const { return !m_navigationActionData.downloadAttribute.isNull(); }
     bool isRedirect() const { return m_navigationActionData.isRedirect; }
+    WebCore::ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy() const { return m_navigationActionData.shouldOpenExternalURLsPolicy; }
 
     bool isProcessingUserGesture() const { return m_userInitiatedAction; }
     UserInitiatedAction* userInitiatedAction() const { return m_userInitiatedAction.get(); }
index 4226bbe..2203d1a 100644 (file)
@@ -49,12 +49,12 @@ NavigationSOAuthorizationSession::~NavigationSOAuthorizationSession()
 
 void NavigationSOAuthorizationSession::shouldStartInternal()
 {
-    auto* pagePtr = page();
-    ASSERT(pagePtr);
+    auto* page = this->page();
+    ASSERT(page);
     beforeStart();
-    if (!pagePtr->isInWindow()) {
+    if (!page->isInWindow()) {
         setState(State::Waiting);
-        pagePtr->addObserver(*this);
+        page->addObserver(*this);
         return;
     }
     start();
@@ -62,11 +62,11 @@ void NavigationSOAuthorizationSession::shouldStartInternal()
 
 void NavigationSOAuthorizationSession::webViewDidMoveToWindow()
 {
-    auto* pagePtr = page();
-    if (state() != State::Waiting || !pagePtr || !pagePtr->isInWindow())
+    auto* page = this->page();
+    if (state() != State::Waiting || !page || !page->isInWindow())
         return;
     start();
-    pagePtr->removeObserver(*this);
+    page->removeObserver(*this);
 }
 
 } // namespace WebKit
index 8d4bb72..b6694fe 100644 (file)
@@ -55,7 +55,7 @@ private:
     void shouldStartInternal() final;
     void fallBackToWebPathInternal() final;
     void abortInternal() final;
-    void completeInternal(WebCore::ResourceResponse&&, NSData *) final;
+    void completeInternal(const WebCore::ResourceResponse&, NSData *) final;
 
     void initSecretWebView();
 
index ef3ee39..98a32ba 100644 (file)
@@ -132,7 +132,7 @@ void PopUpSOAuthorizationSession::abortInternal()
     [m_secretWebView evaluateJavaScript: @"window.close()" completionHandler:nil];
 }
 
-void PopUpSOAuthorizationSession::completeInternal(WebCore::ResourceResponse&& response, NSData *data)
+void PopUpSOAuthorizationSession::completeInternal(const WebCore::ResourceResponse& response, NSData *data)
 {
     if (response.httpStatusCode() != 200 || !page()) {
         fallBackToWebPathInternal();
index 7f84197..3bcc50f 100644 (file)
@@ -43,7 +43,7 @@ private:
     // SOAuthorizationSession
     void fallBackToWebPathInternal() final;
     void abortInternal() final;
-    void completeInternal(WebCore::ResourceResponse&&, NSData *) final;
+    void completeInternal(const WebCore::ResourceResponse&, NSData *) final;
 
     // NavigationSOAuthorizationSession
     void beforeStart() final;
index ee9c029..0f8bf43 100644 (file)
@@ -32,6 +32,7 @@
 #import <WebCore/ResourceResponse.h>
 
 namespace WebKit {
+using namespace WebCore;
 
 Ref<SOAuthorizationSession> RedirectSOAuthorizationSession::create(SOAuthorization *soAuthorization, Ref<API::NavigationAction>&& navigationAction, WebPageProxy& page, Callback&& completionHandler)
 {
@@ -53,37 +54,37 @@ void RedirectSOAuthorizationSession::abortInternal()
     invokeCallback(true);
 }
 
-void RedirectSOAuthorizationSession::completeInternal(WebCore::ResourceResponse&& response, NSData *data)
+void RedirectSOAuthorizationSession::completeInternal(const ResourceResponse& response, NSData *data)
 {
-    auto* pagePtr = page();
-    if ((response.httpStatusCode() != 302 && response.httpStatusCode() != 200) || !pagePtr) {
+    auto* navigationAction = this->navigationAction();
+    ASSERT(navigationAction);
+    auto* page = this->page();
+    if ((response.httpStatusCode() != 302 && response.httpStatusCode() != 200) || !page) {
         fallBackToWebPathInternal();
         return;
     }
     invokeCallback(true);
     if (response.httpStatusCode() == 302) {
 #if PLATFORM(IOS)
-        auto* navigationActionPtr = navigationAction();
-        ASSERT(navigationActionPtr);
         // MobileSafari has a WBSURLSpoofingMitigator, which will not display the provisional URL for navigations without user gestures.
         // For slow loads that are initiated from the MobileSafari Favorites screen, the aforementioned behavior will create a period
         // after authentication completion where the new request to the application site loads with a blank URL and blank page. To
         // workaround this issue, we load an html page that does a client side redirection to the application site on behalf of the
         // request URL, instead of directly loading a new request. The html page should be super fast to load and therefore will not
         // show an empty URL or a blank page. These changes ensure a relevant URL bar and useful page content during the load.
-        if (!navigationActionPtr->isProcessingUserGesture()) {
-            pagePtr->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
-            auto html = makeString("<script>location = '", response.httpHeaderFields().get(WebCore::HTTPHeaderName::Location), "'</script>").utf8();
+        if (!navigationAction->isProcessingUserGesture()) {
+            page->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
+            auto html = makeString("<script>location = '", response.httpHeaderFields().get(HTTPHeaderName::Location), "'</script>").utf8();
             auto data = IPC::DataReference(reinterpret_cast<const uint8_t*>(html.data()), html.length());
-            pagePtr->loadData(data, "text/html"_s, "UTF-8"_s, navigationActionPtr->request().url());
+            page->loadData(data, "text/html"_s, "UTF-8"_s, navigationAction->request().url(), nullptr, navigationAction->shouldOpenExternalURLsPolicy());
             return;
         }
 #endif
-        pagePtr->loadRequest(WebCore::ResourceRequest(response.httpHeaderFields().get(WebCore::HTTPHeaderName::Location)));
+        page->loadRequest(ResourceRequest(response.httpHeaderFields().get(HTTPHeaderName::Location)));
     }
     if (response.httpStatusCode() == 200) {
-        pagePtr->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
-        pagePtr->loadData(IPC::DataReference(static_cast<const uint8_t*>(data.bytes), data.length), "text/html"_s, "UTF-8"_s, response.url().string());
+        page->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
+        page->loadData(IPC::DataReference(static_cast<const uint8_t*>(data.bytes), data.length), "text/html"_s, "UTF-8"_s, response.url().string(), nullptr, navigationAction->shouldOpenExternalURLsPolicy());
     }
 }
 
index 1d1db23..a66365b 100644 (file)
@@ -98,7 +98,7 @@ private:
     virtual void shouldStartInternal() = 0;
     virtual void fallBackToWebPathInternal() = 0;
     virtual void abortInternal() = 0;
-    virtual void completeInternal(WebCore::ResourceResponse&&, NSData *) = 0;
+    virtual void completeInternal(const WebCore::ResourceResponse&, NSData *) = 0;
 
     void becomeCompleted();
     void dismissViewController();
index 83bb5c6..4678fe3 100644 (file)
@@ -154,7 +154,7 @@ void SOAuthorizationSession::complete(NSHTTPURLResponse *httpResponse, NSData *d
     // Set cookies.
     auto cookies = toCookieVector([NSHTTPCookie cookiesWithResponseHeaderFields:httpResponse.allHeaderFields forURL:response.url()]);
     if (cookies.isEmpty()) {
-        completeInternal(WTFMove(response), data);
+        completeInternal(response, data);
         return;
     }
 
@@ -163,7 +163,7 @@ void SOAuthorizationSession::complete(NSHTTPURLResponse *httpResponse, NSData *d
     m_page->websiteDataStore().cookieStore().setCookies(cookies, [weakThis = makeWeakPtr(*this), response = WTFMove(response), data = adoptNS([[NSData alloc] initWithData:data])] () mutable {
         if (!weakThis)
             return;
-        weakThis->completeInternal(WTFMove(response), data.get());
+        weakThis->completeInternal(response, data.get());
     });
 }
 
index 681f53a..7f7b1f9 100644 (file)
@@ -47,7 +47,7 @@ private:
     // SOAuthorizationSession
     void fallBackToWebPathInternal() final;
     void abortInternal() final;
-    void completeInternal(WebCore::ResourceResponse&&, NSData *) final;
+    void completeInternal(const WebCore::ResourceResponse&, NSData *) final;
 
     // NavigationSOAuthorizationSession
     void beforeStart() final;
index beabc53..0656614 100644 (file)
@@ -59,14 +59,14 @@ void SubFrameSOAuthorizationSession::fallBackToWebPathInternal()
     postDidCancelMessageToParent([weakThis = makeWeakPtr(*this)] {
         if (!weakThis)
             return;
-        auto* pagePtr = weakThis->page();
+        auto* page = weakThis->page();
         auto* navigationActionPtr = weakThis->navigationAction();
-        if (!pagePtr || !navigationActionPtr)
+        if (!page || !navigationActionPtr)
             return;
 
         if (auto* targetFrame = navigationActionPtr->targetFrame()) {
-            if (auto* frame = pagePtr->process().webFrame(targetFrame->handle().frameID())) {
-                pagePtr->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
+            if (auto* frame = page->process().webFrame(targetFrame->handle().frameID())) {
+                page->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
                 // Issue a new load to the original URL as the original load is aborted before start.
                 frame->loadURL(navigationActionPtr->request().url());
             }
@@ -79,7 +79,7 @@ void SubFrameSOAuthorizationSession::abortInternal()
     ASSERT_NOT_REACHED();
 }
 
-void SubFrameSOAuthorizationSession::completeInternal(WebCore::ResourceResponse&& response, NSData *data)
+void SubFrameSOAuthorizationSession::completeInternal(const WebCore::ResourceResponse& response, NSData *data)
 {
     if (response.httpStatusCode() != 200) {
         fallBackToWebPathInternal();
@@ -103,14 +103,14 @@ void SubFrameSOAuthorizationSession::beforeStart()
 
 void SubFrameSOAuthorizationSession::loadDataToFrame(const IPC::DataReference& data, const URL& baseURL)
 {
-    auto* pagePtr = page();
+    auto* page = this->page();
     auto* navigationActionPtr = navigationAction();
-    if (!pagePtr || !navigationActionPtr)
+    if (!page || !navigationActionPtr)
         return;
 
     if (auto* targetFrame = navigationActionPtr->targetFrame()) {
-        if (auto* frame = pagePtr->process().webFrame(targetFrame->handle().frameID())) {
-            pagePtr->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
+        if (auto* frame = page->process().webFrame(targetFrame->handle().frameID())) {
+            page->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
             frame->loadData(data, "text/html", "UTF-8", baseURL);
         }
     }
@@ -118,13 +118,13 @@ void SubFrameSOAuthorizationSession::loadDataToFrame(const IPC::DataReference& d
 
 void SubFrameSOAuthorizationSession::postDidCancelMessageToParent(Function<void()>&& callback)
 {
-    auto* pagePtr = page();
+    auto* page = this->page();
     auto* navigationActionPtr = navigationAction();
-    if (!pagePtr || !navigationActionPtr)
+    if (!page || !navigationActionPtr)
         return;
 
     if (auto* targetFrame = navigationActionPtr->targetFrame()) {
-        pagePtr->runJavaScriptInFrame(targetFrame->handle().frameID(), soAuthorizationPostDidCancelMessageToParent, false, [callback = WTFMove(callback)] (API::SerializedScriptValue*, bool, const ExceptionDetails&, ScriptValueCallback::Error) {
+        page->runJavaScriptInFrame(targetFrame->handle().frameID(), soAuthorizationPostDidCancelMessageToParent, false, [callback = WTFMove(callback)] (API::SerializedScriptValue*, bool, const ExceptionDetails&, ScriptValueCallback::Error) {
             callback();
         });
     }
index deb2ada..d7b6d75 100644 (file)
@@ -1117,7 +1117,7 @@ void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& proces
     LoadParameters loadParameters;
     loadParameters.navigationID = navigation.navigationID();
     loadParameters.request = WTFMove(request);
-    loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)shouldOpenExternalURLsPolicy;
+    loadParameters.shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy;
     loadParameters.userData = UserData(process->transformObjectsToHandles(userData).get());
     loadParameters.shouldTreatAsContinuingLoad = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::Yes;
     loadParameters.websitePolicies = WTFMove(websitePolicies);
@@ -1172,7 +1172,7 @@ RefPtr<API::Navigation> WebPageProxy::loadFile(const String& fileURLString, cons
     LoadParameters loadParameters;
     loadParameters.navigationID = navigation->navigationID();
     loadParameters.request = fileURL;
-    loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+    loadParameters.shouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow;
     loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
     SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::Type::ReadOnly, loadParameters.sandboxExtensionHandle);
     addPlatformLoadParameters(loadParameters);
@@ -1184,7 +1184,7 @@ RefPtr<API::Navigation> WebPageProxy::loadFile(const String& fileURLString, cons
     return navigation;
 }
 
-RefPtr<API::Navigation> WebPageProxy::loadData(const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
+RefPtr<API::Navigation> WebPageProxy::loadData(const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
 {
     RELEASE_LOG_IF_ALLOWED(Loading, "loadData: webPID = %i, pageID = %" PRIu64, m_process->processIdentifier(), m_pageID.toUInt64());
 
@@ -1197,11 +1197,11 @@ RefPtr<API::Navigation> WebPageProxy::loadData(const IPC::DataReference& data, c
         launchProcess({ });
 
     auto navigation = m_navigationState->createLoadDataNavigation(std::make_unique<API::SubstituteData>(data.vector(), MIMEType, encoding, baseURL, userData));
-    loadDataWithNavigationShared(m_process.copyRef(), navigation, data, MIMEType, encoding, baseURL, userData, ShouldTreatAsContinuingLoad::No);
+    loadDataWithNavigationShared(m_process.copyRef(), navigation, data, MIMEType, encoding, baseURL, userData, ShouldTreatAsContinuingLoad::No, WTF::nullopt, shouldOpenExternalURLsPolicy);
     return navigation;
 }
 
-void WebPageProxy::loadDataWithNavigationShared(Ref<WebProcessProxy>&& process, API::Navigation& navigation, const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies)
+void WebPageProxy::loadDataWithNavigationShared(Ref<WebProcessProxy>&& process, API::Navigation& navigation, const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
 {
     RELEASE_LOG_IF_ALLOWED(Loading, "loadDataWithNavigation: webPID = %i, pageID = %" PRIu64, process->processIdentifier(), m_pageID.toUInt64());
 
@@ -1220,6 +1220,7 @@ void WebPageProxy::loadDataWithNavigationShared(Ref<WebProcessProxy>&& process,
     loadParameters.shouldTreatAsContinuingLoad = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::Yes;
     loadParameters.userData = UserData(process->transformObjectsToHandles(userData).get());
     loadParameters.websitePolicies = WTFMove(websitePolicies);
+    loadParameters.shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy;
     addPlatformLoadParameters(loadParameters);
 
     process->assumeReadAccessToBaseURL(*this, baseURL);
index 457fadf..6e3297d 100644 (file)
@@ -528,7 +528,7 @@ public:
     void addPlatformLoadParameters(LoadParameters&);
     RefPtr<API::Navigation> loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes, API::Object* userData = nullptr);
     RefPtr<API::Navigation> loadFile(const String& fileURL, const String& resourceDirectoryURL, API::Object* userData = nullptr);
-    RefPtr<API::Navigation> loadData(const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr);
+    RefPtr<API::Navigation> loadData(const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     void loadAlternateHTML(const IPC::DataReference&, const String& encoding, const URL& baseURL, const URL& unreachableURL, API::Object* userData = nullptr);
     void loadWebArchiveData(API::Data*, API::Object* userData = nullptr);
     void navigateToPDFLinkWithSimulatedClick(const String& url, WebCore::IntPoint documentPoint, WebCore::IntPoint screenPoint);
@@ -1509,7 +1509,7 @@ public:
     void decidePolicyForResponseShared(Ref<WebProcessProxy>&&, uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, WebCore::PolicyCheckIdentifier,
         uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, uint64_t listenerID, const UserData&);
     void startURLSchemeTaskShared(Ref<WebProcessProxy>&&, URLSchemeTaskParameters&&);
-    void loadDataWithNavigationShared(Ref<WebProcessProxy>&&, API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt);
+    void loadDataWithNavigationShared(Ref<WebProcessProxy>&&, API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
     void loadRequestWithNavigationShared(Ref<WebProcessProxy>&&, API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt);
     void backForwardGoToItemShared(Ref<WebProcessProxy>&&, const WebCore::BackForwardItemIdentifier&, CompletionHandler<void(SandboxExtension::Handle&&)>&&);
     void decidePolicyForNavigationActionSyncShared(Ref<WebProcessProxy>&&, uint64_t frameID, bool isMainFrame, WebCore::SecurityOriginData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, NavigationActionData&&,
index 1c10ec1..7f0de8c 100644 (file)
@@ -1533,8 +1533,7 @@ void WebPage::loadRequest(LoadParameters&& loadParameters)
 
     // Initate the load in WebCore.
     FrameLoadRequest frameLoadRequest { *m_mainFrame->coreFrame(), loadParameters.request, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
-    ShouldOpenExternalURLsPolicy externalURLsPolicy = static_cast<ShouldOpenExternalURLsPolicy>(loadParameters.shouldOpenExternalURLsPolicy);
-    frameLoadRequest.setShouldOpenExternalURLsPolicy(externalURLsPolicy);
+    frameLoadRequest.setShouldOpenExternalURLsPolicy(loadParameters.shouldOpenExternalURLsPolicy);
     frameLoadRequest.setShouldTreatAsContinuingLoad(loadParameters.shouldTreatAsContinuingLoad);
     frameLoadRequest.setLockHistory(loadParameters.lockHistory);
     frameLoadRequest.setlockBackForwardList(loadParameters.lockBackForwardList);
@@ -1547,7 +1546,7 @@ void WebPage::loadRequest(LoadParameters&& loadParameters)
     ASSERT(!m_pendingWebsitePolicies);
 }
 
-void WebPage::loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies, Ref<SharedBuffer>&& sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData)
+void WebPage::loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies, Ref<SharedBuffer>&& sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
 {
     SendStopResponsivenessTimer stopper;
 
@@ -1563,7 +1562,7 @@ void WebPage::loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLo
     m_loaderClient->willLoadDataRequest(*this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), WebProcess::singleton().transformHandlesToObjects(userData.object()).get());
 
     // Initate the load in WebCore.
-    FrameLoadRequest frameLoadRequest(*m_mainFrame->coreFrame(), request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData);
+    FrameLoadRequest frameLoadRequest(*m_mainFrame->coreFrame(), request, shouldOpenExternalURLsPolicy, substituteData);
     frameLoadRequest.setShouldTreatAsContinuingLoad(shouldTreatAsContinuingLoad);
     m_mainFrame->coreFrame()->loader().load(WTFMove(frameLoadRequest));
 }
@@ -1574,7 +1573,7 @@ void WebPage::loadData(LoadParameters&& loadParameters)
 
     auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
     URL baseURL = loadParameters.baseURLString.isEmpty() ? WTF::blankURL() : URL(URL(), loadParameters.baseURLString);
-    loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData);
+    loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData, loadParameters.shouldOpenExternalURLsPolicy);
 }
 
 void WebPage::loadAlternateHTML(LoadParameters&& loadParameters)
index ea36885..d5423bb 100644 (file)
@@ -1284,7 +1284,7 @@ private:
 
     String sourceForFrame(WebFrame*);
 
-    void loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&&, Ref<WebCore::SharedBuffer>&&, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& failingURL, const UserData&);
+    void loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&&, Ref<WebCore::SharedBuffer>&&, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& failingURL, const UserData&, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 
     // Actions
     void tryClose();
index 8f9237c..708e11d 100644 (file)
@@ -1,3 +1,17 @@
+2019-06-21  Jiewen Tan  <jiewen_tan@apple.com>
+
+        WebPageProxy::loadData should accept ShouldOpenExternalURLsPolicy
+        https://bugs.webkit.org/show_bug.cgi?id=199114
+        <rdar://problem/51671674>
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/TestSOAuthorization.mm:
+        (-[TestSOAuthorizationNavigationDelegate init]):
+        (-[TestSOAuthorizationNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
+        (configureSOAuthorizationWebView):
+        (TestWebKitAPI::TEST):
+
 2019-06-21  Youenn Fablet  <youenn@apple.com>
 
         WebPageProxy should use the right path for sandbox extension
index 8c947a5..42197e4 100644 (file)
@@ -32,6 +32,7 @@
 #import "InstanceMethodSwizzler.h"
 #import "PlatformUtilities.h"
 #import "TestWKWebView.h"
+#import <WebKit/WKNavigationActionPrivate.h>
 #import <WebKit/WKNavigationDelegatePrivate.h>
 #import <WebKit/WKNavigationPrivate.h>
 #import <pal/cocoa/AppSSOSoftLink.h>
@@ -121,6 +122,7 @@ static const char* samlResponse =
 
 @interface TestSOAuthorizationNavigationDelegate : NSObject <WKNavigationDelegate, WKUIDelegate>
 @property bool isDefaultPolicy;
+@property bool shouldOpenExternalSchemes;
 - (instancetype)init;
 @end
 
@@ -128,8 +130,10 @@ static const char* samlResponse =
 
 - (instancetype)init
 {
-    if (self = [super init])
+    if (self = [super init]) {
         self.isDefaultPolicy = true;
+        self.shouldOpenExternalSchemes = false;
+    }
     return self;
 }
 
@@ -142,6 +146,7 @@ static const char* samlResponse =
 
 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
 {
+    EXPECT_EQ(navigationAction._shouldOpenExternalSchemes, self.shouldOpenExternalSchemes);
     if (self.isDefaultPolicy) {
         decisionHandler(WKNavigationActionPolicyAllow);
         return;
@@ -242,10 +247,16 @@ static void resetState()
     gNewWindow = nullptr;
 }
 
-static void configureSOAuthorizationWebView(TestWKWebView *webView, TestSOAuthorizationNavigationDelegate *delegate)
+enum class OpenExternalSchemesPolicy : bool {
+    Allow,
+    Disallow
+};
+
+static void configureSOAuthorizationWebView(TestWKWebView *webView, TestSOAuthorizationNavigationDelegate *delegate, OpenExternalSchemesPolicy policy = OpenExternalSchemesPolicy::Disallow)
 {
     [webView setNavigationDelegate:delegate];
     [webView setUIDelegate:delegate];
+    delegate.shouldOpenExternalSchemes = policy == OpenExternalSchemesPolicy::Allow;
 }
 
 static String generateHtml(const char* templateHtml, const String& substitute, const String& optionalSubstitute1 = emptyString(), const String& optionalSubstitute2 = emptyString())
@@ -277,7 +288,7 @@ TEST(SOAuthorizationRedirect, NoInterceptions)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&navigationCompleted);
@@ -294,7 +305,7 @@ TEST(SOAuthorizationRedirect, InterceptionError)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&navigationCompleted);
@@ -313,7 +324,7 @@ TEST(SOAuthorizationRedirect, InterceptionDoNotHandle)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -336,7 +347,7 @@ TEST(SOAuthorizationRedirect, InterceptionCancel)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -359,7 +370,7 @@ TEST(SOAuthorizationRedirect, InterceptionCompleteWithoutData)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -382,7 +393,7 @@ TEST(SOAuthorizationRedirect, InterceptionUnexpectedCompletion)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -406,7 +417,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceed1)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -433,7 +444,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceed2)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     // Force App Links with a request.URL that has a different host than the current one (empty host) and ShouldOpenExternalURLsPolicy::ShouldAllow.
     auto testURL = URL(URL(), "https://www.example.com");
@@ -467,7 +478,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceed3)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     // Force App Links with a request.URL that has a different host than the current one (empty host) and ShouldOpenExternalURLsPolicy::ShouldAllow.
     auto testURL = URL(URL(), "https://www.example.com");
@@ -504,7 +515,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceed4)
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     // A separate delegate that implements decidePolicyForNavigationAction.
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
     [delegate setIsDefaultPolicy:false];
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
@@ -533,7 +544,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedWithOtherHttpStatusCode)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -557,7 +568,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedWithCookie)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -592,7 +603,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedWithCookies)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -626,7 +637,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedWithRedirectionAndCookie)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     auto testURL = URL(URL(), "https://www.example.com");
 #if PLATFORM(MAC)
@@ -667,7 +678,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedWithDifferentOrigin)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -691,8 +702,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedWithWaitingSession)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    [webView setNavigationDelegate:delegate.get()];
-    [webView setUIDelegate:delegate.get()];
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     // The session will be waiting since the web view is is not int the window.
     [webView removeFromSuperview];
@@ -727,7 +737,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedWithActiveSessionDidMoveWindow)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -758,7 +768,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedTwice)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     for (int i = 0; i < 2; i++) {
         authorizationPerformed = false;
@@ -791,7 +801,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedSuppressActiveSession)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -826,8 +836,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedSuppressWaitingSession)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    [webView setNavigationDelegate:delegate.get()];
-    [webView setUIDelegate:delegate.get()];
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     // The session will be waiting since the web view is is not int the window.
     [webView removeFromSuperview];
@@ -867,7 +876,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedSAML)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     // Add a http body to the request to mimic a SAML request.
     auto request = adoptNS([NSMutableURLRequest requestWithURL:testURL.get()]);
@@ -897,6 +906,8 @@ TEST(SOAuthorizationRedirect, AuthorizationOptions)
 
     [webView loadHTMLString:@"" baseURL:(NSURL *)URL(URL(), "http://www.webkit.org")];
     Util::run(&navigationCompleted);
+
+    [delegate setShouldOpenExternalSchemes:true];
     [webView evaluateJavaScript: @"location = 'http://www.example.com'" completionHandler:nil];
     Util::run(&authorizationPerformed);
     checkAuthorizationOptions(true, "http://www.webkit.org", 0);
@@ -913,7 +924,7 @@ TEST(SOAuthorizationRedirect, InterceptionDidNotHandleTwice)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -934,7 +945,7 @@ TEST(SOAuthorizationRedirect, InterceptionCompleteTwice)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -959,7 +970,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedWithUI)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -992,7 +1003,7 @@ TEST(SOAuthorizationRedirect, InterceptionCancelWithUI)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -1024,7 +1035,7 @@ TEST(SOAuthorizationRedirect, InterceptionErrorWithUI)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -1056,7 +1067,7 @@ TEST(SOAuthorizationRedirect, InterceptionSucceedSuppressActiveSessionWithUI)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -1095,7 +1106,7 @@ TEST(SOAuthorizationRedirect, ShowUITwice)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -1132,7 +1143,7 @@ TEST(SOAuthorizationRedirect, NSNotificationCenter)
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
-    configureSOAuthorizationWebView(webView.get(), delegate.get());
+    configureSOAuthorizationWebView(webView.get(), delegate.get(), OpenExternalSchemesPolicy::Allow);
 
     [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     Util::run(&authorizationPerformed);
@@ -1167,6 +1178,7 @@ TEST(SOAuthorizationPopUp, NoInterceptions)
     [webView loadHTMLString:testHtml baseURL:testURL.get()];
     Util::run(&navigationCompleted);
 
+    [delegate setShouldOpenExternalSchemes:true];
     navigationCompleted = false;
 #if PLATFORM(MAC)
     [webView sendClicksAtPoint:NSMakePoint(200, 200) numberOfClicks:1];
@@ -1244,6 +1256,7 @@ TEST(SOAuthorizationPopUp, InterceptionError)
     [webView loadHTMLString:testHtml baseURL:baseURL.get()];
     Util::run(&navigationCompleted);
 
+    [delegate setShouldOpenExternalSchemes:true];
 #if PLATFORM(MAC)
     [webView sendClicksAtPoint:NSMakePoint(200, 200) numberOfClicks:1];
 #elif PLATFORM(IOS)
@@ -1420,6 +1433,7 @@ TEST(SOAuthorizationPopUp, InterceptionSucceedWithOtherHttpStatusCode)
     [webView loadHTMLString:testHtml baseURL:baseURL.get()];
     Util::run(&navigationCompleted);
 
+    [delegate setShouldOpenExternalSchemes:true];
 #if PLATFORM(MAC)
     [webView sendClicksAtPoint:NSMakePoint(200, 200) numberOfClicks:1];
 #elif PLATFORM(IOS)