Commit b5c8c48a authored by Kai Koehne's avatar Kai Koehne
Browse files

Fix logic to check for proxy settings


The previous code tried to find out whether a user has set an
application proxy by checking the type of the applicationProxy.
This is wrong, because a system proxy will actually also change the
applicationProxy type.

Instead, we now rely on QNetworkProxyFactory::usesSystemConfiguration
to decide whether to use QtNetwork's application proxy, or Chromium's
logic for the system proxy. We also save the state of
QNetworkProxy::useSystemConfiguration to be able to track changes.

[ChangeLog][Networking] Fixed an issue where system proxy settings were
not picked up correctly.

Task-number: QTBUG-61910
Change-Id: I1d9af3f6006ba187266fe50c645f425a46632e41
Reviewed-by: default avatarPeter Varga <pvarga@inf.u-szeged.hu>
Showing with 63 additions and 35 deletions
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
** $QT_END_LICENSE$ ** $QT_END_LICENSE$
** **
****************************************************************************/ ****************************************************************************/
//================ Based on ChromeProxyConfigService =======================
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -67,11 +70,10 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt ...@@ -67,11 +70,10 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt
return net::ProxyServer(proxyScheme, net::HostPortPair(qtProxy.hostName().toStdString(), qtProxy.port())); return net::ProxyServer(proxyScheme, net::HostPortPair(qtProxy.hostName().toStdString(), qtProxy.port()));
} }
//================ Based on ChromeProxyConfigService =======================
ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService) ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService)
: m_baseService(baseService.release()), : m_baseService(baseService.release()),
m_registeredObserver(false) m_registeredObserver(false),
m_usesSystemConfiguration(false)
{ {
} }
...@@ -83,7 +85,6 @@ ProxyConfigServiceQt::~ProxyConfigServiceQt() ...@@ -83,7 +85,6 @@ ProxyConfigServiceQt::~ProxyConfigServiceQt()
void ProxyConfigServiceQt::AddObserver(net::ProxyConfigService::Observer *observer) void ProxyConfigServiceQt::AddObserver(net::ProxyConfigService::Observer *observer)
{ {
RegisterObserver();
m_observers.AddObserver(observer); m_observers.AddObserver(observer);
} }
...@@ -94,28 +95,31 @@ void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *obs ...@@ -94,28 +95,31 @@ void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *obs
net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfig *config) net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfig *config)
{ {
RegisterObserver(); #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
m_usesSystemConfiguration = QNetworkProxyFactory::usesSystemConfiguration();
// Ask the base service if available. #endif
net::ProxyConfig systemConfig; if (m_usesSystemConfiguration) {
ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET; // Use Chromium's base service to retrieve system settings
if (m_baseService.get()) net::ProxyConfig systemConfig;
systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig); ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET;
if (m_baseService.get())
systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
*config = systemConfig;
// make sure to get updates via OnProxyConfigChanged
RegisterObserver();
return systemAvailability;
}
// Use QNetworkProxy::applicationProxy settings
const QNetworkProxy &qtProxy = QNetworkProxy::applicationProxy(); const QNetworkProxy &qtProxy = QNetworkProxy::applicationProxy();
if (qtProxy == m_qtApplicationProxy && !m_qtProxyConfig.proxy_rules().empty()) { if (qtProxy == m_qtApplicationProxy && !m_qtProxyConfig.proxy_rules().empty()) {
// no changes
*config = m_qtProxyConfig; *config = m_qtProxyConfig;
return CONFIG_VALID; return CONFIG_VALID;
} }
m_qtApplicationProxy = qtProxy; m_qtApplicationProxy = qtProxy;
m_qtProxyConfig = net::ProxyConfig(); m_qtProxyConfig = net::ProxyConfig();
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
if (qtProxy.type() == QNetworkProxy::NoProxy
&& QNetworkProxyFactory::usesSystemConfiguration()) {
*config = systemConfig;
return systemAvailability;
}
#endif
net::ProxyConfig::ProxyRules qtRules; net::ProxyConfig::ProxyRules qtRules;
net::ProxyServer server = fromQNetworkProxy(qtProxy); net::ProxyServer server = fromQNetworkProxy(qtProxy);
...@@ -145,31 +149,51 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy ...@@ -145,31 +149,51 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy
void ProxyConfigServiceQt::OnLazyPoll() void ProxyConfigServiceQt::OnLazyPoll()
{ {
if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
net::ProxyConfig unusedConfig;
OnProxyConfigChanged(unusedConfig, CONFIG_VALID); #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
// We need to update if
// - setUseSystemConfiguration() was called in between
// - user changed application proxy
if (m_usesSystemConfiguration != QNetworkProxyFactory::usesSystemConfiguration()
|| (!m_usesSystemConfiguration && m_qtApplicationProxy != QNetworkProxy::applicationProxy())) {
Update();
} else if (m_usesSystemConfiguration) {
if (m_baseService.get())
m_baseService->OnLazyPoll();
} }
if (m_baseService.get()) #else
m_baseService->OnLazyPoll(); if (m_qtApplicationProxy != QNetworkProxy::applicationProxy())
Update();
#endif
} }
// Called when the base service changed
void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfig &config, ConfigAvailability availability) void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfig &config, ConfigAvailability availability)
{ {
Q_UNUSED(config);
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
Q_UNUSED(config);
if (m_qtApplicationProxy != QNetworkProxy::applicationProxy() if (!m_usesSystemConfiguration)
|| m_qtApplicationProxy.type() == QNetworkProxy::NoProxy) { return;
net::ProxyConfig actual_config;
availability = GetLatestProxyConfig(&actual_config); Update();
if (availability == CONFIG_PENDING) }
return;
for (net::ProxyConfigService::Observer &observer: m_observers) // Update our observers
observer.OnProxyConfigChanged(actual_config, availability); void ProxyConfigServiceQt::Update()
} {
net::ProxyConfig actual_config;
ConfigAvailability availability = GetLatestProxyConfig(&actual_config);
if (availability == CONFIG_PENDING)
return;
for (net::ProxyConfigService::Observer &observer: m_observers)
observer.OnProxyConfigChanged(actual_config, availability);
} }
// Register ourselves as observer of the base service.
// This has to be done on the IO thread, and therefore cannot be done
// in the constructor.
void ProxyConfigServiceQt::RegisterObserver() void ProxyConfigServiceQt::RegisterObserver()
{ {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
......
...@@ -69,13 +69,17 @@ private: ...@@ -69,13 +69,17 @@ private:
void OnProxyConfigChanged(const net::ProxyConfig& config, void OnProxyConfigChanged(const net::ProxyConfig& config,
ConfigAvailability availability) override; ConfigAvailability availability) override;
// Retrieve new proxy settings and notify observers.
void Update();
// Makes sure that the observer registration with the base service is set up. // Makes sure that the observer registration with the base service is set up.
void RegisterObserver(); void RegisterObserver();
std::unique_ptr<net::ProxyConfigService> m_baseService; std::unique_ptr<net::ProxyConfigService> m_baseService;
base::ObserverList<net::ProxyConfigService::Observer, true> m_observers; base::ObserverList<net::ProxyConfigService::Observer, true> m_observers;
// Keep the last QNetworkProxy::applicationProxy state around. // Keep the last state around.
bool m_usesSystemConfiguration;
QNetworkProxy m_qtApplicationProxy; QNetworkProxy m_qtApplicationProxy;
net::ProxyConfig m_qtProxyConfig; net::ProxyConfig m_qtProxyConfig;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment