aboutsummaryrefslogtreecommitdiff
path: root/lib/web/urlfilter/filterrule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/web/urlfilter/filterrule.cpp')
-rw-r--r--lib/web/urlfilter/filterrule.cpp168
1 files changed, 59 insertions, 109 deletions
diff --git a/lib/web/urlfilter/filterrule.cpp b/lib/web/urlfilter/filterrule.cpp
index 73b357b..ba2181f 100644
--- a/lib/web/urlfilter/filterrule.cpp
+++ b/lib/web/urlfilter/filterrule.cpp
@@ -1,139 +1,89 @@
#include "filterrule.h"
-#include <QWebEngineUrlRequestInfo>
-#include <QJsonArray>
-void parseJson(std::unique_ptr<FilterRule> &rule, const QJsonObject &filter)
+inline bool isMatchingDomain(const QString &domain, const QString &filter)
{
- // set action
- {
- if(!filter.value("whitelist").isUndefined()) {
- rule->setActionType(FilterRule::Whitelist);
-
- } else if(!filter.value("blacklist").isUndefined()) {
- rule->setActionType(FilterRule::Blacklist);
-
- } else if(!filter.value("redirect").isUndefined()) {
- rule->setActionType(FilterRule::Redirect);
- rule->setRedirectUrl(QUrl::fromUserInput(filter.value("redirect").toString()));
-
- } else if(!filter.value("setheader").isUndefined()) {
- rule->setActionType(FilterRule::SetHeader);
- for(const QJsonValue v : filter.value("setheader").toArray()) {
- QStringList h = v.toString().split(':');
- rule->addHeaderRule(h.at(0).toLatin1(), h.at(1).toLatin1());
- }
- }
-
+ // domain and filter are the same
+ if(domain == filter) {
+ return true;
}
- // set match type
- {
- const QJsonValue regexpValue = filter.value("regexp");
- const QJsonValue endswithValue = filter.value("endswith");
- const QJsonValue containsValue = filter.value("contains");
-
- if(!regexpValue.isUndefined()) {
- rule->setMatchType(FilterRule::RegExpMatchRule, regexpValue.toString());
-
- } else if(!endswithValue.isUndefined()) {
- rule->setMatchType(FilterRule::StringEndsMatchRule, endswithValue.toString());
-
- } else if(!containsValue.isUndefined()) {
- rule->setMatchType(FilterRule::StringContainsMatchRule, containsValue.toString());
-
- } else
- rule->setMatchType(FilterRule::MatchAllUrlsRule);
+ // domain can't be matched by filter if it doesn't end with filter
+ // ex. example2.com isn't matched by example.com
+ if(!domain.endsWith(filter)) {
+ return false;
}
-}
+ // match with subdomains
+ // ex. subdomain.example.com is matched by example.com
+ int index = domain.indexOf(filter);
-FilterRule::FilterRule(const QJsonObject &filter)
-{
- m_matcher.setCaseSensitivity(Qt::CaseInsensitive);
+ // match if (domain ends with filter) && (filter has been found) and (character before filter is '.')
+ return index > 0 && domain[index - 1] == QLatin1Char('.');
}
-void FilterRule::setActionType(ActionType type)
+bool FilterRule::isEnabled() const
{
- m_actionType = type;
+ return m_isEnabled;
}
-void FilterRule::setMatchType(MatchType type, const QString &pattern)
+bool FilterRule::matchesDomain(const QString &domain) const
{
- m_matchType = type;
- switch (type) {
- case RegExpMatchRule:
- m_regexp.setPattern(pattern);
- break;
- case StringEndsMatchRule:
- m_pattern = pattern;
- break;
- case StringContainsMatchRule:
- m_matcher.setPattern(pattern);
- default:
- break;
+ // no domains have been allowed or blocked -> allow on all domains
+ if(allowedDomains.isEmpty() && blockedDomains.isEmpty())
+ return true;
+
+ if(!blockedDomains.isEmpty()) {
+ // do not match rule if the domain has been blocked
+ if(blockedDomains.contains(domain))
+ return false;
}
-}
-void FilterRule::setRedirectUrl(const QUrl &url)
-{
- m_redirectUrl = url;
-}
+ if(!allowedDomains.isEmpty()) {
+ if(allowedDomains.contains(domain))
+ return true;
+ }
-void FilterRule::addHeaderRule(const QByteArray &header, const QByteArray &value)
-{
- m_headers.insert(header, value);
+ return false;
}
-bool FilterRule::isValid() const
+bool FilterRule::matchesType(QWebEngineUrlRequestInfo::ResourceType type) const
{
- return (m_matchType != MatchType::InvalidMatch) && (m_actionType != ActionType::InvalidAction);
+ // no options have been specified -> match all resource types
+ if(m_resourceTypeOptions.isEmpty())
+ return true;
+
+ // this resource type has not been specified -> reject it
+ if(!m_resourceTypeOptions.contains(type))
+ return false;
+
+ // resource type has been specified; true to match, false to exception
+ return m_resourceTypeOptions.value(type);
}
-bool FilterRule::process(QWebEngineUrlRequestInfo &info) const
+bool FilterRule::matchesUrl(const QUrl &url) const
{
- Q_ASSERT(m_actionType != ActionType::InvalidAction);
+ switch (urlMatchType) {
+ case InvalidMatch:
+ return false;
- if(matchRequestUrl(info.requestUrl().toString(), info.resourceType())) {
- switch (m_actionType) {
- case ActionType::Whitelist:
- info.block(false);
- return true;
- case ActionType::Blacklist:
- info.block(true);
- return true;
- case ActionType::Redirect:
- info.redirect(m_redirectUrl);
- return true;
- case ActionType::SetHeader:
- for(auto it = m_headers.constBegin(); it != m_headers.constEnd(); ++it) {
- info.setHttpHeader(it.key(), it.value());
- }
- return true;
- case ActionType::InvalidAction:
- break;
- }
- }
+ case RegularExpressionMatch:
+ if(regexp.match(url.toString()).hasMatch())
+ return !m_isException;
- return false;
-}
+ case StringContains:
+ return url.toString().contains(match);
-bool FilterRule::matchRequestUrl(const QString &requestUrl, const QWebEngineUrlRequestInfo::ResourceType type) const
-{
- Q_ASSERT(m_matchType != MatchType::InvalidMatch);
+ case StringStartsWith:
+ return url.toString().startsWith(match);
- if(!m_resourceTypeOptions.isEmpty() && !m_resourceTypeOptions.contains(type))
- return false;
+ case StringEndsWith:
+ return url.toString().endsWith(match);
+
+ case StringEquals:
+ return url.toString() == match;
+
+ case DomainMatch:
+ return isMatchingDomain(url.host(), match);
- switch (m_matchType) {
- case MatchType::RegExpMatchRule:
- return m_regexp.match(requestUrl).hasMatch();
- case MatchType::StringEndsMatchRule:
- return requestUrl.endsWith(m_pattern);
- case MatchType::StringContainsMatchRule:
- return m_matcher.indexIn(requestUrl) != -1;
- case MatchType::MatchAllUrlsRule:
- return true;
- default:
- return false;
}
}