diff options
Diffstat (limited to 'src/adblock')
| -rw-r--r-- | src/adblock/adblockmanager.cpp | 53 | ||||
| -rw-r--r-- | src/adblock/adblockmanager.h | 11 | ||||
| -rw-r--r-- | src/adblock/adblocknetworkreply.cpp | 88 | ||||
| -rw-r--r-- | src/adblock/adblocknetworkreply.h | 81 | ||||
| -rw-r--r-- | src/adblock/adblockrule.cpp | 173 | ||||
| -rw-r--r-- | src/adblock/adblockrule.h | 83 | 
6 files changed, 484 insertions, 5 deletions
diff --git a/src/adblock/adblockmanager.cpp b/src/adblock/adblockmanager.cpp index b25edcb1..209c2ab0 100644 --- a/src/adblock/adblockmanager.cpp +++ b/src/adblock/adblockmanager.cpp @@ -24,9 +24,12 @@  * ============================================================ */ +// Self Includes  #include "adblockmanager.h"  #include "adblockmanager.moc" +// Local Includes +#include "adblocknetworkreply.h"  // KDE Includes  #include <KSharedConfig> @@ -53,10 +56,56 @@ AdBlockManager::~AdBlockManager()  void AdBlockManager::loadSettings()  { +    KSharedConfig::Ptr config = KSharedConfig::openConfig("khtmlrc", KConfig::NoGlobals); +    KConfigGroup cg( config, "Filter Settings" ); + +    if ( cg.exists() ) +    { +        _isAdblockEnabled = cg.readEntry("Enabled", false); +        _isHideAdsEnabled = cg.readEntry("Shrink", false); + +        filterList.clear(); +         +        // no need to load filters if adblock is not enabled :) +        if(!_isAdblockEnabled) +            return; +         +        QMap<QString,QString> entryMap = cg.entryMap(); +        QMap<QString,QString>::ConstIterator it; +        for( it = entryMap.constBegin(); it != entryMap.constEnd(); ++it ) +        { +            QString name = it.key(); +            QString url = it.value(); + +            if (name.startsWith(QLatin1String("Filter"))) +            { +                AdBlockRule filter(url); +                filterList << filter; +            } +        } +    }  } -bool AdBlockManager::isUrlAllowed(const QUrl &url) +QNetworkReply *AdBlockManager::block(const QNetworkRequest &request)  { -    return true; +    if (!_isAdblockEnabled) +        return 0; +     +    // we (ad)block just http traffic +    if(request.url().scheme() != QLatin1String("http")) +        return 0; +     +    QString urlString = request.url().toString(); + +    foreach(const AdBlockRule &filter, filterList) +    { +        if(filter.match(urlString)) +        { +            kDebug() << "****ADBLOCK: Matched: ***********" << urlString; +            AdBlockNetworkReply *reply = new AdBlockNetworkReply(request, urlString, this); +            return reply;         +        } +    } +    return 0;  } diff --git a/src/adblock/adblockmanager.h b/src/adblock/adblockmanager.h index 10f72366..499a0cde 100644 --- a/src/adblock/adblockmanager.h +++ b/src/adblock/adblockmanager.h @@ -28,13 +28,16 @@  #ifndef ADBLOCK_MANAGER_H  #define ADBLOCK_MANAGER_H +// Local Includes +#include "adblockrule.h" +typedef QList<AdBlockRule> AdBlockRuleList;  // Qt Includes  #include <QObject> -#include <QStringList> +#include <QNetworkReply>  // Forward Includes -class QUrl; +class QNetworkRequest;  class AdBlockManager : public QObject @@ -46,11 +49,13 @@ public:      ~AdBlockManager();      void loadSettings(); -    bool isUrlAllowed(const QUrl &url); +    QNetworkReply *block(const QNetworkRequest &request);  private:      bool _isAdblockEnabled;      bool _isHideAdsEnabled; + +    AdBlockRuleList filterList;  };  #endif diff --git a/src/adblock/adblocknetworkreply.cpp b/src/adblock/adblocknetworkreply.cpp new file mode 100644 index 00000000..1ccca96d --- /dev/null +++ b/src/adblock/adblocknetworkreply.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com> + * + * + * 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 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy  + * defined in Section 14 of version 3 of the license. + *  + * 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 <http://www.gnu.org/licenses/>. + * + * ============================================================ */ + + +// Self Includes +#include "adblocknetworkreply.h" +#include "adblocknetworkreply.moc" + +// KDE Includes +#include <klocalizedstring.h> + +// Qt Includes +#include <QNetworkRequest> +#include <QTimer> + + +AdBlockNetworkReply::AdBlockNetworkReply(const QNetworkRequest &request, const QString &urlString, QObject *parent) +    : QNetworkReply(parent) +{ +    setOperation(QNetworkAccessManager::GetOperation); +    setRequest(request); +    setUrl(request.url()); +    setError(QNetworkReply::ContentAccessDenied, i18n("Blocked by AdBlockRule: %1").arg(urlString)); +    QTimer::singleShot(0, this, SLOT(delayedFinished())); +} + + +qint64 AdBlockNetworkReply::readData(char *data, qint64 maxSize) +{ +    Q_UNUSED(data); +    Q_UNUSED(maxSize); +    return -1; +} + + +void AdBlockNetworkReply::delayedFinished() +{ +    emit error(QNetworkReply::ContentAccessDenied); +    emit finished(); +} diff --git a/src/adblock/adblocknetworkreply.h b/src/adblock/adblocknetworkreply.h new file mode 100644 index 00000000..b5bb8300 --- /dev/null +++ b/src/adblock/adblocknetworkreply.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com> + * + * + * 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 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy  + * defined in Section 14 of version 3 of the license. + *  + * 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 <http://www.gnu.org/licenses/>. + * + * ============================================================ */ + + +#ifndef ADBLOCK_NETWORK_REPLY_H +#define ADBLOCK_NETWORK_REPLY_H + + +// Qt Includes +#include <QNetworkReply> +#include <QString> + +// Forward Declarations +class AdBlockRule; + + +class AdBlockNetworkReply : public QNetworkReply +{ +    Q_OBJECT + +public: +    AdBlockNetworkReply(const QNetworkRequest &request, const QString &urlString, QObject *parent = 0); +    void abort() {}; + +protected: +    qint64 readData(char *data, qint64 maxSize); + +private slots: +    void delayedFinished(); + +}; + +#endif // ADBLOCKBLOCKEDNETWORKREPLY_H diff --git a/src/adblock/adblockrule.cpp b/src/adblock/adblockrule.cpp new file mode 100644 index 00000000..870ad825 --- /dev/null +++ b/src/adblock/adblockrule.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2009, Zsombor Gegesy <gzsombor@gmail.com> + * Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com> + * + * + * 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 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy  + * defined in Section 14 of version 3 of the license. + *  + * 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 <http://www.gnu.org/licenses/>. + * + * ============================================================ */ + + +#include "adblockrule.h" + +#include <QDebug> +#include <QRegExp> +#include <QUrl> + + +AdBlockRule::AdBlockRule(const QString &filter) +    : m_cssRule(false) +    , m_exceptionRule(false) +    , m_enabledRule(true) +{ +    bool isRegExpRule = false; + +    if (filter.startsWith(QLatin1String("!")) || filter.trimmed().isEmpty()) +        m_enabledRule = false; + +    if (filter.contains(QLatin1String("##"))) +        m_cssRule = true; + +    QString parsedLine = filter; +    if (parsedLine.startsWith(QLatin1String("@@")))  +    { +        m_exceptionRule = true; +        parsedLine = parsedLine.mid(2); +    } +     +    if (parsedLine.startsWith(QLatin1Char('/')))  +    { +        if (parsedLine.endsWith(QLatin1Char('/')))  +        { +            parsedLine = parsedLine.mid(1); +            parsedLine = parsedLine.left(parsedLine.size() - 1); +            isRegExpRule = true; +        } +    } +     +    int options = parsedLine.indexOf(QLatin1String("$"), 0); +    if (options >= 0)  +    { +        m_options = parsedLine.mid(options + 1).split(QLatin1Char(',')); +        parsedLine = parsedLine.left(options); +    } + +    if(!isRegExpRule) +        parsedLine = convertPatternToRegExp(parsedLine); +    m_regExp = QRegExp(parsedLine, Qt::CaseInsensitive, QRegExp::RegExp2); + +    if (m_options.contains(QLatin1String("match-case")))  +    { +        m_regExp.setCaseSensitivity(Qt::CaseSensitive); +        m_options.removeOne(QLatin1String("match-case")); +    } +} + + +// here return false means that rule doesn't match, +// so that url is allowed +// return true means "matched rule", so stop url! +bool AdBlockRule::match(const QString &encodedUrl) const +{ +    if (m_cssRule) +        return false; + +    if (!m_enabledRule) +        return false; + +    bool matched = m_regExp.indexIn(encodedUrl) != -1; + +    if (matched && !m_options.isEmpty())  +    { +        // we only support domain right now +        if (m_options.count() == 1) +        { +            foreach (const QString &option, m_options)  +            { +                if (option.startsWith(QLatin1String("domain=")))  +                { +                    QUrl url = QUrl::fromEncoded(encodedUrl.toUtf8()); +                    QString host = url.host(); +                    QStringList domainOptions = option.mid(7).split(QLatin1Char('|')); +                    foreach (QString domainOption, domainOptions)  +                    { +                        bool negate = domainOption.at(0) == QLatin1Char('~'); +                        if (negate) +                            domainOption = domainOption.mid(1); +                        bool hostMatched = domainOption == host; +                        if (hostMatched && !negate) +                            return true; +                        if (!hostMatched && negate) +                            return true; +                    } +                } +            } +        } +        return false; +    } + +    return matched; +} + + +QString AdBlockRule::convertPatternToRegExp(const QString &wildcardPattern) +{ +    QString pattern = wildcardPattern; +    return pattern.replace(QRegExp(QLatin1String("\\*+")), QLatin1String("*"))   // remove multiple wildcards +        .replace(QRegExp(QLatin1String("\\^\\|$")), QLatin1String("^"))        // remove anchors following separator placeholder +        .replace(QRegExp(QLatin1String("^(\\*)")), QLatin1String(""))          // remove leading wildcards +        .replace(QRegExp(QLatin1String("(\\*)$")), QLatin1String(""))          // remove trailing wildcards +        .replace(QRegExp(QLatin1String("(\\W)")), QLatin1String("\\\\1"))      // escape special symbols +        .replace(QRegExp(QLatin1String("^\\\\\\|\\\\\\|")), +                 QLatin1String("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?"))       // process extended anchor at expression start +        .replace(QRegExp(QLatin1String("\\\\\\^")), +                 QLatin1String("(?:[^\\w\\d\\-.%]|$)"))                        // process separator placeholders +        .replace(QRegExp(QLatin1String("^\\\\\\|")), QLatin1String("^"))       // process anchor at expression start +        .replace(QRegExp(QLatin1String("\\\\\\|$")), QLatin1String("$"))       // process anchor at expression end +        .replace(QRegExp(QLatin1String("\\\\\\*")), QLatin1String(".*"))       // replace wildcards by .* +        ; +} diff --git a/src/adblock/adblockrule.h b/src/adblock/adblockrule.h new file mode 100644 index 00000000..8680942f --- /dev/null +++ b/src/adblock/adblockrule.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com> + * + * + * 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 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy  + * defined in Section 14 of version 3 of the license. + *  + * 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 <http://www.gnu.org/licenses/>. + * + * ============================================================ */ + + +#ifndef ADBLOCKRULE_H +#define ADBLOCKRULE_H + +// Qt Includes +#include <QStringList> + +// Forward Includes +class QUrl; +class QRegExp; + + +class AdBlockRule +{ +public: +    AdBlockRule(const QString &filter); + +    bool match(const QString &encodedUrl) const; + +private:     +    QString convertPatternToRegExp(const QString &wildcardPattern); +     +    bool m_cssRule; +    bool m_exceptionRule; +    bool m_enabledRule; +    QRegExp m_regExp; +    QStringList m_options; +}; + + +#endif // ADBLOCKRULE_H  | 
