Refine environment variable scope

Previously the proxy environment variable will affect the qbt process globally. Now it is
limited to where it required.
This commit is contained in:
Chocobo1 2025-03-22 04:47:46 +08:00
commit 943e403241
No known key found for this signature in database
GPG key ID: 210D9C873253A68C
4 changed files with 55 additions and 43 deletions

View file

@ -41,7 +41,7 @@ SearchDownloadHandler::SearchDownloadHandler(const QString &pluginName, const QS
, m_manager {manager}
, m_downloadProcess {new QProcess(this)}
{
m_downloadProcess->setEnvironment(QProcess::systemEnvironment());
m_downloadProcess->setProcessEnvironment(m_manager->proxyEnvironment());
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
m_downloadProcess->setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors);
#endif

View file

@ -70,7 +70,7 @@ SearchHandler::SearchHandler(const QString &pattern, const QString &category, co
, m_searchTimeout {new QTimer(this)}
{
// Load environment variables (proxy)
m_searchProcess->setEnvironment(QProcess::systemEnvironment());
m_searchProcess->setProcessEnvironment(m_manager->proxyEnvironment());
m_searchProcess->setProgram(Utils::ForeignApps::pythonInfo().executableName);
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
m_searchProcess->setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors);

View file

@ -88,6 +88,7 @@ QPointer<SearchPluginManager> SearchPluginManager::m_instance = nullptr;
SearchPluginManager::SearchPluginManager()
: m_updateUrl(u"https://searchplugins.qbittorrent.org/nova3/engines/"_s)
, m_proxyEnv {QProcessEnvironment::systemEnvironment()}
{
Q_ASSERT(!m_instance); // only one instance is allowed
m_instance = this;
@ -362,6 +363,11 @@ SearchHandler *SearchPluginManager::startSearch(const QString &pattern, const QS
return new SearchHandler(pattern, category, usedPlugins, this);
}
QProcessEnvironment SearchPluginManager::proxyEnvironment() const
{
return m_proxyEnv;
}
QString SearchPluginManager::categoryFullName(const QString &categoryName)
{
const QHash<QString, QString> categoryTable
@ -403,50 +409,52 @@ Path SearchPluginManager::engineLocation()
void SearchPluginManager::applyProxySettings()
{
const auto *proxyManager = Net::ProxyConfigurationManager::instance();
const Net::ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration();
// Define environment variables for urllib in search engine plugins
QString proxyStrHTTP, proxyStrSOCK;
if ((proxyConfig.type != Net::ProxyType::None) && Preferences::instance()->useProxyForGeneralPurposes())
const QString HTTP_PROXY = u"http_proxy"_s;
const QString HTTPS_PROXY = u"https_proxy"_s;
const QString SOCKS_PROXY = u"sock_proxy"_s;
if (!Preferences::instance()->useProxyForGeneralPurposes())
{
m_proxyEnv.remove(HTTP_PROXY);
m_proxyEnv.remove(HTTPS_PROXY);
m_proxyEnv.remove(SOCKS_PROXY);
return;
}
const Net::ProxyConfiguration proxyConfig = Net::ProxyConfigurationManager::instance()->proxyConfiguration();
switch (proxyConfig.type)
{
case Net::ProxyType::None:
case Net::ProxyType::SOCKS4: // TODO: implement python code
m_proxyEnv.remove(HTTP_PROXY);
m_proxyEnv.remove(HTTPS_PROXY);
m_proxyEnv.remove(SOCKS_PROXY);
break;
case Net::ProxyType::HTTP:
if (proxyConfig.authEnabled)
{
proxyStrHTTP = u"http://%1:%2@%3:%4"_s.arg(proxyConfig.username
, proxyConfig.password, proxyConfig.ip, QString::number(proxyConfig.port));
}
else
{
proxyStrHTTP = u"http://%1:%2"_s.arg(proxyConfig.ip, QString::number(proxyConfig.port));
const QString proxyURL = proxyConfig.authEnabled
? u"http://%1:%2@%3:%4"_s.arg(proxyConfig.username, proxyConfig.password, proxyConfig.ip, QString::number(proxyConfig.port))
: u"http://%1:%2"_s.arg(proxyConfig.ip, QString::number(proxyConfig.port));
m_proxyEnv.insert(HTTP_PROXY, proxyURL);
m_proxyEnv.insert(HTTPS_PROXY, proxyURL);
m_proxyEnv.remove(SOCKS_PROXY);
}
break;
case Net::ProxyType::SOCKS5:
if (proxyConfig.authEnabled)
{
proxyStrSOCK = u"%1:%2@%3:%4"_s.arg(proxyConfig.username
, proxyConfig.password, proxyConfig.ip, QString::number(proxyConfig.port));
}
else
{
proxyStrSOCK = u"%1:%2"_s.arg(proxyConfig.ip, QString::number(proxyConfig.port));
const QString proxyURL = proxyConfig.authEnabled
? u"%1:%2@%3:%4"_s.arg(proxyConfig.username, proxyConfig.password, proxyConfig.ip, QString::number(proxyConfig.port))
: u"%1:%2"_s.arg(proxyConfig.ip, QString::number(proxyConfig.port));
m_proxyEnv.remove(HTTP_PROXY);
m_proxyEnv.remove(HTTPS_PROXY);
m_proxyEnv.insert(SOCKS_PROXY, proxyURL);
}
break;
default:
qDebug("Disabling HTTP communications proxy");
}
qDebug("HTTP communications proxy string: %s"
, qUtf8Printable((proxyConfig.type == Net::ProxyType::SOCKS5) ? proxyStrSOCK : proxyStrHTTP));
}
qputenv("http_proxy", proxyStrHTTP.toLocal8Bit());
qputenv("https_proxy", proxyStrHTTP.toLocal8Bit());
qputenv("sock_proxy", proxyStrSOCK.toLocal8Bit());
}
void SearchPluginManager::versionInfoDownloadFinished(const Net::DownloadResult &result)
@ -519,7 +527,7 @@ void SearchPluginManager::updateNova()
void SearchPluginManager::update()
{
QProcess nova;
nova.setProcessEnvironment(QProcessEnvironment::systemEnvironment());
nova.setProcessEnvironment(proxyEnvironment());
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
nova.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors);
#endif

View file

@ -32,6 +32,7 @@
#include <QHash>
#include <QMetaType>
#include <QObject>
#include <QProcessEnvironment>
#include "base/path.h"
#include "base/utils/version.h"
@ -87,6 +88,8 @@ public:
SearchHandler *startSearch(const QString &pattern, const QString &category, const QStringList &usedPlugins);
SearchDownloadHandler *downloadTorrent(const QString &pluginName, const QString &url);
QProcessEnvironment proxyEnvironment() const;
static PluginVersion getPluginVersion(const Path &filePath);
static QString categoryFullName(const QString &categoryName);
QString pluginFullName(const QString &pluginName) const;
@ -122,4 +125,5 @@ private:
const QString m_updateUrl;
QHash<QString, PluginInfo*> m_plugins;
QProcessEnvironment m_proxyEnv;
};