From 9740e7557a6cae28261d6a520c08ab6b25ee145a Mon Sep 17 00:00:00 2001 From: aiamnezia Date: Wed, 31 Dec 2025 18:48:57 +0400 Subject: [PATCH] feat: add dynamic local proxy lifecycle in depence of settings --- client/core/controllers/coreController.cpp | 39 ++++++++++++++++--- client/core/controllers/coreController.h | 1 - client/core/local-proxy/proxyserver.cpp | 29 +++++++++++++- client/core/local-proxy/proxyserver.h | 2 + .../ui/qml/Pages2/PageSettingsLocalProxy.qml | 15 ++----- 5 files changed, 67 insertions(+), 19 deletions(-) diff --git a/client/core/controllers/coreController.cpp b/client/core/controllers/coreController.cpp index f12dc8bf1..0e3cdd106 100644 --- a/client/core/controllers/coreController.cpp +++ b/client/core/controllers/coreController.cpp @@ -1,6 +1,7 @@ #include "coreController.h" #include +#include #include #include @@ -36,13 +37,39 @@ CoreController::CoreController(const QSharedPointer &vpnConnectio void CoreController::initLocalProxy() { #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) - // Logger and proxy initialization - ProxyLogger::getInstance().init(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/logs/proxy.log"); - ProxyLogger::getInstance().setLogLevel(ProxyLogger::LogLevel::Info); - m_proxyServer.reset(new ProxyServer(this)); - const quint16 proxyPort = 49490; - m_proxyServer->start(proxyPort); + + auto syncLocalProxy = [this]() { + if (!m_proxyServer) { + return; + } + + const bool httpEnabled = m_settings->isLocalProxyHttpEnabled(); + const quint16 port = m_settings->localProxyPort(); + + if (!httpEnabled) { + qInfo() << "Local proxy: HTTP API disabled"; + m_proxyServer->stop(); + return; + } + + if (port < 1024) { + qWarning() << "Local proxy: invalid HTTP API port" << port << ", stopping server"; + m_proxyServer->stop(); + return; + } + + if (!m_proxyServer->start(port)) { + qWarning() << "Local proxy: failed to start on port" << port; + return; + } + + qInfo() << "Local proxy: running on 127.0.0.1:" << port; + }; + + syncLocalProxy(); + + connect(m_settings.get(), &Settings::localProxySettingsChanged, this, syncLocalProxy); #endif } diff --git a/client/core/controllers/coreController.h b/client/core/controllers/coreController.h index 9da66b60c..d88b16a30 100644 --- a/client/core/controllers/coreController.h +++ b/client/core/controllers/coreController.h @@ -52,7 +52,6 @@ #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) #include "core/local-proxy/proxyserver.h" -#include "core/local-proxy/proxylogger.h" #include "ui/notificationhandler.h" #endif diff --git a/client/core/local-proxy/proxyserver.cpp b/client/core/local-proxy/proxyserver.cpp index b7f8a8d40..30e205161 100644 --- a/client/core/local-proxy/proxyserver.cpp +++ b/client/core/local-proxy/proxyserver.cpp @@ -5,11 +5,19 @@ #include #include #include +#include +#include + +#include "proxylogger.h" ProxyServer::ProxyServer(QObject *parent) : QObject(parent) , m_service(new ProxyService(this)) { + const QString logDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/logs"; + ProxyLogger::getInstance().init(logDir + "/proxy.log"); + ProxyLogger::getInstance().setLogLevel(ProxyLogger::LogLevel::Info); + connect(m_service.data(), &ProxyService::configsChanged, this, &ProxyServer::startXrayProcess); } @@ -20,10 +28,23 @@ ProxyServer::~ProxyServer() bool ProxyServer::start(quint16 port) { + if (m_isRunning) { + if (m_currentPort == port) { + qInfo() << "Local proxy: already running on port" << port; + return true; + } + + qInfo() << "Local proxy: restarting on new port" << port; + stop(); + } + m_api.reset(new HttpApi(m_service.toWeakRef())); - bool apiStarted = m_api->start(port); + const bool apiStarted = m_api->start(port); if (!apiStarted) { qWarning() << "Local proxy: port is busy:" << port; + m_api.reset(); + m_isRunning = false; + m_currentPort = 0; return false; } @@ -35,6 +56,9 @@ bool ProxyServer::start(quint16 port) qDebug() << "No config found, Xray will not start automatically"; } + m_isRunning = true; + m_currentPort = port; + return true; } @@ -43,7 +67,10 @@ void ProxyServer::stop() stopXrayProcess(); if (m_api) { m_api->stop(); + m_api.reset(); } + m_isRunning = false; + m_currentPort = 0; } bool ProxyServer::startXrayProcess() diff --git a/client/core/local-proxy/proxyserver.h b/client/core/local-proxy/proxyserver.h index 0419058fa..520e1ce0e 100644 --- a/client/core/local-proxy/proxyserver.h +++ b/client/core/local-proxy/proxyserver.h @@ -23,4 +23,6 @@ private: QScopedPointer m_api; QSharedPointer m_service; + bool m_isRunning {false}; + quint16 m_currentPort {0}; }; \ No newline at end of file diff --git a/client/ui/qml/Pages2/PageSettingsLocalProxy.qml b/client/ui/qml/Pages2/PageSettingsLocalProxy.qml index e87326d86..5b7249161 100644 --- a/client/ui/qml/Pages2/PageSettingsLocalProxy.qml +++ b/client/ui/qml/Pages2/PageSettingsLocalProxy.qml @@ -114,9 +114,13 @@ PageType { PageController.showNotificationMessage(qsTr("Failed to enable local proxy. Check the port (%1-%2).") .arg(root.localProxyPortMin) .arg(root.localProxyPortMax)) + localProxySwitch.syncState() + return } + localProxySwitch.syncState() } else { SettingsController.disableLocalProxy() + localProxySwitch.syncState() } } } @@ -192,16 +196,5 @@ PageType { } } } - - Connections { - target: ServersModel - - function onProcessedServerChanged() { - localProxySwitch.syncState() - if (!portField.textField.activeFocus) { - portField.syncPortValue() - } - } - } }