// For license of this file, see /LICENSE.md. #include "network-web/gemini/geminischemehandler.h" #include "definitions/definitions.h" #include "miscellaneous/iofactory.h" #include "network-web/gemini/geminiparser.h" #include 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(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(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(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(job); auto* gemini_client = m_jobs.value(key); if (gemini_client != nullptr) { gemini_client->deleteLater(); } if (key != nullptr) { m_jobs.remove(key); } }