summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Rossi <pierre.rossi@theqtcompany.com>2015-05-13 15:22:08 +0200
committerPierre Rossi <pierre.rossi@theqtcompany.com>2015-05-29 11:50:56 +0000
commit47ee541a9f0f8ee811187cf37838264379153163 (patch)
treea542bba8b6b9d2ceb37edb540ce164078058ae92
parente4361807da9db0609697e7a650947dbf26321cdc (diff)
Support QNetworkProxy::applicationProxy
Implement a ProxyConfigService that keeps track of the state of Qt's application proxy which, if set, takes precedence over the system settings. Change-Id: I7f1eba9015b70cf90f53a41736dd0a6d0ad28489 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
-rw-r--r--src/core/core_gyp_generator.pro2
-rw-r--r--src/core/proxy_config_service_qt.cpp171
-rw-r--r--src/core/proxy_config_service_qt.h87
-rw-r--r--src/core/url_request_context_getter_qt.cpp5
4 files changed, 263 insertions, 2 deletions
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 07ce48317..c2eb9bff1 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -58,6 +58,7 @@ SOURCES = \
network_delegate_qt.cpp \
ozone_platform_eglfs.cpp \
process_main.cpp \
+ proxy_config_service_qt.cpp \
qrc_protocol_handler_qt.cpp \
qt_render_view_observer_host.cpp \
render_widget_host_view_qt.cpp \
@@ -126,6 +127,7 @@ HEADERS = \
network_delegate_qt.h \
ozone_platform_eglfs.h \
process_main.h \
+ proxy_config_service_qt.h \
qrc_protocol_handler_qt.h \
qt_render_view_observer_host.h \
qtwebenginecoreglobal.h \
diff --git a/src/core/proxy_config_service_qt.cpp b/src/core/proxy_config_service_qt.cpp
new file mode 100644
index 000000000..2c28c0820
--- /dev/null
+++ b/src/core/proxy_config_service_qt.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "proxy_config_service_qt.h"
+
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qtProxy)
+{
+ net::ProxyServer::Scheme proxyScheme = net::ProxyServer::SCHEME_INVALID;
+ switch (qtProxy.type()) {
+ case QNetworkProxy::Socks5Proxy:
+ proxyScheme = net::ProxyServer::SCHEME_SOCKS5;
+ break;
+ case QNetworkProxy::HttpProxy:
+ case QNetworkProxy::HttpCachingProxy:
+ case QNetworkProxy::FtpCachingProxy:
+ proxyScheme = net::ProxyServer::SCHEME_HTTP;
+ break;
+ case QNetworkProxy::NoProxy:
+ default:
+ proxyScheme = net::ProxyServer::SCHEME_DIRECT;
+ break;
+ }
+ return net::ProxyServer(proxyScheme, net::HostPortPair(qtProxy.hostName().toStdString(), qtProxy.port()));
+}
+
+//================ Based on ChromeProxyConfigService =======================
+
+ProxyConfigServiceQt::ProxyConfigServiceQt(net::ProxyConfigService *baseService)
+ : m_baseService(baseService),
+ m_registeredObserver(false)
+{
+}
+
+ProxyConfigServiceQt::~ProxyConfigServiceQt()
+{
+ if (m_registeredObserver && m_baseService.get())
+ m_baseService->RemoveObserver(this);
+}
+
+void ProxyConfigServiceQt::AddObserver(net::ProxyConfigService::Observer *observer)
+{
+ RegisterObserver();
+ m_observers.AddObserver(observer);
+}
+
+void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *observer)
+{
+ m_observers.RemoveObserver(observer);
+}
+
+net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfig *config)
+{
+ RegisterObserver();
+
+ // Ask the base service if available.
+ net::ProxyConfig systemConfig;
+ ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET;
+ if (m_baseService.get())
+ systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
+
+ const QNetworkProxy &qtProxy = QNetworkProxy::applicationProxy();
+ if (qtProxy == m_qtApplicationProxy && !m_qtProxyConfig.proxy_rules().empty()) {
+ *config = m_qtProxyConfig;
+ return CONFIG_VALID;
+ }
+ m_qtApplicationProxy = qtProxy;
+ m_qtProxyConfig = net::ProxyConfig();
+ if (qtProxy.type() == QNetworkProxy::NoProxy) {
+ *config = systemConfig;
+ return systemAvailability;
+ }
+
+ net::ProxyConfig::ProxyRules qtRules;
+ net::ProxyServer server = fromQNetworkProxy(qtProxy);
+ switch (qtProxy.type()) {
+ case QNetworkProxy::HttpProxy:
+ case QNetworkProxy::Socks5Proxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+ qtRules.single_proxies.SetSingleProxyServer(server);
+ break;
+ case QNetworkProxy::HttpCachingProxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+ qtRules.proxies_for_http.SetSingleProxyServer(server);
+ break;
+ case QNetworkProxy::FtpCachingProxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+ qtRules.proxies_for_ftp.SetSingleProxyServer(server);
+ break;
+ default:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_NO_RULES;
+ }
+
+ m_qtProxyConfig.proxy_rules() = qtRules;
+ *config = m_qtProxyConfig;
+ return CONFIG_VALID;
+}
+
+void ProxyConfigServiceQt::OnLazyPoll()
+{
+ if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()) {
+ net::ProxyConfig unusedConfig;
+ OnProxyConfigChanged(unusedConfig, CONFIG_VALID);
+ }
+ if (m_baseService.get())
+ m_baseService->OnLazyPoll();
+}
+
+
+void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfig &config, ConfigAvailability availability)
+{
+ Q_UNUSED(config);
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()
+ || m_qtApplicationProxy.type() == QNetworkProxy::NoProxy) {
+ net::ProxyConfig actual_config;
+ availability = GetLatestProxyConfig(&actual_config);
+ FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, m_observers,
+ OnProxyConfigChanged(actual_config, availability));
+ }
+}
+
+void ProxyConfigServiceQt::RegisterObserver()
+{
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (!m_registeredObserver && m_baseService.get()) {
+ m_baseService->AddObserver(this);
+ m_registeredObserver = true;
+ }
+}
diff --git a/src/core/proxy_config_service_qt.h b/src/core/proxy_config_service_qt.h
new file mode 100644
index 000000000..f2f06d3fa
--- /dev/null
+++ b/src/core/proxy_config_service_qt.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROXY_CONFIG_SERVICE_QT_H
+#define PROXY_CONFIG_SERVICE_QT_H
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service.h"
+
+#include <QNetworkProxy>
+
+class ProxyConfigServiceQt
+ : public net::ProxyConfigService,
+ public net::ProxyConfigService::Observer {
+public:
+
+ static net::ProxyServer fromQNetworkProxy(const QNetworkProxy &);
+
+ explicit ProxyConfigServiceQt(net::ProxyConfigService *baseService);
+ ~ProxyConfigServiceQt() override;
+
+ // ProxyConfigService implementation:
+ void AddObserver(net::ProxyConfigService::Observer *observer) override;
+ void RemoveObserver(net::ProxyConfigService::Observer *observer) override;
+ ConfigAvailability GetLatestProxyConfig(net::ProxyConfig *config) override;
+ void OnLazyPoll() override;
+
+private:
+ // ProxyConfigService::Observer implementation:
+ void OnProxyConfigChanged(const net::ProxyConfig& config,
+ ConfigAvailability availability) override;
+
+ // Makes sure that the observer registration with the base service is set up.
+ void RegisterObserver();
+
+ scoped_ptr<net::ProxyConfigService> m_baseService;
+ ObserverList<net::ProxyConfigService::Observer, true> m_observers;
+
+ // Keep the last QNetworkProxy::applicationProxy state around.
+ QNetworkProxy m_qtApplicationProxy;
+ net::ProxyConfig m_qtProxyConfig;
+
+ // Indicates whether the base service registration is done.
+ bool m_registeredObserver;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt);
+};
+
+#endif // PROXY_CONFIG_SERVICE_QT_H
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index 4f893175a..8247e07eb 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -66,6 +66,7 @@
#include "custom_url_scheme_handler.h"
#include "content_client_qt.h"
#include "network_delegate_qt.h"
+#include "proxy_config_service_qt.h"
#include "qrc_protocol_handler_qt.h"
#include "type_conversion.h"
@@ -111,10 +112,10 @@ void URLRequestContextGetterQt::updateStorageSettings()
// We must create the proxy config service on the UI loop on Linux because it
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
- m_proxyConfigService = net::ProxyService::CreateSystemProxyConfigService(
+ m_proxyConfigService = new ProxyConfigServiceQt(net::ProxyService::CreateSystemProxyConfigService(
content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
- );
+ ));
if (m_storage)
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateStorage, this));
}