diff options
Diffstat (limited to 'lib/urlfilter/hostlist')
-rw-r--r-- | lib/urlfilter/hostlist/hostlist.cpp | 79 | ||||
-rw-r--r-- | lib/urlfilter/hostlist/hostlist.h | 44 |
2 files changed, 123 insertions, 0 deletions
diff --git a/lib/urlfilter/hostlist/hostlist.cpp b/lib/urlfilter/hostlist/hostlist.cpp new file mode 100644 index 0000000..ec0b214 --- /dev/null +++ b/lib/urlfilter/hostlist/hostlist.cpp @@ -0,0 +1,79 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "hostlist.h" +#include <QIODevice> +#include <QTextStream> +#include <QDebug> + +HostList::HostList(QIODevice *device) +{ + Q_ASSERT(device->isOpen()); + + QTextStream list(device); + while (!list.atEnd()) { + parseLine(list.readLine()); + } + + qDebug() << m_metadata; +} + +QString HostList::metadata(const QString& key) const +{ + return m_metadata.value(key); +} + +int HostList::ruleCount() const +{ + return rules.size(); +} + +std::pair<UrlFilter::MatchResult, QString> HostList::match(const QUrl& firstParty, const QUrl& requestUrl, QWebEngineUrlRequestInfo::ResourceType type) const +{ + Q_UNUSED(firstParty); + Q_UNUSED(type); + + const QString domain = requestUrl.host(); + const uint domainHash = qHash(domain); + + for(const Rule &r : rules) { + if(r.domainHash == domainHash) + return std::make_pair(r.action, r.redirect); + } + + return std::make_pair(UrlFilter::NotMatched, QString()); +} + +void HostList::parseLine(const QString& line) +{ + // check comment + if(line.startsWith(QLatin1Literal("#"))) + return; + + QString parsedLine = line.trimmed(); + + // malformed rule + if(!parsedLine.contains(QLatin1Literal(" "))) + return; + + const QStringList parts = parsedLine.split(QLatin1Literal(" ")); + const QString redirect = parts.at(0); + const auto action = (redirect == QLatin1Literal("0.0.0.0")) ? UrlFilter::Block : UrlFilter::Redirect; + + for(int i = 1; i < parts.size(); i++) { + const QString domain = parts.at(i); + Rule r; + r.action = action; + r.domainHash = qHash(domain); + if(action == UrlFilter::Redirect) + r.redirect = redirect; + + rules.emplace_back(std::move(r)); + } +} + diff --git a/lib/urlfilter/hostlist/hostlist.h b/lib/urlfilter/hostlist/hostlist.h new file mode 100644 index 0000000..d4a8d87 --- /dev/null +++ b/lib/urlfilter/hostlist/hostlist.h @@ -0,0 +1,44 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_URLFILTER_HOSTLIST +#define SMOLBOTE_URLFILTER_HOSTLIST + +#include "urlfilter.h" +#include <QHash> +#include <vector> +#include <QWebEngineUrlRequestInfo> + +class QIODevice; +class HostList : public UrlFilter +{ +public: + + HostList(QIODevice *device); + ~HostList() = default; + + QString metadata(const QString &key) const override; + int ruleCount() const; + std::pair<MatchResult, QString> match(const QUrl &firstParty, const QUrl &requestUrl, QWebEngineUrlRequestInfo::ResourceType type) const override; + +protected: + void parseLine(const QString &line); + +private: + QHash<QString, QString> m_metadata; + + struct Rule { + UrlFilter::MatchResult action = UrlFilter::NotMatched; + uint domainHash; + QString redirect; + }; + + std::vector<Rule> rules; +}; + +#endif // SMOLBOTE_URLFILTER_HOSTLIST |