aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--baseconfig2
-rw-r--r--lib/configuration/configuration.cpp2
-rw-r--r--lib/urlfilter/domain.cpp4
-rw-r--r--lib/urlfilter/filterleaf.h2
-rw-r--r--lib/urlfilter/filtertree.cpp4
-rw-r--r--lib/urlfilter/filtertree.h2
-rw-r--r--lib/urlfilter/formats/hostlistrule.cpp5
-rw-r--r--lib/urlfilter/formats/hostlistrule.h2
-rw-r--r--linux/.config2
-rw-r--r--src/webengine/filter.cpp74
-rw-r--r--src/webengine/filter.h9
-rw-r--r--src/webengine/urlinterceptor.cpp5
-rw-r--r--test/hostlist/hostlisttest.cpp10
13 files changed, 44 insertions, 79 deletions
diff --git a/baseconfig b/baseconfig
index eb05765..0e2fb71 100644
--- a/baseconfig
+++ b/baseconfig
@@ -52,7 +52,7 @@ menu "Configuration defaults"
default "~/.config/smolbote/crash.d"
config PATH_FILTER
string "Host filter path"
- default "~/.config/smolbote/host.d"
+ default "~/.config/smolbote/hosts.d"
config PATH_PLUGINS
string "Plugin load location"
default "~/.config/smolbote/plugins.d"
diff --git a/lib/configuration/configuration.cpp b/lib/configuration/configuration.cpp
index cf58d82..25f783c 100644
--- a/lib/configuration/configuration.cpp
+++ b/lib/configuration/configuration.cpp
@@ -100,7 +100,7 @@ Configuration::Configuration(QObject *parent)
("subwindow.shortcuts.fullscreen", po::value<std::string>()->default_value("F11"))
// Filter settings
- ("filter.path", po::value<std::string>()->default_value(Path_Filter))
+ ("filter.hosts", po::value<std::string>()->default_value(Path_Filter))
("filter.adblock", po::value<std::string>())
("filter.header", po::value<std::vector<std::string>>())
// ("filter.cookies.block.all", po::value<bool>()->default_value(false))
diff --git a/lib/urlfilter/domain.cpp b/lib/urlfilter/domain.cpp
index 20c4f3a..2bfd524 100644
--- a/lib/urlfilter/domain.cpp
+++ b/lib/urlfilter/domain.cpp
@@ -29,6 +29,10 @@ Domain &Domain::operator=(Domain &&other)
bool Domain::matches(const QUrl &url) const
{
+ // empty domain matches all
+ if(m_domain.isEmpty() || url.isEmpty())
+ return true;
+
const QString domain = url.host();
// domain and filter are the same
diff --git a/lib/urlfilter/filterleaf.h b/lib/urlfilter/filterleaf.h
index 36c00e9..dcd3ec0 100644
--- a/lib/urlfilter/filterleaf.h
+++ b/lib/urlfilter/filterleaf.h
@@ -28,7 +28,7 @@ public:
FilterLeaf &operator=(FilterLeaf &&other);
~FilterLeaf() = default;
- virtual bool match(const QString &requestUrl) const = 0;
+ virtual bool match(const QUrl &requestUrl) const = 0;
virtual Action action() const = 0;
const QString request() const;
diff --git a/lib/urlfilter/filtertree.cpp b/lib/urlfilter/filtertree.cpp
index dcde196..2cdd6d0 100644
--- a/lib/urlfilter/filtertree.cpp
+++ b/lib/urlfilter/filtertree.cpp
@@ -57,11 +57,11 @@ const QStringList FilterTree::branches() const
return branches;
}
-QVector<const FilterLeaf *> FilterTree::match(const QString &domain, const QString &requestUrl) const
+QVector<const FilterLeaf *> FilterTree::match(const QUrl &domain, const QUrl &requestUrl) const
{
QVector<const FilterLeaf *> leaves;
for(const auto &branch : m_branches) {
- if(branch.domain.matches(QUrl(domain))) {
+ if(branch.domain.matches(domain)) {
for(const auto leaf : branch.leaves) {
if(leaf->match(requestUrl)) {
diff --git a/lib/urlfilter/filtertree.h b/lib/urlfilter/filtertree.h
index 3da82e0..f453a3d 100644
--- a/lib/urlfilter/filtertree.h
+++ b/lib/urlfilter/filtertree.h
@@ -30,7 +30,7 @@ public:
~FilterTree();
const QStringList branches() const;
- QVector<const FilterLeaf *> match(const QString &domain, const QString &requestUrl) const;
+ QVector<const FilterLeaf *> match(const QUrl &domain, const QUrl &requestUrl) const;
bool addRule(FilterLeaf *rule, const QString &domain);
diff --git a/lib/urlfilter/formats/hostlistrule.cpp b/lib/urlfilter/formats/hostlistrule.cpp
index f0cb4af..e4561f0 100644
--- a/lib/urlfilter/formats/hostlistrule.cpp
+++ b/lib/urlfilter/formats/hostlistrule.cpp
@@ -15,9 +15,10 @@ HostlistRule::HostlistRule(const QString &domain, const QString &redirect)
this->m_redirect = redirect;
}
-bool HostlistRule::match(const QString &requestUrl) const
+bool HostlistRule::match(const QUrl &requestUrl) const
{
- return (m_request == requestUrl);
+ //qDebug("checking [%s] against [%s]", qUtf8Printable(requestUrl.host()), qUtf8Printable(m_request));
+ return (m_request == requestUrl.host());
}
FilterLeaf::Action HostlistRule::action() const
diff --git a/lib/urlfilter/formats/hostlistrule.h b/lib/urlfilter/formats/hostlistrule.h
index 19fd63f..c65a98f 100644
--- a/lib/urlfilter/formats/hostlistrule.h
+++ b/lib/urlfilter/formats/hostlistrule.h
@@ -17,7 +17,7 @@ class HostlistRule : public FilterLeaf
public:
explicit HostlistRule(const QString &domain, const QString &redirect);
- bool match(const QString &requestUrl) const override;
+ bool match(const QUrl &requestUrl) const override;
FilterLeaf::Action action() const override;
};
diff --git a/linux/.config b/linux/.config
index 8a84cad..09b5a4a 100644
--- a/linux/.config
+++ b/linux/.config
@@ -36,7 +36,7 @@ CONFIG_POI_EXE="poi"
#
CONFIG_PATH_CONFIG="~/.config/smolbote/smolbote.cfg"
CONFIG_PATH_CRASHDUMP="~/.config/smolbote/crash.d"
-CONFIG_PATH_FILTER="~/.config/smolbote/host.d"
+CONFIG_PATH_FILTER="~/.config/smolbote/hosts.d"
CONFIG_PATH_PLUGINS="~/.config/smolbote/plugins.d"
CONFIG_PATH_PROFILES="~/.config/smolbote/profiles.d"
CONFIG_PATH_BOOKMARKS="~/.config/smolbote/bookmarks.xbel"
diff --git a/src/webengine/filter.cpp b/src/webengine/filter.cpp
index b250843..3ff6a04 100644
--- a/src/webengine/filter.cpp
+++ b/src/webengine/filter.cpp
@@ -15,53 +15,6 @@
#include <configuration/configuration.h>
#include "util.h"
-
-QHash<QString, Filter::HostRule> parseHostlist(const QString &filename)
-{
- QHash<QString, Filter::HostRule> rules;
-
- if(QFile hostfile(filename); hostfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
-
- // with a QTextStream we can read lines without getting linebreaks at the end
- QTextStream hostfile_stream(&hostfile);
-
- while(!hostfile_stream.atEnd()) {
-
- // read line and remove any whitespace at the end
- const QString &line = hostfile_stream.readLine().trimmed();
-
- // skip comments and empty lines
- if(line.isEmpty() || line.startsWith('#'))
- continue;
-
- // everything else should be a rule
- // format is <redirect> <host>
- // 0.0.0.0 hostname
- const QStringList &parts = line.split(' ');
- const QString &redirect = parts.at(0);
-
- for(auto i = parts.constBegin() + 1; i != parts.constEnd(); ++i) {
- if(!rules.contains(*i)) {
- Filter::HostRule rule{};
- rule.isBlocking = (redirect == "0.0.0.0");
- rules.insert(*i, rule);
- }
- }
-
- // for(const QString &host : parts.mid(1)) {
- // if(!rules.contains(host)) {
- // UrlRequestInterceptor::HostRule rule{};
- // rule.isBlocking = redirect == "0.0.0.0";
- // rules.insert(host, rule);
- // }
- // }
- }
-
- hostfile.close();
- }
-
- return rules;
-}
/*
inline std::vector<FilterRule> parseAdBlockList(const QString &filename)
{
@@ -95,9 +48,17 @@ Filter::Filter::Filter(const std::unique_ptr<Configuration> &config, QObject* pa
}
}
- const QStringList hostfiles = Util::files(config->value<QString>("filter.path").value());
+ const QStringList hostfiles = Util::files(config->value<QString>("filter.hosts").value());
+ //qDebug("filter.path=[%s]", qUtf8Printable(config->value<QString>("filter.hosts").value()));
for(const QString &hostfile : hostfiles) {
- m_hostlist.unite(parseHostlist(hostfile));
+ QFile f(hostfile);
+ if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+#ifdef QT_DEBUG
+ qDebug("Loading hostlist filters [%s]", qUtf8Printable(hostfile));
+#endif
+ loadHostlist(f, &filters);
+ f.close();
+ }
}
/*
@@ -107,10 +68,15 @@ Filter::Filter::Filter(const std::unique_ptr<Configuration> &config, QObject* pa
*/
}
-std::optional<Filter::HostRule> Filter::hostlistRule(const QString& url) const
+void Filter::filterRequest(QWebEngineUrlRequestInfo& info) const
{
- if(!m_hostlist.contains(url))
- return std::nullopt;
-
- return std::optional<Filter::HostRule>(m_hostlist.value(url));
+ auto matches = filters.match(info.firstPartyUrl().toString(), info.requestUrl().toString());
+ for(const auto &rule : matches) {
+ switch(rule->action()) {
+ case FilterLeaf::Block:
+ qDebug("block %s", qUtf8Printable(info.requestUrl().toString()));
+ info.block(true);
+ break;
+ }
+ }
}
diff --git a/src/webengine/filter.h b/src/webengine/filter.h
index 3eac5ee..c610b29 100644
--- a/src/webengine/filter.h
+++ b/src/webengine/filter.h
@@ -13,6 +13,7 @@
#include <QByteArray>
#include <QVector>
#include <optional>
+#include "urlfilter/filtertree.h"
class Configuration;
class Filter : public QObject
@@ -26,11 +27,7 @@ public:
explicit Filter(const std::unique_ptr<Configuration> &config, QObject *parent = nullptr);
~Filter() override = default;
- const QHash<QString, HostRule> hostlist() const
- {
- return qAsConst(m_hostlist);
- }
- std::optional<HostRule> hostlistRule(const QString &url) const;
+ void filterRequest(QWebEngineUrlRequestInfo &info) const;
const QMap<QByteArray, QByteArray> headers() const
{
@@ -38,7 +35,7 @@ public:
}
private:
- QHash<QString, HostRule> m_hostlist;
+ FilterTree filters;
QMap<QByteArray, QByteArray> m_headers;
};
diff --git a/src/webengine/urlinterceptor.cpp b/src/webengine/urlinterceptor.cpp
index cf9b85f..e6bd523 100644
--- a/src/webengine/urlinterceptor.cpp
+++ b/src/webengine/urlinterceptor.cpp
@@ -30,10 +30,7 @@ UrlRequestInterceptor::UrlRequestInterceptor(Filter* filter, WebProfile* profile
void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
{
- auto hostlistCheck = m_filter->hostlistRule(info.requestUrl().host());
- if(hostlistCheck) {
- info.block(hostlistCheck.value().isBlocking);
- }
+ m_filter->filterRequest(info);
// set headers
for(auto i = m_filter->headers().constBegin(); i != m_filter->headers().constEnd(); ++i) {
diff --git a/test/hostlist/hostlisttest.cpp b/test/hostlist/hostlisttest.cpp
index 46f6a85..cd1d39f 100644
--- a/test/hostlist/hostlisttest.cpp
+++ b/test/hostlist/hostlisttest.cpp
@@ -16,26 +16,26 @@ void HostlistTest::parseList()
void HostlistTest::checkRules()
{
// test block
- QVector<const FilterLeaf *> block = tree.match(QString(), "blockeddomain.com");
+ QVector<const FilterLeaf *> block = tree.match(QUrl(), QUrl::fromUserInput("blockeddomain.com"));
QCOMPARE(block.length(), 1);
QCOMPARE(block.constFirst()->action(), FilterLeaf::Block);
// test redirect
- QVector<const FilterLeaf *> redirectResult = tree.match(QString(), "localhost.localdomain");
+ QVector<const FilterLeaf *> redirectResult = tree.match(QUrl(), QUrl::fromUserInput("localhost.localdomain"));
QCOMPARE(redirectResult.length(), 1);
QCOMPARE(redirectResult.at(0)->action(), FilterLeaf::Redirect);
QCOMPARE(redirectResult.at(0)->redirect(), "127.0.0.1");
// two domains on one line
- QVector<const FilterLeaf *> blockFirst = tree.match(QString(), "blockeddomain.first");
+ QVector<const FilterLeaf *> blockFirst = tree.match(QUrl(), QUrl::fromUserInput("blockeddomain.first"));
QCOMPARE(blockFirst.length(), 1);
QCOMPARE(blockFirst.constFirst()->action(), FilterLeaf::Block);
- QVector<const FilterLeaf *> blockSecond = tree.match(QString(), "blockeddomain.second");
+ QVector<const FilterLeaf *> blockSecond = tree.match(QUrl(), QUrl::fromUserInput("blockeddomain.second"));
QCOMPARE(blockSecond.length(), 1);
QCOMPARE(blockSecond.constFirst()->action(), FilterLeaf::Block);
// domain not on list
- QVector<const FilterLeaf *> missing = tree.match(QString(), "other.domain");
+ QVector<const FilterLeaf *> missing = tree.match(QUrl(), QUrl::fromUserInput("other.domain"));
QCOMPARE(missing.length(), 0);
}