aboutsummaryrefslogtreecommitdiff
path: root/lib/web/urlfilter/filterrule.cpp
blob: 5a9310e6fcf0b115a9f1fb65fc9e80b7ca124c19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "filterrule.h"
#include <QWebEngineUrlRequestInfo>
#include <QJsonArray>

FilterRule::FilterRule(const QJsonObject &filter)
{
    const QString action = filter.value("action").toString();

    // there is no action specified => this rule is invalid
    if(action.isEmpty())
        return;

    if(action == "Whitelist")
        m_action = ActionType::Whitelist;
    else if (action == "Blacklist")
        m_action = ActionType::Blacklist;
    else if (action == "Redirect") {
        m_action = ActionType::Redirect;
        m_redirectUrl = QUrl::fromUserInput(filter.value("url").toString());
    } else if (action == "SetHeader")
        m_action = ActionType::SetHeader;
    else        // invalid action
        return;

    QJsonValue regexp = filter.value("regexp");
    QJsonValue endswith = filter.value("endswith");
    QJsonValue contains = filter.value("contains");

    if(!regexp.isUndefined()) {
        m_type = RuleType::RegExpMatchRule;
        this->regexp.setPattern(regexp.toString());
    } else if(!endswith.isUndefined()) {
        m_type = RuleType::StringEndsMatchRule;
        pattern = endswith.toString();
    } else if(!contains.isUndefined()) {
        m_type = RuleType::StringContainsMatchRule;
        this->matcher.setPattern(contains.toString());
        this->matcher.setCaseSensitivity(Qt::CaseInsensitive);
    } else      // invalid rule
        return;

    m_options.insert(QWebEngineUrlRequestInfo::ResourceTypeImage, true);
}

bool FilterRule::isValid() const
{
    return m_type != RuleType::Invalid;
}

bool FilterRule::process(QWebEngineUrlRequestInfo &info) const
{
    Q_ASSERT(m_type != RuleType::Invalid);

    if(matchRequestUrl(info.requestUrl().toString(), info.resourceType())) {
        switch (m_action) {
        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:
            break;
        }
    }

    return false;
}

bool FilterRule::matchRequestUrl(const QString &requestUrl, const QWebEngineUrlRequestInfo::ResourceType type) const
{
    if(!m_options.contains(type))
        return false;

    switch (m_type) {
    case RuleType::RegExpMatchRule:
        return regexp.match(requestUrl).hasMatch();
    case RuleType::StringEndsMatchRule:
        return requestUrl.endsWith(pattern);
    case RuleType::StringContainsMatchRule:
        return matcher.indexIn(requestUrl) != -1;
    default:
        return false;
    }
}