#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) { _settings.reloadInterval *= 1000; if (_settings.fullscreen) { this->showFullScreen(); this->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); } //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() { _reset.stop(); if (_settings.reloadInterval > 0) { _reset.start(_settings.reloadInterval + 10000); } _normalError.clear(); _sslErrors.clear(); _progress->setValue(0); _progress->show(); } void SLXbrowser::loadFinished(bool ok) { _progress->hide(); 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); } 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("

" "

Zugriff verweigert

" "

Diese URL wurde gefiltert.
" "Zurück

" ""); */ } 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); } _sslErrors.clear(); _normalError.clear(); _reset.start(qMin(30000, _settings.reloadInterval > 0 ? _settings.reloadInterval : 30000)); } else if (_settings.reloadInterval > 0) { _reset.start(_settings.reloadInterval); } _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() { _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('|') + ")$"); }