aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--smolbote.qbs13
-rw-r--r--src/browser.cpp15
-rw-r--r--src/browser.h8
-rw-r--r--src/filter/filter.cpp212
-rw-r--r--src/filter/filter.h91
-rw-r--r--src/webengine/urlinterceptor.cpp49
-rw-r--r--src/webengine/urlinterceptor.h18
7 files changed, 103 insertions, 303 deletions
diff --git a/smolbote.qbs b/smolbote.qbs
index d18af60..a6044c3 100644
--- a/smolbote.qbs
+++ b/smolbote.qbs
@@ -116,14 +116,23 @@ Project {
"src/widgets/webviewtabbar.h",
]
}
+
+ Group {
+ name: "Request Filter"
+ files: [
+ "src/filter/filter.cpp",
+ "src/filter/filter.h",
+ "src/webengine/urlinterceptor.cpp",
+ "src/webengine/urlinterceptor.h",
+ ]
+ }
+
/*
Group {
name: "Request Filter"
files: [
"src/filter/blockermanager.cpp",
"src/filter/blockermanager.h",
- "src/filter/filter.cpp",
- "src/filter/filter.h",
"src/filter/filtercollection.cpp",
"src/filter/filtercollection.h",
"src/filter/filtertree.cpp",
diff --git a/src/browser.cpp b/src/browser.cpp
index 354b179..82972dd 100644
--- a/src/browser.cpp
+++ b/src/browser.cpp
@@ -21,6 +21,7 @@
#include "browser.h"
#include <bookmarks/bookmarkswidget.h>
#include <downloads/downloadswidget.h>
+#include "webengine/urlinterceptor.h"
#include "mainwindow.h"
#include <QtWebEngine>
#include <QDir>
@@ -39,8 +40,12 @@ Browser::Browser(int &argc, char *argv[]) :
Browser::~Browser()
{
+ // TODO: fix crash here
// qDeleteAll(m_windows);
// m_windows.clear();
+
+// qDeleteAll(m_profiles);
+// m_profiles.clear();
}
void Browser::setConfiguration(std::shared_ptr<Configuration> &config)
@@ -49,6 +54,8 @@ void Browser::setConfiguration(std::shared_ptr<Configuration> &config)
m_bookmarksManager = std::make_shared<BookmarksWidget>(QString::fromStdString(m_config->value<std::string>("bookmarks.path").value()));
m_downloadManager = std::make_shared<DownloadsWidget>(QString::fromStdString(m_config->value<std::string>("downloads.path").value()));
+ m_urlRequestInterceptor = std::make_shared<UrlRequestInterceptor>(QString::fromStdString(m_config->value<std::string>("browser.filterPath").value()));
+
}
void Browser::loadProfiles()
@@ -66,11 +73,15 @@ void Browser::loadProfiles()
const QStringList profileList = profileDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for(const QString &name : profileList) {
- m_profiles.insert(name, new WebEngineProfile(name, profileDir.absoluteFilePath(name), this));
+ WebEngineProfile *profile = new WebEngineProfile(name, profileDir.absoluteFilePath(name), this);
+ profile->setRequestInterceptor(m_urlRequestInterceptor.get());
+ m_profiles.insert(name, profile);
}
// Also add the Off-the-record profile
- m_profiles.insert("", new WebEngineProfile(this));
+ WebEngineProfile *otr = new WebEngineProfile(this);
+ otr->setRequestInterceptor(m_urlRequestInterceptor.get());
+ m_profiles.insert("", otr);
// set default profile
m_defaultProfile = m_profiles[QString::fromStdString(m_config->value<std::string>("browser.profile").value())];
diff --git a/src/browser.h b/src/browser.h
index b3af5e6..a1557b4 100644
--- a/src/browser.h
+++ b/src/browser.h
@@ -23,10 +23,6 @@
#include "singleapplication.h"
#include "webengine/webengineprofile.h"
-
-//#include "filter/blockermanager.h"
-//#include "webengine/urlinterceptor.h"
-
#include <QVector>
#include <memory>
#include "settings/configuration.h"
@@ -34,6 +30,7 @@
class MainWindow;
class BookmarksWidget;
class DownloadsWidget;
+class UrlRequestInterceptor;
class Browser : public SingleApplication
{
Q_OBJECT
@@ -63,11 +60,10 @@ private:
std::shared_ptr<Configuration> m_config;
QVector<MainWindow *> m_windows;
-// QVector<QPointer<MainWindow>> m_windows;
QHash<QString, WebEngineProfile *> m_profiles;
WebEngineProfile* m_defaultProfile;
-// UrlRequestInterceptor *m_urlRequestInterceptor = nullptr;
+ std::shared_ptr<UrlRequestInterceptor> m_urlRequestInterceptor;
std::shared_ptr<BookmarksWidget> m_bookmarksManager;
std::shared_ptr<DownloadsWidget> m_downloadManager;
// BlockerManager *m_blocklistManager = nullptr;
diff --git a/src/filter/filter.cpp b/src/filter/filter.cpp
index fcba05c..1d14f9d 100644
--- a/src/filter/filter.cpp
+++ b/src/filter/filter.cpp
@@ -19,220 +19,28 @@
******************************************************************************/
#include "filter.h"
+#include <QUrl>
-Filter::Filter(const QString &domain, const QString &request, ResourceRules rules, bool shouldBlock, Filter *parentItem)
+FilterRule::FilterRule(const QString &line)
{
- m_parentItem = parentItem;
-
- m_domainUrl.setPattern(domain);
- m_requestUrl.setPattern(request);
- m_rules = rules;
- m_shouldBlock = shouldBlock;
-
- m_valid = false;
-}
-
-Filter::~Filter()
-{
- qDeleteAll(m_children);
+ parse(line);
}
-void Filter::enable()
+FilterRule::~FilterRule()
{
- m_valid = true;
-}
-
-Filter *Filter::parentItem()
-{
- return m_parentItem;
-}
-
-void Filter::appendChild(Filter *child)
-{
- m_children.append(child);
-}
-
-Filter *Filter::child(int row)
-{
- return m_children.value(row);
-}
-
-int Filter::childCount() const
-{
- return m_children.count();
-}
-
-QString Filter::domain() const
-{
- return m_domainUrl.pattern();
-}
-
-QString Filter::request() const
-{
- return m_requestUrl.pattern();
-}
-
-bool Filter::isBlocking()
-{
- return m_shouldBlock;
-}
-
-QString Filter::allowedTypes() const
-{
- return flags(m_rules.allowed);
-}
-
-QString Filter::blockedTypes() const
-{
- return flags(m_rules.blocked);
-}
-
-int Filter::row() const
-{
- if(m_parentItem) {
- return m_parentItem->m_children.indexOf(const_cast<Filter*>(this));
- }
-
- return 0;
}
-bool Filter::hasDomainMatch(const QString &string)
+bool FilterRule::shouldBlock(const QUrl &requestUrl) const
{
- return m_domainUrl.hasMatch(string);
-}
-
-bool Filter::hasRuleMatch(const QString &string)
-{
- return m_requestUrl.hasMatch(string);
-}
-
-bool Filter::shouldBlock(const QWebEngineUrlRequestInfo &info)
-{
- if(!m_valid) {
+ if(matcher.indexIn(requestUrl.toString()) == -1) {
+ // pattern not found in url
return false;
}
- // Check options
- switch (info.resourceType()) {
- case QWebEngineUrlRequestInfo::ResourceTypeMainFrame:
- return testFlag(MainFrame);
- case QWebEngineUrlRequestInfo::ResourceTypeSubFrame:
- return testFlag(SubFrame);
- case QWebEngineUrlRequestInfo::ResourceTypeStylesheet:
- return testFlag(Stylesheet);
- case QWebEngineUrlRequestInfo::ResourceTypeScript:
- return testFlag(Script);
- case QWebEngineUrlRequestInfo::ResourceTypeImage:
- return testFlag(Image);
- case QWebEngineUrlRequestInfo::ResourceTypeFontResource:
- return testFlag(Font);
- case QWebEngineUrlRequestInfo::ResourceTypeSubResource:
- return testFlag(SubResource);
- case QWebEngineUrlRequestInfo::ResourceTypeObject:
- return testFlag(Object);
- case QWebEngineUrlRequestInfo::ResourceTypeMedia:
- return testFlag(Media);
- case QWebEngineUrlRequestInfo::ResourceTypeWorker:
- return testFlag(Worker);
- case QWebEngineUrlRequestInfo::ResourceTypeSharedWorker:
- return testFlag(SharedWorker);
- case QWebEngineUrlRequestInfo::ResourceTypePrefetch:
- return testFlag(Prefetch);
- case QWebEngineUrlRequestInfo::ResourceTypeFavicon:
- return testFlag(Favicon);
- case QWebEngineUrlRequestInfo::ResourceTypeXhr:
- return testFlag(Xhr);
- case QWebEngineUrlRequestInfo::ResourceTypePing:
- return testFlag(Ping);
- case QWebEngineUrlRequestInfo::ResourceTypeServiceWorker:
- return testFlag(ServiceWorker);
- case QWebEngineUrlRequestInfo::ResourceTypeCspReport:
- return testFlag(CspReport);
- case QWebEngineUrlRequestInfo::ResourceTypePluginResource:
- return testFlag(PluginResource);
- case QWebEngineUrlRequestInfo::ResourceTypeUnknown:
- break;
- }
-
- return m_shouldBlock;
-
+ return true;
}
-bool Filter::isValid()
+void FilterRule::parse(const QString &line)
{
- return m_valid;
-}
-
-bool Filter::testFlag(ResourceType flag)
-{
- if(m_rules.allowed.testFlag(flag)) {
- return false;
- } else if(m_rules.blocked.testFlag(flag)) {
- return true;
- } else {
- return m_shouldBlock;
- }
-}
-
-QString Filter::flags(Resources f) const
-{
- QStringList r;
- if(f.testFlag(MainFrame)) {
- r << QObject::tr("Main Frame");
- }
- if(f.testFlag(SubFrame)) {
- r << QObject::tr("Sub Frame");
- }
- if(f.testFlag(Stylesheet)) {
- r << QObject::tr("Stylesheet");
- }
- if(f.testFlag(Script)) {
- r << QObject::tr("Script");
- }
- if(f.testFlag(Image)) {
- r << QObject::tr("Image");
- }
- if(f.testFlag(Font)) {
- r << QObject::tr("Font");
- }
- if(f.testFlag(SubResource)) {
- r << QObject::tr("Sub Resource");
- }
- if(f.testFlag(Object)) {
- r << QObject::tr("Object");
- }
- if(f.testFlag(Media)) {
- r << QObject::tr("Media");
- }
- if(f.testFlag(Worker)) {
- r << QObject::tr("Worker");
- }
- if(f.testFlag(SharedWorker)) {
- r << QObject::tr("Shared Worker");
- }
- if(f.testFlag(Prefetch)) {
- r << QObject::tr("Prefetch");
- }
- if(f.testFlag(Favicon)) {
- r << QObject::tr("Favicon");
- }
- if(f.testFlag(Xhr)) {
- r << QObject::tr("Xhr");
- }
- if(f.testFlag(Ping)) {
- r << QObject::tr("Ping");
- }
- if(f.testFlag(ServiceWorker)) {
- r << QObject::tr("Service Worker");
- }
- if(f.testFlag(CspReport)) {
- r << QObject::tr("Csp Report");
- }
- if(f.testFlag(PluginResource)) {
- r << QObject::tr("Plugin Resource");
- }
- if(f.testFlag(Unknown)) {
- r << QObject::tr("Unknown");
- }
- return r.join(',');
+ matcher.setPattern(line);
}
diff --git a/src/filter/filter.h b/src/filter/filter.h
index aeababd..bd3e2ca 100644
--- a/src/filter/filter.h
+++ b/src/filter/filter.h
@@ -18,90 +18,37 @@
**
******************************************************************************/
-#ifndef FILTERNODE_H
-#define FILTERNODE_H
+#ifndef FILTERRULE_H
+#define FILTERRULE_H
-#include <QList>
-#include <QVariant>
-#include <QUrl>
-#include "regexp.h"
-#include <QWebEngineUrlRequestInfo>
+#include <QStringMatcher>
-class Filter
+class QUrl;
+class FilterRule
{
public:
- enum ResourceType {
- NoType = 0,
- MainFrame = 1,
- SubFrame = 2,
- Stylesheet = 4,
- Script = 8,
- Image = 16,
- Font = 32,
- SubResource = 64,
- Object = 128,
- Media = 256,
- Worker = 512,
- SharedWorker = 1024,
- Prefetch = 2048,
- Favicon = 4096,
- Xhr = 8192,
- Ping = 16384,
- ServiceWorker = 32768,
- CspReport = 65536,
- PluginResource = 131072,
- Unknown = 262144
- };
- Q_DECLARE_FLAGS(Resources, ResourceType)
+ FilterRule(const QString &line);
- struct ResourceRules {
- Resources allowed;
- Resources blocked;
- };
+ // delete the copy constructor and assignment operator
+ FilterRule(const FilterRule&) = delete;
+ FilterRule& operator=(const FilterRule&) = delete;
- explicit Filter(const QString &domain, const QString &request, ResourceRules rules, bool shouldBlock, Filter *parentItem = 0);
- ~Filter();
+ // move constructor
+ FilterRule(FilterRule&& other) {
+ matcher = other.matcher;
+ }
- void enable();
+ ~FilterRule();
- Filter *parentItem();
-
- // children
- void appendChild(Filter *child);
- Filter *child(int row);
- int childCount() const;
-
- // data
- QString domain() const;
- QString request() const;
- bool isBlocking();
- QString allowedTypes() const;
- QString blockedTypes() const;
-
- int row() const;
-
- // filtering
- bool hasDomainMatch(const QString &string);
- bool hasRuleMatch(const QString &string);
- bool shouldBlock(const QWebEngineUrlRequestInfo &info);
-
- bool isValid();
+ bool shouldBlock(const QUrl &requestUrl) const;
private:
- bool testFlag(ResourceType flag);
- QString flags(Resources f) const;
-
- Filter *m_parentItem;
- QList<Filter*> m_children;
-
- RegExp m_domainUrl;
- RegExp m_requestUrl;
+ void parse(const QString &line);
- ResourceRules m_rules;
+ // QStringMatcher: holds a pattern you want to repeatedly match against some strings
+ QStringMatcher matcher;
- bool m_valid = false;
- bool m_shouldBlock;
};
-#endif // FILTERNODE_H
+#endif // FILTERRULE_H
diff --git a/src/webengine/urlinterceptor.cpp b/src/webengine/urlinterceptor.cpp
index 19bc64f..cbf1c86 100644
--- a/src/webengine/urlinterceptor.cpp
+++ b/src/webengine/urlinterceptor.cpp
@@ -19,31 +19,56 @@
******************************************************************************/
#include "urlinterceptor.h"
-#include "filter/filtercollection.h"
+#include <QFile>
+#include <QTextStream>
-UrlRequestInterceptor::UrlRequestInterceptor(QObject *parent) :
+UrlRequestInterceptor::UrlRequestInterceptor(const QString &path, QObject *parent) :
QWebEngineUrlRequestInterceptor(parent)
{
+#ifdef QT_DEBUG
+ qDebug("Reading request blocklist: %s", qUtf8Printable(path));
+#endif
+
+ int n_rules = 0;
+
+ QFile filter(path);
+ if(filter.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream out(&filter);
+ while(!out.atEnd()) {
+ const QString &line = out.readLine();
+ if(!line.startsWith('!')) {
+ FilterRule r(line);
+ // check if valid
+ m_rules.push_back(std::move(r));
+ ++n_rules;
+ }
+ }
+ filter.close();
+ }
+
+ qDebug("Added %i rules", n_rules);
}
void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
{
-#ifdef DEBUG_VERBOSE
- qDebug("%s -[%i]-> %s", qUtf8Printable(info.firstPartyUrl().toString()), info.resourceType(), qUtf8Printable(info.requestUrl().toString()));
-#endif
- for(auto s : m_manager->subscriptions()) {
- bool shouldBlock = s->match(info);
- if(shouldBlock) {
+ for(const FilterRule &test : m_rules) {
+ const QUrl &url = info.requestUrl();
+
+ if(test.shouldBlock(url)) {
info.block(true);
-#ifdef DEBUG_VERBOSE
- qDebug(">> blocked");
+
+#ifdef QT_DEBUG
+ qDebug("blocked [%s] %s", qUtf8Printable(info.firstPartyUrl().toString()), qUtf8Printable(url.toString()));
#endif
return;
}
}
}
-void UrlRequestInterceptor::setSubscription(BlockerManager *manager)
+bool shouldBlock(const QUrl &url, const QString &test)
{
- m_manager = manager;
+ if(url.toString().contains(test)) {
+ return true;
+ }
+ return false;
}
diff --git a/src/webengine/urlinterceptor.h b/src/webengine/urlinterceptor.h
index acd076a..4466523 100644
--- a/src/webengine/urlinterceptor.h
+++ b/src/webengine/urlinterceptor.h
@@ -18,27 +18,31 @@
**
******************************************************************************/
-#ifndef ADBLOCKINTERCEPTOR_H
-#define ADBLOCKINTERCEPTOR_H
+#ifndef URLREQUESTINTERCEPTOR_H
+#define URLREQUESTINTERCEPTOR_H
#include <QWebEngineUrlRequestInterceptor>
-#include "filter/blockermanager.h"
+#include <vector>
+#include "filter/filter.h"
class UrlRequestInterceptor : public QWebEngineUrlRequestInterceptor
{
Q_OBJECT
public:
- explicit UrlRequestInterceptor(QObject *parent = 0);
+ explicit UrlRequestInterceptor(const QString &path, QObject *parent = nullptr);
+ //~UrlRequestInterceptor();
void interceptRequest(QWebEngineUrlRequestInfo &info);
- void setSubscription(BlockerManager *manager);
signals:
public slots:
private:
- BlockerManager *m_manager;
+
+ std::vector<FilterRule> m_rules;
};
-#endif // ADBLOCKINTERCEPTOR_H
+bool shouldBlock(const QUrl &url, const QString &test);
+
+#endif // URLREQUESTINTERCEPTOR_H