gemini scheme handler for webengine
This commit is contained in:
parent
65bb665f92
commit
55246c6261
@ -443,6 +443,8 @@ if(NO_LITE)
|
||||
network-web/webengine/urlinterceptor.h
|
||||
network-web/webengine/webenginepage.cpp
|
||||
network-web/webengine/webenginepage.h
|
||||
network-web/gemini/geminischemehandler.cpp
|
||||
network-web/gemini/geminischemehandler.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -49,7 +49,7 @@ void Downloader::geminiFinished(const QByteArray& data, const QString& mime) {
|
||||
m_lastOutputError = QNetworkReply::NetworkError::NoError;
|
||||
m_lastOutputMultipartData = {};
|
||||
|
||||
if (mime.startsWith(QSL("text/gemini"))) {
|
||||
if (mime.startsWith(QSL(GEMINI_MIME_TYPE))) {
|
||||
m_lastOutputData = GeminiParser().geminiToHtml(data).toUtf8();
|
||||
}
|
||||
else {
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <QSslSocket>
|
||||
#include <QUrl>
|
||||
|
||||
#define GEMINI_MIME_TYPE "text/gemini"
|
||||
|
||||
//! Cryptographic user identitiy consisting
|
||||
//! of a key-certificate pair and some user information.
|
||||
struct CryptoIdentity {
|
||||
|
@ -129,7 +129,7 @@ QString GeminiParser::parseLink(const QRegularExpressionMatch& mtch) const {
|
||||
QString link = mtch.captured(1);
|
||||
QString name = mtch.captured(2);
|
||||
|
||||
return QSL("<p>🔗 <a href=\"%1\">%2</a></p>\n").arg(link, name.isEmpty() ? link : name);
|
||||
return QSL("<p>🔗 <a href=\"%1\">%2</a></p>\n").arg(link, name.isEmpty() ? link : name);
|
||||
}
|
||||
|
||||
QString GeminiParser::parseHeading(const QRegularExpressionMatch& mtch, QString* clean_header) const {
|
||||
@ -147,7 +147,7 @@ QString GeminiParser::parseHeading(const QRegularExpressionMatch& mtch, QString*
|
||||
QString GeminiParser::parseQuote(const QRegularExpressionMatch& mtch) const {
|
||||
QString text = mtch.captured(1);
|
||||
|
||||
return QSL("<div>%1</div>\n").arg(text.isEmpty() ? QString() : QSL("“%1”").arg(text));
|
||||
return QSL("<div>%1</div>\n").arg(text.isEmpty() ? QString() : QSL("“%1”").arg(text));
|
||||
}
|
||||
|
||||
QString GeminiParser::parseList(const QRegularExpressionMatch& mtch) const {
|
||||
|
89
src/librssguard/network-web/gemini/geminischemehandler.cpp
Normal file
89
src/librssguard/network-web/gemini/geminischemehandler.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#include "network-web/gemini/geminischemehandler.h"
|
||||
|
||||
#include "definitions/definitions.h"
|
||||
#include "miscellaneous/iofactory.h"
|
||||
#include "network-web/gemini/geminiparser.h"
|
||||
|
||||
#include <QBuffer>
|
||||
|
||||
GeminiSchemeHandler::GeminiSchemeHandler(QObject* parent) : QWebEngineUrlSchemeHandler(parent) {}
|
||||
|
||||
void GeminiSchemeHandler::requestStarted(QWebEngineUrlRequestJob* request) {
|
||||
GeminiClient* gemini_client = new GeminiClient(this);
|
||||
|
||||
m_jobs.insert(request, gemini_client);
|
||||
|
||||
connect(gemini_client, &GeminiClient::redirected, this, &GeminiSchemeHandler::onRedirect);
|
||||
connect(gemini_client, &GeminiClient::requestComplete, this, &GeminiSchemeHandler::onCompleted);
|
||||
connect(gemini_client, &GeminiClient::networkError, this, &GeminiSchemeHandler::onNetworkError);
|
||||
|
||||
connect(request, &QWebEngineUrlRequestJob::destroyed, this, &GeminiSchemeHandler::onJobDeleted);
|
||||
|
||||
gemini_client->startRequest(request->requestUrl(), GeminiClient::RequestOptions::IgnoreTlsErrors);
|
||||
}
|
||||
|
||||
void GeminiSchemeHandler::onRedirect(const QUrl& uri, bool is_permanent) {
|
||||
GeminiClient* gemini_client = qobject_cast<GeminiClient*>(sender());
|
||||
auto* job = m_jobs.key(gemini_client);
|
||||
|
||||
if (job != nullptr) {
|
||||
job->redirect(uri);
|
||||
m_jobs.remove(job);
|
||||
gemini_client->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void GeminiSchemeHandler::onCompleted(const QByteArray& data, const QString& mime) {
|
||||
GeminiClient* gemini_client = qobject_cast<GeminiClient*>(sender());
|
||||
auto* job = m_jobs.key(gemini_client);
|
||||
|
||||
if (job != nullptr) {
|
||||
QBuffer* buf = new QBuffer();
|
||||
QString target_mime;
|
||||
buf->open(QBuffer::ReadWrite);
|
||||
|
||||
if (mime.startsWith(QSL(GEMINI_MIME_TYPE))) {
|
||||
// IOFactory::writeFile("a", data);
|
||||
|
||||
buf->write(GeminiParser().geminiToHtml(data).toUtf8());
|
||||
target_mime = QSL("text/html");
|
||||
}
|
||||
else {
|
||||
buf->write(data);
|
||||
target_mime = mime;
|
||||
}
|
||||
|
||||
buf->seek(0);
|
||||
|
||||
connect(job, &QWebEngineUrlRequestJob::destroyed, buf, &QBuffer::deleteLater);
|
||||
job->reply(target_mime.toLocal8Bit(), buf);
|
||||
m_jobs.remove(job);
|
||||
gemini_client->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void GeminiSchemeHandler::onNetworkError(GeminiClient::NetworkError error, const QString& reason) {
|
||||
GeminiClient* gemini_client = qobject_cast<GeminiClient*>(sender());
|
||||
auto* job = m_jobs.key(gemini_client);
|
||||
|
||||
if (job != nullptr) {
|
||||
job->fail(QWebEngineUrlRequestJob::Error::RequestFailed);
|
||||
m_jobs.remove(job);
|
||||
gemini_client->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void GeminiSchemeHandler::onJobDeleted(QObject* job) {
|
||||
auto* key = qobject_cast<QWebEngineUrlRequestJob*>(job);
|
||||
auto* gemini_client = m_jobs.value(key);
|
||||
|
||||
if (gemini_client != nullptr) {
|
||||
gemini_client->deleteLater();
|
||||
}
|
||||
|
||||
if (key != nullptr) {
|
||||
m_jobs.remove(key);
|
||||
}
|
||||
}
|
28
src/librssguard/network-web/gemini/geminischemehandler.h
Normal file
28
src/librssguard/network-web/gemini/geminischemehandler.h
Normal file
@ -0,0 +1,28 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#ifndef GEMINISCHEMEHANDLER_H
|
||||
#define GEMINISCHEMEHANDLER_H
|
||||
|
||||
#include "network-web/gemini/geminiclient.h"
|
||||
|
||||
#include <QWebEngineUrlRequestJob>
|
||||
#include <QWebEngineUrlSchemeHandler>
|
||||
|
||||
class GeminiSchemeHandler : public QWebEngineUrlSchemeHandler {
|
||||
public:
|
||||
explicit GeminiSchemeHandler(QObject* parent = nullptr);
|
||||
|
||||
virtual void requestStarted(QWebEngineUrlRequestJob* request);
|
||||
|
||||
private slots:
|
||||
void onRedirect(const QUrl& uri, bool is_permanent);
|
||||
void onCompleted(const QByteArray& data, const QString& mime);
|
||||
void onNetworkError(GeminiClient::NetworkError error, const QString& reason);
|
||||
|
||||
void onJobDeleted(QObject* job);
|
||||
|
||||
private:
|
||||
QHash<QWebEngineUrlRequestJob*, GeminiClient*> m_jobs;
|
||||
};
|
||||
|
||||
#endif // GEMINISCHEMEHANDLER_H
|
@ -17,6 +17,7 @@
|
||||
#include <QUrl>
|
||||
|
||||
#if defined(NO_LITE)
|
||||
#include "network-web/gemini/geminischemehandler.h"
|
||||
#include "network-web/webengine/networkurlinterceptor.h"
|
||||
|
||||
#if QT_VERSION_MAJOR == 6
|
||||
@ -40,6 +41,16 @@ WebFactory::WebFactory(QObject* parent) : QObject(parent), m_apiServer(nullptr),
|
||||
}
|
||||
|
||||
#if defined(NO_LITE)
|
||||
|
||||
QWebEngineUrlScheme gemini_scheme("gemini");
|
||||
|
||||
gemini_scheme.setSyntax(QWebEngineUrlScheme::Syntax::Host);
|
||||
// gemini_scheme.setFlags(QWebEngineUrlScheme::Flag::SecureScheme);
|
||||
|
||||
QWebEngineUrlScheme::registerScheme(gemini_scheme);
|
||||
|
||||
m_geminiHandler = new GeminiSchemeHandler(this);
|
||||
|
||||
if (qApp->settings()->value(GROUP(Browser), SETTING(Browser::DisableCache)).toBool()) {
|
||||
qWarningNN << LOGSEC_NETWORK << "Using off-the-record WebEngine profile.";
|
||||
|
||||
@ -49,6 +60,8 @@ WebFactory::WebFactory(QObject* parent) : QObject(parent), m_apiServer(nullptr),
|
||||
m_engineProfile = new QWebEngineProfile(QSL(APP_LOW_NAME), this);
|
||||
}
|
||||
|
||||
m_engineProfile->installUrlSchemeHandler("gemini", m_geminiHandler);
|
||||
|
||||
m_engineSettings = nullptr;
|
||||
m_urlInterceptor = new NetworkUrlInterceptor(this);
|
||||
#endif
|
||||
|
@ -13,6 +13,7 @@ class QWebEngineProfile;
|
||||
class QWebEngineSettings;
|
||||
class QAction;
|
||||
class NetworkUrlInterceptor;
|
||||
class GeminiSchemeHandler;
|
||||
#endif
|
||||
|
||||
class QMenu;
|
||||
@ -92,6 +93,7 @@ class RSSGUARD_DLLSPEC WebFactory : public QObject {
|
||||
QWebEngineProfile* m_engineProfile;
|
||||
NetworkUrlInterceptor* m_urlInterceptor;
|
||||
QAction* m_engineSettings;
|
||||
GeminiSchemeHandler* m_geminiHandler;
|
||||
#endif
|
||||
|
||||
ApiServer* m_apiServer;
|
||||
|
Loading…
x
Reference in New Issue
Block a user