diff --git a/resources/binaries b/resources/binaries index 572da127b..176715f7b 160000 --- a/resources/binaries +++ b/resources/binaries @@ -1 +1 @@ -Subproject commit 572da127bb14842bba6f84e6315a5ecefb44ed07 +Subproject commit 176715f7b3229289e2fb0dffb000c436664a26ff diff --git a/src/gui/dialogs/formsettings.cpp b/src/gui/dialogs/formsettings.cpp index 71e2d64ac..6fd996193 100755 --- a/src/gui/dialogs/formsettings.cpp +++ b/src/gui/dialogs/formsettings.cpp @@ -30,7 +30,6 @@ #include "miscellaneous/skinfactory.h" #include "miscellaneous/textfactory.h" #include "network-web/webfactory.h" -#include "network-web/webbrowsernetworkaccessmanager.h" #include "network-web/silentnetworkaccessmanager.h" #include "network-web/webbrowser.h" #include "gui/systemtrayicon.h" @@ -448,7 +447,6 @@ void FormSettings::saveProxy() { // Reload settings for all network access managers. SilentNetworkAccessManager::instance()->loadSettings(); - WebBrowserNetworkAccessManager::instance()->loadSettings(); } void FormSettings::loadLanguage() { diff --git a/src/miscellaneous/settings.cpp b/src/miscellaneous/settings.cpp index e901730c0..0b81bb8f9 100755 --- a/src/miscellaneous/settings.cpp +++ b/src/miscellaneous/settings.cpp @@ -19,12 +19,14 @@ #include "miscellaneous/application.h" #include "miscellaneous/iofactory.h" +#include "network-web/adblock/requestinterceptor.h" #include #include #include #include #include +#include // Feeds. @@ -357,6 +359,9 @@ Settings *Settings::setupSettings(QObject *parent) { // Portable settings are available, use them. new_settings = new Settings(properties.m_absoluteSettingsFileName, QSettings::IniFormat, properties.m_type, parent); + // Set Blick communication interceptor for simple Adblocking. + QWebEngineProfile::defaultProfile()->setRequestInterceptor(new RequestInterceptor(new_settings)); + // Check if portable settings are available. if (properties.m_type == SettingsProperties::Portable) { qDebug("Initializing settings in '%s' (portable way).", qPrintable(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName))); diff --git a/src/network-web/adblock/adblockblockednetworkreply.cpp b/src/network-web/adblock/adblockblockednetworkreply.cpp deleted file mode 100755 index 8431f3396..000000000 --- a/src/network-web/adblock/adblockblockednetworkreply.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// This file is part of RSS Guard. -// -// Copyright (C) 2014-2015 by Martin Rotter -// Copyright (C) 2010-2014 by David Rosca -// -// RSS Guard 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. -// -// RSS Guard 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 RSS Guard. If not, see . - -/** - * Copyright (c) 2009, Benjamin C. Meyer - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Benjamin Meyer nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "network-web/adblock/adblockblockednetworkreply.h" - -#include "network-web/adblock/adblocksubscription.h" -#include "network-web/adblock/adblockrule.h" - -#include -#include - - -AdBlockBlockedNetworkReply::AdBlockBlockedNetworkReply(const AdBlockRule *rule, QObject *parent) - : QNetworkReply(parent) { - setOperation(QNetworkAccessManager::GetOperation); - setError(QNetworkReply::ContentAccessDenied, QString("Adblock: %1 (%2)").arg(rule->subscription()->title(), rule->filter())); - open(QIODevice::ReadOnly); - QTimer::singleShot(0, this, SLOT(delayedFinished())); -} - -void AdBlockBlockedNetworkReply::abort() { -} - -void AdBlockBlockedNetworkReply::setRequest(const QNetworkRequest &request) { - QNetworkReply::setRequest(request); - setUrl(request.url()); -} - -qint64 AdBlockBlockedNetworkReply::readData(char *data, qint64 maxSize) { - Q_UNUSED(data); - Q_UNUSED(maxSize); - return -1; -} - -void AdBlockBlockedNetworkReply::delayedFinished() { - emit error(QNetworkReply::ContentAccessDenied); - emit finished(); -} diff --git a/src/network-web/adblock/adblockblockednetworkreply.h b/src/network-web/adblock/adblockblockednetworkreply.h deleted file mode 100755 index 7ded70a29..000000000 --- a/src/network-web/adblock/adblockblockednetworkreply.h +++ /dev/null @@ -1,73 +0,0 @@ -// This file is part of RSS Guard. -// -// Copyright (C) 2014-2015 by Martin Rotter -// Copyright (C) 2010-2014 by David Rosca -// -// RSS Guard 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. -// -// RSS Guard 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 RSS Guard. If not, see . - -/** - * Copyright (c) 2009, Benjamin C. Meyer - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Benjamin Meyer nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef ADBLOCKBLOCKEDNETWORKREPLY_H -#define ADBLOCKBLOCKEDNETWORKREPLY_H - -#include - - -class AdBlockRule; -class AdBlockSubscription; - -class AdBlockBlockedNetworkReply : public QNetworkReply{ - Q_OBJECT - - public: - explicit AdBlockBlockedNetworkReply(const AdBlockRule *rule, QObject *parent = 0); - - void abort(); - void setRequest(const QNetworkRequest &request); - - protected: - qint64 readData(char *data, qint64 maxSize); - - private slots: - void delayedFinished(); -}; - -#endif // ADBLOCKBLOCKEDNETWORKREPLY_H - diff --git a/src/network-web/adblock/adblockicon.cpp b/src/network-web/adblock/adblockicon.cpp index d138eea51..30ccab7b3 100755 --- a/src/network-web/adblock/adblockicon.cpp +++ b/src/network-web/adblock/adblockicon.cpp @@ -30,7 +30,6 @@ #include #include -#include AdBlockIcon::AdBlockIcon(QWidget *window, QWidget *parent) @@ -77,9 +76,9 @@ void AdBlockIcon::createMenu(QMenu *menu) { menu->addSeparator(); if (!page_url.host().isEmpty() && m_enabled && manager->canRunOnScheme(page_url.scheme())) { - const QString host = page_url.host().contains(QLatin1String("www.")) ? page_url.host().mid(4) : page_url.host(); - const QString host_filter = QString("@@||%1^$document").arg(host); - const QString page_filter = QString("@@|%1|$document").arg(page_url.toString()); + const QString host = page_url.host().contains(QSL("www.")) ? page_url.host().mid(4) : page_url.host(); + const QString host_filter = QString(QSL("@@||%1^$document")).arg(host); + const QString page_filter = QString(QSL("@@|%1|$document")).arg(page_url.toString()); QAction *act; @@ -97,41 +96,6 @@ void AdBlockIcon::createMenu(QMenu *menu) { menu->addSeparator(); } - - if (!m_blockedPopups.isEmpty()) { - menu->addAction(tr("Blocked popup windows"))->setEnabled(false); - - for (int i = 0; i < m_blockedPopups.count(); i++) { - const QPair &pair = m_blockedPopups.at(i); - - const QString address = pair.second.toString().right(55); - QString action_text = tr("%1 with (%2)").arg(address, - pair.first->filter()).replace(QLatin1Char('&'), QLatin1String("&&")); - - QAction *action = menu->addAction(action_text, manager, SLOT(showRule())); - action->setData(QVariant::fromValue((void*)pair.first)); - } - } - - menu->addSeparator(); - - const QVector entries = page->adBlockedEntries(); - - if (entries.isEmpty()) { - menu->addAction(tr("No content blocked"))->setEnabled(false); - } - else { - menu->addAction(tr("Blocked some content - click to edit rule"))->setEnabled(false); - - foreach (const WebPage::AdBlockedEntry &entry, entries) { - QString address = entry.url.toString().right(55); - QString action_text = tr("%1 with (%2)").arg(address, - entry.rule->filter()).replace(QLatin1Char('&'), QLatin1String("&&")); - - QAction *action = menu->addAction(action_text, manager, SLOT(showRule())); - action->setData(QVariant::fromValue((void*)entry.rule)); - } - } } void AdBlockIcon::showMenu(const QPoint &pos) { diff --git a/src/network-web/adblock/adblockmanager.cpp b/src/network-web/adblock/adblockmanager.cpp index 9cdea163f..d685acff0 100755 --- a/src/network-web/adblock/adblockmanager.cpp +++ b/src/network-web/adblock/adblockmanager.cpp @@ -21,10 +21,8 @@ #include "network-web/adblock/adblockdialog.h" #include "network-web/adblock/adblockmatcher.h" #include "network-web/adblock/adblocksubscription.h" -#include "network-web/adblock/adblockblockednetworkreply.h" #include "network-web/adblock/adblockicon.h" #include "network-web/webpage.h" -#include "network-web/silentnetworkaccessmanager.h" #include "miscellaneous/application.h" #include "miscellaneous/settings.h" #include "definitions/definitions.h" @@ -34,7 +32,6 @@ #include #include #include -#include AdBlockManager *AdBlockManager::s_adBlockManager = NULL; @@ -51,7 +48,7 @@ AdBlockManager::~AdBlockManager() { AdBlockManager *AdBlockManager::instance() { if (s_adBlockManager == NULL) { - s_adBlockManager = new AdBlockManager(SilentNetworkAccessManager::instance()); + s_adBlockManager = new AdBlockManager(qApp); } return s_adBlockManager; @@ -74,36 +71,27 @@ QList AdBlockManager::subscriptions() const { return m_subscriptions; } -QNetworkReply *AdBlockManager::block(const QNetworkRequest &request) { - const QString url_string = request.url().toEncoded().toLower(); - const QString url_domain = request.url().host().toLower(); - const QString url_scheme = request.url().scheme().toLower(); +bool AdBlockManager::shouldBlock(const QUrl &url, const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) { + const QString url_string = url.toEncoded().toLower(); + const QString url_domain = url.host().toLower(); + const QString url_scheme = url.scheme().toLower(); if (!isEnabled() || !canRunOnScheme(url_scheme)) { return NULL; } - const AdBlockRule *blocked_rule = m_matcher->match(request, url_domain, url_string); + const AdBlockRule *blocked_rule = m_matcher->match(url, url_domain, url_string, referer, resource_type); if (blocked_rule != NULL) { - QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100)); - WebPage *web_page = static_cast(v.value()); - - if (WebPage::isPointerSafeToUse(web_page)) { - if (!canBeBlocked(web_page->url())) { - return NULL; - } - - web_page->addAdBlockRule(blocked_rule, request.url()); + if (!canBeBlocked(url, referer, resource_type)) { + return false; + } + else { + return true; } - - AdBlockBlockedNetworkReply *reply = new AdBlockBlockedNetworkReply(blocked_rule, this); - reply->setRequest(request); - - return reply; } - return NULL; + return false; } QStringList AdBlockManager::disabledRules() const { @@ -306,25 +294,8 @@ void AdBlockManager::setUseLimitedEasyList(bool use_limited) { } } -bool AdBlockManager::canBeBlocked(const QUrl &url) const { - return !m_matcher->adBlockDisabledForUrl(url); -} - -QString AdBlockManager::elementHidingRules() const { - return m_matcher->elementHidingRules(); -} - -QString AdBlockManager::elementHidingRulesForDomain(const QUrl &url) const { - if (!isEnabled() || !canRunOnScheme(url.scheme()) || !canBeBlocked(url)) { - return QString(); - } - // Acid3 doesn't like the way element hiding rules are embedded into page - else if (url.host() == QL1S("acid3.acidtests.org")) { - return QString(); - } - else { - return m_matcher->elementHidingRulesForDomain(url.host()); - } +bool AdBlockManager::canBeBlocked(const QUrl &url, const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) const { + return !m_matcher->adBlockDisabledForUrl(url, referer, resource_type); } AdBlockSubscription *AdBlockManager::subscriptionByName(const QString &name) const { diff --git a/src/network-web/adblock/adblockmanager.h b/src/network-web/adblock/adblockmanager.h index 02e6f3f21..2678a6c60 100755 --- a/src/network-web/adblock/adblockmanager.h +++ b/src/network-web/adblock/adblockmanager.h @@ -23,12 +23,10 @@ #include #include +#include class QUrl; -class QNetworkReply; -class QNetworkRequest; - class AdBlockRule; class AdBlockDialog; class AdBlockMatcher; @@ -52,13 +50,10 @@ class AdBlockManager : public QObject { bool useLimitedEasyList() const; void setUseLimitedEasyList(bool use_limited); - QString elementHidingRules() const; - QString elementHidingRulesForDomain(const QUrl &url) const; - AdBlockSubscription *subscriptionByName(const QString &name) const; QList subscriptions() const; - QNetworkReply *block(const QNetworkRequest &request); + bool shouldBlock(const QUrl &url, const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type); QStringList disabledRules() const; void addDisabledRule(const QString &filter); @@ -74,9 +69,6 @@ class AdBlockManager : public QObject { static QString baseSubscriptionDirectory(); static AdBlockManager *instance(); - signals: - void enabledChanged(bool enabled); - public slots: void setEnabled(bool enabled); void showRule(); @@ -84,8 +76,11 @@ class AdBlockManager : public QObject { AdBlockDialog *showDialog(); + signals: + void enabledChanged(bool enabled); + private: - bool canBeBlocked(const QUrl &url) const; + bool canBeBlocked(const QUrl &url, const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) const; bool m_loaded; bool m_enabled; diff --git a/src/network-web/adblock/adblockmatcher.cpp b/src/network-web/adblock/adblockmatcher.cpp index 6a0b77edd..9874586c3 100755 --- a/src/network-web/adblock/adblockmatcher.cpp +++ b/src/network-web/adblock/adblockmatcher.cpp @@ -32,30 +32,31 @@ AdBlockMatcher::~AdBlockMatcher() { clear(); } -const AdBlockRule *AdBlockMatcher::match(const QNetworkRequest &request, const QString &url_domain, - const QString &url_string) const { +const AdBlockRule *AdBlockMatcher::match(const QUrl &url, const QString &url_domain, + const QString &url_string, const QString &referer, + QWebEngineUrlRequestInfo::ResourceType resource_type) const { // Exception rules. - if (m_networkExceptionTree.find(request, url_domain, url_string)) { + if (m_networkExceptionTree.find(url, url_domain, url_string, referer, resource_type)) { return NULL; } for (int i = 0, count = m_networkExceptionRules.size(); i < count; i++) { const AdBlockRule *rule = m_networkExceptionRules.at(i); - if (rule->networkMatch(request, url_domain, url_string)) { + if (rule->networkMatch(url, url_domain, url_string, referer, resource_type)) { return NULL; } } // Block rules. - if (const AdBlockRule* rule = m_networkBlockTree.find(request, url_domain, url_string)) { + if (const AdBlockRule* rule = m_networkBlockTree.find(url, url_domain, url_string, referer, resource_type)) { return rule; } for (int i = 0, count = m_networkBlockRules.size(); i < count; i++) { const AdBlockRule *rule = m_networkBlockRules.at(i); - if (rule->networkMatch(request, url_domain, url_string)) { + if (rule->networkMatch(url, url_domain, url_string, referer, resource_type)) { return rule; } } @@ -63,9 +64,10 @@ const AdBlockRule *AdBlockMatcher::match(const QNetworkRequest &request, const Q return NULL; } -bool AdBlockMatcher::adBlockDisabledForUrl(const QUrl &url) const { +bool AdBlockMatcher::adBlockDisabledForUrl(const QUrl &url, const QString &referer, + QWebEngineUrlRequestInfo::ResourceType resource_type) const { for (int i = 0, count = m_documentRules.size(); i < count; i++) { - if (m_documentRules.at(i)->urlMatch(url)) { + if (m_documentRules.at(i)->urlMatch(url, referer, resource_type)) { return true; } } @@ -73,60 +75,9 @@ bool AdBlockMatcher::adBlockDisabledForUrl(const QUrl &url) const { return false; } -bool AdBlockMatcher::elemHideDisabledForUrl(const QUrl &url) const { - if (adBlockDisabledForUrl(url)) { - return true; - } - - for (int i = 0, count = m_elemhideRules.size(); i < count; i++) { - if (m_elemhideRules.at(i)->urlMatch(url)) { - return true; - } - } - - return false; -} - -QString AdBlockMatcher::elementHidingRules() const { - return m_elementHidingRules; -} - -QString AdBlockMatcher::elementHidingRulesForDomain(const QString &domain) const { - QString rules; - int added_rules_count = 0; - - for (int i = 0, count = m_domainRestrictedCssRules.size(); i < count; i++) { - const AdBlockRule *rule = m_domainRestrictedCssRules.at(i); - - if (!rule->matchDomain(domain)) { - continue; - } - - if (added_rules_count == 1000) { - rules.append(rule->cssSelector()); - rules.append(QL1S("{display:none !important;}\n")); - added_rules_count = 0; - } - else { - rules.append(rule->cssSelector() + QL1C(',')); - added_rules_count++; - } - } - - if (added_rules_count != 0) { - rules = rules.left(rules.size() - 1); - rules.append(QLatin1String("{display:none !important;}\n")); - } - - return rules; -} - void AdBlockMatcher::update() { clear(); - QHash css_rules_hash; - QVector exception_css_rules; - foreach (const AdBlockSubscription *subscription, m_manager->subscriptions()) { foreach (const AdBlockRule *rule, subscription->allRules()) { // Don't add internally disabled rules to cache @@ -134,26 +85,9 @@ void AdBlockMatcher::update() { continue; } - if (rule->isCssRule()) { - // We will add only enabled css rules to cache, because there is no enabled/disabled - // check on match. They are directly embedded to pages. - if (!rule->isEnabled()) { - continue; - } - - if (rule->isException()) { - exception_css_rules.append(rule); - } - else { - css_rules_hash.insert(rule->cssSelector(), rule); - } - } - else if (rule->isDocument()) { + if (rule->isDocument()) { m_documentRules.append(rule); } - else if (rule->isElemhide()) { - m_elemhideRules.append(rule); - } else if (rule->isException()) { if (!m_networkExceptionTree.add(rule)) { m_networkExceptionRules.append(rule); @@ -166,52 +100,6 @@ void AdBlockMatcher::update() { } } } - - foreach (const AdBlockRule *rule, exception_css_rules) { - const AdBlockRule *original_rule = css_rules_hash.value(rule->cssSelector()); - - // If we don't have this selector, the exception does nothing. - if (original_rule == NULL) { - continue; - } - - AdBlockRule *copied_rule = original_rule->copy(); - - copied_rule->m_options |= AdBlockRule::DomainRestrictedOption; - copied_rule->m_blockedDomains.append(rule->m_allowedDomains); - css_rules_hash[rule->cssSelector()] = copied_rule; - m_createdRules.append(copied_rule); - } - - // Apparently, excessive amount of selectors for one CSS rule is not what WebKit likes. - // (In my testings, 4931 is the number that makes it crash) - // So let's split it by 1000 selectors. - int hiding_rules_count = 0; - - QHashIterator it(css_rules_hash); - - while (it.hasNext()) { - it.next(); - const AdBlockRule *rule = it.value(); - - if (rule->isDomainRestricted()) { - m_domainRestrictedCssRules.append(rule); - } - else if (hiding_rules_count == 1000) { - m_elementHidingRules.append(rule->cssSelector()); - m_elementHidingRules.append(QL1S("{display:none !important;} ")); - hiding_rules_count = 0; - } - else { - m_elementHidingRules.append(rule->cssSelector() + QL1C(',')); - hiding_rules_count++; - } - } - - if (hiding_rules_count != 0) { - m_elementHidingRules = m_elementHidingRules.left(m_elementHidingRules.size() - 1); - m_elementHidingRules.append(QLatin1String("{display:none !important;} ")); - } } void AdBlockMatcher::clear() { @@ -222,12 +110,7 @@ void AdBlockMatcher::clear() { m_networkBlockRules.clear(); m_domainRestrictedCssRules.clear(); - m_elementHidingRules.clear(); m_documentRules.clear(); - m_elemhideRules.clear(); - - qDeleteAll(m_createdRules); - m_createdRules.clear(); } void AdBlockMatcher::enabledChanged(bool enabled) { diff --git a/src/network-web/adblock/adblockmatcher.h b/src/network-web/adblock/adblockmatcher.h index ed5fd85ec..dcc695803 100755 --- a/src/network-web/adblock/adblockmatcher.h +++ b/src/network-web/adblock/adblockmatcher.h @@ -37,13 +37,10 @@ class AdBlockMatcher : public QObject { explicit AdBlockMatcher(AdBlockManager *manager); virtual ~AdBlockMatcher(); - const AdBlockRule *match(const QNetworkRequest &request, const QString &url_domain, const QString &url_string) const; + const AdBlockRule *match(const QUrl &url, const QString &url_domain, const QString &url_string, + const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) const; - bool adBlockDisabledForUrl(const QUrl &url) const; - bool elemHideDisabledForUrl(const QUrl &url) const; - - QString elementHidingRules() const; - QString elementHidingRulesForDomain(const QString &domain) const; + bool adBlockDisabledForUrl(const QUrl &url, const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) const; public slots: void update(); @@ -55,14 +52,11 @@ class AdBlockMatcher : public QObject { private: AdBlockManager *m_manager; - QVector m_createdRules; QVector m_networkExceptionRules; QVector m_networkBlockRules; QVector m_domainRestrictedCssRules; QVector m_documentRules; - QVector m_elemhideRules; - QString m_elementHidingRules; AdBlockSearchTree m_networkBlockTree; AdBlockSearchTree m_networkExceptionTree; }; diff --git a/src/network-web/adblock/adblockrule.cpp b/src/network-web/adblock/adblockrule.cpp index e364c959e..40c77626d 100755 --- a/src/network-web/adblock/adblockrule.cpp +++ b/src/network-web/adblock/adblockrule.cpp @@ -111,14 +111,6 @@ void AdBlockRule::setFilter(const QString &filter) { parseFilter(); } -bool AdBlockRule::isCssRule() const { - return m_type == CssRule; -} - -QString AdBlockRule::cssSelector() const { - return m_matchString; -} - bool AdBlockRule::isDocument() const { return hasOption(DocumentOption); } @@ -155,17 +147,19 @@ bool AdBlockRule::isInternalDisabled() const { return m_isInternalDisabled; } -bool AdBlockRule::urlMatch(const QUrl &url) const { +bool AdBlockRule::urlMatch(const QUrl &url, const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) const { if (!hasOption(DocumentOption) && !hasOption(ElementHideOption)) { return false; } else { - return networkMatch(QNetworkRequest(url), url.host(), url.toEncoded()); + return networkMatch(url, url.host(), url.toEncoded(), referer, resource_type); } } -bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &domain, const QString &encoded_url) const { - if (m_type == CssRule || !m_isEnabled || m_isInternalDisabled) { +bool AdBlockRule::networkMatch(const QUrl &url, const QString &domain, + const QString &encoded_url, const QString &referer, + QWebEngineUrlRequestInfo::ResourceType resource_type) const { + if (!m_isEnabled || m_isInternalDisabled) { return false; } @@ -195,22 +189,22 @@ bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &do } // Check third-party restriction. - if (hasOption(ThirdPartyOption) && !matchThirdParty(request)) { + if (hasOption(ThirdPartyOption) && !matchThirdParty(referer, url)) { return false; } // Check object restrictions. - if (hasOption(ObjectOption) && !matchObject(request)) { + if (hasOption(ObjectOption) && !matchObject(resource_type)) { return false; } // Check subdocument restriction. - if (hasOption(SubdocumentOption) && !matchSubdocument(request)) { + if (hasOption(SubdocumentOption)) { return false; } // Check xmlhttprequest restriction - if (hasOption(XMLHttpRequestOption) && !matchXmlHttpRequest(request)) { + if (hasOption(XMLHttpRequestOption)) { return false; } @@ -265,38 +259,26 @@ bool AdBlockRule::matchDomain(const QString &domain) const { return false; } -bool AdBlockRule::matchThirdParty(const QNetworkRequest &request) const { - const QString referer = request.attribute(QNetworkRequest::Attribute(QNetworkRequest::User + 151), QString()).toString(); - +bool AdBlockRule::matchThirdParty(const QString &referer, const QUrl &url) const { if (referer.isEmpty()) { return false; } // Third-party matching should be performed on second-level domains. const QString refererHost = WebFactory::instance()->toSecondLevelDomain(QUrl(referer)); - const QString host = WebFactory::instance()->toSecondLevelDomain(request.url()); + const QString host = WebFactory::instance()->toSecondLevelDomain(url); bool match = refererHost != host; return hasException(ThirdPartyOption) ? !match : match; } -bool AdBlockRule::matchObject(const QNetworkRequest &request) const { - bool match = request.attribute(QNetworkRequest::Attribute(QNetworkRequest::User + 150)).toString() == QL1S("object"); +bool AdBlockRule::matchObject(QWebEngineUrlRequestInfo::ResourceType type) const { + bool match = type == QWebEngineUrlRequestInfo::ResourceTypeObject; return hasException(ObjectOption) ? !match : match; } -bool AdBlockRule::matchSubdocument(const QNetworkRequest &request) const { - return false; -} - -bool AdBlockRule::matchXmlHttpRequest(const QNetworkRequest &request) const { - bool match = request.rawHeader("X-Requested-With") == QByteArray("XMLHttpRequest"); - - return hasException(XMLHttpRequestOption) ? !match : match; -} - bool AdBlockRule::matchImage(const QString &encoded_url) const { bool match = encoded_url.endsWith(QL1S(".png")) || encoded_url.endsWith(QL1S(".jpg")) || @@ -321,19 +303,7 @@ void AdBlockRule::parseFilter() { // CSS Element hiding rule. if (parsed_line.contains(QL1S("##")) || parsed_line.contains(QL1S("#@#"))) { - m_type = CssRule; - int pos = parsed_line.indexOf(QL1C('#')); - - // Domain restricted rule - if (!parsed_line.startsWith(QL1S("##"))) { - QString domains = parsed_line.left(pos); - parseDomains(domains, QL1C(',')); - } - - m_isException = parsed_line.at(pos + 1) == QL1C('@'); - m_matchString = parsed_line.mid(m_isException ? pos + 3 : pos + 2); - - // CSS rule cannot have more options -> stop parsing. + // Do not parse CSS rules. return; } diff --git a/src/network-web/adblock/adblockrule.h b/src/network-web/adblock/adblockrule.h index 19b1a37a0..5a6e2b5c9 100755 --- a/src/network-web/adblock/adblockrule.h +++ b/src/network-web/adblock/adblockrule.h @@ -49,6 +49,7 @@ #include #include +#include class QNetworkRequest; class QUrl; @@ -72,9 +73,6 @@ class AdBlockRule { QString filter() const; void setFilter(const QString &filter); - bool isCssRule() const; - QString cssSelector() const; - bool isDocument() const; bool isElemhide() const; @@ -88,14 +86,13 @@ class AdBlockRule { bool isSlow() const; bool isInternalDisabled() const; - bool urlMatch(const QUrl &url) const; - bool networkMatch(const QNetworkRequest &request, const QString &domain, const QString &encoded_url) const; + bool urlMatch(const QUrl &url, const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) const; + bool networkMatch(const QUrl &url, const QString &domain, const QString &encoded_url, + const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) const; bool matchDomain(const QString &domain) const; - bool matchThirdParty(const QNetworkRequest &request) const; - bool matchObject(const QNetworkRequest &request) const; - bool matchSubdocument(const QNetworkRequest &request) const; - bool matchXmlHttpRequest(const QNetworkRequest &request) const; + bool matchThirdParty(const QString &referer, const QUrl &url) const; + bool matchObject(QWebEngineUrlRequestInfo::ResourceType type) const; bool matchImage(const QString &encoded_url) const; protected: @@ -105,7 +102,6 @@ class AdBlockRule { private: enum RuleType { - CssRule = 0, DomainMatchRule = 1, RegExpMatchRule = 2, StringEndsMatchRule = 3, diff --git a/src/network-web/adblock/adblocksearchtree.cpp b/src/network-web/adblock/adblocksearchtree.cpp index 969b731c8..f7f272e89 100755 --- a/src/network-web/adblock/adblocksearchtree.cpp +++ b/src/network-web/adblock/adblocksearchtree.cpp @@ -65,8 +65,9 @@ bool AdBlockSearchTree::add(const AdBlockRule *rule) { return true; } -const AdBlockRule *AdBlockSearchTree::find(const QNetworkRequest &request, const QString &domain, - const QString &url_string) const { +const AdBlockRule *AdBlockSearchTree::find(const QUrl &url, const QString &domain, + const QString &url_string, const QString &referer, + QWebEngineUrlRequestInfo::ResourceType resource_type) const { const int len = url_string.size(); if (len <= 0) { @@ -76,7 +77,7 @@ const AdBlockRule *AdBlockSearchTree::find(const QNetworkRequest &request, const const QChar *string = url_string.constData(); for (int i = 0; i < len; i++) { - const AdBlockRule *rule = prefixSearch(request, domain, url_string, string++, len - i); + const AdBlockRule *rule = prefixSearch(url, domain, url_string, string++, referer, resource_type, len - i); if (rule != NULL) { return rule; @@ -86,8 +87,10 @@ const AdBlockRule *AdBlockSearchTree::find(const QNetworkRequest &request, const return NULL; } -const AdBlockRule *AdBlockSearchTree::prefixSearch(const QNetworkRequest &request, const QString &domain, - const QString &url_string, const QChar* string, int len) const { +const AdBlockRule *AdBlockSearchTree::prefixSearch(const QUrl &url, const QString &domain, + const QString &url_string, const QChar* string, + const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type, + int len) const { if (len <= 0) { return NULL; } @@ -103,7 +106,7 @@ const AdBlockRule *AdBlockSearchTree::prefixSearch(const QNetworkRequest &reques for (int i = 1; i < len; i++) { const QChar c = (++string)[0]; - if (node->rule && node->rule->networkMatch(request, domain, url_string)) { + if (node->rule && node->rule->networkMatch(url, domain, url_string, referer, resource_type)) { return node->rule; } @@ -114,7 +117,7 @@ const AdBlockRule *AdBlockSearchTree::prefixSearch(const QNetworkRequest &reques node = node->children[c]; } - if (node->rule && node->rule->networkMatch(request, domain, url_string)) { + if (node->rule && node->rule->networkMatch(url, domain, url_string, referer, resource_type)) { return node->rule; } diff --git a/src/network-web/adblock/adblocksearchtree.h b/src/network-web/adblock/adblocksearchtree.h index 83e3c6431..09a539ad8 100755 --- a/src/network-web/adblock/adblocksearchtree.h +++ b/src/network-web/adblock/adblocksearchtree.h @@ -21,6 +21,8 @@ #include #include +#include +#include class QNetworkRequest; @@ -34,7 +36,8 @@ class AdBlockSearchTree { void clear(); bool add(const AdBlockRule *rule); - const AdBlockRule *find(const QNetworkRequest &request, const QString &domain, const QString &url_string) const; + const AdBlockRule *find(const QUrl &url, const QString &domain, const QString &url_string, + const QString &referer, QWebEngineUrlRequestInfo::ResourceType resource_type) const; private: struct Node { @@ -48,8 +51,9 @@ class AdBlockSearchTree { }; void deleteNode(Node *node); - const AdBlockRule *prefixSearch(const QNetworkRequest &request, const QString &domain, - const QString &url_string, const QChar* string, int len) const; + const AdBlockRule *prefixSearch(const QUrl &url, const QString &domain, + const QString &url_string, const QChar* string, const QString &referer, + QWebEngineUrlRequestInfo::ResourceType resource_type, int len) const; Node *m_root; }; diff --git a/src/network-web/adblock/adblocktreewidget.cpp b/src/network-web/adblock/adblocktreewidget.cpp index f5909139b..77110f5d4 100755 --- a/src/network-web/adblock/adblocktreewidget.cpp +++ b/src/network-web/adblock/adblocktreewidget.cpp @@ -203,10 +203,6 @@ void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem *item, const AdBlockR item->setForeground(0, QColor(Qt::darkGreen)); item->setFont(0, QFont()); } - else if (rule->isCssRule()) { - item->setForeground(0, QColor(Qt::darkBlue)); - item->setFont(0, QFont()); - } else { item->setForeground(0, QColor()); item->setFont(0, QFont()); diff --git a/src/network-web/adblock/requestinterceptor.cpp b/src/network-web/adblock/requestinterceptor.cpp index 1f192dc6b..d9c53d354 100644 --- a/src/network-web/adblock/requestinterceptor.cpp +++ b/src/network-web/adblock/requestinterceptor.cpp @@ -1,5 +1,41 @@ +// This file is part of RSS Guard. +// +// Copyright (C) 2011-2016 by Martin Rotter +// +// RSS Guard 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. +// +// RSS Guard 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 RSS Guard. If not, see . + #include "network-web/adblock/requestinterceptor.h" +#include "network-web/adblock/adblockmanager.h" +#include "miscellaneous/application.h" -RequestInterceptor::RequestInterceptor(QObject *p) : QWebEngineUrlRequestInterceptor(p) { + +RequestInterceptor::RequestInterceptor(QObject *parent) : QWebEngineUrlRequestInterceptor(parent) { +} + +RequestInterceptor::~RequestInterceptor() { +} + +void RequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) { + if (AdBlockManager::instance()->shouldBlock(info.requestUrl(), info.firstPartyUrl().toString(), info.resourceType())) { + info.block(true); + qWarning("%s just blocked network resource:\n URL: '%s'.", APP_NAME, qPrintable(info.requestUrl().toString())); + + /* + qApp->showGuiMessage(tr("Network resource blocked"), + tr("%1 just blocked network resource:\n URL: %2").arg(APP_NAME, info.requestUrl().toString()), + QSystemTrayIcon::Information); + */ + } } diff --git a/src/network-web/adblock/requestinterceptor.h b/src/network-web/adblock/requestinterceptor.h index d06b1503e..2b8eafc95 100644 --- a/src/network-web/adblock/requestinterceptor.h +++ b/src/network-web/adblock/requestinterceptor.h @@ -1,10 +1,33 @@ +// This file is part of RSS Guard. +// +// Copyright (C) 2011-2016 by Martin Rotter +// +// RSS Guard 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. +// +// RSS Guard 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 RSS Guard. If not, see . + #ifndef REQUESTINTERCEPTOR_H #define REQUESTINTERCEPTOR_H +#include + + class RequestInterceptor : public QWebEngineUrlRequestInterceptor { public: - RequestInterceptor(); + explicit RequestInterceptor(QObject *parent = 0); + virtual ~RequestInterceptor(); + + void interceptRequest(QWebEngineUrlRequestInfo &info); }; #endif // REQUESTINTERCEPTOR_H diff --git a/src/network-web/webbrowsernetworkaccessmanager.cpp b/src/network-web/webbrowsernetworkaccessmanager.cpp deleted file mode 100755 index 643d0cf4b..000000000 --- a/src/network-web/webbrowsernetworkaccessmanager.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// This file is part of RSS Guard. -// -// Copyright (C) 2011-2016 by Martin Rotter -// -// RSS Guard 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. -// -// RSS Guard 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 RSS Guard. If not, see . - -#include "network-web/webbrowsernetworkaccessmanager.h" - -#include "miscellaneous/application.h" - -#include "network-web/adblock/adblockmanager.h" - -#include - - -QPointer WebBrowserNetworkAccessManager::s_instance; - -WebBrowserNetworkAccessManager::WebBrowserNetworkAccessManager(WebPage *page, QObject *parent) - : BaseNetworkAccessManager(parent), m_page(page) { - connect(this, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), - this, SLOT(onAuthenticationRequired(QNetworkReply*,QAuthenticator*))); -} - -WebBrowserNetworkAccessManager::~WebBrowserNetworkAccessManager() { - qDebug("Destroying WebBrowserNetworkAccessManager instance."); -} - -void WebBrowserNetworkAccessManager::onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator) { - Q_UNUSED(authenticator); - - // FIXME: Support authentication for web pages. - qDebug("URL '%s' requested authentication but username/password is not available.", qPrintable(reply->url().toString())); -} - -QNetworkReply *WebBrowserNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) { - if (m_page != NULL) { - QNetworkRequest page_request = request; - m_page->populateNetworkRequest(page_request); - return WebBrowserNetworkAccessManager::instance()->createRequest(op, page_request, outgoingData); - } - - if (op == QNetworkAccessManager::GetOperation) { - QNetworkReply *reply = AdBlockManager::instance()->block(request); - - if (reply != NULL) { - return reply; - } - } - - return BaseNetworkAccessManager::createRequest(op, request, outgoingData); -} - -WebBrowserNetworkAccessManager *WebBrowserNetworkAccessManager::instance() { - if (s_instance.isNull()) { - s_instance = new WebBrowserNetworkAccessManager(0, qApp); - } - - return s_instance; -} diff --git a/src/network-web/webbrowsernetworkaccessmanager.h b/src/network-web/webbrowsernetworkaccessmanager.h deleted file mode 100755 index b4893cee7..000000000 --- a/src/network-web/webbrowsernetworkaccessmanager.h +++ /dev/null @@ -1,53 +0,0 @@ -// This file is part of RSS Guard. -// -// Copyright (C) 2011-2016 by Martin Rotter -// -// RSS Guard 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. -// -// RSS Guard 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 RSS Guard. If not, see . - -#ifndef WEBBROWSERNETWORKACCESSMANAGER_H -#define WEBBROWSERNETWORKACCESSMANAGER_H - -#include "network-web/basenetworkaccessmanager.h" - -#include "webpage.h" - -#include - - -// This is network access manager for web browsers. -class WebBrowserNetworkAccessManager : public BaseNetworkAccessManager { - Q_OBJECT - - public: - // Constructors and destructors. - explicit WebBrowserNetworkAccessManager(WebPage *page = 0, QObject *parent = 0); - virtual ~WebBrowserNetworkAccessManager(); - - // Returns pointer to global network access manager - // used by ALL web browsers and download manager. - static WebBrowserNetworkAccessManager *instance(); - - protected: - QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData); - - protected slots: - void onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator); - - private: - WebPage *m_page; - - static QPointer s_instance; -}; - -#endif // WEBBROWSERNETWORKACCESSMANAGER_H diff --git a/src/network-web/webpage.cpp b/src/network-web/webpage.cpp index 74063dc1c..81bdb5ded 100755 --- a/src/network-web/webpage.cpp +++ b/src/network-web/webpage.cpp @@ -20,24 +20,14 @@ #include "network-web/webbrowser.h" #include "miscellaneous/application.h" -#include "network-web/adblock/adblockmanager.h" - -#include - - -QList WebPage::s_livingPages; WebPage::WebPage(QObject *parent) : QWebEnginePage(parent), m_loadProgress(-1) { connect(this, SIGNAL(loadProgress(int)), this, SLOT(progress(int))); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(finished())); - connect(this, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl))); - - s_livingPages.append(this); } WebPage::~WebPage() { - s_livingPages.removeOne(this); } bool WebPage::isLoading() const { @@ -52,44 +42,6 @@ void WebPage::finished() { progress(100); } -void WebPage::urlChanged(const QUrl &url) { - Q_UNUSED(url) - - if (isLoading()) { - m_adBlockedEntries.clear(); - } -} - -void WebPage::addAdBlockRule(const AdBlockRule *rule, const QUrl &url) { - AdBlockedEntry entry; - - entry.rule = rule; - entry.url = url; - - if (!m_adBlockedEntries.contains(entry)) { - m_adBlockedEntries.append(entry); - } -} - -QVector WebPage::adBlockedEntries() const { - return m_adBlockedEntries; -} - -bool WebPage::isPointerSafeToUse(WebPage *page) { - // Pointer to WebPage is passed with every QNetworkRequest casted to void* - // So there is no way to test whether pointer is still valid or not, except - // this hack. - - return page == 0 ? false : s_livingPages.contains(page); -} - -void WebPage::populateNetworkRequest(QNetworkRequest &request) { - WebPage *page_pointer = this; - - QVariant variant = QVariant::fromValue((void*) page_pointer); - request.setAttribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100), variant); -} - QString WebPage::toHtml() const { return QString(); // TODO: TODO diff --git a/src/network-web/webpage.h b/src/network-web/webpage.h index eb61186e1..1da11261a 100755 --- a/src/network-web/webpage.h +++ b/src/network-web/webpage.h @@ -28,35 +28,18 @@ class WebPage : public QWebEnginePage { Q_OBJECT public: - struct AdBlockedEntry { - const AdBlockRule *rule; - QUrl url; - - bool operator==(const AdBlockedEntry &other) const { - return (this->rule == other.rule && this->url == other.url); - } - }; - // Constructors and destructors. explicit WebPage(QObject *parent = 0); virtual ~WebPage(); QString toHtml() const; bool isLoading() const; - QVector adBlockedEntries() const; - - void populateNetworkRequest(QNetworkRequest &request); - void addAdBlockRule(const AdBlockRule *rule, const QUrl &url); - - static bool isPointerSafeToUse(WebPage *page); private slots: void progress(int prog); void finished(); - void urlChanged(const QUrl &url); private: - QVector m_adBlockedEntries; int m_loadProgress; static QList s_livingPages;