#include "slxbrowser.h" #include "webview.h" #include "nam.h" #include #include #include #include #include #include static QRegularExpression urlListToRegExp(const QStringList &list); SlxBrowser::SlxBrowser(BrowserSettings settings) : QMainWindow(nullptr), _settings(settings), _unsupportedUri(false), _blockedSite(false), _lastPageLoad(0), _activity(false), _lastActivity(0), _pageValid(false) { _settings.reloadInterval *= 1000; if (_settings.fullscreen) { this->showFullScreen(); this->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); } else if (_settings.maximized) { this->showMaximized(); } //QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); QWidget *w = new QWidget; QLayout *l = new QVBoxLayout; _browser = new WebView; _progress = new QProgressBar; _progress->hide(); l->addWidget(_browser); l->addWidget(_progress); l->setMargin(0); l->setSpacing(0); l->setContentsMargins(0,0,0,0); w->setContentsMargins(0,0,0,0); w->setLayout(l); this->setCentralWidget(w); _reset.setSingleShot(true); connect(&_reset, &QTimer::timeout, this, &SlxBrowser::reloadInitial); connect(_browser, &WebView::loadStarted, this, &SlxBrowser::loadStarted); connect(_browser, &WebView::loadFinished, this, &SlxBrowser::loadFinished); connect(_browser, &WebView::loadProgress, this, &SlxBrowser::loadProgress); // QWebPage *page = _browser->page(); 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, &QNetworkAccessManager::sslErrors, this, &SlxBrowser::sslErrors); connect(nam, &QNetworkAccessManager::finished, this, &SlxBrowser::requestFinished); page->setNetworkAccessManager(nam); page->mainFrame()->load(_settings.url); // _browser->show(); } SlxBrowser::~SlxBrowser() { } void SlxBrowser::loadStarted() { _pageValid = false; _reset.stop(); if (_settings.reloadInterval > 0) { _reset.start(_settings.reloadInterval + 5000); } _normalError.clear(); _sslErrors.clear(); _progress->setValue(0); _progress->show(); } void SlxBrowser::loadFinished(bool ok) { _progress->hide(); qint64 now = QDateTime::currentMSecsSinceEpoch(); bool abortedDl = _browser->wasAbortedDownload(); if (!abortedDl && !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); } 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.")); }); } else { _browser->page()->mainFrame()->setHtml("

" "

Page Load Error

" ""); 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); _pageValid = false; if (_settings.reloadInterval > 0) { _reset.start(qMin(30000, _settings.reloadInterval)); } else { _reset.start(30000); } } _sslErrors.clear(); _normalError.clear(); } else { _pageValid = true; if (_settings.reloadInterval > 0) { _reset.start(qMax(_settings.reloadInterval / 20, 1000)); } } _unsupportedUri = false; _blockedSite = false; _lastPageLoad = now; } void SlxBrowser::loadProgress(int progress) { _progress->setValue(progress); } void SlxBrowser::sslErrors(QNetworkReply* reply, const QList& errors) { if (_settings.ignoreSslErrors) { reply->ignoreSslErrors(); return; } _sslErrors.append(errors); } void SlxBrowser::requestFinished(QNetworkReply *reply) { if (reply->error() == QNetworkReply::ProtocolUnknownError) { _unsupportedUri = true; } else if (reply->error() == QNetworkReply::UnknownNetworkError) { _blockedSite = true; } else { //qDebug() << reply->error(); _normalError = reply->errorString(); } } void SlxBrowser::reloadInitial() { if (_pageValid) { if (_activity) { _lastActivity = QDateTime::currentMSecsSinceEpoch(); _activity = false; _reset.start(qMax(_settings.reloadInterval / 20, 1000)); return; } qint64 now = QDateTime::currentMSecsSinceEpoch(); if (now - qMax(_lastActivity, _lastPageLoad) > _settings.reloadInterval) { _browser->page()->mainFrame()->load(_settings.url); } else { _reset.start(qMax(_settings.reloadInterval / 20, 1000)); } } else { _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('|') + ")$"); }