Allow to use proxy per subsystem

This commit is contained in:
Vladimir Golovnev (Glassez)
2023-01-28 20:40:38 +03:00
parent 4745a40f0b
commit 6ac14d0c57
23 changed files with 357 additions and 339 deletions

View File

@@ -1629,37 +1629,40 @@ lt::settings_pack SessionImpl::loadLTSettings() const
settingsPack.set_int(lt::settings_pack::active_checking, maxActiveCheckingTorrents());
// proxy
const auto proxyManager = Net::ProxyConfigurationManager::instance();
const Net::ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration();
switch (proxyConfig.type)
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::none);
if (Preferences::instance()->useProxyForBT())
{
case Net::ProxyType::HTTP:
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::http);
break;
case Net::ProxyType::HTTP_PW:
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::http_pw);
break;
case Net::ProxyType::SOCKS4:
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::socks4);
break;
case Net::ProxyType::SOCKS5:
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::socks5);
break;
case Net::ProxyType::SOCKS5_PW:
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::socks5_pw);
break;
case Net::ProxyType::None:
default:
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::none);
}
const auto proxyManager = Net::ProxyConfigurationManager::instance();
const Net::ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration();
switch (proxyConfig.type)
{
case Net::ProxyType::SOCKS4:
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::socks4);
break;
case Net::ProxyType::HTTP:
if (proxyConfig.authEnabled)
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::http_pw);
else
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::http);
break;
case Net::ProxyType::SOCKS5:
if (proxyConfig.authEnabled)
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::socks5_pw);
else
settingsPack.set_int(lt::settings_pack::proxy_type, lt::settings_pack::socks5);
break;
default:
break;
}
if (proxyConfig.type != Net::ProxyType::None)
{
settingsPack.set_str(lt::settings_pack::proxy_hostname, proxyConfig.ip.toStdString());
settingsPack.set_int(lt::settings_pack::proxy_port, proxyConfig.port);
if (proxyManager->isAuthenticationRequired())
if (proxyConfig.authEnabled)
{
settingsPack.set_str(lt::settings_pack::proxy_username, proxyConfig.username.toStdString());
settingsPack.set_str(lt::settings_pack::proxy_password, proxyConfig.password.toStdString());
@@ -2493,7 +2496,7 @@ bool SessionImpl::addTorrent(const QString &source, const AddTorrentParams &para
LogMsg(tr("Downloading torrent, please wait... Source: \"%1\"").arg(source));
// Launch downloader
Net::DownloadManager::instance()->download(Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE)
, true, this, &SessionImpl::handleDownloadFinished);
, Preferences::instance()->useProxyForGeneralPurposes(), this, &SessionImpl::handleDownloadFinished);
m_downloadedTorrents[source] = params;
return true;
}

View File

@@ -81,7 +81,7 @@ void DNSUpdater::checkPublicIP()
DownloadManager::instance()->download(
DownloadRequest(u"http://checkip.dyndns.org"_qs).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2))
, true, this, &DNSUpdater::ipRequestFinished);
, Preferences::instance()->useProxyForGeneralPurposes(), this, &DNSUpdater::ipRequestFinished);
m_lastIPCheckTime = QDateTime::currentDateTime();
}
@@ -129,7 +129,7 @@ void DNSUpdater::updateDNSService()
m_lastIPCheckTime = QDateTime::currentDateTime();
DownloadManager::instance()->download(
DownloadRequest(getUpdateUrl()).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2))
, true, this, &DNSUpdater::ipUpdateFinished);
, Preferences::instance()->useProxyForGeneralPurposes(), this, &DNSUpdater::ipUpdateFinished);
}
QString DNSUpdater::getUpdateUrl() const

View File

@@ -119,12 +119,14 @@ Net::DownloadManager *Net::DownloadManager::m_instance = nullptr;
Net::DownloadManager::DownloadManager(QObject *parent)
: QObject(parent)
, m_networkCookieJar {new NetworkCookieJar(this)}
, m_networkManager {new QNetworkAccessManager(this)}
{
m_networkManager->setCookieJar(m_networkCookieJar);
connect(m_networkManager, &QNetworkAccessManager::sslErrors, this, &Net::DownloadManager::ignoreSslErrors);
connect(ProxyConfigurationManager::instance(), &ProxyConfigurationManager::proxyConfigurationChanged
, this, &DownloadManager::applyProxySettings);
connect(Preferences::instance(), &Preferences::changed, this, &DownloadManager::applyProxySettings);
applyProxySettings();
}
@@ -224,10 +226,10 @@ void Net::DownloadManager::applyProxySettings()
m_proxy = QNetworkProxy(QNetworkProxy::NoProxy);
if (!proxyManager->isProxyOnlyForTorrents() && (proxyConfig.type != ProxyType::None))
if (proxyConfig.type != ProxyType::SOCKS4)
{
// Proxy enabled
if ((proxyConfig.type == ProxyType::SOCKS5) || (proxyConfig.type == ProxyType::SOCKS5_PW))
if (proxyConfig.type == ProxyType::SOCKS5)
{
qDebug() << Q_FUNC_INFO << "using SOCKS proxy";
m_proxy.setType(QNetworkProxy::Socks5Proxy);
@@ -242,7 +244,7 @@ void Net::DownloadManager::applyProxySettings()
m_proxy.setPort(proxyConfig.port);
// Authentication?
if (proxyManager->isAuthenticationRequired())
if (proxyConfig.authEnabled)
{
qDebug("Proxy requires authentication, authenticating...");
m_proxy.setUser(proxyConfig.username);

View File

@@ -129,7 +129,9 @@ void GeoIPManager::downloadDatabaseFile()
{
const QDateTime curDatetime = QDateTime::currentDateTimeUtc();
const QString curUrl = DATABASE_URL.arg(QLocale::c().toString(curDatetime, u"yyyy-MM"));
DownloadManager::instance()->download({curUrl}, true, this, &GeoIPManager::downloadFinished);
DownloadManager::instance()->download(
{curUrl}, Preferences::instance()->useProxyForGeneralPurposes()
, this, &GeoIPManager::downloadFinished);
}
QString GeoIPManager::lookup(const QHostAddress &hostAddr) const

View File

@@ -35,6 +35,7 @@ bool Net::operator==(const ProxyConfiguration &left, const ProxyConfiguration &r
return (left.type == right.type)
&& (left.ip == right.ip)
&& (left.port == right.port)
&& (left.authEnabled == right.authEnabled)
&& (left.username == right.username)
&& (left.password == right.password);
}
@@ -49,19 +50,20 @@ using namespace Net;
ProxyConfigurationManager *ProxyConfigurationManager::m_instance = nullptr;
ProxyConfigurationManager::ProxyConfigurationManager(QObject *parent)
: QObject {parent}
, m_storeProxyOnlyForTorrents {SETTINGS_KEY(u"OnlyForTorrents"_qs)}
: QObject(parent)
, m_storeProxyType {SETTINGS_KEY(u"Type"_qs)}
, m_storeProxyIP {SETTINGS_KEY(u"IP"_qs)}
, m_storeProxyPort {SETTINGS_KEY(u"Port"_qs)}
, m_storeProxyAuthEnabled {SETTINGS_KEY(u"AuthEnabled"_qs)}
, m_storeProxyUsername {SETTINGS_KEY(u"Username"_qs)}
, m_storeProxyPassword {SETTINGS_KEY(u"Password"_qs)}
{
m_config.type = m_storeProxyType.get(ProxyType::None);
if ((m_config.type < ProxyType::None) || (m_config.type > ProxyType::SOCKS4))
m_config.type = ProxyType::None;
m_config.type = m_storeProxyType.get(ProxyType::HTTP);
if ((m_config.type < ProxyType::HTTP) || (m_config.type > ProxyType::SOCKS4))
m_config.type = ProxyType::HTTP;
m_config.ip = m_storeProxyIP.get(u"0.0.0.0"_qs);
m_config.port = m_storeProxyPort.get(8080);
m_config.authEnabled = m_storeProxyAuthEnabled;
m_config.username = m_storeProxyUsername;
m_config.password = m_storeProxyPassword;
}
@@ -96,25 +98,10 @@ void ProxyConfigurationManager::setProxyConfiguration(const ProxyConfiguration &
m_storeProxyType = config.type;
m_storeProxyIP = config.ip;
m_storeProxyPort = config.port;
m_storeProxyAuthEnabled = config.authEnabled;
m_storeProxyUsername = config.username;
m_storeProxyPassword = config.password;
emit proxyConfigurationChanged();
}
}
bool ProxyConfigurationManager::isProxyOnlyForTorrents() const
{
return m_storeProxyOnlyForTorrents || (m_config.type == ProxyType::SOCKS4);
}
void ProxyConfigurationManager::setProxyOnlyForTorrents(const bool onlyForTorrents)
{
m_storeProxyOnlyForTorrents = onlyForTorrents;
}
bool ProxyConfigurationManager::isAuthenticationRequired() const
{
return m_config.type == ProxyType::SOCKS5_PW
|| m_config.type == ProxyType::HTTP_PW;
}

View File

@@ -39,20 +39,18 @@ namespace Net
enum class ProxyType
{
None = 0,
HTTP = 1,
SOCKS5 = 2,
HTTP_PW = 3,
SOCKS5_PW = 4,
SOCKS4 = 5
};
Q_ENUM_NS(ProxyType)
struct ProxyConfiguration
{
ProxyType type = ProxyType::None;
ProxyType type = ProxyType::HTTP;
QString ip = u"0.0.0.0"_qs;
ushort port = 8080;
bool authEnabled = false;
QString username;
QString password;
};
@@ -74,10 +72,6 @@ namespace Net
ProxyConfiguration proxyConfiguration() const;
void setProxyConfiguration(const ProxyConfiguration &config);
bool isProxyOnlyForTorrents() const;
void setProxyOnlyForTorrents(bool onlyForTorrents);
bool isAuthenticationRequired() const;
signals:
void proxyConfigurationChanged();
@@ -85,10 +79,10 @@ namespace Net
private:
static ProxyConfigurationManager *m_instance;
ProxyConfiguration m_config;
SettingValue<bool> m_storeProxyOnlyForTorrents;
SettingValue<ProxyType> m_storeProxyType;
SettingValue<QString> m_storeProxyIP;
SettingValue<ushort> m_storeProxyPort;
SettingValue<bool> m_storeProxyAuthEnabled;
SettingValue<QString> m_storeProxyUsername;
SettingValue<QString> m_storeProxyPassword;
};

View File

@@ -1619,6 +1619,37 @@ void Preferences::setNetworkCookies(const QList<QNetworkCookie> &cookies)
setValue(u"Network/Cookies"_qs, rawCookies);
}
bool Preferences::useProxyForBT() const
{
return value<bool>(u"Network/Proxy/Profiles/BitTorrent"_qs);
}
void Preferences::setUseProxyForBT(const bool value)
{
setValue(u"Network/Proxy/Profiles/BitTorrent"_qs, value);
}
bool Preferences::useProxyForRSS() const
{
return value<bool>(u"Network/Proxy/Profiles/RSS"_qs);
}
void Preferences::setUseProxyForRSS(const bool value)
{
setValue(u"Network/Proxy/Profiles/RSS"_qs, value);
}
bool Preferences::useProxyForGeneralPurposes() const
{
return value<bool>(u"Network/Proxy/Profiles/Misc"_qs);
}
void Preferences::setUseProxyForGeneralPurposes(const bool value)
{
setValue(u"Network/Proxy/Profiles/Misc"_qs, value);
}
bool Preferences::isSpeedWidgetEnabled() const
{
return value(u"SpeedWidget/Enabled"_qs, true);

View File

@@ -397,6 +397,13 @@ public:
QList<QNetworkCookie> getNetworkCookies() const;
void setNetworkCookies(const QList<QNetworkCookie> &cookies);
bool useProxyForBT() const;
void setUseProxyForBT(bool value);
bool useProxyForRSS() const;
void setUseProxyForRSS(bool value);
bool useProxyForGeneralPurposes() const;
void setUseProxyForGeneralPurposes(bool value);
// SpeedWidget
bool isSpeedWidgetEnabled() const;
void setSpeedWidgetEnabled(bool enabled);

View File

@@ -45,6 +45,7 @@
#include "base/global.h"
#include "base/logger.h"
#include "base/net/downloadmanager.h"
#include "base/preferences.h"
#include "base/profile.h"
#include "base/utils/fs.h"
#include "feed_serializer.h"
@@ -148,7 +149,7 @@ void Feed::refresh()
// NOTE: Should we allow manually refreshing for disabled session?
m_downloadHandler = Net::DownloadManager::instance()->download(m_url, true);
m_downloadHandler = Net::DownloadManager::instance()->download(m_url, Preferences::instance()->useProxyForRSS());
connect(m_downloadHandler, &Net::DownloadHandler::finished, this, &Feed::handleDownloadFinished);
if (!m_iconPath.exists())
@@ -378,7 +379,7 @@ void Feed::downloadIcon()
const auto iconUrl = u"%1://%2/favicon.ico"_qs.arg(url.scheme(), url.host());
Net::DownloadManager::instance()->download(
Net::DownloadRequest(iconUrl).saveToFile(true).destFileName(m_iconPath)
, true, this, &Feed::handleIconDownloadFinished);
, Preferences::instance()->useProxyForRSS(), this, &Feed::handleIconDownloadFinished);
}
int Feed::updateArticles(const QList<QVariantHash> &loadedArticles)

View File

@@ -94,6 +94,8 @@ SearchPluginManager::SearchPluginManager()
connect(Net::ProxyConfigurationManager::instance(), &Net::ProxyConfigurationManager::proxyConfigurationChanged
, this, &SearchPluginManager::applyProxySettings);
connect(Preferences::instance(), &Preferences::changed
, this, &SearchPluginManager::applyProxySettings);
applyProxySettings();
updateNova();
@@ -213,7 +215,8 @@ void SearchPluginManager::installPlugin(const QString &source)
{
using namespace Net;
DownloadManager::instance()->download(DownloadRequest(source).saveToFile(true)
, true, this, &SearchPluginManager::pluginDownloadFinished);
, Preferences::instance()->useProxyForGeneralPurposes()
, this, &SearchPluginManager::pluginDownloadFinished);
}
else
{
@@ -329,7 +332,8 @@ void SearchPluginManager::checkForUpdates()
// Download version file from update server
using namespace Net;
DownloadManager::instance()->download({m_updateUrl + u"versions.txt"}
, true, this, &SearchPluginManager::versionInfoDownloadFinished);
, Preferences::instance()->useProxyForGeneralPurposes()
, this, &SearchPluginManager::versionInfoDownloadFinished);
}
SearchDownloadHandler *SearchPluginManager::downloadTorrent(const QString &siteUrl, const QString &url)
@@ -391,31 +395,40 @@ void SearchPluginManager::applyProxySettings()
// Define environment variables for urllib in search engine plugins
QString proxyStrHTTP, proxyStrSOCK;
if (!proxyManager->isProxyOnlyForTorrents())
if (Preferences::instance()->useProxyForGeneralPurposes())
{
switch (proxyConfig.type)
{
case Net::ProxyType::HTTP_PW:
proxyStrHTTP = u"http://%1:%2@%3:%4"_qs.arg(proxyConfig.username
, proxyConfig.password, proxyConfig.ip, QString::number(proxyConfig.port));
break;
case Net::ProxyType::HTTP:
proxyStrHTTP = u"http://%1:%2"_qs.arg(proxyConfig.ip, QString::number(proxyConfig.port));
if (proxyConfig.authEnabled)
{
proxyStrHTTP = u"http://%1:%2@%3:%4"_qs.arg(proxyConfig.username
, proxyConfig.password, proxyConfig.ip, QString::number(proxyConfig.port));
}
else
{
proxyStrHTTP = u"http://%1:%2"_qs.arg(proxyConfig.ip, QString::number(proxyConfig.port));
}
break;
case Net::ProxyType::SOCKS5:
proxyStrSOCK = u"%1:%2"_qs.arg(proxyConfig.ip, QString::number(proxyConfig.port));
break;
case Net::ProxyType::SOCKS5_PW:
proxyStrSOCK = u"%1:%2@%3:%4"_qs.arg(proxyConfig.username
, proxyConfig.password, proxyConfig.ip, QString::number(proxyConfig.port));
if (proxyConfig.authEnabled)
{
proxyStrSOCK = u"%1:%2@%3:%4"_qs.arg(proxyConfig.username
, proxyConfig.password, proxyConfig.ip, QString::number(proxyConfig.port));
}
else
{
proxyStrSOCK = u"%1:%2"_qs.arg(proxyConfig.ip, QString::number(proxyConfig.port));
}
break;
default:
qDebug("Disabling HTTP communications proxy");
}
qDebug("HTTP communications proxy string: %s"
, qUtf8Printable((proxyConfig.type == Net::ProxyType::SOCKS5) || (proxyConfig.type == Net::ProxyType::SOCKS5_PW)
? proxyStrSOCK : proxyStrHTTP));
, qUtf8Printable((proxyConfig.type == Net::ProxyType::SOCKS5) ? proxyStrSOCK : proxyStrHTTP));
}
qputenv("http_proxy", proxyStrHTTP.toLocal8Bit());