From 373606a1ede173a0e8037ab46af0acf68ab60594 Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Sun, 14 Jun 2020 18:01:09 -0400 Subject: [PATCH] fix(browser): fix regressions in external link handling Fixes #1238. --- src/libs/browser/CMakeLists.txt | 1 - src/libs/browser/settings.cpp | 9 --- src/libs/browser/urlrequestinterceptor.cpp | 86 ---------------------- src/libs/browser/urlrequestinterceptor.h | 47 ------------ src/libs/browser/webpage.cpp | 35 +++++++-- src/libs/browser/webpage.h | 2 +- 6 files changed, 28 insertions(+), 152 deletions(-) delete mode 100644 src/libs/browser/urlrequestinterceptor.cpp delete mode 100644 src/libs/browser/urlrequestinterceptor.h diff --git a/src/libs/browser/CMakeLists.txt b/src/libs/browser/CMakeLists.txt index 4d94acc..f69c629 100644 --- a/src/libs/browser/CMakeLists.txt +++ b/src/libs/browser/CMakeLists.txt @@ -1,7 +1,6 @@ add_library(Browser STATIC searchtoolbar.cpp settings.cpp - urlrequestinterceptor.cpp webbridge.cpp webcontrol.cpp webpage.cpp diff --git a/src/libs/browser/settings.cpp b/src/libs/browser/settings.cpp index 2b9d87b..49599ed 100644 --- a/src/libs/browser/settings.cpp +++ b/src/libs/browser/settings.cpp @@ -22,8 +22,6 @@ #include "settings.h" -#include "urlrequestinterceptor.h" - #include #include @@ -51,13 +49,6 @@ Settings::Settings(Core::Settings *appSettings, QObject *parent) // Create a new off-the-record profile. m_webProfile = new QWebEngineProfile(this); - // Setup URL interceptor. -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - m_webProfile->setUrlRequestInterceptor(new UrlRequestInterceptor(this)); -#else - m_webProfile->setRequestInterceptor(new UrlRequestInterceptor(this)); -#endif - // Listen to settings changes. connect(m_appSettings, &Core::Settings::updated, this, &Settings::applySettings); applySettings(); diff --git a/src/libs/browser/urlrequestinterceptor.cpp b/src/libs/browser/urlrequestinterceptor.cpp deleted file mode 100644 index f6ff657..0000000 --- a/src/libs/browser/urlrequestinterceptor.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Oleg Shparber -** Copyright (C) 2019 Kay Gawlik -** Contact: https://go.zealdocs.org/l/contact -** -** This file is part of Zeal. -** -** Zeal is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** Zeal is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with Zeal. If not, see . -** -****************************************************************************/ - -#include "urlrequestinterceptor.h" - -#include -#include -#include - -#include - -using namespace Zeal::Browser; - -static Q_LOGGING_CATEGORY(log, "zeal.browser.urlrequestinterceptor") - -UrlRequestInterceptor::UrlRequestInterceptor(QObject *parent) - : QWebEngineUrlRequestInterceptor(parent) -{ -} - -void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) -{ - const QUrl requestUrl = info.requestUrl(); - const QUrl firstPartyUrl = info.firstPartyUrl(); - - if (!firstPartyUrl.isValid()) { - return; - } - - bool firstPartyUrlLocal = Core::NetworkAccessManager::isLocalUrl(firstPartyUrl); - bool requestUrlLocal = Core::NetworkAccessManager::isLocalUrl(requestUrl); - - if (firstPartyUrlLocal && requestUrlLocal) { - return; - } - - if (firstPartyUrlLocal != requestUrlLocal) { - blockRequest(info); - return; - } - - // TODO: [C++20] using enum Core::Settings::ExternalLinkPolicy; - typedef Core::Settings::ExternalLinkPolicy ExternalLinkPolicy; - - ExternalLinkPolicy linkPolicy = Core::Application::instance()->settings()->externalLinkPolicy; - switch (info.resourceType()) { - case QWebEngineUrlRequestInfo::ResourceTypeMainFrame: - if (linkPolicy != ExternalLinkPolicy::Open && linkPolicy != ExternalLinkPolicy::Ask) { - blockRequest(info); - } - break; - case QWebEngineUrlRequestInfo::ResourceTypeSubFrame: - if (linkPolicy != ExternalLinkPolicy::Open) { - blockRequest(info); - } - break; - default: - break; - } -} - -void UrlRequestInterceptor::blockRequest(QWebEngineUrlRequestInfo &info) -{ - qCDebug(log, "Blocked request: %s '%s'.", info.requestMethod().data(), qPrintable(info.requestUrl().toString())); - info.block(true); -} diff --git a/src/libs/browser/urlrequestinterceptor.h b/src/libs/browser/urlrequestinterceptor.h deleted file mode 100644 index 72be71c..0000000 --- a/src/libs/browser/urlrequestinterceptor.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Oleg Shparber -** Copyright (C) 2019 Kay Gawlik -** Contact: https://go.zealdocs.org/l/contact -** -** This file is part of Zeal. -** -** Zeal is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** Zeal is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with Zeal. If not, see . -** -****************************************************************************/ - -#ifndef ZEAL_BROWSER_URLREQUESTINTERCEPTOR_H -#define ZEAL_BROWSER_URLREQUESTINTERCEPTOR_H - -#include - -namespace Zeal { -namespace Browser { - -class UrlRequestInterceptor final : public QWebEngineUrlRequestInterceptor -{ - Q_OBJECT - Q_DISABLE_COPY(UrlRequestInterceptor) -public: - UrlRequestInterceptor(QObject *parent = nullptr); - void interceptRequest(QWebEngineUrlRequestInfo &info) override; - -private: - void blockRequest(QWebEngineUrlRequestInfo &info); -}; - -} // namespace Browser -} // namespace Zeal - -#endif // ZEAL_BROWSER_URLREQUESTINTERCEPTOR_H diff --git a/src/libs/browser/webpage.cpp b/src/libs/browser/webpage.cpp index 3036b6c..e45fa79 100644 --- a/src/libs/browser/webpage.cpp +++ b/src/libs/browser/webpage.cpp @@ -32,38 +32,53 @@ #include #include #include +#include #include #include using namespace Zeal::Browser; +static Q_LOGGING_CATEGORY(log, "zeal.browser.webpage") + WebPage::WebPage(QObject *parent) : QWebEnginePage(Settings::defaultProfile(), parent) { } -bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) +bool WebPage::acceptNavigationRequest(const QUrl &requestUrl, QWebEnginePage::NavigationType type, bool isMainFrame) { Q_UNUSED(type) - Q_UNUSED(isMainFrame) - if (Core::NetworkAccessManager::isLocalUrl(url)) { + // Local elements are always allowed. + if (Core::NetworkAccessManager::isLocalUrl(requestUrl)) { return true; } + // Allow external resources if already on an external page. + const QUrl pageUrl = url(); + if (pageUrl.isValid() && !Core::NetworkAccessManager::isLocalUrl(pageUrl)) { + return true; + } + + // Block external elements on local pages. + if (!isMainFrame) { + qCDebug(log, "Blocked request to '%s'.", qPrintable(requestUrl.toString())); + return false; + } + auto appSettings = Core::Application::instance()->settings(); + // TODO: [C++20] using enum Core::Settings::ExternalLinkPolicy; typedef Core::Settings::ExternalLinkPolicy ExternalLinkPolicy; switch (appSettings->externalLinkPolicy) { case ExternalLinkPolicy::Open: - break; + return true; case ExternalLinkPolicy::Ask: { QMessageBox mb; mb.setIcon(QMessageBox::Question); mb.setText(tr("How do you want to open the external link?
URL: %1") - .arg(url.toString())); - + .arg(requestUrl.toString())); QCheckBox *checkBox = new QCheckBox("Do ¬ ask again"); mb.setCheckBox(checkBox); @@ -75,6 +90,7 @@ bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::Navigatio mb.setDefaultButton(openInBrowserButton); if (mb.exec() == QMessageBox::Cancel) { + qCDebug(log, "Blocked request to '%s'.", qPrintable(requestUrl.toString())); return false; } @@ -93,17 +109,20 @@ bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::Navigatio appSettings->save(); } - QDesktopServices::openUrl(url); + QDesktopServices::openUrl(requestUrl); return false; } break; } case ExternalLinkPolicy::OpenInSystemBrowser: - QDesktopServices::openUrl(url); + QDesktopServices::openUrl(requestUrl); return false; } + // This code should not be reachable so log a warning. + qCWarning(log, "Blocked request to '%s'.", qPrintable(requestUrl.toString())); + return false; } diff --git a/src/libs/browser/webpage.h b/src/libs/browser/webpage.h index 8871ba9..195bd58 100644 --- a/src/libs/browser/webpage.h +++ b/src/libs/browser/webpage.h @@ -37,7 +37,7 @@ public: explicit WebPage(QObject *parent = nullptr); protected: - bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) override; + bool acceptNavigationRequest(const QUrl &requestUrl, NavigationType type, bool isMainFrame) override; void javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceId) override; };