/******************************************************************************* ** ** smolbote: yet another qute browser ** Copyright (C) 2017 Xian Nox ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . ** ******************************************************************************/ #include "blockersubscription.h" #include "ui_subscriptionform.h" #include "browser.h" #include #include BlockerSubscription::BlockerSubscription(const QUrl url, QWidget *parent) : QWidget(parent), ui(new Ui::SubscriptionForm) { ui->setupUi(this); m_name = url.fileName(); m_url = url; QString subPath = sSettings->value("blocker.path").toString() + m_name; qDebug("Adding subscription [%s]", qUtf8Printable(subPath)); QFile *sub = new QFile(subPath); if(sub->exists()) { sub->open(QIODevice::ReadOnly); load(sub); } else { if(!url.scheme().startsWith("http")) { qWarning("Invalid url, subscription cannot be updated"); sub->deleteLater(); return; } qDebug("Subscription doesn't exist, updating..."); sub->open(QIODevice::ReadWrite); update(sub); } } BlockerSubscription::~BlockerSubscription() { delete ui; } QString BlockerSubscription::name() const { return m_name; } /** * Check if a URL request should be blocked or not * @param info * @return true if it should be blocked; false otherwise */ BlockerSubscription::MatchResult BlockerSubscription::match(QWebEngineUrlRequestInfo &info) { MatchResult result; for(auto rule : qAsConst(m_urlWhitelist)) { if(rule->match(info)) { // this request is whitelisted result.match = true; result.block = false; result.pattern = rule->filter(); return result; } } // request is not in the whitelist for(auto rule : qAsConst(m_urlBlacklist)) { if(rule->match(info)) { // this request is blacklisted result.match = true; result.block = true; result.pattern = rule->filter(); return result; } } // request matches neither whitelist nor blacklist result.match = false; result.block = false; return result; } void BlockerSubscription::update(QFile *cache) { // no cache path specified - pull the subscription QNetworkRequest request; request.setUrl(m_url); QNetworkReply *reply = sNetwork->get(request); connect(reply, &QNetworkReply::readyRead, [this, reply, cache]() { cache->write(reply->readAll()); }); connect(reply, &QNetworkReply::finished, [this, reply, cache]() { cache->write(reply->readAll()); cache->flush(); cache->seek(0); reply->deleteLater(); qDebug("Subscription updated: [%s]", qUtf8Printable(this->m_name)); this->load(cache); }); } void BlockerSubscription::load(QIODevice *dev) { QTextStream subscription(dev); QString header = subscription.readLine(); if(!header.startsWith("[Adblock Plus")) { qWarning("Invalid format of subscription: %s", qUtf8Printable(m_name)); } // clear all lists m_urlBlacklist.clear(); m_urlWhitelist.clear(); int rules = 0; while(!subscription.atEnd()) { QString line = subscription.readLine(); if(!line.isEmpty()) { if(line.startsWith('!')) { parseComment(line); } else { // The line is not empty or a comment rules++; BlockerRule *rule = new BlockerRule(line, this); if(rule->isValid()) { if(rule->isException()) { m_urlWhitelist.append(rule); ui->whitelist_listWidget->addItem(rule->filter()); } else { ui->blacklist_listWidget->addItem(rule->filter()); m_urlBlacklist.append(rule); } } } } // line.isEmpty } // subscription.atEnd() qDebug("Loaded %i/%i rules from subscription %s", m_urlBlacklist.count() + m_urlWhitelist.count(), rules, qUtf8Printable(m_name)); dev->deleteLater(); } void BlockerSubscription::parseComment(const QString &line) { if(line.startsWith("! Title: ")) { ui->title->setText(line.right(line.length() - 9)); return; } if(line.startsWith("! Homepage: ")) { ui->homepage->setText(line.right(line.length() - 12)); return; } if(line.startsWith("! Licence: ")) { ui->license->setText(line.right(line.length() - 11)); return; } if(line.startsWith("! Version: ")) { ui->version->setText(line.right(line.length() - 11)); return; } if(line.startsWith("! Last modified: ")) { ui->lastModified->setText(line.right(line.length() - 17)); return; } if(line.startsWith("! Expires: ")) { ui->expires->setText(line.right(line.length() - 11).left(2)); return; } }