summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorViktor Engelmann <viktor.engelmann@qt.io>2017-07-03 15:51:51 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-18 18:06:55 +0000
commit49c0ce8403e5caeb864f66553f122c68a7c975fb (patch)
treea3b4c1f89754c316fe1fb5cce4392dd05f1db4e7 /src/core
parent8365186b3fdc2f1eca7e015147688d23bfdf81e9 (diff)
Add Setting to allow passing unknown URL schemes to QDesktopServices
A new enum UnknownUrlSchemePolicy was added to WebEngineSettings, QWebEngineSettings and QQuickWebEngineSettings. WebContentsDelegate now has a new attribute of that type, which can be read and written through the public APIs Q(Quick)WebEngineSettings::unknownUrlSchemeNavigationPolicy and Q(Quick)WebEngineSettings::setUnknownUrlSchemeNavigationPolicy. This way, one can control, whether URLs with unknown schemes are passed to QDesktopServices. WebContentsAdapterClient::navigationRequested is called on these requests, so this allows more fine-grained control over the schemes and origins, that are allowed. Task-number: QTBUG-58627 Change-Id: Ie81d9503456d63ea1ed5606483254acf437cd8f7 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp10
-rw-r--r--src/core/web_contents_delegate_qt.cpp41
-rw-r--r--src/core/web_contents_delegate_qt.h2
-rw-r--r--src/core/web_engine_settings.cpp18
-rw-r--r--src/core/web_engine_settings.h12
5 files changed, 71 insertions, 12 deletions
diff --git a/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp b/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp
index afc2ea8fa..279a03d42 100644
--- a/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp
+++ b/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp
@@ -138,7 +138,7 @@ void ResourceDispatcherHostLoginDelegateQt::destroy()
static void LaunchURL(const GURL& url, int render_process_id,
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
- ui::PageTransition page_transition, bool is_main_frame)
+ ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture)
{
Q_UNUSED(render_process_id);
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
@@ -146,16 +146,13 @@ static void LaunchURL(const GURL& url, int render_process_id,
if (!webContents)
return;
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
- contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame);
+ contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame, has_user_gesture);
}
bool ResourceDispatcherHostDelegateQt::HandleExternalProtocol(const GURL& url, content::ResourceRequestInfo* info)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- // We don't want to launch external applications unless it is based on a user action
- if (!info->HasUserGesture())
- return false;
content::BrowserThread::PostTask(
content::BrowserThread::UI,
@@ -164,7 +161,8 @@ bool ResourceDispatcherHostDelegateQt::HandleExternalProtocol(const GURL& url, c
info->GetChildID(),
info->GetWebContentsGetterForRequest(),
info->GetPageTransition(),
- info->IsMainFrame())
+ info->IsMainFrame(),
+ info->HasUserGesture())
);
return true;
}
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index ad0e7ad6d..31180a1c1 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -499,14 +499,45 @@ void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingO
extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
-void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame)
+void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture)
{
- int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
- m_viewClient->navigationRequested(pageTransitionToNavigationType(page_transition), url, navigationRequestAction, is_main_frame);
+ WebEngineSettings *settings = m_viewClient->webEngineSettings();
+ bool navigationAllowedByPolicy = false;
+ bool navigationRequestAccepted = true;
+
+ switch (settings->unknownUrlSchemePolicy()) {
+ case WebEngineSettings::DisallowUnknownUrlSchemes:
+ break;
+ case WebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction:
+ navigationAllowedByPolicy = has_user_gesture;
+ break;
+ case WebEngineSettings::AllowAllUnknownUrlSchemes:
+ navigationAllowedByPolicy = true;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ if (navigationAllowedByPolicy) {
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ m_viewClient->navigationRequested(pageTransitionToNavigationType(page_transition), url, navigationRequestAction, is_main_frame);
+ navigationRequestAccepted = navigationRequestAction == WebContentsAdapterClient::AcceptRequest;
#ifndef QT_NO_DESKTOPSERVICES
- if (navigationRequestAction == WebContentsAdapterClient::AcceptRequest)
- QDesktopServices::openUrl(url);
+ if (navigationRequestAccepted)
+ QDesktopServices::openUrl(url);
#endif
+ }
+
+ if (!navigationAllowedByPolicy || !navigationRequestAccepted) {
+ if (!navigationAllowedByPolicy)
+ didFailLoad(url, 420, QStringLiteral("Launching external protocol forbidden by WebEngineSettings::UnknownUrlSchemePolicy"));
+ else
+ didFailLoad(url, 420, QStringLiteral("Launching external protocol suppressed by WebContentsAdapterClient::navigationRequested"));
+ if (settings->testAttribute(WebEngineSettings::ErrorPageEnabled)) {
+ EmitLoadStarted(toQt(GURL(content::kUnreachableWebDataURL)), true);
+ m_viewClient->webContentsAdapter()->load(toQt(GURL(content::kUnreachableWebDataURL)));
+ }
+ }
}
void WebContentsDelegateQt::ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text)
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 2e37c498a..dab693780 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -142,7 +142,7 @@ public:
void overrideWebPreferences(content::WebContents *, content::WebPreferences*);
void allowCertificateError(const QSharedPointer<CertificateErrorController> &) ;
void requestGeolocationPermission(const QUrl &requestingOrigin);
- void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame);
+ void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture);
FaviconManager *faviconManager();
void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; }
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 4c944892a..7b9c1225d 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -110,6 +110,7 @@ WebEngineSettings::WebEngineSettings(WebEngineSettings *_parentSettings)
: m_adapter(0)
, m_batchTimer(new BatchTimer(this))
, parentSettings(_parentSettings)
+ , m_unknownUrlSchemePolicy(WebEngineSettings::InheritedUnknownUrlSchemePolicy)
{
if (parentSettings)
parentSettings->childSettings.insert(this);
@@ -212,6 +213,22 @@ QString WebEngineSettings::defaultTextEncoding() const
return m_defaultEncoding.isEmpty()? parentSettings->defaultTextEncoding() : m_defaultEncoding;
}
+void WebEngineSettings::setUnknownUrlSchemePolicy(WebEngineSettings::UnknownUrlSchemePolicy policy)
+{
+ m_unknownUrlSchemePolicy = policy;
+}
+
+WebEngineSettings::UnknownUrlSchemePolicy WebEngineSettings::unknownUrlSchemePolicy() const
+{
+ // value InheritedUnknownUrlSchemePolicy means it is taken from parent, if possible. If there
+ // is no parent, then AllowUnknownUrlSchemesFromUserInteraction (the default behavior) is used.
+ if (m_unknownUrlSchemePolicy != InheritedUnknownUrlSchemePolicy)
+ return m_unknownUrlSchemePolicy;
+ if (parentSettings)
+ return parentSettings->unknownUrlSchemePolicy();
+ return AllowUnknownUrlSchemesFromUserInteraction;
+}
+
void WebEngineSettings::initDefaults()
{
if (s_defaultAttributes.isEmpty()) {
@@ -284,6 +301,7 @@ void WebEngineSettings::initDefaults()
}
m_defaultEncoding = QStringLiteral("ISO-8859-1");
+ m_unknownUrlSchemePolicy = InheritedUnknownUrlSchemePolicy;
}
void WebEngineSettings::scheduleApply()
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index 639d314f3..d4c5e02a8 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -107,6 +107,14 @@ public:
DefaultFixedFontSize
};
+ // Must match the values from the public API in qwebenginesettings.h.
+ enum UnknownUrlSchemePolicy {
+ InheritedUnknownUrlSchemePolicy = 0,
+ DisallowUnknownUrlSchemes = 1,
+ AllowUnknownUrlSchemesFromUserInteraction,
+ AllowAllUnknownUrlSchemes
+ };
+
explicit WebEngineSettings(WebEngineSettings *parentSettings = 0);
~WebEngineSettings();
@@ -129,6 +137,9 @@ public:
void setDefaultTextEncoding(const QString &encoding);
QString defaultTextEncoding() const;
+ void setUnknownUrlSchemePolicy(UnknownUrlSchemePolicy policy);
+ UnknownUrlSchemePolicy unknownUrlSchemePolicy() const;
+
void initDefaults();
void scheduleApply();
@@ -155,6 +166,7 @@ private:
static QHash<Attribute, bool> s_defaultAttributes;
static QHash<FontFamily, QString> s_defaultFontFamilies;
static QHash<FontSize, int> s_defaultFontSizes;
+ UnknownUrlSchemePolicy m_unknownUrlSchemePolicy;
friend class BatchTimer;
friend class WebContentsAdapter;