summaryrefslogtreecommitdiffstats
path: root/src/slxbrowser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/slxbrowser.cpp')
-rw-r--r--src/slxbrowser.cpp290
1 files changed, 116 insertions, 174 deletions
diff --git a/src/slxbrowser.cpp b/src/slxbrowser.cpp
index 8eceea0..3bb1161 100644
--- a/src/slxbrowser.cpp
+++ b/src/slxbrowser.cpp
@@ -1,24 +1,29 @@
#include "slxbrowser.h"
#include "webview.h"
#include "nam.h"
-#include <QtWebKitWidgets>
-#include <QWebPage>
-#include <QNetworkReply>
-#include <QSslConfiguration>
+#include <QtWebEngineWidgets/QWebEngineSettings>
+#include <QtWebEngineWidgets/QWebEnginePage>
+#include <QtWebEngineWidgets/QWebEngineProfile>
+#include <QtWebEngineWidgets/QWebEngineHistory>
#include <QProgressBar>
#include <QDateTime>
+#include <QVBoxLayout>
+#include <QMessageBox>
+#include <QRegularExpression>
+#include <QDebug>
+#include <utility>
static QRegularExpression urlListToRegExp(const QStringList &list);
SlxBrowser::SlxBrowser(BrowserSettings settings)
: QMainWindow(nullptr),
- _settings(settings),
+ _settings(std::move(settings)),
_unsupportedUri(false),
- _blockedSite(false),
- _lastPageLoad(0),
- _activity(false),
- _lastActivity(0),
- _pageValid(false)
+ _blockedSite(false),
+ _lastPageLoad(0),
+ _activity(false),
+ _lastActivity(0),
+ _pageValid(false)
{
_settings.reloadInterval *= 1000;
if (_settings.zoom <= 0) {
@@ -32,16 +37,17 @@ SlxBrowser::SlxBrowser(BrowserSettings settings)
} else if (_settings.maximized) {
this->showMaximized();
}
- QWebSettings::globalSettings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
- //QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
- QWidget *w = new QWidget;
- QLayout *l = new QVBoxLayout;
- _browser = new WebView;
- _browser->setZoomFactor(float(_settings.zoom) * .01f);
- _progress = new QProgressBar;
- _progress->hide();
- l->addWidget(_browser);
- l->addWidget(_progress);
+ // Enable local storage in WebEngine
+ _browser = new WebView;
+ _browser->page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
+ _browser->setIgnoreSslErrors(_settings.ignoreSslErrors);
+ auto *w = new QWidget;
+ QLayout *l = new QVBoxLayout;
+ _browser->setZoomFactor(float(_settings.zoom) * .01f);
+ _progress = new QProgressBar;
+ _progress->hide();
+ l->addWidget(_browser);
+ l->addWidget(_progress);
l->setMargin(0);
l->setSpacing(0);
l->setContentsMargins(0,0,0,0);
@@ -52,180 +58,117 @@ SlxBrowser::SlxBrowser(BrowserSettings settings)
_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.whiteList.isEmpty() && _settings.blackList.isEmpty()) {
- nam = new QNetworkAccessManager(this);
- } else {
- if (_settings.blackList.isEmpty()) {
- _settings.blackList << "*";
- }
- // Just to be safe
- _settings.whiteList << _settings.url;
- nam = new SlxNetworkAccessManager(urlListToRegExp(_settings.blackList), urlListToRegExp(_settings.whiteList));
- }
- connect(nam, &QNetworkAccessManager::sslErrors, this, &SlxBrowser::sslErrors);
- connect(nam, &QNetworkAccessManager::finished, this, &SlxBrowser::requestFinished);
- page->setNetworkAccessManager(nam);
- page->mainFrame()->load(_settings.url);
- //
- _browser->show();
+ connect(_browser, &WebView::loadStarted, this, &SlxBrowser::loadStarted);
+ connect(_browser, &WebView::loadFinished, this, &SlxBrowser::loadFinished);
+ connect(_browser, &WebView::loadProgress, this, &SlxBrowser::loadProgress);
+ // URL filtering via interceptor
+ if (!_settings.whiteList.isEmpty() || !_settings.blackList.isEmpty()) {
+ if (_settings.blackList.isEmpty()) {
+ _settings.blackList << "*";
+ }
+ _settings.whiteList << _settings.url; // ensure initial URL allowed
+ auto *interceptor = new SlxRequestInterceptor(urlListToRegExp(_settings.blackList), urlListToRegExp(_settings.whiteList), this);
+ connect(interceptor, &SlxRequestInterceptor::urlBlocked, this, [this](const QUrl&){
+ _blockedSite = true;
+ });
+ connect(interceptor, &SlxRequestInterceptor::unsupportedScheme, this, [this](const QUrl&){
+ _unsupportedUri = true;
+ });
+ _browser->page()->profile()->setUrlRequestInterceptor(interceptor);
+ }
+ _browser->load(QUrl(_settings.url));
+ //
+ _browser->show();
}
SlxBrowser::~SlxBrowser()
-{
-}
+= default;
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();
+ _pageValid = false;
+ _reset.stop();
+ if (_settings.reloadInterval > 0) {
+ _reset.start(_settings.reloadInterval + 5000);
+ }
+ _progress->setValue(0);
+ _progress->show();
}
void SlxBrowser::maybeTriggerBack()
{
- auto elems = _browser->page()->mainFrame()->documentElement().findAll("*");
- if (elems.count() > 10)
- return;
- QStringList want{{ "HEAD", "TITLE", "H1", "HR", "A", "PRE" }};
- for (auto x : elems) {
- if (x.tagName() != want.first())
- continue;
- want.pop_front();
- if (want.isEmpty())
- break;
- }
- if (want.isEmpty()) {
- // Was probably a JS redirect, go back before displaying the error
- _browser->page()->triggerAction(QWebPage::Back);
- }
+ // Best-effort: if there is a back entry, go back
+ if (_browser->page()->history()->canGoBack())
+ _browser->back();
}
void SlxBrowser::loadFinished(bool ok)
{
- _progress->hide();
- 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) {
- maybeTriggerBack();
- QTimer::singleShot(10, [=]() {
- maybeTriggerBack();
- 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->blockSignals(true);
- _browser->page()->mainFrame()->setHtml("<html><body style='background:blue;color:white'><br><br>"
- "<center><h1>Page Load Error</h1><div id='content'></div><br>"
- "<p><a style='color:white' href='#' onclick='window.history.back()'>Back</a></p>"
- "</center></body></html>");
- _browser->blockSignals(false);
- 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.isEmpty()) {
- 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));
- }
- }
+ _progress->hide();
+ 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) {
+ maybeTriggerBack();
+ QTimer::singleShot(10, [this]() {
+ QMessageBox::warning(this, QString::fromUtf8("Denied"),
+ QString::fromUtf8("Target URL not allowed.\n\n"
+ "Dieser Link führt auf eine nicht erlaubte Seite."));
+ });
+ } else {
+ QString html = QString::fromUtf8(
+ "<html><body style='background:blue;color:white'><br><br>"
+ "<center><h1>Page Load Error</h1><div>%1</div><br>"
+ "<p><a style='color:white' href='#' onclick='history.back()'>Back</a></p>"
+ "</center></body></html>")
+ .arg(QDateTime::currentDateTime().toString());
+ _browser->setHtml(html);
+ _pageValid = false;
+ if (_settings.reloadInterval > 0) {
+ _reset.start(qMin(30000, _settings.reloadInterval));
+ } else {
+ _reset.start(30000);
+ }
+ }
+ } else {
+ _pageValid = true;
+ if (_settings.reloadInterval > 0) {
+ _reset.start(qMax(_settings.reloadInterval / 20, 1000));
+ }
+ }
_unsupportedUri = false;
- _blockedSite = false;
- _lastPageLoad = QDateTime::currentMSecsSinceEpoch();;
+ _blockedSite = false;
+ _lastPageLoad = QDateTime::currentMSecsSinceEpoch();;
}
void SlxBrowser::loadProgress(int progress)
{
- _progress->setValue(progress);
-}
-
-void SlxBrowser::sslErrors(QNetworkReply* reply, const QList<QSslError>& errors)
-{
- if (_settings.ignoreSslErrors) {
- reply->ignoreSslErrors();
- return;
- }
- for (const auto& err : errors) {
- qDebug() << "SSL:" << err;
- }
- _sslErrors.append(errors);
-}
-
-void SlxBrowser::requestFinished(QNetworkReply *reply)
-{
- if (reply->error() == QNetworkReply::ProtocolUnknownError) {
- _unsupportedUri = true;
- } else if (reply->error() == QNetworkReply::UnknownNetworkError) {
- _blockedSite = true;
- } else {
- _normalError = reply->errorString();
- if (_normalError.isEmpty()) {
- int ec = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- if (ec >= 400) {
- _normalError = QString::asprintf("HTTP ERROR %d", ec);
- }
- }
- }
+ _progress->setValue(progress);
}
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);
- }
+ 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->load(QUrl(_settings.url));
+ } else {
+ _reset.start(qMax(_settings.reloadInterval / 20, 1000));
+ }
+ } else {
+ _browser->load(QUrl(_settings.url));
+ }
}
static QRegularExpression urlListToRegExp(const QStringList &list)
@@ -233,10 +176,9 @@ 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 QRegularExpression STARSTAR(R"((^|[^\\])\\\*\\\*)");
+ static const QRegularExpression STAR(R"((^|[^\\])\\\*)");
+ static const QRegularExpression QUEST(R"((^|[^\\])\\\?)");
static const QString STARSTAR_REP("\\1.*");
static const QString STAR_REP("\\1[^/]*");
static const QString QUEST_REP("\\1.?");