diff options
Diffstat (limited to 'src/slxbrowser.cpp')
-rw-r--r-- | src/slxbrowser.cpp | 149 |
1 files changed, 110 insertions, 39 deletions
diff --git a/src/slxbrowser.cpp b/src/slxbrowser.cpp index 0690102..5ffe281 100644 --- a/src/slxbrowser.cpp +++ b/src/slxbrowser.cpp @@ -1,19 +1,24 @@ #include "slxbrowser.h" #include "webview.h" +#include "nam.h" #include <QtWebKitWidgets> #include <QWebPage> #include <QNetworkReply> #include <QSslConfiguration> #include <QProgressBar> +#include <QDateTime> -SLXbrowser::SLXbrowser(QString url, bool fullscreen, bool ignoreSslErrors, int reloadIntervalSeconds) +static QRegularExpression urlListToRegExp(const QStringList &list); + +SLXbrowser::SLXbrowser(BrowserSettings settings) : QMainWindow(nullptr), - _url(url), - _ignoreSslErrors(ignoreSslErrors), + _settings(settings), _unsupportedUri(false), - _reloadIntervalMs(reloadIntervalSeconds * 1000) + _blockedSite(false), + _lastPageLoad(0) { - if (fullscreen) { + _settings.reloadInterval *= 1000; + if (_settings.fullscreen) { this->showFullScreen(); this->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); } @@ -40,12 +45,21 @@ SLXbrowser::SLXbrowser(QString url, bool fullscreen, bool ignoreSslErrors, int r connect(_browser, SIGNAL(loadProgress(int)), this, SLOT(loadProgress(int))); // QWebPage *page = _browser->page(); - QNetworkAccessManager *nam = new QNetworkAccessManager(this); + QNetworkAccessManager *nam; + if (_settings.urlList.isEmpty()) { + nam = new QNetworkAccessManager(this); + } else { + if (_settings.isWhitelist) { + // Just to be safe + _settings.urlList << _settings.url; + } + nam = new SlxNetworkAccessManager(urlListToRegExp(_settings.urlList), _settings.isWhitelist); + } connect(nam, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(sslErrors(QNetworkReply*, const QList<QSslError>&))); connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*))); page->setNetworkAccessManager(nam); - page->mainFrame()->load(url); + page->mainFrame()->load(_settings.url); // _browser->show(); } @@ -57,8 +71,8 @@ SLXbrowser::~SLXbrowser() void SLXbrowser::loadStarted() { _reset.stop(); - if (_reloadIntervalMs > 0) { - _reset.start(_reloadIntervalMs + 10000); + if (_settings.reloadInterval > 0) { + _reset.start(_settings.reloadInterval + 10000); } _normalError.clear(); _sslErrors.clear(); @@ -69,37 +83,63 @@ void SLXbrowser::loadStarted() void SLXbrowser::loadFinished(bool ok) { _progress->hide(); - if (!_browser->wasAbortedDownload() && !_unsupportedUri && !ok) { - _browser->page()->mainFrame()->setHtml("<html><body style='background:blue;color:white'><br><br><center><h1>Page Load Error</h1><pre id='content'></pre></body></html>"); - QWebElement el = _browser->page()->mainFrame()->documentElement().findFirst("#content"); - QString str; - if (!_sslErrors.empty()) { - str.append("SSL Errors:\n"); - for (QSslError err : _sslErrors) { - str.append(err.errorString()); - str.append('\n'); + qint64 now = QDateTime::currentMSecsSinceEpoch(); + if (!_browser->wasAbortedDownload() && !ok) { + + if (_unsupportedUri) { + QMessageBox::warning(this, QString::fromUtf8("Denied"), + QString::fromUtf8("This URL type is not supported.\n\n" + "Diese Art Link wird nicht unterstützt.\n\n" + "(z.B. Mail)")); + } else if (_blockedSite) { + int numElems = _browser->page()->mainFrame()->documentElement().findAll("*").count(); + if (now - _lastPageLoad < 500 && numElems < 15) { + // Was probably a JS redirect, go back before displaying the error + _browser->page()->triggerAction(QWebPage::Back); } - } else if (_normalError.length() != 0) { - str.append("Load Error:\n"); - str.append(_normalError); + QTimer::singleShot(5, [=]() { + QMessageBox::warning(this, QString::fromUtf8("Denied"), + QString::fromUtf8("Target URL not allowed.\n\n" + "Dieser Link führt auf eine nicht erlaubte Seite.")); + }); + /* + _browser->page()->mainFrame()->setHtml("<html><body style='background:white;color:black'><br><br>" + "<center><h1>Zugriff verweigert</h1>" + "<p>Diese URL wurde gefiltert.<br>" + "<a href='javascript:window.history.back()'>Zurück</a></p></center>" + "</body></html>"); + */ } else { - str.append("Unknown Error"); + _browser->page()->mainFrame()->setHtml("<html><body style='background:blue;color:white'><br><br>" + "<center><h1>Page Load Error</h1><pre id='content'></pre></center>" + "</body></html>"); + QWebElement el = _browser->page()->mainFrame()->documentElement().findFirst("#content"); + QString str; + if (!_sslErrors.empty()) { + str.append("SSL Errors:\n"); + for (QSslError err : _sslErrors) { + str.append(err.errorString()); + str.append('\n'); + } + } else if (_normalError.length() != 0) { + str.append("Load Error:\n"); + str.append(_normalError); + } else { + str.append("Unknown Error"); + } + str.append("\n\n\n\n" + QDateTime::currentDateTime().toString()); + el.setPlainText(str); } - str.append("\n\n\n\n" + QDateTime::currentDateTime().toString()); - el.setPlainText(str); _sslErrors.clear(); _normalError.clear(); - _reset.start(30000); - } else if (_reloadIntervalMs > 0) { - _reset.start(_reloadIntervalMs); + _reset.start(qMin(30000, _settings.reloadInterval > 0 ? _settings.reloadInterval : 30000)); + } else if (_settings.reloadInterval > 0) { + _reset.start(_settings.reloadInterval); } - if (_unsupportedUri && !ok) { - QMessageBox::warning(this, QString::fromUtf8("Denied"), - QString::fromUtf8("This URL type is not supported.\n\n" - "Diese Art Link wird nicht unterstützt.\n\n" - "(z.B. Mail)")); - } + _unsupportedUri = false; + _blockedSite = false; + _lastPageLoad = now; } void SLXbrowser::loadProgress(int progress) @@ -109,7 +149,7 @@ void SLXbrowser::loadProgress(int progress) void SLXbrowser::sslErrors(QNetworkReply* reply, const QList<QSslError>& errors) { - if (_ignoreSslErrors) { + if (_settings.ignoreSslErrors) { reply->ignoreSslErrors(); return; } @@ -118,17 +158,48 @@ void SLXbrowser::sslErrors(QNetworkReply* reply, const QList<QSslError>& errors) void SLXbrowser::requestFinished(QNetworkReply *reply) { - if (reply->error() == QNetworkReply::NoError) { - _unsupportedUri = false; - } else if (reply->error() == QNetworkReply::ProtocolUnknownError) { + if (reply->error() == QNetworkReply::ProtocolUnknownError) { _unsupportedUri = true; + } else if (reply->error() == QNetworkReply::UnknownNetworkError) { + _blockedSite = true; } else { - qDebug() << reply->error(); + //qDebug() << reply->error(); _normalError = reply->errorString(); } } void SLXbrowser::reloadInitial() { - _browser->page()->mainFrame()->load(_url); + _browser->page()->mainFrame()->load(_settings.url); +} + +static QRegularExpression urlListToRegExp(const QStringList &list) +{ + // We search in the escaped string, so actually look for \*\* and \* + // Capture char before that because it must not be another backslash, as that + // means the star was already escaped in the list. + // Since these are C strings there are some additional backslashes here. + static const QRegularExpression STARSTAR("(^|[^\\\\])\\\\\\*\\\\\\*"); + static const QRegularExpression STAR("(^|[^\\\\])\\\\\\*"); + static const QRegularExpression QUEST("(^|[^\\\\])\\\\\\?"); + static const QString STARSTAR_REP("\\1.*"); + static const QString STAR_REP("\\1[^/]*"); + static const QString QUEST_REP("\\1.?"); + QStringList regexes; // All my regex's live in Regtexas + for (const QString &str : list) { + QString mangled; + if (str.contains(QLatin1String("//"))) { + mangled = str; + } else if (str.contains(QLatin1Char('/')) || str.contains(QLatin1String("**"))) { + mangled = "*//" + str; + } else { + mangled = "*//" + str + "/**"; + } + mangled = QRegularExpression::escape(mangled); + mangled = mangled.replace(STARSTAR, STARSTAR_REP).replace(STAR, STAR_REP) + .replace(QUEST, QUEST_REP); + regexes << mangled; + } + qDebug() << regexes; + return QRegularExpression("^(" + regexes.join('|') + ")$"); } |