summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------src/3rdparty0
-rw-r--r--src/core/content_browser_client_qt.cpp67
-rw-r--r--src/core/content_browser_client_qt.h5
-rw-r--r--src/core/net/network_delegate_qt.cpp3
-rw-r--r--src/core/net/url_request_notification.cpp32
-rw-r--r--src/core/qtwebengine.gni1
-rw-r--r--tests/auto/widgets/schemes/tst_schemes.cpp76
7 files changed, 121 insertions, 63 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 88a931558e2e960eacccb32483713fcc4bbaf43
+Subproject d61464c1e69fa96a47ab731f0ee4549890ae465
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 29b6e09ed..49617329e 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -49,6 +49,8 @@
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
#endif
+#include "components/navigation_interception/intercept_navigation_throttle.h"
+#include "components/navigation_interception/navigation_params.h"
#include "components/guest_view/browser/guest_view_base.h"
#include "components/network_hints/browser/network_hints_message_filter.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
@@ -121,6 +123,7 @@
#include "renderer_host/user_resource_controller_host.h"
#include "service/service_qt.h"
#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
#include "web_contents_delegate_qt.h"
#include "web_engine_context.h"
#include "web_engine_library_info.h"
@@ -846,6 +849,70 @@ ContentBrowserClientQt::CreateURLLoaderThrottles(
return result;
}
+extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
+
+static bool navigationThrottleCallback(content::WebContents *source,
+ const navigation_interception::NavigationParams &params)
+{
+ // We call navigationRequested later in launchExternalUrl for external protocols.
+ // The is_external_protocol parameter here is not fully accurate though,
+ // and doesn't know about profile specific custom URL schemes.
+ ProfileQt *profile = static_cast<ProfileQt *>(source->GetBrowserContext());
+ if (params.is_external_protocol() && !profile->profileAdapter()->urlSchemeHandler(toQByteArray(params.url().scheme())))
+ return false;
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(source->GetDelegate());
+ WebContentsAdapterClient *client = delegate->adapterClient();
+ client->navigationRequested(pageTransitionToNavigationType(params.transition_type()),
+ toQt(params.url()),
+ navigationRequestAction,
+ params.is_main_frame());
+ return navigationRequestAction == static_cast<int>(WebContentsAdapterClient::IgnoreRequest);
+}
+
+std::vector<std::unique_ptr<content::NavigationThrottle>> ContentBrowserClientQt::CreateThrottlesForNavigation(
+ content::NavigationHandle *navigation_handle)
+{
+ std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
+ throttles.push_back(std::make_unique<navigation_interception::InterceptNavigationThrottle>(
+ navigation_handle,
+ base::BindRepeating(&navigationThrottleCallback),
+ navigation_interception::SynchronyMode::kSync));
+ return throttles;
+}
+
+bool ContentBrowserClientQt::IsHandledURL(const GURL &url)
+{
+ static const char *const kProtocolList[] = {
+ url::kFileScheme,
+ content::kChromeDevToolsScheme,
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::kExtensionScheme,
+#endif
+ content::kChromeUIScheme,
+ url::kDataScheme,
+ url::kAboutScheme,
+#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
+ url::kFtpScheme,
+#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT)
+ url::kBlobScheme,
+ url::kFileSystemScheme,
+ url::kQrcScheme,
+ };
+
+ // We don't check url.IsCustom() here because we don't
+ // know if the registered protocol is installed in the
+ // profile that will be used to load the URL.
+
+ const std::string scheme = url.scheme();
+
+ for (const char *protocol : kProtocolList) {
+ if (scheme == protocol)
+ return true;
+ }
+ return net::URLRequest::IsHandledProtocol(scheme);
+}
+
std::unique_ptr<content::LoginDelegate> ContentBrowserClientQt::CreateLoginDelegate(
const net::AuthChallengeInfo &authInfo,
content::WebContents *web_contents,
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index f5b03a8d9..5d8a1519c 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -216,6 +216,11 @@ public:
const base::RepeatingCallback<content::WebContents *()> &wc_getter,
content::NavigationUIData *navigation_ui_data, int frame_tree_node_id) override;
+ std::vector<std::unique_ptr<content::NavigationThrottle>> CreateThrottlesForNavigation(
+ content::NavigationHandle *navigation_handle) override;
+
+ bool IsHandledURL(const GURL &url) override;
+
static std::string getUserAgent();
std::string GetUserAgent() override { return getUserAgent(); }
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
index 7d3801ffe..684558abb 100644
--- a/src/core/net/network_delegate_qt.cpp
+++ b/src/core/net/network_delegate_qt.cpp
@@ -178,8 +178,7 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
return net::OK;
// try to bail out
- if (!m_profileIOData->hasPageInterceptors() && (!m_profileIOData->requestInterceptor() || m_profileIOData->isInterceptorDeprecated()) &&
- !content::IsResourceTypeFrame(resourceType))
+ if (!m_profileIOData->hasPageInterceptors() && (!m_profileIOData->requestInterceptor() || m_profileIOData->isInterceptorDeprecated()))
return net::OK;
auto webContentsGetter = resourceInfo->GetWebContentsGetterForRequest();
diff --git a/src/core/net/url_request_notification.cpp b/src/core/net/url_request_notification.cpp
index fa6d61f65..eb48160bf 100644
--- a/src/core/net/url_request_notification.cpp
+++ b/src/core/net/url_request_notification.cpp
@@ -44,11 +44,12 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request.h"
-#include "web_contents_adapter_client.h"
-#include "web_contents_view_qt.h"
+
+#include "api/qwebengineurlrequestinfo_p.h"
#include "profile_io_data_qt.h"
-#include "qwebengineurlrequestinfo_p.h"
#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
namespace QtWebEngineCore {
@@ -66,11 +67,6 @@ private:
const char UserData::key[] = "QtWebEngineCore::URLRequestNotification";
-static content::ResourceType fromQt(QWebEngineUrlRequestInfo::ResourceType resourceType)
-{
- return static_cast<content::ResourceType>(resourceType);
-}
-
URLRequestNotification::URLRequestNotification(net::URLRequest *request, bool isMainFrameRequest, GURL *newUrl,
QWebEngineUrlRequestInfo &&requestInfo,
content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
@@ -105,7 +101,6 @@ void URLRequestNotification::notify()
content::WebContents *webContents = m_webContentsGetter.Run();
if (webContents) {
-
if (m_profileAdapter && m_profileAdapter->requestInterceptor()) {
QWebEngineUrlRequestInterceptor *interceptor = m_profileAdapter->requestInterceptor();
if (!interceptor->property("deprecated").toBool())
@@ -123,25 +118,6 @@ void URLRequestNotification::notify()
result = m_requestInfo.d_ptr->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
// We handle the rest of the changes later when we are back in I/O thread
}
-
- // Only do navigationRequested on MAIN_FRAME and SUB_FRAME resources
- if (result == net::OK && content::IsResourceTypeFrame(fromQt(m_requestInfo.resourceType()))) {
- int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
- client->navigationRequested(m_requestInfo.navigationType(),
- m_requestInfo.requestUrl(),
- navigationRequestAction,
- m_isMainFrameRequest);
- result = net::ERR_FAILED;
- switch (static_cast<WebContentsAdapterClient::NavigationRequestAction>(navigationRequestAction)) {
- case WebContentsAdapterClient::AcceptRequest:
- result = net::OK;
- break;
- case WebContentsAdapterClient::IgnoreRequest:
- result = net::ERR_ABORTED;
- break;
- }
- DCHECK(result != net::ERR_FAILED);
- }
}
// Run the callback on the IO thread.
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index cd8514352..b529290c0 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -20,6 +20,7 @@ deps = [
"//components/cdm/renderer",
"//components/error_page/common",
"//components/keyed_service/content",
+ "//components/navigation_interception",
"//components/network_hints/browser",
"//components/network_hints/common",
"//components/network_hints/renderer",
diff --git a/tests/auto/widgets/schemes/tst_schemes.cpp b/tests/auto/widgets/schemes/tst_schemes.cpp
index 1b6093571..a4a0e34ff 100644
--- a/tests/auto/widgets/schemes/tst_schemes.cpp
+++ b/tests/auto/widgets/schemes/tst_schemes.cpp
@@ -38,6 +38,7 @@ class tst_Schemes : public QObject
Q_OBJECT
private Q_SLOTS:
+ void unknownUrlSchemePolicy_data();
void unknownUrlSchemePolicy();
};
@@ -58,8 +59,27 @@ public:
}
};
+Q_DECLARE_METATYPE(QWebEngineSettings::UnknownUrlSchemePolicy)
+
+void tst_Schemes::unknownUrlSchemePolicy_data()
+{
+ QTest::addColumn<QWebEngineSettings::UnknownUrlSchemePolicy>("policy");
+ QTest::addColumn<bool>("userAction");
+ QTest::newRow("DisallowUnknownUrlSchemes, script") << QWebEngineSettings::DisallowUnknownUrlSchemes << false;
+ QTest::newRow("DisallowUnknownUrlSchemes, user") << QWebEngineSettings::DisallowUnknownUrlSchemes << true;
+ QTest::newRow("AllowUnknownUrlSchemesFromUserInteraction, script") << QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction << false;
+ QTest::newRow("AllowUnknownUrlSchemesFromUserInteraction, user") << QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction << true;
+ QTest::newRow("AllowAllUnknownUrlSchemes, script") << QWebEngineSettings::AllowAllUnknownUrlSchemes << false;
+ QTest::newRow("AllowAllUnknownUrlSchemes, user") << QWebEngineSettings::AllowAllUnknownUrlSchemes << true;
+ QTest::newRow("default UnknownUrlSchemePolicy, script") << QWebEngineSettings::UnknownUrlSchemePolicy(0) << false;
+ QTest::newRow("default UnknownUrlSchemePolicy, user") << QWebEngineSettings::UnknownUrlSchemePolicy(0) << true;
+}
+
void tst_Schemes::unknownUrlSchemePolicy()
{
+ QFETCH(QWebEngineSettings::UnknownUrlSchemePolicy, policy);
+ QFETCH(bool, userAction);
+
QWebEngineView view;
AcceptNavigationRequestHandler page;
QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
@@ -71,41 +91,31 @@ void tst_Schemes::unknownUrlSchemePolicy()
settings->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
settings->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
- QWebEngineSettings::UnknownUrlSchemePolicy policies[6] = {QWebEngineSettings::DisallowUnknownUrlSchemes,
- QWebEngineSettings::DisallowUnknownUrlSchemes,
- QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction,
- QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction,
- QWebEngineSettings::AllowAllUnknownUrlSchemes,
- QWebEngineSettings::AllowAllUnknownUrlSchemes};
- // even iterations are for navigation-requests from javascript,
- // odd iterations are for navigations-requests from user-interaction
- for (int i = 0; i < 8; i++) {
- if (i <= 5)
- settings->setUnknownUrlSchemePolicy(policies[i]);
- else
- settings->resetUnknownUrlSchemePolicy();
- loadFinishedSpy.clear();
- page.acceptNavigationRequestCalls = 0;
- bool shouldAccept;
-
- if (i % 2 == 0) { // navigation request coming from javascript
- shouldAccept = (4 <= i && i <= 5); // only case AllowAllUnknownUrlSchemes
- view.setHtml("<html><script>setTimeout(function(){ window.location.href='nonexistentscheme://somewhere'; }, 10);</script><body>testing...</body></html>");
- } else { // navigation request coming from user interaction
- shouldAccept = (2 <= i); // all cases except DisallowUnknownUrlSchemes
- view.setHtml("<html><body><a id='nonexlink' href='nonexistentscheme://somewhere'>nonexistentscheme://somewhere</a></body></html>");
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 15000);
- // focus and trigger the link
- view.page()->runJavaScript("document.getElementById('nonexlink').focus();", [&view](const QVariant &result) {
- Q_UNUSED(result);
- QTest::sendKeyEvent(QTest::Press, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
- QTest::sendKeyEvent(QTest::Release, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
- });
- }
+ if (policy > 0)
+ settings->setUnknownUrlSchemePolicy(policy);
+ else
+ settings->resetUnknownUrlSchemePolicy();
+ loadFinishedSpy.clear();
+ page.acceptNavigationRequestCalls = 0;
+ bool shouldAccept;
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 2, 60000);
- QCOMPARE(page.acceptNavigationRequestCalls, shouldAccept ? 1 : 0);
+ if (!userAction) { // navigation request coming from javascript
+ shouldAccept = (policy == QWebEngineSettings::AllowAllUnknownUrlSchemes);
+ view.setHtml("<html><script>setTimeout(function(){ window.location.href='nonexistentscheme://somewhere'; }, 10);</script><body>testing...</body></html>");
+ } else { // navigation request coming from user interaction
+ shouldAccept = (policy != QWebEngineSettings::DisallowUnknownUrlSchemes);
+ view.setHtml("<html><body><a id='nonexlink' href='nonexistentscheme://somewhere'>nonexistentscheme://somewhere</a></body></html>");
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 15000);
+ // focus and trigger the link
+ view.page()->runJavaScript("document.getElementById('nonexlink').focus();", [&view](const QVariant &result) {
+ Q_UNUSED(result);
+ QTest::sendKeyEvent(QTest::Press, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
+ QTest::sendKeyEvent(QTest::Release, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
+ });
}
+
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 2, 60000);
+ QCOMPARE(page.acceptNavigationRequestCalls, shouldAccept ? 1 : 0);
}
QTEST_MAIN(tst_Schemes)