#include "filterrule.h" #include #include void parseJson(std::unique_ptr &rule, const QJsonObject &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()); } } } // 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); } } FilterRule::FilterRule(const QJsonObject &filter) { m_matcher.setCaseSensitivity(Qt::CaseInsensitive); } void FilterRule::setActionType(ActionType type) { m_actionType = type; } void FilterRule::setMatchType(MatchType type, const QString &pattern) { 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; } } void FilterRule::setRedirectUrl(const QUrl &url) { m_redirectUrl = url; } void FilterRule::addHeaderRule(const QByteArray &header, const QByteArray &value) { m_headers.insert(header, value); } bool FilterRule::isValid() const { return (m_matchType != MatchType::InvalidMatch) && (m_actionType != ActionType::InvalidAction); } bool FilterRule::process(QWebEngineUrlRequestInfo &info) const { Q_ASSERT(m_actionType != ActionType::InvalidAction); 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; } } return false; } bool FilterRule::matchRequestUrl(const QString &requestUrl, const QWebEngineUrlRequestInfo::ResourceType type) const { Q_ASSERT(m_matchType != MatchType::InvalidMatch); if(!m_resourceTypeOptions.isEmpty() && !m_resourceTypeOptions.contains(type)) return false; 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; } }