diff options
-rw-r--r-- | data/poi.toml | 9 | ||||
-rw-r--r-- | src/filter/filter.cpp | 13 | ||||
-rw-r--r-- | src/filter/filter.h | 3 | ||||
-rw-r--r-- | src/filter/filtercollection.cpp | 44 | ||||
-rw-r--r-- | src/filter/filtercollection.h | 6 | ||||
-rw-r--r-- | src/filter/filtertree.cpp | 4 | ||||
-rw-r--r-- | src/webengine/urlinterceptor.cpp | 21 | ||||
-rw-r--r-- | test/filter.json | 20 |
8 files changed, 61 insertions, 59 deletions
diff --git a/data/poi.toml b/data/poi.toml index e5fc6ac..93bdb78 100644 --- a/data/poi.toml +++ b/data/poi.toml @@ -1,6 +1,9 @@ # # poi.conf # +## +# This file is read-only; smolbote should never be able to change it. +# ## Settings and default settings # There are two parts to the settings - default values and user overrides. # The default settings are read from: @@ -15,7 +18,7 @@ ## Variables # §home is QStandardPaths::HomeLocation, usually /home/username # $cache is QStandardPaths::CacheLocation, usually /home/username/.cache/smolbote -# $settings is the directory where the settings file is located, usually /home/username/config/.smolbote +# $settings is the directory where the settings file is located, usually /home/username/.config/smolbote # General [general] @@ -26,9 +29,11 @@ search="https://duckduckgo.com/lite?q=$term" # FIXME remove; move to profile #sessionPath="$cache/session.json" # Profile -# A nameless ("") profile is off-the-record [browser.profile] +# Which profile should be used by default for new windows +# A nameless ("") profile is off-the-record default="" +# Where to look for profiles path="$home/.config/smolbote/profiles/" storagePath="$home/.config/smolbote/profiles/" cachePath="$home/.cache/smolbote/profiles/" diff --git a/src/filter/filter.cpp b/src/filter/filter.cpp index e0d01a9..fcba05c 100644 --- a/src/filter/filter.cpp +++ b/src/filter/filter.cpp @@ -96,13 +96,14 @@ int Filter::row() const return 0; } -bool Filter::hasMatch(const QWebEngineUrlRequestInfo &info) +bool Filter::hasDomainMatch(const QString &string) { - if(m_domainUrl.hasMatch(info.firstPartyUrl().toString()) && m_requestUrl.hasMatch(info.requestUrl().toString())) { - return true; - } else { - return false; - } + return m_domainUrl.hasMatch(string); +} + +bool Filter::hasRuleMatch(const QString &string) +{ + return m_requestUrl.hasMatch(string); } bool Filter::shouldBlock(const QWebEngineUrlRequestInfo &info) diff --git a/src/filter/filter.h b/src/filter/filter.h index 37604fe..aeababd 100644 --- a/src/filter/filter.h +++ b/src/filter/filter.h @@ -82,7 +82,8 @@ public: int row() const; // filtering - bool hasMatch(const QWebEngineUrlRequestInfo &info); + bool hasDomainMatch(const QString &string); + bool hasRuleMatch(const QString &string); bool shouldBlock(const QWebEngineUrlRequestInfo &info); bool isValid(); diff --git a/src/filter/filtercollection.cpp b/src/filter/filtercollection.cpp index 7b07606..4c2bfce 100644 --- a/src/filter/filtercollection.cpp +++ b/src/filter/filtercollection.cpp @@ -74,27 +74,21 @@ QString FilterCollection::name() const * @param info * @return true if it should be blocked; false otherwise */ -FilterCollection::MatchResult FilterCollection::match(QWebEngineUrlRequestInfo &info) +bool FilterCollection::match(QWebEngineUrlRequestInfo &info) { - MatchResult result; - - for(Filter *rule : m_filters->filters(info.firstPartyUrl().toString())) { - if(rule->isValid()) { - result.match = rule->hasMatch(info); - if(result.match) { - result.block = rule->shouldBlock(info); - } else { - result.block = false; + for(QString domain : m_filterlist.keys()) { + if(domain.isEmpty() || info.firstPartyUrl().toString().contains(domain)) { + // domain matched + + for(QString rule : m_filterlist.value(domain).keys()) { + if(rule.isEmpty() || info.requestUrl().toString().contains(rule)) { + return m_filterlist.value(domain).value(rule); + } } - result.pattern = rule->domain() + " | " + rule->request(); - return result; } } - // request matches neither whitelist nor blacklist - result.match = false; - result.block = false; - return result; + return false; } /** @@ -108,18 +102,22 @@ int FilterCollection::load(const QJsonObject &json) ui->title->setText(json["name"].toString()); ui->homepage->setText(json["url"].toString()); - for(QJsonValue v : json["rules"].toArray()) { + QJsonObject rules = json["rules"].toObject(); + for(QString key : rules.keys()) { ++number; + qDebug("+ '%s'", qUtf8Printable(key)); - QJsonObject obj = v.toObject(); + QJsonObject domain = rules.value(key).toObject(); + QHash<QString, bool> d; - Filter::ResourceRules r; - r.allowed = parseJsonRules(obj["allowTypes"]); - r.blocked = parseJsonRules(obj["blockTypes"]); + for(QString r : domain.keys()) { + d.insert(r, domain.value(r).toBool()); + qDebug("|-'%s': %i", qUtf8Printable(r), domain.value(r).toBool()); + } - m_filters->addFilter(obj["firstPartyUrl"].toString(), obj["requestUrl"].toString(), r, obj["shouldBlock"].toBool()); - } + m_filterlist.insert(key, d); + } return number; } diff --git a/src/filter/filtercollection.h b/src/filter/filtercollection.h index c39fb0a..0dcc26d 100644 --- a/src/filter/filtercollection.h +++ b/src/filter/filtercollection.h @@ -25,6 +25,8 @@ #include <QFile> #include "filtertree.h" +#include <QHash> + namespace Ui { class SubscriptionForm; } @@ -44,7 +46,7 @@ public: ~FilterCollection(); QString name() const; - MatchResult match(QWebEngineUrlRequestInfo &info); + bool match(QWebEngineUrlRequestInfo &info); private slots: int load(const QJsonObject &json); @@ -56,6 +58,8 @@ private: FilterTree *m_filters; + QHash<QString, QHash<QString, bool>> m_filterlist; + }; #endif // SUBSCRIPTIONFORM_H diff --git a/src/filter/filtertree.cpp b/src/filter/filtertree.cpp index b71c2a3..378b888 100644 --- a/src/filter/filtertree.cpp +++ b/src/filter/filtertree.cpp @@ -155,7 +155,9 @@ QVector<Filter*> FilterTree::filters(const QString &domain) { QVector<Filter*> nodes; for(int i = 0; i < rootItem->childCount(); ++i) { - nodes.append(rootItem->child(i)); + if(rootItem->child(i)->hasDomainMatch(domain)) { + nodes.append(rootItem->child(i)); + } } return nodes; } diff --git a/src/webengine/urlinterceptor.cpp b/src/webengine/urlinterceptor.cpp index 3ffcb44..19bc64f 100644 --- a/src/webengine/urlinterceptor.cpp +++ b/src/webengine/urlinterceptor.cpp @@ -21,10 +21,6 @@ #include "urlinterceptor.h" #include "filter/filtercollection.h" -#ifdef DEBUG_VERBOSE -#include <QTime> -#endif - UrlRequestInterceptor::UrlRequestInterceptor(QObject *parent) : QWebEngineUrlRequestInterceptor(parent) { @@ -33,25 +29,18 @@ UrlRequestInterceptor::UrlRequestInterceptor(QObject *parent) : void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) { #ifdef DEBUG_VERBOSE - QTime time; - qDebug("%s --> [%i] %s", qUtf8Printable(info.firstPartyUrl().toString()), info.resourceType(), qUtf8Printable(info.requestUrl().toString())); - time.start(); + qDebug("%s -[%i]-> %s", qUtf8Printable(info.firstPartyUrl().toString()), info.resourceType(), qUtf8Printable(info.requestUrl().toString())); #endif - for(auto s : m_manager->subscriptions()) { - FilterCollection::MatchResult r = s->match(info); - if(r.match) { - info.block(r.block); + bool shouldBlock = s->match(info); + if(shouldBlock) { + info.block(true); #ifdef DEBUG_VERBOSE - qDebug(">> matched [%s] [%s] in %i ms", r.block ? "blocked" : "allowed", qUtf8Printable(r.pattern), time.elapsed()); + qDebug(">> blocked"); #endif return; } } - -#ifdef DEBUG_VERBOSE - qDebug(">> passed in %i ms", time.elapsed()); -#endif } void UrlRequestInterceptor::setSubscription(BlockerManager *manager) diff --git a/test/filter.json b/test/filter.json index dc4c55b..d52efe7 100644 --- a/test/filter.json +++ b/test/filter.json @@ -1,13 +1,15 @@ { "name": "Poi Test Filter List", - "url": "todo.url", - "rules": [ - { - "firstPartyUrl": "duckduckgo.com", - "requestUrl": "css", - "allowTypes": ["Stylesheet"], - "blockTypes": [], - "shouldBlock": true + "url": "https://neueland.iserlohn-fortress.net/filter.json", + "rules": { + "": { + "google-analytics.com": true, + "js-agent.newrelic.com": true, + "js": true + }, + "duckduckgo.com": { + "css": false, + "js": false } - ] + } } |