aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/urlfilter/domain.cpp8
-rw-r--r--lib/urlfilter/domain.h2
-rw-r--r--lib/urlfilter/filterleaf.cpp8
-rw-r--r--lib/urlfilter/filterleaf.h23
-rw-r--r--lib/urlfilter/filterrule.cpp1
-rw-r--r--lib/urlfilter/filterrule.h3
-rw-r--r--lib/urlfilter/filtertree.cpp38
-rw-r--r--lib/urlfilter/filtertree.h28
-rw-r--r--lib/urlfilter/formats/adblockrule.cpp4
-rw-r--r--lib/urlfilter/formats/adblockrule.h1
-rw-r--r--lib/urlfilter/formats/hostlistrule.cpp11
11 files changed, 78 insertions, 49 deletions
diff --git a/lib/urlfilter/domain.cpp b/lib/urlfilter/domain.cpp
index 3686210..20c4f3a 100644
--- a/lib/urlfilter/domain.cpp
+++ b/lib/urlfilter/domain.cpp
@@ -8,26 +8,26 @@
#include "domain.h"
-Domain::Domain(const QString& domain)
+Domain::Domain(const QString &domain)
: m_domain(domain)
, m_hash(qHash(domain, 0))
{
}
-Domain::Domain(Domain && other)
+Domain::Domain(Domain &&other)
: m_domain(std::move(other.m_domain))
, m_hash(std::move(other.m_hash))
{
}
-Domain & Domain::operator=(Domain && other)
+Domain &Domain::operator=(Domain &&other)
{
m_domain = std::move(other.m_domain);
m_hash = other.m_hash;
return *this;
}
-bool Domain::matches(const QUrl& url) const
+bool Domain::matches(const QUrl &url) const
{
const QString domain = url.host();
diff --git a/lib/urlfilter/domain.h b/lib/urlfilter/domain.h
index 356762d..0406f0f 100644
--- a/lib/urlfilter/domain.h
+++ b/lib/urlfilter/domain.h
@@ -17,7 +17,7 @@ class Domain
public:
explicit Domain(const QString &domain);
explicit Domain(Domain &&other);
- Domain& operator=(Domain &&other);
+ Domain &operator=(Domain &&other);
// match domain and subdomains of domain
bool matches(const QUrl &url) const;
diff --git a/lib/urlfilter/filterleaf.cpp b/lib/urlfilter/filterleaf.cpp
index 3bd10bf..87cd91d 100644
--- a/lib/urlfilter/filterleaf.cpp
+++ b/lib/urlfilter/filterleaf.cpp
@@ -1,13 +1,13 @@
#include "filterleaf.h"
-FilterLeaf::FilterLeaf(FilterLeaf && other)
+FilterLeaf::FilterLeaf(FilterLeaf &&other)
{
m_isBlocking = other.m_isBlocking;
m_request = std::move(other.m_request);
m_redirect = std::move(other.m_redirect);
}
-FilterLeaf & FilterLeaf::operator=(FilterLeaf && other)
+FilterLeaf &FilterLeaf::operator=(FilterLeaf &&other)
{
m_isBlocking = other.m_isBlocking;
m_request = std::move(other.m_request);
@@ -17,10 +17,10 @@ FilterLeaf & FilterLeaf::operator=(FilterLeaf && other)
const QString FilterLeaf::request() const
{
- return QString::fromStdString(m_request);
+ return m_request;
}
const QString FilterLeaf::redirect() const
{
- return QString::fromStdString(m_redirect);
+ return m_redirect;
}
diff --git a/lib/urlfilter/filterleaf.h b/lib/urlfilter/filterleaf.h
index 6d9caae..36c00e9 100644
--- a/lib/urlfilter/filterleaf.h
+++ b/lib/urlfilter/filterleaf.h
@@ -9,8 +9,10 @@
#ifndef SMOLBOTE_FILTERLEAF_H
#define SMOLBOTE_FILTERLEAF_H
+#include <QHash>
#include <QObject>
#include <QString>
+#include <QWebEngineUrlRequestInfo>
class FilterLeaf
{
@@ -23,7 +25,7 @@ public:
};
FilterLeaf(FilterLeaf &&other);
- FilterLeaf& operator=(FilterLeaf &&other);
+ FilterLeaf &operator=(FilterLeaf &&other);
~FilterLeaf() = default;
virtual bool match(const QString &requestUrl) const = 0;
@@ -33,11 +35,26 @@ public:
const QString redirect() const;
protected:
+ enum UrlMatchType {
+ InvalidMatch,
+ RegularExpressionMatch,
+ StringContains,
+ StringStartsWith,
+ StringEndsWith,
+ StringEquals,
+ DomainMatch
+ };
+
explicit FilterLeaf() = default;
+ // rule matching
+ UrlMatchType matchType = InvalidMatch;
+ QHash<QWebEngineUrlRequestInfo::ResourceType, bool> resourceTypeOptions;
+ QString m_request;
+
+ // rule action
bool m_isBlocking;
- std::string m_request;
- std::string m_redirect;
+ QString m_redirect;
};
#endif // SMOLBOTE_FILTERLEAF_H
diff --git a/lib/urlfilter/filterrule.cpp b/lib/urlfilter/filterrule.cpp
index 739c78c..66a46f1 100644
--- a/lib/urlfilter/filterrule.cpp
+++ b/lib/urlfilter/filterrule.cpp
@@ -53,7 +53,6 @@ bool FilterRule::matchesDomain(uint domainHash) const
// allowedDomains means the rule should only be matched on those domains
return allowedDomains_hashes.contains(domainHash);
-
}
bool FilterRule::matchesType(QWebEngineUrlRequestInfo::ResourceType type) const
diff --git a/lib/urlfilter/filterrule.h b/lib/urlfilter/filterrule.h
index 86f7e87..6afe3c6 100644
--- a/lib/urlfilter/filterrule.h
+++ b/lib/urlfilter/filterrule.h
@@ -14,9 +14,9 @@
#include <QStringList>
#include <QStringMatcher>
#include <QUrl>
+#include <QVector>
#include <QWebEngineUrlRequestInfo>
#include <memory>
-#include <QVector>
class FilterRule
{
@@ -49,7 +49,6 @@ protected:
QString match;
QRegularExpression regexp;
-
};
#endif // SMOLBOTE_FILTERRULE_H
diff --git a/lib/urlfilter/filtertree.cpp b/lib/urlfilter/filtertree.cpp
index 8d88140..dcde196 100644
--- a/lib/urlfilter/filtertree.cpp
+++ b/lib/urlfilter/filtertree.cpp
@@ -8,10 +8,10 @@
#include "filtertree.h"
#include "filterleaf.h"
-#include <QTextStream>
#include "formats/hostlistrule.h"
+#include <QTextStream>
-bool loadHostlist(QIODevice &from, FilterTree* tree)
+bool loadHostlist(QIODevice &from, FilterTree *tree)
{
Q_ASSERT(from.isReadable());
QTextStream stream(&from);
@@ -36,11 +36,18 @@ bool loadHostlist(QIODevice &from, FilterTree* tree)
if(!added)
return false;
}
-
}
return true;
}
+FilterTree::~FilterTree()
+{
+ for(auto &branch : m_branches) {
+ qDeleteAll(branch.leaves);
+ branch.leaves.clear();
+ }
+}
+
const QStringList FilterTree::branches() const
{
QStringList branches;
@@ -50,7 +57,7 @@ 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 QString &domain, const QString &requestUrl) const
{
QVector<const FilterLeaf *> leaves;
for(const auto &branch : m_branches) {
@@ -61,26 +68,27 @@ QVector<const FilterLeaf *> FilterTree::match(const QString& domain, const QStri
leaves.append(leaf);
}
}
-
}
}
return leaves;
}
-bool FilterTree::addRule(FilterLeaf *rule, const QString& domain)
+bool FilterTree::addRule(FilterLeaf *rule, const QString &domain)
+{
+ branchLock.lock();
+ this->branch(domain).leaves.emplace_back(rule);
+ branchLock.unlock();
+ return true;
+}
+
+FilterTree::Branch & FilterTree::branch(const QString& domain)
{
for(auto &branch : m_branches) {
- if(branch.domain.matches(QUrl(domain))) {
- branch.leaves.emplace_back(rule);
- return true;
- }
+ if(branch.domain.matches(QUrl(domain)))
+ return branch;
}
// no branch was found
Branch branch(domain);
- //branch.domain = domain.toStdString();
- // TODO: for some reason, can't add rule here
- //branch.leaves.emplace_back(rule);
- m_branches.emplace_back(std::move(branch));
- return this->addRule(rule, domain);
+ return m_branches.emplace_back(std::move(branch));
}
diff --git a/lib/urlfilter/filtertree.h b/lib/urlfilter/filtertree.h
index 004cf5a..3da82e0 100644
--- a/lib/urlfilter/filtertree.h
+++ b/lib/urlfilter/filtertree.h
@@ -9,22 +9,26 @@
#ifndef SMOLBOTE_FILTERTREE_H
#define SMOLBOTE_FILTERTREE_H
+#include "domain.h"
+#include "filterleaf.h"
+#include <QIODevice>
#include <QObject>
#include <QVector>
#include <vector>
-#include <QIODevice>
-#include "filterleaf.h"
-#include "domain.h"
+#include <QMutex>
/** FilterTree: B+ tree of filter rules
- * The root of the tree contains branches that represent domains, on which their rules are to be applied.
- * Each branch contains leaves - rules
+ * The tree contains branches that represent domains
+ * Each domain-branch contains leaves (rules) that are to be applied to it.
+ * Rules may be applied to multiple branches.
*/
class FilterTree : public QObject
{
Q_OBJECT
public:
+ ~FilterTree();
+
const QStringList branches() const;
QVector<const FilterLeaf *> match(const QString &domain, const QString &requestUrl) const;
@@ -32,19 +36,23 @@ public:
private:
struct Branch {
- explicit Branch(const QString &host) : domain(host) {}
+ explicit Branch(const QString &host)
+ : domain(host)
+ {
+ }
explicit Branch(Branch &&other)
: domain(std::move(other.domain))
, leaves(std::move(other.leaves))
- {}
- ~Branch() { qDeleteAll(leaves); }
+ {
+ }
- // TODO: replace domain type with domain-matching class
Domain domain;
- //std::string domain;
std::vector<FilterLeaf *> leaves;
};
+ Branch& branch(const QString &domain);
+
+ QMutex branchLock;
std::vector<Branch> m_branches;
};
diff --git a/lib/urlfilter/formats/adblockrule.cpp b/lib/urlfilter/formats/adblockrule.cpp
index fc57ab9..c5d6b58 100644
--- a/lib/urlfilter/formats/adblockrule.cpp
+++ b/lib/urlfilter/formats/adblockrule.cpp
@@ -49,8 +49,8 @@ AdBlockRule::AdBlockRule(const QString &filter)
for(const QString &option : options) {
if(option.startsWith(QLatin1Literal("domain"))) {
const auto domainList = option.mid(7).split(QLatin1Literal("|"));
- for (const QString &domain : domainList) {
- if (domain.startsWith(QLatin1Literal("~"))) {
+ for(const QString &domain : domainList) {
+ if(domain.startsWith(QLatin1Literal("~"))) {
blockedDomains_hashes.append(qHash(domain.mid(1)));
} else {
allowedDomains_hashes.append(qHash(domain));
diff --git a/lib/urlfilter/formats/adblockrule.h b/lib/urlfilter/formats/adblockrule.h
index 95cd1a2..3c8edb1 100644
--- a/lib/urlfilter/formats/adblockrule.h
+++ b/lib/urlfilter/formats/adblockrule.h
@@ -17,7 +17,6 @@ public:
explicit AdBlockRule(const QString &filter);
void parseOption(const QString &option);
-
};
#endif // SMOLBOTE_ADBLOCKRULE_H
diff --git a/lib/urlfilter/formats/hostlistrule.cpp b/lib/urlfilter/formats/hostlistrule.cpp
index 8336243..f0cb4af 100644
--- a/lib/urlfilter/formats/hostlistrule.cpp
+++ b/lib/urlfilter/formats/hostlistrule.cpp
@@ -8,16 +8,16 @@
#include "hostlistrule.h"
-HostlistRule::HostlistRule(const QString &domain, const QString& redirect)
+HostlistRule::HostlistRule(const QString &domain, const QString &redirect)
{
this->m_isBlocking = (redirect == QLatin1Literal("0.0.0.0"));
- this->m_request = domain.toStdString();
- this->m_redirect = redirect.toStdString();
+ this->m_request = domain;
+ this->m_redirect = redirect;
}
-bool HostlistRule::match(const QString& requestUrl) const
+bool HostlistRule::match(const QString &requestUrl) const
{
- return (m_request == requestUrl.toStdString());
+ return (m_request == requestUrl);
}
FilterLeaf::Action HostlistRule::action() const
@@ -26,4 +26,3 @@ FilterLeaf::Action HostlistRule::action() const
return FilterLeaf::Block;
return FilterLeaf::Redirect;
}
-