Adblock works.
This commit is contained in:
parent
8e3e6d1b62
commit
c7b127343e
@ -1 +1 @@
|
||||
Subproject commit 572da127bb14842bba6f84e6315a5ecefb44ed07
|
||||
Subproject commit 176715f7b3229289e2fb0dffb000c436664a26ff
|
@ -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() {
|
||||
|
@ -19,12 +19,14 @@
|
||||
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/iofactory.h"
|
||||
#include "network-web/adblock/requestinterceptor.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QPointer>
|
||||
#include <QWebEngineSettings>
|
||||
#include <QLocale>
|
||||
#include <QWebEngineProfile>
|
||||
|
||||
|
||||
// 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)));
|
||||
|
@ -1,81 +0,0 @@
|
||||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
// Copyright (C) 2010-2014 by David Rosca <nowrep@gmail.com>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
||||
*
|
||||
* 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 <QNetworkRequest>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
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();
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
// Copyright (C) 2010-2014 by David Rosca <nowrep@gmail.com>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
||||
*
|
||||
* 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 <QNetworkReply>
|
||||
|
||||
|
||||
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
|
||||
|
@ -30,7 +30,6 @@
|
||||
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QWebEnginePage>
|
||||
|
||||
|
||||
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<AdBlockRule*,QUrl> &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<WebPage::AdBlockedEntry> 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) {
|
||||
|
@ -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 <QTextStream>
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
#include <QWebEnginePage>
|
||||
|
||||
|
||||
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<AdBlockSubscription*> 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<WebPage*>(v.value<void*>());
|
||||
|
||||
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 {
|
||||
|
@ -23,12 +23,10 @@
|
||||
|
||||
#include <QStringList>
|
||||
#include <QPointer>
|
||||
#include <QWebEngineUrlRequestInfo>
|
||||
|
||||
|
||||
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<AdBlockSubscription*> 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;
|
||||
|
@ -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<QString, const AdBlockRule*> css_rules_hash;
|
||||
QVector<const AdBlockRule*> 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<QString,const AdBlockRule*> 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) {
|
||||
|
@ -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<AdBlockRule*> m_createdRules;
|
||||
QVector<const AdBlockRule*> m_networkExceptionRules;
|
||||
QVector<const AdBlockRule*> m_networkBlockRules;
|
||||
QVector<const AdBlockRule*> m_domainRestrictedCssRules;
|
||||
QVector<const AdBlockRule*> m_documentRules;
|
||||
QVector<const AdBlockRule*> m_elemhideRules;
|
||||
|
||||
QString m_elementHidingRules;
|
||||
AdBlockSearchTree m_networkBlockTree;
|
||||
AdBlockSearchTree m_networkExceptionTree;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QWebEngineUrlRequestInfo>
|
||||
|
||||
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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include <QChar>
|
||||
#include <QHash>
|
||||
#include <QUrl>
|
||||
#include <QWebEngineUrlRequestInfo>
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
@ -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());
|
||||
|
@ -1,5 +1,41 @@
|
||||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#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);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,33 @@
|
||||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef REQUESTINTERCEPTOR_H
|
||||
#define REQUESTINTERCEPTOR_H
|
||||
|
||||
#include <QWebEngineUrlRequestInterceptor>
|
||||
|
||||
|
||||
|
||||
class RequestInterceptor : public QWebEngineUrlRequestInterceptor {
|
||||
public:
|
||||
RequestInterceptor();
|
||||
explicit RequestInterceptor(QObject *parent = 0);
|
||||
virtual ~RequestInterceptor();
|
||||
|
||||
void interceptRequest(QWebEngineUrlRequestInfo &info);
|
||||
};
|
||||
|
||||
#endif // REQUESTINTERCEPTOR_H
|
||||
|
@ -1,70 +0,0 @@
|
||||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "network-web/webbrowsernetworkaccessmanager.h"
|
||||
|
||||
#include "miscellaneous/application.h"
|
||||
|
||||
#include "network-web/adblock/adblockmanager.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
|
||||
|
||||
QPointer<WebBrowserNetworkAccessManager> 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;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef WEBBROWSERNETWORKACCESSMANAGER_H
|
||||
#define WEBBROWSERNETWORKACCESSMANAGER_H
|
||||
|
||||
#include "network-web/basenetworkaccessmanager.h"
|
||||
|
||||
#include "webpage.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
|
||||
// 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<WebBrowserNetworkAccessManager> s_instance;
|
||||
};
|
||||
|
||||
#endif // WEBBROWSERNETWORKACCESSMANAGER_H
|
@ -20,24 +20,14 @@
|
||||
#include "network-web/webbrowser.h"
|
||||
#include "miscellaneous/application.h"
|
||||
|
||||
#include "network-web/adblock/adblockmanager.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
|
||||
|
||||
QList<WebPage*> 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::AdBlockedEntry> 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
|
||||
|
@ -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<AdBlockedEntry> 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<AdBlockedEntry> m_adBlockedEntries;
|
||||
int m_loadProgress;
|
||||
|
||||
static QList<WebPage*> s_livingPages;
|
||||
|
Loading…
x
Reference in New Issue
Block a user