Page MenuHome GnuPG

No OneTemporary

diff --git a/client/connectioncontroller.cpp b/client/connectioncontroller.cpp
index 91deeb1..56be59d 100644
--- a/client/connectioncontroller.cpp
+++ b/client/connectioncontroller.cpp
@@ -1,83 +1,101 @@
// SPDX-FileCopyrightText: 2026 g10 code Gmbh
// SPDX-Contributor: Thomas Friedrichsmeier <thomas.friedrichsmeier@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "connectioncontroller.h"
#include "config.h"
#include "websocketclient.h"
+#include <KMessageBox>
+#include <KLocalizedString>
+
#include <QUuid>
#include <QUrl>
#include <QTimer>
using namespace Qt::StringLiterals;
ConnectionController* ConnectionController::m_instance = nullptr;
ConnectionController::ConnectionController()
: QObject()
, m_state(LocalServerStarting)
{
Q_ASSERT(m_instance == nullptr);
m_instance = this;
connect(&m_serverProcess, &QProcess::stateChanged, this, [this](QProcess::ProcessState state) {
if (state == QProcess::Running) {
m_state = LocalServerRunning;
startWebsocketClient();
} else if (state == QProcess::NotRunning) {
m_state = LocalServerFailed;
- QTimer::singleShot(1000, this, [this]() {
- startStopLocalServer();
- });
+ Q_EMIT serverProcessStatusChanged(); // for visuals
+ // This is not a state that should regularly be reached, but will happen, if the port is
+ // blocked (likely by a left-over gpgol-server process). It makes sense to offer to again,
+ // e.g. if the server had crashed, but fully automatic restarts would likely make things
+ // worse, not better (e.g. flood the tray with error messages).
+ auto res = KMessageBox::warningContinueCancel(nullptr,
+ i18n("The GpgOL/Web proxy process has exited. This usually indicates that another application "
+ "is blocking the required port, or a faulty installation. Do you want to attempt to restart "
+ "the proxy, or quit GpgOL/Web to investigate the situation?"),
+ i18n("Proxy process has exited."),
+ KGuiItem(i18nc("@button", "Restart proxy")), KStandardGuiItem::quit());
+ if (res == KMessageBox::Continue) {
+ QTimer::singleShot(0, this, [this]() {
+ startStopLocalServer();
+ });
+ } else {
+ QCoreApplication::quit();
+ }
} else if (m_state != LocalServerFailed) {
m_state = LocalServerStarting;
}
Q_EMIT serverProcessStatusChanged();
});
connect(&m_serverProcess, &QProcess::readyReadStandardError, this, [this]() {
qWarning().noquote() << m_serverProcess.readAllStandardError();
});
connect(&m_serverProcess, &QProcess::readyReadStandardOutput, this, [this]() {
qWarning().noquote() << m_serverProcess.readAllStandardOutput();
});
}
ConnectionController* ConnectionController::instance()
{
return m_instance;
}
ConnectionController::ServerProcessState ConnectionController::serverProcessState() const
{
if (!Config::self()->isLocalServer()) {
return RemoteServer;
}
return m_state;
}
void ConnectionController::startStopLocalServer()
{
if (Config::self()->isLocalServer()) {
if (m_serverProcess.state() == QProcess::NotRunning) {
WebsocketClient::self().disconnectFromProxy();
m_clientSecret = QUuid::createUuid().toString(QUuid::WithoutBraces);
const auto secretHash = QString::fromLatin1(QCryptographicHash::hash(m_clientSecret.toUtf8().data(), QCryptographicHash::Sha256).toHex());
m_serverProcess.start(u"gpgol-server"_s, QStringList{u"--singleclient="_s + secretHash});
}
} else if (m_serverProcess.state() != QProcess::NotRunning) {
m_serverProcess.kill();
}
// NOTE: state change gets signaled via the stateChanged lambda
}
void ConnectionController::startWebsocketClient()
{
WebsocketClient::self().connectToProxy(QUrl(u"wss://"_s + serverDomain() + u"/websocket"_s), m_clientSecret);
}
QString ConnectionController::serverDomain()
{
return (Config::self()->isLocalServer() ? u"localhost:5656"_s : Config::self()->remoteAddress().toString());
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Mar 13, 9:46 AM (1 d, 2 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
83/92/75c04db8600de7a8bded8cb5ae99

Event Timeline