diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 12e6c51ce..8fdebe7aa 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -1782,38 +1782,6 @@ namespace { if (changeInMin) App::main()->updateMutedIn(changeInMin); } - void setProxySettings(QNetworkAccessManager &manager) { -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - manager.setProxy(getHttpProxySettings()); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY - } - -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - QNetworkProxy getHttpProxySettings() { - const ProxyData *proxy = nullptr; - if (Global::started()) { - proxy = (Global::ConnectionType() == dbictHttpProxy) ? (&Global::ConnectionProxy()) : nullptr; - } else { - proxy = Sandbox::PreLaunchProxy().host.isEmpty() ? nullptr : (&Sandbox::PreLaunchProxy()); - } - if (proxy) { - return QNetworkProxy(QNetworkProxy::HttpProxy, proxy->host, proxy->port, proxy->user, proxy->password); - } - return QNetworkProxy(QNetworkProxy::DefaultProxy); - } -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY - - void setProxySettings(QTcpSocket &socket) { -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - if (Global::ConnectionType() == dbictTcpProxy) { - auto &p = Global::ConnectionProxy(); - socket.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, p.host, p.port, p.user, p.password)); - } else { - socket.setProxy(QNetworkProxy(QNetworkProxy::NoProxy)); - } -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY - } - void rectWithCorners(Painter &p, QRect rect, const style::color &bg, RoundCorners index, RectParts corners) { auto parts = RectPart::Top | RectPart::NoTopBottom diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 879327c77..f2e704924 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -225,12 +225,6 @@ namespace App { void unregMuted(not_null peer); void updateMuted(); - void setProxySettings(QNetworkAccessManager &manager); -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - QNetworkProxy getHttpProxySettings(); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY - void setProxySettings(QTcpSocket &socket); - void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners); void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index fe8d656ef..754554f46 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -196,6 +196,7 @@ void Application::singleInstanceChecked() { } Sandbox::start(); + refreshGlobalProxy(); if (!Logs::started() || (!cManyInstance() && !Logs::instanceChecked())) { new NotStartedWindow(); @@ -307,9 +308,35 @@ void Application::startApplication() { void Application::createMessenger() { Expects(!App::quitting()); + _messengerInstance = std::make_unique(_launcher); } +void Application::refreshGlobalProxy() { +#ifndef TDESKTOP_DISABLE_NETWORK_PROXY + const auto proxy = [&] { + if (Global::started()) { + return Global::ConnectionType() == dbictAuto + ? ProxyData() + : Global::ConnectionProxy(); + } + return Sandbox::PreLaunchProxy(); + }(); + if (proxy.type != ProxyData::Type::None) { + QNetworkProxy::setApplicationProxy(QNetworkProxy( + (proxy.type == ProxyData::Type::Socks5 + ? QNetworkProxy::Socks5Proxy + : QNetworkProxy::HttpProxy), + proxy.host, + proxy.port, + proxy.user, + proxy.password)); + } else { + QNetworkProxyFactory::setUseSystemConfiguration(true); + } +#endif // TDESKTOP_DISABLE_NETWORK_PROXY +} + void Application::closeApplication() { if (App::launchState() == App::QuitProcessed) return; App::setLaunchState(App::QuitProcessed); @@ -479,7 +506,6 @@ void Application::startUpdateCheck(bool forceWait) { QNetworkRequest checkVersion(url); if (_updateReply) _updateReply->deleteLater(); - App::setProxySettings(_updateManager); _updateReply = _updateManager.get(checkVersion); connect(_updateReply, SIGNAL(finished()), this, SLOT(updateGotCurrent())); connect(_updateReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(updateFailedCurrent(QNetworkReply::NetworkError))); @@ -648,4 +674,10 @@ void launch() { application()->createMessenger(); } +void refreshGlobalProxy() { + if (const auto instance = application()) { + instance->refreshGlobalProxy(); + } +} + } // namespace Sandbox diff --git a/Telegram/SourceFiles/application.h b/Telegram/SourceFiles/application.h index b38bf568f..116d121f5 100644 --- a/Telegram/SourceFiles/application.h +++ b/Telegram/SourceFiles/application.h @@ -22,6 +22,7 @@ public: bool event(QEvent *e) override; void createMessenger(); + void refreshGlobalProxy(); ~Application(); @@ -128,6 +129,8 @@ void updateReady(); #endif // !TDESKTOP_DISABLE_AUTOUPDATE +void refreshGlobalProxy(); + void connect(const char *signal, QObject *object, const char *method); void launch(); diff --git a/Telegram/SourceFiles/autoupdater.cpp b/Telegram/SourceFiles/autoupdater.cpp index 2bad092cc..dbbfb4dad 100644 --- a/Telegram/SourceFiles/autoupdater.cpp +++ b/Telegram/SourceFiles/autoupdater.cpp @@ -36,7 +36,6 @@ UpdateChecker::UpdateChecker(QThread *thread, const QString &url) : reply(0), al updateUrl = url; moveToThread(thread); manager.moveToThread(thread); - App::setProxySettings(manager); connect(thread, SIGNAL(started()), this, SLOT(start())); initOutput(); diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index e2ce01b63..eba0c2a98 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -20,30 +20,31 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" #include "history/history_location_manager.h" +#include "application.h" #include "styles/style_boxes.h" void ConnectionBox::ShowApplyProxyConfirmation(const QMap &fields) { auto server = fields.value(qsl("server")); - auto port = fields.value(qsl("port")).toInt(); + auto port = fields.value(qsl("port")).toUInt(); if (!server.isEmpty() && port != 0) { - auto weakBox = std::make_shared>(nullptr); - auto box = Ui::show(Box(lng_sure_enable_socks(lt_server, server, lt_port, QString::number(port)), lang(lng_sure_enable), [fields, weakBox] { - auto p = ProxyData(); - p.host = fields.value(qsl("server")); - p.user = fields.value(qsl("user")); - p.password = fields.value(qsl("pass")); - p.port = fields.value(qsl("port")).toInt(); + const auto box = std::make_shared>(); + *box = Ui::show(Box(lng_sure_enable_socks(lt_server, server, lt_port, QString::number(port)), lang(lng_sure_enable), [=] { + auto proxy = ProxyData(); + proxy.type = ProxyData::Type::Socks5; + proxy.host = server; + proxy.user = fields.value(qsl("user")); + proxy.password = fields.value(qsl("pass")); + proxy.port = port; Global::SetConnectionType(dbictTcpProxy); - Global::SetLastProxyType(dbictTcpProxy); - Global::SetConnectionProxy(p); + Global::SetConnectionProxy(proxy); Local::writeSettings(); + Sandbox::refreshGlobalProxy(); Global::RefConnectionTypeChanged().notify(); MTP::restart(); - reinitLocationManager(); - reinitWebLoadManager(); - if (*weakBox) (*weakBox)->closeBox(); + if (const auto strong = box->data()) { + strong->closeBox(); + } }), LayerOption::KeepOther); - *weakBox = box; } } @@ -52,6 +53,7 @@ ConnectionBox::ConnectionBox(QWidget *parent) , _portInput(this, st::connectionPortInputField, langFactory(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port)) , _userInput(this, st::connectionUserInputField, langFactory(lng_connection_user_ph), Global::ConnectionProxy().user) , _passwordInput(this, st::connectionPasswordInputField, langFactory(lng_connection_password_ph), Global::ConnectionProxy().password) +, _currentProxyType(Global::ConnectionProxy().type) , _typeGroup(std::make_shared>(Global::ConnectionType())) , _autoRadio(this, _typeGroup, dbictAuto, lang(lng_connection_auto_rb), st::defaultBoxCheckbox) , _httpProxyRadio(this, _typeGroup, dbictHttpProxy, lang(lng_connection_http_proxy_rb), st::defaultBoxCheckbox) @@ -122,9 +124,9 @@ void ConnectionBox::updateControlsPosition() { _httpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _autoRadio->bottomNoMargins() + st::boxOptionListSkip); auto inputy = 0; - auto fieldsVisible = (type != dbictAuto) || (!badProxyValue() && Global::LastProxyType() != dbictAuto); - auto fieldsBelowHttp = fieldsVisible && (type == dbictHttpProxy || (type == dbictAuto && Global::LastProxyType() == dbictHttpProxy)); - auto fieldsBelowTcp = fieldsVisible && (type == dbictTcpProxy || (type == dbictAuto && Global::LastProxyType() == dbictTcpProxy)); + auto fieldsVisible = (type != dbictAuto) || (!badProxyValue() && _currentProxyType != ProxyData::Type::None); + auto fieldsBelowHttp = fieldsVisible && (type == dbictHttpProxy || (type == dbictAuto && _currentProxyType == ProxyData::Type::Http)); + auto fieldsBelowTcp = fieldsVisible && (type == dbictTcpProxy || (type == dbictAuto && _currentProxyType == ProxyData::Type::Socks5)); if (fieldsBelowHttp) { inputy = _httpProxyRadio->bottomNoMargins() + st::boxOptionInputSkip; _tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), inputy + st::boxOptionInputSkip + 2 * _hostInput->height() + st::boxOptionListSkip); @@ -152,7 +154,11 @@ void ConnectionBox::typeChanged(DBIConnectionType type) { } updateControlsVisibility(); if (type != dbictAuto) { - Global::SetLastProxyType(type); + _currentProxyType = (type == dbictTcpProxy) + ? ProxyData::Type::Socks5 + : (type == dbictHttpProxy) + ? ProxyData::Type::Http + : ProxyData::Type::None; if (!_hostInput->hasFocus() && !_portInput->hasFocus() && !_userInput->hasFocus() && !_passwordInput->hasFocus()) { _hostInput->setFocusFast(); } @@ -165,9 +171,9 @@ void ConnectionBox::typeChanged(DBIConnectionType type) { } void ConnectionBox::onFieldFocus() { - if (Global::LastProxyType() == dbictHttpProxy) { + if (_currentProxyType == ProxyData::Type::Http) { _typeGroup->setValue(dbictHttpProxy); - } else if (Global::LastProxyType() == dbictTcpProxy) { + } else if (_currentProxyType == ProxyData::Type::Socks5) { _typeGroup->setValue(dbictTcpProxy); } } @@ -202,33 +208,33 @@ void ConnectionBox::onSubmit() { } void ConnectionBox::onSave() { - auto p = ProxyData(); - p.host = _hostInput->getLastText().trimmed(); - p.user = _userInput->getLastText().trimmed(); - p.password = _passwordInput->getLastText().trimmed(); - p.port = _portInput->getLastText().toInt(); + auto proxy = ProxyData(); + proxy.host = _hostInput->getLastText().trimmed(); + proxy.user = _userInput->getLastText().trimmed(); + proxy.password = _passwordInput->getLastText().trimmed(); + proxy.port = _portInput->getLastText().toUInt(); auto type = _typeGroup->value(); if (type == dbictAuto) { - if (p.host.isEmpty() || !p.port) { - p = ProxyData(); + if (proxy.host.isEmpty() || !proxy.port) { + proxy = ProxyData(); + } else { + proxy.type = _currentProxyType; } -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - QNetworkProxyFactory::setUseSystemConfiguration(false); - QNetworkProxyFactory::setUseSystemConfiguration(true); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY } else { - if (p.host.isEmpty()) { + if (proxy.host.isEmpty()) { _hostInput->showError(); return; - } else if (!p.port) { + } else if (!proxy.port) { _portInput->showError(); return; } - Global::SetLastProxyType(type); + proxy.type = (type == dbictTcpProxy) + ? ProxyData::Type::Socks5 + : ProxyData::Type::Http; } Global::SetConnectionType(type); - Global::SetConnectionProxy(p); + Global::SetConnectionProxy(proxy); if (cPlatform() == dbipWindows && Global::TryIPv6() != _tryIPv6->checked()) { Global::SetTryIPv6(_tryIPv6->checked()); Local::writeSettings(); @@ -238,11 +244,10 @@ void ConnectionBox::onSave() { } else { Global::SetTryIPv6(_tryIPv6->checked()); Local::writeSettings(); + Sandbox::refreshGlobalProxy(); Global::RefConnectionTypeChanged().notify(); MTP::restart(); - reinitLocationManager(); - reinitWebLoadManager(); closeBox(); } } diff --git a/Telegram/SourceFiles/boxes/connection_box.h b/Telegram/SourceFiles/boxes/connection_box.h index 300c113bf..0aa325010 100644 --- a/Telegram/SourceFiles/boxes/connection_box.h +++ b/Telegram/SourceFiles/boxes/connection_box.h @@ -49,6 +49,7 @@ private: object_ptr _portInput; object_ptr _userInput; object_ptr _passwordInput; + ProxyData::Type _currentProxyType; std::shared_ptr> _typeGroup; object_ptr> _autoRadio; object_ptr> _httpProxyRadio; diff --git a/Telegram/SourceFiles/core/crash_report_window.cpp b/Telegram/SourceFiles/core/crash_report_window.cpp index 1d75e71e9..2e123bab6 100644 --- a/Telegram/SourceFiles/core/crash_report_window.cpp +++ b/Telegram/SourceFiles/core/crash_report_window.cpp @@ -434,7 +434,6 @@ void LastCrashedWindow::onSendReport() { _sendReply->deleteLater(); _sendReply = nullptr; } - App::setProxySettings(_sendManager); QString apiid = getReportField(qstr("apiid"), qstr("ApiId:")), version = getReportField(qstr("version"), qstr("Version:")); _checkReply = _sendManager.get(QNetworkRequest(qsl("https://tdesktop.com/crash.php?act=query_report&apiid=%1&version=%2&dmp=%3&platform=%4").arg(apiid).arg(version).arg(minidumpFileName().isEmpty() ? 0 : 1).arg(cPlatformString()))); @@ -756,17 +755,39 @@ void LastCrashedWindow::updateControls() { } void LastCrashedWindow::onNetworkSettings() { - auto &p = Sandbox::PreLaunchProxy(); - NetworkSettingsWindow *box = new NetworkSettingsWindow(this, p.host, p.port ? p.port : 80, p.user, p.password); - connect(box, SIGNAL(saved(QString, quint32, QString, QString)), this, SLOT(onNetworkSettingsSaved(QString, quint32, QString, QString))); + const auto &proxy = Sandbox::PreLaunchProxy(); + const auto box = new NetworkSettingsWindow( + this, + proxy.host, + proxy.port ? proxy.port : 80, + proxy.user, + proxy.password); + connect( + box, + SIGNAL(saved(QString,quint32,QString,QString)), + this, + SLOT(onNetworkSettingsSaved(QString,quint32,QString,QString))); box->show(); } -void LastCrashedWindow::onNetworkSettingsSaved(QString host, quint32 port, QString username, QString password) { - Sandbox::RefPreLaunchProxy().host = host; - Sandbox::RefPreLaunchProxy().port = port ? port : 80; - Sandbox::RefPreLaunchProxy().user = username; - Sandbox::RefPreLaunchProxy().password = password; +void LastCrashedWindow::onNetworkSettingsSaved( + QString host, + quint32 port, + QString username, + QString password) { + Expects(host.isEmpty() || port != 0); + + auto &proxy = Sandbox::RefPreLaunchProxy(); + proxy.type = host.isEmpty() + ? ProxyData::Type::None + : ProxyData::Type::Http; + proxy.host = host; + proxy.port = port; + proxy.user = username; + proxy.password = password; + + Sandbox::refreshGlobalProxy(); + #ifndef TDESKTOP_DISABLE_AUTOUPDATE if ((_updatingState == UpdatingFail && (_sendingState == SendingNoReport || _sendingState == SendingUpdateCheck)) || (_updatingState == UpdatingCheck)) { Sandbox::stopUpdate(); diff --git a/Telegram/SourceFiles/core/utils.h b/Telegram/SourceFiles/core/utils.h index b208db26f..08ec25862 100644 --- a/Telegram/SourceFiles/core/utils.h +++ b/Telegram/SourceFiles/core/utils.h @@ -428,6 +428,12 @@ enum DBIConnectionType { }; struct ProxyData { + enum class Type { + None, + Socks5, + Http, + }; + Type type = Type::None; QString host; uint32 port = 0; QString user, password; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 955090cb5..2f8aee24e 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -564,7 +564,6 @@ struct Data { bool NotificationsDemoIsShown = false; DBIConnectionType ConnectionType = dbictAuto; - DBIConnectionType LastProxyType = dbictAuto; bool TryIPv6 = (cPlatform() == dbipWindows) ? false : true; ProxyData ConnectionProxy; base::Observable ConnectionTypeChanged; @@ -687,7 +686,6 @@ DefineVar(Global, Notify::ScreenCorner, NotificationsCorner); DefineVar(Global, bool, NotificationsDemoIsShown); DefineVar(Global, DBIConnectionType, ConnectionType); -DefineVar(Global, DBIConnectionType, LastProxyType); DefineVar(Global, bool, TryIPv6); DefineVar(Global, ProxyData, ConnectionProxy); DefineRefVar(Global, base::Observable, ConnectionTypeChanged); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 9f6b1de13..743f61856 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -372,7 +372,6 @@ DeclareVar(Notify::ScreenCorner, NotificationsCorner); DeclareVar(bool, NotificationsDemoIsShown); DeclareVar(DBIConnectionType, ConnectionType); -DeclareVar(DBIConnectionType, LastProxyType); DeclareVar(bool, TryIPv6); DeclareVar(ProxyData, ConnectionProxy); DeclareRefVar(base::Observable, ConnectionTypeChanged); diff --git a/Telegram/SourceFiles/history/history_location_manager.cpp b/Telegram/SourceFiles/history/history_location_manager.cpp index 608da3db9..e208fb0ea 100644 --- a/Telegram/SourceFiles/history/history_location_manager.cpp +++ b/Telegram/SourceFiles/history/history_location_manager.cpp @@ -48,12 +48,6 @@ void initLocationManager() { } } -void reinitLocationManager() { - if (locationManager) { - locationManager->reinit(); - } -} - void deinitLocationManager() { if (locationManager) { locationManager->deinit(); @@ -65,7 +59,6 @@ void deinitLocationManager() { void LocationManager::init() { if (manager) delete manager; manager = new QNetworkAccessManager(); - App::setProxySettings(*manager); connect(manager, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(onFailed(QNetworkReply*))); #ifndef OS_MAC_OLD @@ -83,10 +76,6 @@ void LocationManager::init() { notLoadedPlaceholder = new ImagePtr(App::pixmapFromImageInPlace(std::move(data)), "GIF"); } -void LocationManager::reinit() { - if (manager) App::setProxySettings(*manager); -} - void LocationManager::deinit() { if (manager) { delete manager; diff --git a/Telegram/SourceFiles/history/history_location_manager.h b/Telegram/SourceFiles/history/history_location_manager.h index 72f8a2970..884fabf51 100644 --- a/Telegram/SourceFiles/history/history_location_manager.h +++ b/Telegram/SourceFiles/history/history_location_manager.h @@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once void initLocationManager(); -void reinitLocationManager(); void deinitLocationManager(); class LocationCoords { diff --git a/Telegram/SourceFiles/messenger.cpp b/Telegram/SourceFiles/messenger.cpp index 7a3b74b26..b1a56ac9b 100644 --- a/Telegram/SourceFiles/messenger.cpp +++ b/Telegram/SourceFiles/messenger.cpp @@ -77,12 +77,14 @@ Messenger::Messenger(not_null launcher) Expects(!_logo.isNull()); Expects(!_logoNoMargin.isNull()); Expects(SingleInstance == nullptr); + SingleInstance = this; Fonts::Start(); ThirdParty::start(); Global::start(); + Sandbox::refreshGlobalProxy(); // Depends on Global::started(). startLocalStorage(); @@ -167,10 +169,6 @@ Messenger::Messenger(not_null launcher) _window->showSettings(); } -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - QNetworkProxyFactory::setUseSystemConfiguration(true); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY - _window->updateIsActive(Global::OnlineFocusTimeout()); if (!Shortcuts::errors().isEmpty()) { @@ -391,6 +389,7 @@ void Messenger::setMtpAuthorization(const QByteArray &serialized) { void Messenger::startMtp() { Expects(!_mtproto); + _mtproto = std::make_unique(_dcOptions.get(), MTP::Instance::Mode::Normal, base::take(_private->mtpConfig)); _private->mtpConfig.mainDcId = _mtproto->mainDcId(); diff --git a/Telegram/SourceFiles/mtproto/connection.cpp b/Telegram/SourceFiles/mtproto/connection.cpp index 899828236..f79e49fbd 100644 --- a/Telegram/SourceFiles/mtproto/connection.cpp +++ b/Telegram/SourceFiles/mtproto/connection.cpp @@ -306,7 +306,7 @@ Connection::~Connection() { } void ConnectionPrivate::createConn(bool createIPv4, bool createIPv6) { - destroyConn(); + destroyAllConnections(); if (createIPv4) { QWriteLocker lock(&stateConnMutex); _conn4 = AbstractConnection::create(_dcType, thread()); @@ -327,30 +327,27 @@ void ConnectionPrivate::createConn(bool createIPv4, bool createIPv6) { oldConnectionTimer.start(MTPConnectionOldTimeout); } -void ConnectionPrivate::destroyConn(AbstractConnection **conn) { - if (conn) { - AbstractConnection *toDisconnect = nullptr; +void ConnectionPrivate::destroyAllConnections() { + destroyConnection(_conn4); + destroyConnection(_conn6); + _conn = nullptr; +} - { - QWriteLocker lock(&stateConnMutex); - if (*conn) { - toDisconnect = *conn; - disconnect(*conn, SIGNAL(connected()), nullptr, nullptr); - disconnect(*conn, SIGNAL(disconnected()), nullptr, nullptr); - disconnect(*conn, SIGNAL(error(qint32)), nullptr, nullptr); - disconnect(*conn, SIGNAL(receivedData()), nullptr, nullptr); - disconnect(*conn, SIGNAL(receivedSome()), nullptr, nullptr); - *conn = nullptr; - } +void ConnectionPrivate::destroyConnection(AbstractConnection *&connection) { + const auto taken = [&] { + QWriteLocker lock(&stateConnMutex); + if (connection) { + disconnect(connection, SIGNAL(connected()), nullptr, nullptr); + disconnect(connection, SIGNAL(disconnected()), nullptr, nullptr); + disconnect(connection, SIGNAL(error(qint32)), nullptr, nullptr); + disconnect(connection, SIGNAL(receivedData()), nullptr, nullptr); + disconnect(connection, SIGNAL(receivedSome()), nullptr, nullptr); } - if (toDisconnect) { - toDisconnect->disconnectFromServer(); - toDisconnect->deleteLater(); - } - } else { - destroyConn(&_conn4); - destroyConn(&_conn6); - _conn = nullptr; + return base::take(connection); + }(); + if (taken) { + taken->disconnectFromServer(); + taken->deleteLater(); } } @@ -1198,7 +1195,7 @@ void ConnectionPrivate::onWaitConnectedFailed() { void ConnectionPrivate::onWaitIPv4Failed() { _conn = _conn6; - destroyConn(&_conn4); + destroyConnection(_conn4); if (_conn) { DEBUG_LOG(("MTP Info: can't connect through IPv4, using IPv6 connection.")); @@ -1210,7 +1207,7 @@ void ConnectionPrivate::onWaitIPv4Failed() { } void ConnectionPrivate::doDisconnect() { - destroyConn(); + destroyAllConnections(); { QReadLocker lockFinished(&sessionDataMutex); @@ -2289,7 +2286,7 @@ void ConnectionPrivate::onConnected4() { } _conn = _conn4; - destroyConn(&_conn6); + destroyConnection(_conn6); DEBUG_LOG(("MTP Info: connection through IPv4 succeed.")); @@ -2321,10 +2318,10 @@ void ConnectionPrivate::onDisconnected4() { if (_conn && _conn == _conn6) return; // disconnected the unused if (_conn || !_conn6) { - destroyConn(); + destroyAllConnections(); restart(); } else { - destroyConn(&_conn4); + destroyConnection(_conn4); } } @@ -2332,10 +2329,10 @@ void ConnectionPrivate::onDisconnected6() { if (_conn && _conn == _conn4) return; // disconnected the unused if (_conn || !_conn4) { - destroyConn(); + destroyAllConnections(); restart(); } else { - destroyConn(&_conn6); + destroyConnection(_conn6); } } @@ -2844,7 +2841,7 @@ void ConnectionPrivate::onError4(qint32 errorCode) { if (_conn || !_conn6) { handleError(errorCode); } else { - destroyConn(&_conn4); + destroyConnection(_conn4); } } @@ -2857,12 +2854,12 @@ void ConnectionPrivate::onError6(qint32 errorCode) { if (_conn || !_conn4) { handleError(errorCode); } else { - destroyConn(&_conn6); + destroyConnection(_conn6); } } void ConnectionPrivate::handleError(int errorCode) { - destroyConn(); + destroyAllConnections(); _waitForConnectedTimer.stop(); if (errorCode == -404) { diff --git a/Telegram/SourceFiles/mtproto/connection.h b/Telegram/SourceFiles/mtproto/connection.h index 9160a847b..04db423a3 100644 --- a/Telegram/SourceFiles/mtproto/connection.h +++ b/Telegram/SourceFiles/mtproto/connection.h @@ -156,7 +156,8 @@ private: void handleError(int errorCode); void createConn(bool createIPv4, bool createIPv6); - void destroyConn(AbstractConnection **conn = 0); // 0 - destory all + void destroyAllConnections(); + void destroyConnection(AbstractConnection *&connection); mtpMsgId placeToContainer(mtpRequest &toSendRequest, mtpMsgId &bigMsgId, mtpMsgId *&haveSentArr, mtpRequest &req); mtpMsgId prepareToSend(mtpRequest &request, mtpMsgId currentLastId); @@ -195,7 +196,7 @@ private: Connection *_owner = nullptr; AbstractConnection *_conn = nullptr; AbstractConnection *_conn4 = nullptr; - AbstractConnection *_conn6 = nullptr;; + AbstractConnection *_conn6 = nullptr; SingleTimer retryTimer; // exp retry timer int retryTimeout = 1; diff --git a/Telegram/SourceFiles/mtproto/connection_auto.cpp b/Telegram/SourceFiles/mtproto/connection_auto.cpp index c6e115f12..195814a46 100644 --- a/Telegram/SourceFiles/mtproto/connection_auto.cpp +++ b/Telegram/SourceFiles/mtproto/connection_auto.cpp @@ -20,9 +20,6 @@ AutoConnection::AutoConnection(QThread *thread) : AbstractTCPConnection(thread) , _flagsHttp(0) , _tcpTimeout(MTPMinReceiveDelay) { manager.moveToThread(thread); -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - manager.setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy)); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY httpStartTimer.moveToThread(thread); httpStartTimer.setSingleShot(true); @@ -33,9 +30,6 @@ AutoConnection::AutoConnection(QThread *thread) : AbstractTCPConnection(thread) connect(&tcpTimeoutTimer, SIGNAL(timeout()), this, SLOT(onTcpTimeoutTimer())); sock.moveToThread(thread); -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - sock.setProxy(QNetworkProxy(QNetworkProxy::NoProxy)); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY connect(&sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); connect(&sock, SIGNAL(connected()), this, SLOT(onSocketConnected())); connect(&sock, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected())); diff --git a/Telegram/SourceFiles/mtproto/connection_http.cpp b/Telegram/SourceFiles/mtproto/connection_http.cpp index a7fb9945d..87337046a 100644 --- a/Telegram/SourceFiles/mtproto/connection_http.cpp +++ b/Telegram/SourceFiles/mtproto/connection_http.cpp @@ -54,7 +54,7 @@ qint32 HTTPConnection::handleError(QNetworkReply *reply) { // returnes "maybe ba case QNetworkReply::ProxyNotFoundError: case QNetworkReply::ProxyTimeoutError: case QNetworkReply::ProxyAuthenticationRequiredError: - case QNetworkReply::UnknownProxyError:LOG(("HTTP Error: proxy error %1 - %2").arg(reply->error()).arg(reply->errorString())); break; + case QNetworkReply::UnknownProxyError: LOG(("HTTP Error: proxy error %1 - %2").arg(reply->error()).arg(reply->errorString())); break; // content errors (201-299): case QNetworkReply::ContentAccessDenied: @@ -79,7 +79,6 @@ HTTPConnection::HTTPConnection(QThread *thread) : AbstractConnection(thread) , httpNonce(rand_value()) , _flags(0) { manager.moveToThread(thread); - App::setProxySettings(manager); } void HTTPConnection::sendData(mtpBuffer &buffer) { diff --git a/Telegram/SourceFiles/mtproto/connection_tcp.cpp b/Telegram/SourceFiles/mtproto/connection_tcp.cpp index 9b7a3d2ca..854c3051f 100644 --- a/Telegram/SourceFiles/mtproto/connection_tcp.cpp +++ b/Telegram/SourceFiles/mtproto/connection_tcp.cpp @@ -201,7 +201,6 @@ TCPConnection::TCPConnection(QThread *thread) : AbstractTCPConnection(thread) connect(&tcpTimeoutTimer, SIGNAL(timeout()), this, SLOT(onTcpTimeoutTimer())); sock.moveToThread(thread); - App::setProxySettings(sock); connect(&sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); connect(&sock, SIGNAL(connected()), this, SLOT(onSocketConnected())); connect(&sock, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected())); @@ -327,6 +326,7 @@ void TCPConnection::connectTcp(const DcOptions::Endpoint &endpoint) { connect(&sock, SIGNAL(readyRead()), this, SLOT(socketRead())); sock.connectToHost(QHostAddress(_addr), _port); + auto proxy = sock.proxy(); } void TCPConnection::socketPacket(const char *packet, uint32 length) { diff --git a/Telegram/SourceFiles/mtproto/special_config_request.cpp b/Telegram/SourceFiles/mtproto/special_config_request.cpp index 9882d1128..b30295b32 100644 --- a/Telegram/SourceFiles/mtproto/special_config_request.cpp +++ b/Telegram/SourceFiles/mtproto/special_config_request.cpp @@ -35,8 +35,6 @@ SpecialConfigRequest::SpecialConfigRequest( const std::string &ip, int port)> callback) : _callback(std::move(callback)) { - App::setProxySettings(_manager); - performApp1Request(); performApp2Request(); performDnsRequest(); diff --git a/Telegram/SourceFiles/storage/file_download.cpp b/Telegram/SourceFiles/storage/file_download.cpp index a02689e61..054951801 100644 --- a/Telegram/SourceFiles/storage/file_download.cpp +++ b/Telegram/SourceFiles/storage/file_download.cpp @@ -1080,14 +1080,6 @@ private: friend class WebLoadManager; }; -void reinitWebLoadManager() { -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - if (webLoadManager()) { - webLoadManager()->setProxySettings(App::getHttpProxySettings()); - } -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY -} - void stopWebLoadManager() { if (webLoadManager()) { _webLoadThread->quit(); @@ -1102,21 +1094,12 @@ void stopWebLoadManager() { } } -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY -void WebLoadManager::setProxySettings(const QNetworkProxy &proxy) { - QMutexLocker lock(&_loaderPointersMutex); - _proxySettings = proxy; - emit proxyApplyDelayed(); -} -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY - WebLoadManager::WebLoadManager(QThread *thread) { moveToThread(thread); _manager.moveToThread(thread); connect(thread, SIGNAL(started()), this, SLOT(process())); connect(thread, SIGNAL(finished()), this, SLOT(finish())); connect(this, SIGNAL(processDelayed()), this, SLOT(process()), Qt::QueuedConnection); - connect(this, SIGNAL(proxyApplyDelayed()), this, SLOT(proxyApply()), Qt::QueuedConnection); connect(this, SIGNAL(progress(webFileLoader*,qint64,qint64)), _webLoadMainManager, SLOT(progress(webFileLoader*,qint64,qint64))); connect(this, SIGNAL(finished(webFileLoader*,QByteArray)), _webLoadMainManager, SLOT(finished(webFileLoader*,QByteArray))); @@ -1336,13 +1319,6 @@ void WebLoadManager::sendRequest(webFileLoaderPrivate *loader, const QString &re _replies.insert(r, loader); } -void WebLoadManager::proxyApply() { -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - QMutexLocker lock(&_loaderPointersMutex); - _manager.setProxy(_proxySettings); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY -} - void WebLoadManager::finish() { clear(); } diff --git a/Telegram/SourceFiles/storage/file_download.h b/Telegram/SourceFiles/storage/file_download.h index 59e88c1ba..21f5909ba 100644 --- a/Telegram/SourceFiles/storage/file_download.h +++ b/Telegram/SourceFiles/storage/file_download.h @@ -325,10 +325,6 @@ class WebLoadManager : public QObject { public: WebLoadManager(QThread *thread); -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - void setProxySettings(const QNetworkProxy &proxy); -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY - void append(webFileLoader *loader, const QString &url); void stop(webFileLoader *reader); bool carries(webFileLoader *reader) const; @@ -337,7 +333,6 @@ public: signals: void processDelayed(); - void proxyApplyDelayed(); void progress(webFileLoader *loader, qint64 already, qint64 size); void finished(webFileLoader *loader, QByteArray data); @@ -350,7 +345,6 @@ public slots: void onMeta(); void process(); - void proxyApply(); void finish(); private: @@ -358,9 +352,6 @@ private: void sendRequest(webFileLoaderPrivate *loader, const QString &redirect = QString()); bool handleReplyResult(webFileLoaderPrivate *loader, WebReplyProcessResult result); -#ifndef TDESKTOP_DISABLE_NETWORK_PROXY - QNetworkProxy _proxySettings; -#endif // !TDESKTOP_DISABLE_NETWORK_PROXY QNetworkAccessManager _manager; typedef QMap LoaderPointers; LoaderPointers _loaderPointers; @@ -392,5 +383,4 @@ static mtpFileLoader * const CancelledMtpFileLoader = static_cast(CancelledFileLoader); static WebLoadManager * const FinishedWebLoadManager = SharedMemoryLocation(); -void reinitWebLoadManager(); void stopWebLoadManager(); diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index ffafea1f7..aca0b1394 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -38,6 +38,7 @@ namespace { constexpr auto kThemeFileSizeLimit = 5 * 1024 * 1024; constexpr auto kFileLoaderQueueStopTimeout = TimeMs(5000); constexpr auto kDefaultStickerInstallDate = TimeId(1); +constexpr auto kProxyTypeShift = 1024; using FileKey = quint64; @@ -1147,51 +1148,55 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting stream >> v; if (!_checkStreamStatus(stream)) return false; + ProxyData proxy; switch (v) { case dbictHttpProxy: case dbictTcpProxy: { - ProxyData p; qint32 port; - stream >> p.host >> port >> p.user >> p.password; + stream >> proxy.host >> port >> proxy.user >> proxy.password; if (!_checkStreamStatus(stream)) return false; - p.port = uint32(port); - Global::SetConnectionProxy(p); + proxy.port = uint32(port); + proxy.type = (v == dbictTcpProxy) + ? ProxyData::Type::Socks5 + : ProxyData::Type::Http; Global::SetConnectionType(DBIConnectionType(v)); } break; case dbictHttpAuto: default: Global::SetConnectionType(dbictAuto); break; }; - Global::SetLastProxyType(Global::ConnectionType()); + Global::SetConnectionProxy(proxy); + Sandbox::refreshGlobalProxy(); } break; case dbiConnectionType: { - ProxyData p; - qint32 connectionType, lastProxyType, port; - stream >> connectionType >> lastProxyType >> p.host >> port >> p.user >> p.password; - if (!_checkStreamStatus(stream)) return false; + ProxyData proxy; + qint32 connectionType, proxyType, port; + stream >> connectionType >> proxyType >> proxy.host >> port >> proxy.user >> proxy.password; + if (!_checkStreamStatus(stream)) { + return false; + } - p.port = port; + proxy.port = port; + proxy.type = (proxyType == kProxyTypeShift + int(ProxyData::Type::Socks5)) + ? ProxyData::Type::Socks5 + : (proxyType == kProxyTypeShift + int(ProxyData::Type::Http)) + ? ProxyData::Type::Http + : (proxyType == dbictTcpProxy) + ? ProxyData::Type::Socks5 + : (proxyType == dbictHttpProxy) + ? ProxyData::Type::Http + : ProxyData::Type::None; switch (connectionType) { case dbictHttpProxy: case dbictTcpProxy: { - Global::SetConnectionType(DBIConnectionType(lastProxyType)); + Global::SetConnectionType(DBIConnectionType(connectionType)); } break; case dbictHttpAuto: default: Global::SetConnectionType(dbictAuto); break; }; - switch (lastProxyType) { - case dbictHttpProxy: - case dbictTcpProxy: { - Global::SetLastProxyType(DBIConnectionType(lastProxyType)); - Global::SetConnectionProxy(p); - } break; - case dbictHttpAuto: - default: { - Global::SetLastProxyType(dbictAuto); - Global::SetConnectionProxy(ProxyData()); - } break; - } + Global::SetConnectionProxy(proxy); + Sandbox::refreshGlobalProxy(); } break; case dbiThemeKey: { @@ -2403,7 +2408,7 @@ void writeSettings() { data.stream << quint32(dbiScale) << qint32(cConfigScale()); data.stream << quint32(dbiDcOptions) << dcOptionsSerialized; - data.stream << quint32(dbiConnectionType) << qint32(Global::ConnectionType()) << qint32(Global::LastProxyType()); + data.stream << quint32(dbiConnectionType) << qint32(Global::ConnectionType()) << qint32(kProxyTypeShift + int(proxy.type)); data.stream << proxy.host << qint32(proxy.port) << proxy.user << proxy.password; data.stream << quint32(dbiTryIPv6) << qint32(Global::TryIPv6());