summaryrefslogtreecommitdiffstats
path: root/src/core/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/net')
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp169
-rw-r--r--src/core/net/cookie_monster_delegate_qt.h46
-rw-r--r--src/core/net/custom_protocol_handler.cpp62
-rw-r--r--src/core/net/custom_protocol_handler.h89
-rw-r--r--src/core/net/custom_url_loader_factory.cpp446
-rw-r--r--src/core/net/custom_url_loader_factory.h (renamed from src/core/net/url_request_context_getter_qt.h)40
-rw-r--r--src/core/net/network_delegate_qt.cpp305
-rw-r--r--src/core/net/network_delegate_qt.h102
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp135
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.h (renamed from src/core/net/url_request_notification.h)62
-rw-r--r--src/core/net/proxy_config_monitor.cpp125
-rw-r--r--src/core/net/proxy_config_monitor.h104
-rw-r--r--src/core/net/proxy_config_service_qt.cpp32
-rw-r--r--src/core/net/proxy_config_service_qt.h12
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.cpp231
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.h (renamed from src/core/net/restricted_cookie_manager_qt.h)53
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp560
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.h107
-rw-r--r--src/core/net/restricted_cookie_manager_qt.cpp185
-rw-r--r--src/core/net/system_network_context_manager.cpp351
-rw-r--r--src/core/net/system_network_context_manager.h187
-rw-r--r--src/core/net/url_request_context_getter_qt.cpp69
-rw-r--r--src/core/net/url_request_custom_job.cpp253
-rw-r--r--src/core/net/url_request_custom_job.h93
-rw-r--r--src/core/net/url_request_custom_job_delegate.cpp22
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp88
-rw-r--r--src/core/net/url_request_custom_job_proxy.h23
-rw-r--r--src/core/net/url_request_notification.cpp193
28 files changed, 2523 insertions, 1621 deletions
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index dad9a8db5..dba79b4db 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -44,7 +44,9 @@
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "net/cookies/cookie_util.h"
+#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "api/qwebenginecookiestore.h"
#include "api/qwebenginecookiestore_p.h"
@@ -52,6 +54,25 @@
namespace QtWebEngineCore {
+class CookieChangeListener : public network::mojom::CookieChangeListener
+{
+public:
+ CookieChangeListener(CookieMonsterDelegateQt *delegate) : m_delegate(delegate) { }
+ ~CookieChangeListener() override = default;
+
+ // network::mojom::CookieChangeListener:
+ void OnCookieChange(const net::CanonicalCookie &canonical_cookie,
+ network::mojom::CookieChangeCause cause) override
+ {
+ m_delegate->OnCookieChanged(canonical_cookie, net::CookieChangeCause(cause));
+ }
+
+private:
+ CookieMonsterDelegateQt *m_delegate;
+
+ DISALLOW_COPY_AND_ASSIGN(CookieChangeListener);
+};
+
static GURL sourceUrlForCookie(const QNetworkCookie &cookie)
{
QString urlFragment = QStringLiteral("%1%2").arg(cookie.domain()).arg(cookie.path());
@@ -60,7 +81,8 @@ static GURL sourceUrlForCookie(const QNetworkCookie &cookie)
CookieMonsterDelegateQt::CookieMonsterDelegateQt()
: m_client(0)
- , m_cookieMonster(nullptr)
+ , m_listener(new CookieChangeListener(this))
+ , m_binding(m_listener.get())
{
}
@@ -81,22 +103,12 @@ void CookieMonsterDelegateQt::AddStore(net::CookieStore *store)
bool CookieMonsterDelegateQt::hasCookieMonster()
{
- return m_cookieMonster;
+ return m_mojoCookieManager.is_bound();
}
void CookieMonsterDelegateQt::getAllCookies(quint64 callbackId)
{
- net::CookieMonster::GetCookieListCallback callback =
- base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesCallbackOnIOThread, this, callbackId);
-
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesOnIOThread, this, std::move(callback)));
-}
-
-void CookieMonsterDelegateQt::GetAllCookiesOnIOThread(net::CookieMonster::GetCookieListCallback callback)
-{
- if (m_cookieMonster)
- m_cookieMonster->GetAllCookiesAsync(std::move(callback));
+ m_mojoCookieManager->GetAllCookies(base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread, this, callbackId));
}
void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie &cookie, const QUrl &origin)
@@ -105,24 +117,16 @@ void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie
Q_ASSERT(m_client);
net::CookieStore::SetCookiesCallback callback;
- if (callbackId != CallbackDirectory::NoCallbackId)
- callback = base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnIOThread, this, callbackId);
GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin);
+ std::string cookie_line = cookie.toRawForm().toStdString();
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&CookieMonsterDelegateQt::SetCookieOnIOThread, this,
- gurl, cookie.toRawForm().toStdString(), std::move(callback)));
-}
-
-void CookieMonsterDelegateQt::SetCookieOnIOThread(const GURL &url, const std::string &cookie_line,
- net::CookieMonster::SetCookiesCallback callback)
-{
+ if (callbackId != CallbackDirectory::NoCallbackId)
+ callback = base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnUIThread, this, callbackId);
net::CookieOptions options;
options.set_include_httponly();
-
- if (m_cookieMonster)
- m_cookieMonster->SetCookieWithOptionsAsync(url, cookie_line, options, std::move(callback));
+ auto canonCookie = net::CanonicalCookie::Create(gurl, cookie_line, base::Time::Now(), options);
+ m_mojoCookieManager->SetCanonicalCookie(*canonCookie.get(), gurl.scheme(), options, std::move(callback));
}
void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin)
@@ -131,53 +135,23 @@ void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const Q
Q_ASSERT(m_client);
GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin);
-
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&CookieMonsterDelegateQt::DeleteCookieOnIOThread, this,
- gurl, cookie.name().toStdString()));
-}
-
-void CookieMonsterDelegateQt::DeleteCookieOnIOThread(const GURL &url, const std::string &cookie_name)
-{
- if (m_cookieMonster) {
- net::CookieMonster::GetCookieListCallback callback =
- base::BindOnce(&CookieMonsterDelegateQt::GetCookiesToDeleteCallback, this, cookie_name);
- m_cookieMonster->GetAllCookiesForURLAsync(url, std::move(callback));
- }
-}
-
-void CookieMonsterDelegateQt::GetCookiesToDeleteCallback(const std::string &cookie_name, const net::CookieList &cookies,
- const net::CookieStatusList &statusList)
-{
- Q_UNUSED(statusList);
- if (!m_cookieMonster)
- return;
-
- net::CookieList cookiesToDelete;
- for (auto cookie : cookies) {
- if (cookie.Name() == cookie_name)
- cookiesToDelete.push_back(cookie);
- }
- for (auto cookie : cookiesToDelete)
- m_cookieMonster->DeleteCanonicalCookieAsync(cookie, base::DoNothing());
+ std::string cookie_name = cookie.name().toStdString();
+ auto filter = network::mojom::CookieDeletionFilter::New();
+ filter->url = gurl;
+ filter->cookie_name = cookie_name;
+ m_mojoCookieManager->DeleteCookies(std::move(filter), network::mojom::CookieManager::DeleteCookiesCallback());
}
-
void CookieMonsterDelegateQt::deleteSessionCookies(quint64 callbackId)
{
Q_ASSERT(hasCookieMonster());
Q_ASSERT(m_client);
- net::CookieMonster::DeleteCallback callback =
- base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnIOThread, this, callbackId);
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&CookieMonsterDelegateQt::DeleteSessionCookiesOnIOThread, this, std::move(callback)));
-}
-
-void CookieMonsterDelegateQt::DeleteSessionCookiesOnIOThread(net::CookieMonster::DeleteCallback callback)
-{
- if (m_cookieMonster)
- m_cookieMonster->DeleteSessionCookiesAsync(std::move(callback));
+ network::mojom::CookieManager::DeleteCookiesCallback callback =
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnUIThread, this, callbackId);
+ auto filter = network::mojom::CookieDeletionFilter::New();
+ filter->session_control = network::mojom::CookieDeletionSessionControl::SESSION_COOKIES;
+ m_mojoCookieManager->DeleteCookies(std::move(filter), std::move(callback));
}
void CookieMonsterDelegateQt::deleteAllCookies(quint64 callbackId)
@@ -185,36 +159,30 @@ void CookieMonsterDelegateQt::deleteAllCookies(quint64 callbackId)
Q_ASSERT(hasCookieMonster());
Q_ASSERT(m_client);
- net::CookieMonster::DeleteCallback callback =
- base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnIOThread, this, callbackId);
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&CookieMonsterDelegateQt::DeleteAllOnIOThread, this, std::move(callback)));
-}
-
-void CookieMonsterDelegateQt::DeleteAllOnIOThread(net::CookieMonster::DeleteCallback callback)
-{
- if (m_cookieMonster)
- m_cookieMonster->DeleteAllAsync(std::move(callback));
+ network::mojom::CookieManager::DeleteCookiesCallback callback =
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnUIThread, this, callbackId);
+ auto filter = network::mojom::CookieDeletionFilter::New();
+ m_mojoCookieManager->DeleteCookies(std::move(filter), std::move(callback));
}
-void CookieMonsterDelegateQt::setCookieMonster(net::CookieMonster *monster)
+void CookieMonsterDelegateQt::setMojoCookieManager(network::mojom::CookieManagerPtrInfo cookie_manager_info)
{
- if (monster == m_cookieMonster)
- return;
-
- m_subscriptions.clear();
- if (monster)
- AddStore(monster);
+// DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ m_mojoCookieManager.Bind(std::move(cookie_manager_info));
- m_cookieMonster = monster;
+ network::mojom::CookieChangeListenerPtr listener_ptr;
+ m_binding.Bind(mojo::MakeRequest(&listener_ptr));
- if (!m_client)
- return;
+ m_mojoCookieManager->AddGlobalChangeListener(std::move(listener_ptr));
- if (monster)
+ if (m_client)
m_client->d_func()->processPendingUserCookies();
- else
- m_client->d_func()->rejectPendingUserCookies();
+}
+
+void CookieMonsterDelegateQt::unsetMojoCookieManager()
+{
+ m_binding.Close();
+ m_mojoCookieManager.reset();
}
void CookieMonsterDelegateQt::setClient(QWebEngineCookieStore *client)
@@ -253,32 +221,17 @@ void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie &cookie
m_client->d_func()->onCookieChanged(toQt(cookie), cause != net::CookieChangeCause::INSERTED);
}
-void CookieMonsterDelegateQt::GetAllCookiesCallbackOnIOThread(qint64 callbackId, const net::CookieList &cookies, const net::CookieStatusList &statusList)
+void CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread(qint64 callbackId, const std::vector<net::CanonicalCookie> &cookies)
{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
QByteArray rawCookies;
for (auto &&cookie : cookies)
rawCookies += toQt(cookie).toRawForm() % QByteArrayLiteral("\n");
- base::PostTaskWithTraits(
- FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread, this, callbackId, rawCookies));
-}
-
-void CookieMonsterDelegateQt::SetCookieCallbackOnIOThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status)
-{
- base::PostTaskWithTraits(
- FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnUIThread, this, callbackId, status));
-}
-
-void CookieMonsterDelegateQt::DeleteCookiesCallbackOnIOThread(qint64 callbackId, uint numCookies)
-{
- base::PostTaskWithTraits(
- FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnUIThread, this, callbackId, numCookies));
+ GetAllCookiesResultOnUIThread(callbackId, rawCookies);
}
-void CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread(qint64 callbackId, const QByteArray &cookies)
+void CookieMonsterDelegateQt::GetAllCookiesResultOnUIThread(qint64 callbackId, const QByteArray &cookies)
{
if (m_client)
m_client->d_func()->onGetAllCallbackResult(callbackId, cookies);
diff --git a/src/core/net/cookie_monster_delegate_qt.h b/src/core/net/cookie_monster_delegate_qt.h
index 23b803790..f7ebe38c2 100644
--- a/src/core/net/cookie_monster_delegate_qt.h
+++ b/src/core/net/cookie_monster_delegate_qt.h
@@ -57,8 +57,22 @@ QT_WARNING_PUSH
// For some reason adding -Wno-unused-parameter to QMAKE_CXXFLAGS has no
// effect with clang, so use a pragma for these dirty chromium headers
QT_WARNING_DISABLE_CLANG("-Wunused-parameter")
+
+// We need to work around Chromium using 'signals' as a variable name in headers:
+#ifdef signals
+#define StAsH_signals signals
+#undef signals
+#endif
#include "base/memory/ref_counted.h"
-#include "net/cookies/cookie_monster.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "net/cookies/cookie_change_dispatcher.h"
+#include "net/cookies/cookie_store.h"
+#include "services/network/public/mojom/cookie_manager.mojom-forward.h"
+#include "services/network/public/mojom/cookie_manager.mojom.h"
+#ifdef StAsH_signals
+#define signals StAsH_signals
+#undef StAsH_signals
+#endif
QT_WARNING_POP
#include <QNetworkCookie>
@@ -68,18 +82,16 @@ QT_FORWARD_DECLARE_CLASS(QWebEngineCookieStore)
namespace QtWebEngineCore {
-// Extends net::CookieMonster::kDefaultCookieableSchemes with qrc, without enabling
-// cookies for the file:// scheme, which is disabled by default in Chromium.
-// Since qrc:// is similar to file:// and there are some unknowns about how
-// to correctly handle file:// cookies, qrc:// should only be used for testing.
-static const char *const kCookieableSchemes[] = { "http", "https", "qrc", "ws", "wss" };
+class CookieMonsterDelegateQtPrivate;
class Q_WEBENGINECORE_PRIVATE_EXPORT CookieMonsterDelegateQt : public base::RefCountedThreadSafe<CookieMonsterDelegateQt>
{
QPointer<QWebEngineCookieStore> m_client;
- net::CookieMonster *m_cookieMonster;
std::vector<std::unique_ptr<net::CookieChangeSubscription>> m_subscriptions;
+ network::mojom::CookieManagerPtr m_mojoCookieManager;
+ std::unique_ptr<network::mojom::CookieChangeListener> m_listener;
+ mojo::Binding<network::mojom::CookieChangeListener> m_binding;
public:
CookieMonsterDelegateQt();
~CookieMonsterDelegateQt();
@@ -92,8 +104,9 @@ public:
void deleteSessionCookies(quint64 callbackId);
void deleteAllCookies(quint64 callbackId);
- void setCookieMonster(net::CookieMonster *monster);
void setClient(QWebEngineCookieStore *client);
+ void setMojoCookieManager(network::mojom::CookieManagerPtrInfo cookie_manager_info);
+ void unsetMojoCookieManager();
bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url) const;
bool canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) const;
@@ -102,21 +115,8 @@ public:
void OnCookieChanged(const net::CanonicalCookie &cookie, net::CookieChangeCause cause);
private:
- void GetAllCookiesOnIOThread(net::CookieMonster::GetCookieListCallback callback);
- void SetCookieOnIOThread(const GURL &url, const std::string &cookie_line,
- net::CookieMonster::SetCookiesCallback callback);
- void DeleteCookieOnIOThread(const GURL &url, const std::string &cookie_name);
- void DeleteSessionCookiesOnIOThread(net::CookieMonster::DeleteCallback callback);
- void DeleteAllOnIOThread(net::CookieMonster::DeleteCallback callback);
-
- void GetCookiesToDeleteCallback(const std::string &cookie_name, const net::CookieList &cookies,
- const net::CookieStatusList &statusList);
- void GetAllCookiesCallbackOnIOThread(qint64 callbackId, const net::CookieList &cookies,
- const net::CookieStatusList &statusList);
- void SetCookieCallbackOnIOThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status);
- void DeleteCookiesCallbackOnIOThread(qint64 callbackId, uint numCookies);
-
- void GetAllCookiesCallbackOnUIThread(qint64 callbackId, const QByteArray &cookies);
+ void GetAllCookiesCallbackOnUIThread(qint64 callbackId, const std::vector<net::CanonicalCookie> &cookies);
+ void GetAllCookiesResultOnUIThread(qint64 callbackId, const QByteArray &cookies);
void SetCookieCallbackOnUIThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status);
void DeleteCookiesCallbackOnUIThread(qint64 callbackId, uint numCookies);
};
diff --git a/src/core/net/custom_protocol_handler.cpp b/src/core/net/custom_protocol_handler.cpp
deleted file mode 100644
index 7e8ee47ab..000000000
--- a/src/core/net/custom_protocol_handler.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "custom_protocol_handler.h"
-#include "url_request_custom_job.h"
-
-#include "net/base/net_errors.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_error_job.h"
-
-namespace QtWebEngineCore {
-
-CustomProtocolHandler::CustomProtocolHandler(QPointer<ProfileAdapter> profileAdapter)
- : m_profileAdapter(profileAdapter)
-{
-}
-
-net::URLRequestJob *CustomProtocolHandler::MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const
-{
- if (!networkDelegate)
- return new net::URLRequestErrorJob(request, nullptr, net::ERR_ACCESS_DENIED);
-
- return new URLRequestCustomJob(request, networkDelegate, request->url().scheme(), m_profileAdapter);
-}
-
-} // namespace
diff --git a/src/core/net/custom_protocol_handler.h b/src/core/net/custom_protocol_handler.h
deleted file mode 100644
index 625afc1d5..000000000
--- a/src/core/net/custom_protocol_handler.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef CUSTOM_PROTOCOL_HANDLER_H_
-#define CUSTOM_PROTOCOL_HANDLER_H_
-
-#include "qtwebenginecoreglobal_p.h"
-#include "net/url_request/url_request_job_factory.h"
-
-#include <QtCore/QByteArray>
-#include <QtCore/QObject>
-#include <QtCore/QPointer>
-
-QT_FORWARD_DECLARE_CLASS(QIODevice)
-
-namespace net {
-class NetworkDelegate;
-class URLRequestJob;
-} // namespace
-
-namespace QtWebEngineCore {
-
-class ProfileAdapter;
-
-// Implements a ProtocolHandler for custom URL schemes.
-// If |network_delegate_| is NULL then all file requests will fail with ERR_ACCESS_DENIED.
-class Q_WEBENGINECORE_PRIVATE_EXPORT CustomProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler
-{
-
-public:
- CustomProtocolHandler(QPointer<ProfileAdapter> profileAdapter);
-
- net::URLRequestJob *MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
- QPointer<ProfileAdapter> m_profileAdapter;
-};
-
-} // namespace
-
-#endif // CUSTOM_PROTOCOL_HANDLER_H_
diff --git a/src/core/net/custom_url_loader_factory.cpp b/src/core/net/custom_url_loader_factory.cpp
new file mode 100644
index 000000000..555eccf42
--- /dev/null
+++ b/src/core/net/custom_url_loader_factory.cpp
@@ -0,0 +1,446 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "custom_url_loader_factory.h"
+
+#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_status_code.h"
+#include "net/http/http_util.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+
+#include "api/qwebengineurlscheme.h"
+#include "net/url_request_custom_job_proxy.h"
+#include "profile_adapter.h"
+#include "type_conversion.h"
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qiodevice.h>
+#include <QtCore/qmimedatabase.h>
+#include <QtCore/qmimedata.h>
+#include <QtCore/qurl.h>
+
+namespace QtWebEngineCore {
+
+namespace {
+
+class CustomURLLoader : public network::mojom::URLLoader
+ , private URLRequestCustomJobProxy::Client
+{
+public:
+ static void CreateAndStart(const network::ResourceRequest &request,
+ network::mojom::URLLoaderRequest loader,
+ network::mojom::URLLoaderClientPtrInfo client_info,
+ QPointer<ProfileAdapter> profileAdapter)
+ {
+ // CustomURLLoader will handle its own life-cycle, and delete when
+ // the client lets go.
+ auto *customUrlLoader = new CustomURLLoader(request, std::move(loader), std::move(client_info), profileAdapter);
+ customUrlLoader->Start();
+ }
+
+ // network::mojom::URLLoader:
+ void FollowRedirect(const std::vector<std::string> &removed_headers,
+ const net::HttpRequestHeaders &modified_headers,
+ const base::Optional<GURL> &new_url) override
+ {
+ // We can be asked for follow our own redirect
+ scoped_refptr<URLRequestCustomJobProxy> proxy = new URLRequestCustomJobProxy(this, m_proxy->m_scheme, m_proxy->m_profileAdapter);
+ m_proxy->m_client = nullptr;
+// m_taskRunner->PostTask(FROM_HERE, base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
+ base::PostTaskWithTraits(FROM_HERE, { content::BrowserThread::UI },
+ base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
+ m_proxy = std::move(proxy);
+ if (new_url)
+ m_request.url = *new_url;
+ else
+ m_request.url = m_redirect;
+ m_redirect = GURL();
+ for (const std::string &header: removed_headers)
+ m_request.headers.RemoveHeader(header);
+ m_request.headers.MergeFrom(modified_headers);
+ Start();
+ }
+ void SetPriority(net::RequestPriority priority, int32_t intra_priority_value) override { }
+ void PauseReadingBodyFromNet() override { }
+ void ResumeReadingBodyFromNet() override { }
+ void ProceedWithResponse() override { }
+
+private:
+ CustomURLLoader(const network::ResourceRequest &request,
+ network::mojom::URLLoaderRequest loader,
+ network::mojom::URLLoaderClientPtrInfo client_info,
+ QPointer<ProfileAdapter> profileAdapter)
+ // ### We can opt to run the url-loader on the UI thread instead
+ : m_taskRunner(base::CreateSingleThreadTaskRunner({ content::BrowserThread::IO }))
+ , m_proxy(new URLRequestCustomJobProxy(this, request.url.scheme(), profileAdapter))
+ , m_binding(this, std::move(loader))
+ , m_client(std::move(client_info))
+ , m_request(request)
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_binding.set_connection_error_handler(
+ base::BindOnce(&CustomURLLoader::OnConnectionError, m_weakPtrFactory.GetWeakPtr()));
+ m_firstBytePosition = 0;
+ m_device = nullptr;
+ m_error = 0;
+ QWebEngineUrlScheme scheme = QWebEngineUrlScheme::schemeByName(QByteArray::fromStdString(request.url.scheme()));
+ m_corsEnabled = scheme.flags().testFlag(QWebEngineUrlScheme::CorsEnabled);
+ }
+
+ ~CustomURLLoader() override = default;
+
+ void Start()
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_head.request_start = base::TimeTicks::Now();
+
+ if (!m_pipe.consumer_handle.is_valid())
+ return CompleteWithFailure(net::ERR_FAILED);
+
+ std::map<std::string, std::string> headers;
+ net::HttpRequestHeaders::Iterator it(m_request.headers);
+ while (it.GetNext())
+ headers.emplace(it.name(), it.value());
+ if (!m_request.referrer.is_empty())
+ headers.emplace("Referer", m_request.referrer.spec());
+
+ std::string rangeHeader;
+ if (m_request.headers.GetHeader(net::HttpRequestHeaders::kRange, &rangeHeader)) {
+ std::vector<net::HttpByteRange> ranges;
+ if (net::HttpUtil::ParseRangeHeader(rangeHeader, &ranges)) {
+ // Chromium doesn't support multiple range requests in one single URL request.
+ if (ranges.size() == 1)
+ m_firstBytePosition = ranges[0].first_byte_position();
+ }
+ }
+
+// m_taskRunner->PostTask(FROM_HERE,
+ base::PostTaskWithTraits(FROM_HERE, { content::BrowserThread::UI },
+ base::BindOnce(&URLRequestCustomJobProxy::initialize, m_proxy,
+ m_request.url, m_request.method, m_request.request_initiator, std::move(headers)));
+ }
+
+ void CompleteWithFailure(net::Error net_error)
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_client->OnComplete(network::URLLoaderCompletionStatus(net_error));
+ ClearProxyAndClient(false);
+ }
+
+ void OnConnectionError()
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_binding.Close();
+ if (m_client.is_bound())
+ ClearProxyAndClient(false);
+ else
+ delete this;
+ }
+
+ void OnTransferComplete(MojoResult result)
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ if (result == MOJO_RESULT_OK) {
+ network::URLLoaderCompletionStatus status(net::OK);
+ status.encoded_data_length = m_totalBytesRead + m_head.headers->raw_headers().length();
+ status.encoded_body_length = m_totalBytesRead;
+ status.decoded_body_length = m_totalBytesRead;
+ m_client->OnComplete(status);
+ } else {
+ m_client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ }
+ ClearProxyAndClient(false /* result == MOJO_RESULT_OK */);
+ }
+
+ void ClearProxyAndClient(bool wait_for_loader_error = false)
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_proxy->m_client = nullptr;
+ m_client.reset();
+ if (m_device && m_device->isOpen())
+ m_device->close();
+ m_device = nullptr;
+// m_taskRunner->PostTask(FROM_HERE, base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
+ base::PostTaskWithTraits(FROM_HERE, { content::BrowserThread::UI },
+ base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
+ if (!wait_for_loader_error || !m_binding.is_bound())
+ delete this;
+ }
+
+ // URLRequestCustomJobProxy::Client:
+ void notifyExpectedContentSize(qint64 size) override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_head.content_length = size;
+ }
+ void notifyHeadersComplete() override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ DCHECK(!m_error);
+ m_head.response_start = base::TimeTicks::Now();
+
+ std::string headers;
+ if (!m_redirect.is_empty()) {
+ headers += "HTTP/1.1 303 See Other\n";
+ headers += base::StringPrintf("Location: %s\n", m_redirect.spec().c_str());
+ } else {
+ headers += "HTTP/1.1 200 OK\n";
+ if (m_mimeType.size() > 0) {
+ headers += base::StringPrintf("Content-Type: %s", m_mimeType.c_str());
+ if (m_charset.size() > 0)
+ headers += base::StringPrintf("; charset=%s", m_charset.c_str());
+ headers += "\n";
+ }
+ }
+ if (m_corsEnabled) {
+ std::string origin;
+ if (m_request.headers.GetHeader("Origin", &origin)) {
+ headers += base::StringPrintf("Access-Control-Allow-Origin: %s\n", origin.c_str());
+ headers += "Access-Control-Allow-Credentials: true\n";
+ }
+ }
+ m_head.headers = base::MakeRefCounted<net::HttpResponseHeaders>(net::HttpUtil::AssembleRawHeaders(headers));
+ m_head.encoded_data_length = m_head.headers->raw_headers().length();
+
+ if (!m_redirect.is_empty()) {
+ m_head.content_length = m_head.encoded_body_length = -1;
+ net::URLRequest::FirstPartyURLPolicy first_party_url_policy =
+ m_request.update_first_party_url_on_redirect ? net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT
+ : net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
+ net::RedirectInfo redirectInfo = net::RedirectInfo::ComputeRedirectInfo(
+ m_request.method, m_request.url,
+ m_request.site_for_cookies, m_request.top_frame_origin,
+ first_party_url_policy, m_request.referrer_policy,
+ m_request.referrer.spec(), net::HTTP_SEE_OTHER,
+ m_redirect, base::nullopt, false /*insecure_scheme_was_upgraded*/);
+ m_client->OnReceiveRedirect(redirectInfo, m_head);
+ // ### should m_request be updated with RedirectInfo? (see FollowRedirect)
+ return;
+ }
+ DCHECK(m_device);
+ m_head.mime_type = m_mimeType;
+ m_head.charset = m_charset;
+ m_client->OnReceiveResponse(m_head);
+ m_client->OnStartLoadingResponseBody(std::move(m_pipe.consumer_handle));
+
+ readAvailableData();
+ if (m_device) {
+ m_watcher = std::make_unique<mojo::SimpleWatcher>(
+ FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC, m_taskRunner);
+ m_watcher->Watch(m_pipe.producer_handle.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ MOJO_WATCH_CONDITION_SATISFIED,
+ base::BindRepeating(&CustomURLLoader::notifyReadyWrite,
+ m_weakPtrFactory.GetWeakPtr()));
+ }
+ }
+ void notifyCanceled() override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ OnTransferComplete(MOJO_RESULT_CANCELLED);
+ }
+ void notifyAborted() override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ notifyStartFailure(net::ERR_ABORTED);
+ }
+ void notifyStartFailure(int error) override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_head.response_start = base::TimeTicks::Now();
+ std::string headers;
+ switch (error) {
+ case net::ERR_INVALID_URL:
+ headers = "HTTP/1.1 400 Bad Request\n";
+ break;
+ case net::ERR_FILE_NOT_FOUND:
+ headers = "HTTP/1.1 404 Not Found\n";
+ break;
+ case net::ERR_ABORTED:
+ headers = "HTTP/1.1 503 Request Aborted\n";
+ break;
+ case net::ERR_ACCESS_DENIED:
+ headers = "HTTP/1.1 403 Forbidden\n";
+ break;
+ case net::ERR_FAILED:
+ headers = "HTTP/1.1 400 Request Failed\n";
+ break;
+ default:
+ headers = "HTTP/1.1 500 Internal Error\n";
+ break;
+ }
+ m_head.headers = base::MakeRefCounted<net::HttpResponseHeaders>(net::HttpUtil::AssembleRawHeaders(headers));
+ m_head.encoded_data_length = m_head.headers->raw_headers().length();
+ m_head.content_length = m_head.encoded_body_length = -1;
+ m_client->OnReceiveResponse(m_head);
+ CompleteWithFailure(net::Error(error));
+ }
+ void notifyReadyRead() override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ readAvailableData();
+ }
+ void notifyReadyWrite(MojoResult result, const mojo::HandleSignalsState &state)
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ if (result != MOJO_RESULT_OK) {
+ CompleteWithFailure(net::ERR_FAILED);
+ return;
+ }
+ readAvailableData();
+ }
+ void readAvailableData()
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ for (;;) {
+ if (m_error || !m_device)
+ break;
+
+ void *buffer = nullptr;
+ uint32_t bufferSize = 0;
+ MojoResult beginResult = m_pipe.producer_handle->BeginWriteData(
+ &buffer, &bufferSize, MOJO_BEGIN_WRITE_DATA_FLAG_NONE);
+ if (beginResult == MOJO_RESULT_SHOULD_WAIT)
+ return; // Wait for pipe watcher
+ if (beginResult != MOJO_RESULT_OK)
+ break;
+
+ int readResult = m_device->read(static_cast<char *>(buffer), bufferSize);
+ uint32_t bytesRead = std::max(readResult, 0);
+ m_pipe.producer_handle->EndWriteData(bytesRead);
+ m_totalBytesRead += bytesRead;
+ m_client->OnTransferSizeUpdated(m_totalBytesRead);
+
+ if (m_device->atEnd()) {
+ OnTransferComplete(MOJO_RESULT_OK);
+ return;
+ }
+
+ if (readResult == 0)
+ return; // Wait for readyRead
+ if (readResult < 0)
+ break;
+ }
+
+ CompleteWithFailure(m_error ? net::Error(m_error) : net::ERR_FAILED);
+ }
+ base::TaskRunner *taskRunner() override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ return m_taskRunner.get();
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> m_taskRunner;
+ scoped_refptr<URLRequestCustomJobProxy> m_proxy;
+
+ mojo::Binding<network::mojom::URLLoader> m_binding;
+ network::mojom::URLLoaderClientPtr m_client;
+ mojo::DataPipe m_pipe;
+ std::unique_ptr<mojo::SimpleWatcher> m_watcher;
+
+ network::ResourceRequest m_request;
+ network::ResourceResponseHead m_head;
+ qint64 m_totalBytesRead = 0;
+ bool m_corsEnabled;
+
+ base::WeakPtrFactory<CustomURLLoader> m_weakPtrFactory{this};
+
+ DISALLOW_COPY_AND_ASSIGN(CustomURLLoader);
+};
+
+class CustomURLLoaderFactory : public network::mojom::URLLoaderFactory {
+public:
+ CustomURLLoaderFactory(ProfileAdapter *profileAdapter)
+ : m_taskRunner(base::CreateSequencedTaskRunner({ content::BrowserThread::IO }))
+ , m_profileAdapter(profileAdapter)
+ {
+ }
+ ~CustomURLLoaderFactory() override = default;
+
+ // network::mojom::URLLoaderFactory:
+ void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest &request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation) override
+ {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ Q_UNUSED(routing_id);
+ Q_UNUSED(request_id);
+ Q_UNUSED(options);
+ Q_UNUSED(traffic_annotation);
+
+ m_taskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&CustomURLLoader::CreateAndStart, request,
+ std::move(loader), client.PassInterface(),
+ m_profileAdapter));
+
+ }
+
+ void Clone(network::mojom::URLLoaderFactoryRequest request) override
+ {
+ m_bindings.AddBinding(this, std::move(request));
+ }
+
+ const scoped_refptr<base::SequencedTaskRunner> m_taskRunner;
+ mojo::BindingSet<network::mojom::URLLoaderFactory> m_bindings;
+ QPointer<ProfileAdapter> m_profileAdapter;
+ DISALLOW_COPY_AND_ASSIGN(CustomURLLoaderFactory);
+};
+
+} // namespace
+
+std::unique_ptr<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter)
+{
+ return std::make_unique<CustomURLLoaderFactory>(profileAdapter);
+}
+
+} // namespace QtWebEngineCore
+
diff --git a/src/core/net/url_request_context_getter_qt.h b/src/core/net/custom_url_loader_factory.h
index a6ef6eae0..58adf4b79 100644
--- a/src/core/net/url_request_context_getter_qt.h
+++ b/src/core/net/custom_url_loader_factory.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,27 +37,33 @@
**
****************************************************************************/
-#ifndef URL_REQUEST_CONTEXT_GETTER_QT_H
-#define URL_REQUEST_CONTEXT_GETTER_QT_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
-#include "net/url_request/url_request_context_getter.h"
+#ifndef CUSTOM_URL_LOADER_FACTORY_H_
+#define CUSTOM_URL_LOADER_FACTORY_H_
-namespace QtWebEngineCore {
+#include <memory>
-class ProfileIODataQt;
+namespace network {
+namespace mojom {
+class URLLoaderFactory;
+} // namespace mojom
+} // namespace network
-class URLRequestContextGetterQt : public net::URLRequestContextGetter
-{
-public:
- URLRequestContextGetterQt(ProfileIODataQt *data);
- net::URLRequestContext *GetURLRequestContext() override;
- scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const override;
+namespace QtWebEngineCore {
+class ProfileAdapter;
-private:
- virtual ~URLRequestContextGetterQt();
- ProfileIODataQt *m_profileIOData;
-};
+std::unique_ptr<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter);
} // namespace QtWebEngineCore
-#endif // URL_REQUEST_CONTEXT_GETTER_QT_H
+#endif // CUSTOM_URL_LOADER_FACTORY_H_
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
deleted file mode 100644
index 7d3801ffe..000000000
--- a/src/core/net/network_delegate_qt.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "network_delegate_qt.h"
-
-#include "base/task/post_task.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/resource_request_info.h"
-#include "net/base/load_flags.h"
-#include "net/url_request/url_request.h"
-#include "ui/base/page_transition_types.h"
-
-#include "profile_adapter.h"
-#include "cookie_monster_delegate_qt.h"
-#include "profile_io_data_qt.h"
-#include "qwebengineurlrequestinfo.h"
-#include "qwebengineurlrequestinfo_p.h"
-#include "qwebengineurlrequestinterceptor.h"
-#include "type_conversion.h"
-#include "web_contents_adapter_client.h"
-#include "web_contents_view_qt.h"
-#include "url_request_notification.h"
-
-namespace QtWebEngineCore {
-
-WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition)
-{
- if (ui::PageTransitionIsRedirect(transition))
- return WebContentsAdapterClient::RedirectNavigation;
-
- int32_t qualifier = ui::PageTransitionGetQualifier(transition);
-
- if (qualifier & ui::PAGE_TRANSITION_FORWARD_BACK)
- return WebContentsAdapterClient::BackForwardNavigation;
-
- ui::PageTransition strippedTransition = ui::PageTransitionStripQualifier(transition);
-
- switch (strippedTransition) {
- case ui::PAGE_TRANSITION_LINK:
- return WebContentsAdapterClient::LinkNavigation;
- case ui::PAGE_TRANSITION_TYPED:
- return WebContentsAdapterClient::TypedNavigation;
- case ui::PAGE_TRANSITION_FORM_SUBMIT:
- return WebContentsAdapterClient::FormSubmittedNavigation;
- case ui::PAGE_TRANSITION_RELOAD:
- return WebContentsAdapterClient::ReloadNavigation;
- default:
- return WebContentsAdapterClient::OtherNavigation;
- }
-}
-
-static QWebEngineUrlRequestInfo::ResourceType toQt(content::ResourceType resourceType)
-{
- if (resourceType >= content::ResourceType::kMainFrame && resourceType <= content::ResourceType::kMaxValue)
- return static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType);
- return QWebEngineUrlRequestInfo::ResourceTypeUnknown;
-}
-
-static QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::NavigationType navigationType)
-{
- return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
-}
-
-NetworkDelegateQt::NetworkDelegateQt(ProfileIODataQt *data)
- : m_profileIOData(data)
-{
-}
-
-int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::CompletionOnceCallback callback, GURL *newUrl)
-{
- Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- Q_ASSERT(m_profileIOData);
- content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request);
-
- content::ResourceType resourceType = content::ResourceType::kMaxValue;
- WebContentsAdapterClient::NavigationType navigationType = WebContentsAdapterClient::OtherNavigation;
-
- if (resourceInfo) {
- resourceType = resourceInfo->GetResourceType();
- navigationType = pageTransitionToNavigationType(resourceInfo->GetPageTransition());
- }
-
- const QUrl qUrl = toQt(request->url());
-
- QUrl firstPartyUrl = QUrl();
- if (resourceType == content::ResourceType::kSubFrame)
- firstPartyUrl = toQt(request->first_party_url());
- else
- firstPartyUrl = toQt(request->site_for_cookies());
-
- const QUrl initiator = request->initiator().has_value() ? toQt(request->initiator()->GetURL()) : QUrl();
-
- QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(toQt(resourceType),
- toQt(navigationType),
- qUrl,
- firstPartyUrl,
- initiator,
- QByteArray::fromStdString(request->method()));
- QWebEngineUrlRequestInfo requestInfo(infoPrivate);
-
- // Deprecated =begin
- // quick peek if deprecated
-
- if (m_profileIOData->isInterceptorDeprecated()) {
- QWebEngineUrlRequestInterceptor *profileInterceptor = m_profileIOData->acquireInterceptor();
- if (profileInterceptor && m_profileIOData->isInterceptorDeprecated()) {
- profileInterceptor->interceptRequest(requestInfo);
- m_profileIOData->releaseInterceptor();
- if (requestInfo.changed()) {
- int result = infoPrivate->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
-
- if (qUrl != infoPrivate->url)
- *newUrl = toGurl(infoPrivate->url);
-
- if (!infoPrivate->extraHeaders.isEmpty()) {
- auto end = infoPrivate->extraHeaders.constEnd();
- for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header) {
- std::string h = header.key().toStdString();
- if (base::LowerCaseEqualsASCII(h, "referer")) {
- request->SetReferrer(header.value().toStdString());
- } else {
- request->SetExtraRequestHeaderByName(h, header.value().toStdString(), /* overwrite */ true);
- }
- }
- }
-
- if (result != net::OK)
- return result;
-
- requestInfo.resetChanged();
- }
- } else {
- m_profileIOData->releaseInterceptor();
- }
- }
- // Deprecated =cut
-
- if (!resourceInfo)
- return net::OK;
-
- // try to bail out
- if (!m_profileIOData->hasPageInterceptors() && (!m_profileIOData->requestInterceptor() || m_profileIOData->isInterceptorDeprecated()) &&
- !content::IsResourceTypeFrame(resourceType))
- return net::OK;
-
- auto webContentsGetter = resourceInfo->GetWebContentsGetterForRequest();
- new URLRequestNotification(
- request,
- resourceInfo->IsMainFrame(),
- newUrl,
- std::move(requestInfo),
- webContentsGetter,
- std::move(callback),
- m_profileIOData->profileAdapter()
- );
-
- // We'll run the callback after we notified the UI thread.
- return net::ERR_IO_PENDING;
-}
-
-void NetworkDelegateQt::OnURLRequestDestroyed(net::URLRequest *) {}
-
-void NetworkDelegateQt::OnCompleted(net::URLRequest * /*request*/, bool /*started*/, int /*net_error*/) {}
-
-bool NetworkDelegateQt::OnCanSetCookie(const net::URLRequest &request, const net::CanonicalCookie & /*cookie*/,
- net::CookieOptions *, bool allowedFromCaller)
-{
- if (!allowedFromCaller)
- return false;
- return canSetCookies(request.site_for_cookies(), request.url(), std::string());
-}
-
-bool NetworkDelegateQt::OnCanGetCookies(const net::URLRequest &request, const net::CookieList &, bool allowedFromCaller)
-{
- if (!allowedFromCaller)
- return false;
- return canGetCookies(request.site_for_cookies(), request.url());
-}
-
-bool NetworkDelegateQt::OnForcePrivacyMode(const GURL &url, const GURL &site_for_cookies) const
-{
- return false;
- // FIXME: This is what the NetworkContext implementation does (changes tst_QWebEngineCookieStore tests since 72)
- // return !canGetCookies(site_for_cookies, url);
-}
-
-bool NetworkDelegateQt::canSetCookies(const GURL &first_party, const GURL &url, const std::string &cookie_line) const
-{
- Q_ASSERT(m_profileIOData);
- return m_profileIOData->canSetCookie(toQt(first_party), QByteArray::fromStdString(cookie_line), toQt(url));
-}
-
-bool NetworkDelegateQt::canGetCookies(const GURL &first_party, const GURL &url) const
-{
- Q_ASSERT(m_profileIOData);
- return m_profileIOData->canGetCookies(toQt(first_party), toQt(url));
-}
-
-int NetworkDelegateQt::OnBeforeStartTransaction(net::URLRequest *, net::CompletionOnceCallback, net::HttpRequestHeaders *)
-{
- return net::OK;
-}
-
-void NetworkDelegateQt::OnBeforeSendHeaders(net::URLRequest *request, const net::ProxyInfo &proxy_info,
- const net::ProxyRetryInfoMap &proxy_retry_info,
- net::HttpRequestHeaders *headers)
-{}
-
-void NetworkDelegateQt::OnStartTransaction(net::URLRequest *request, const net::HttpRequestHeaders &headers) {}
-
-int NetworkDelegateQt::OnHeadersReceived(net::URLRequest *, net::CompletionOnceCallback, const net::HttpResponseHeaders *,
- scoped_refptr<net::HttpResponseHeaders> *, GURL *)
-{
- return net::OK;
-}
-
-void NetworkDelegateQt::OnBeforeRedirect(net::URLRequest *, const GURL &) {}
-
-void NetworkDelegateQt::OnResponseStarted(net::URLRequest *, int) {}
-
-void NetworkDelegateQt::OnNetworkBytesReceived(net::URLRequest *, int64_t) {}
-
-void NetworkDelegateQt::OnNetworkBytesSent(net::URLRequest *, int64_t) {}
-
-void NetworkDelegateQt::OnPACScriptError(int, const base::string16 &) {}
-
-net::NetworkDelegate::AuthRequiredResponse NetworkDelegateQt::OnAuthRequired(net::URLRequest *,
- const net::AuthChallengeInfo &,
- AuthCallback, net::AuthCredentials *)
-{
- return AUTH_REQUIRED_RESPONSE_NO_ACTION;
-}
-
-bool NetworkDelegateQt::OnCanAccessFile(const net::URLRequest &, const base::FilePath &, const base::FilePath &) const
-{
- return true;
-}
-
-bool NetworkDelegateQt::OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest &, const GURL &,
- const GURL &) const
-{
- return false;
-}
-
-bool NetworkDelegateQt::OnCanQueueReportingReport(const url::Origin &origin) const
-{
- return false;
-}
-
-void NetworkDelegateQt::OnCanSendReportingReports(std::set<url::Origin> origins,
- base::OnceCallback<void(std::set<url::Origin>)> result_callback) const
-{
- std::move(result_callback).Run(std::set<url::Origin>());
-}
-
-bool NetworkDelegateQt::OnCanSetReportingClient(const url::Origin &origin, const GURL &endpoint) const
-{
- return false;
-}
-
-bool NetworkDelegateQt::OnCanUseReportingClient(const url::Origin &origin, const GURL &endpoint) const
-{
- return false;
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/net/network_delegate_qt.h b/src/core/net/network_delegate_qt.h
deleted file mode 100644
index f294c6c7c..000000000
--- a/src/core/net/network_delegate_qt.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef NETWORK_DELEGATE_QT_H
-#define NETWORK_DELEGATE_QT_H
-
-#include "net/base/network_delegate.h"
-#include "net/base/net_errors.h"
-
-#include <QUrl>
-#include <QSet>
-
-namespace content {
-class WebContents;
-}
-
-namespace QtWebEngineCore {
-
-class ProfileIODataQt;
-
-class NetworkDelegateQt : public net::NetworkDelegate
-{
- ProfileIODataQt *m_profileIOData;
-
-public:
- NetworkDelegateQt(ProfileIODataQt *data);
-
- // net::NetworkDelegate implementation
- int OnBeforeURLRequest(net::URLRequest *request, net::CompletionOnceCallback callback, GURL *new_url) override;
- void OnURLRequestDestroyed(net::URLRequest *request) override;
- bool OnCanSetCookie(const net::URLRequest &request, const net::CanonicalCookie &cookie, net::CookieOptions *options,
- bool) override;
- int OnBeforeStartTransaction(net::URLRequest *request, const net::CompletionOnceCallback callback,
- net::HttpRequestHeaders *headers) override;
- void OnBeforeSendHeaders(net::URLRequest *request, const net::ProxyInfo &proxy_info,
- const net::ProxyRetryInfoMap &proxy_retry_info, net::HttpRequestHeaders *headers) override;
- void OnStartTransaction(net::URLRequest *request, const net::HttpRequestHeaders &headers) override;
- int OnHeadersReceived(net::URLRequest *, net::CompletionOnceCallback, const net::HttpResponseHeaders *,
- scoped_refptr<net::HttpResponseHeaders> *, GURL *) override;
- void OnBeforeRedirect(net::URLRequest *, const GURL &) override;
- void OnResponseStarted(net::URLRequest *, int) override;
- void OnNetworkBytesReceived(net::URLRequest *, int64_t) override;
- void OnNetworkBytesSent(net::URLRequest *, int64_t) override;
- void OnCompleted(net::URLRequest *request, bool started, int net_error) override;
- void OnPACScriptError(int, const base::string16 &) override;
- net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(net::URLRequest *, const net::AuthChallengeInfo &,
- AuthCallback, net::AuthCredentials *) override;
- bool OnCanGetCookies(const net::URLRequest &, const net::CookieList &, bool) override;
- bool OnCanAccessFile(const net::URLRequest &, const base::FilePath &, const base::FilePath &) const override;
- bool OnForcePrivacyMode(const GURL &, const GURL &) const override;
- bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest &, const GURL &,
- const GURL &) const override;
-
- bool OnCanQueueReportingReport(const url::Origin &origin) const override;
- void OnCanSendReportingReports(std::set<url::Origin> origins,
- base::OnceCallback<void(std::set<url::Origin>)> result_callback) const override;
- bool OnCanSetReportingClient(const url::Origin &origin, const GURL &endpoint) const override;
- bool OnCanUseReportingClient(const url::Origin &origin, const GURL &endpoint) const override;
-
- bool canSetCookies(const GURL &first_party, const GURL &url, const std::string &cookie_line) const;
- bool canGetCookies(const GURL &first_party, const GURL &url) const;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // NETWORK_DELEGATE_QT_H
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
new file mode 100644
index 000000000..cfd011ade
--- /dev/null
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "plugin_response_interceptor_url_loader_throttle.h"
+
+#include "base/bind.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_manager.h"
+#include "content/public/browser/download_request_utils.h"
+#include "content/public/browser/download_utils.h"
+#include "content/public/common/resource_type.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+
+#include "extensions/extension_system_qt.h"
+#include "profile_adapter.h"
+#include "profile_io_data_qt.h"
+#include "profile_qt.h"
+#include "web_contents_delegate_qt.h"
+
+#include <string>
+
+namespace QtWebEngineCore {
+
+void onPdfStreamIntercepted(const GURL &original_url, std::string extension_id, int frame_tree_node_id)
+{
+ content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
+ if (!web_contents)
+ return;
+
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate());
+ if (!contentsDelegate)
+ return;
+
+ WebEngineSettings *settings = contentsDelegate->webEngineSettings();
+ if (!settings->testAttribute(WebEngineSettings::PdfViewerEnabled)
+ || !settings->testAttribute(WebEngineSettings::PluginsEnabled)) {
+ // If the applications has been set up to always download PDF files to open them in an
+ // external viewer, trigger the download.
+ std::unique_ptr<download::DownloadUrlParameters> params(
+ content::DownloadRequestUtils::CreateDownloadForWebContentsMainFrame(web_contents, original_url,
+ MISSING_TRAFFIC_ANNOTATION));
+ content::BrowserContext::GetDownloadManager(web_contents->GetBrowserContext())->DownloadUrl(std::move(params));
+ return;
+ }
+
+ // The URL passes the original pdf resource url, that will be requested
+ // by the pdf viewer extension page.
+ content::NavigationController::LoadURLParams params(
+ GURL(base::StringPrintf("%s://%s/index.html?%s", extensions::kExtensionScheme,
+ extension_id.c_str(), original_url.spec().c_str())));
+
+ params.frame_tree_node_id = frame_tree_node_id;
+ web_contents->GetController().LoadURLWithParams(params);
+}
+
+
+PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
+ content::ResourceContext *resource_context, int resource_type, int frame_tree_node_id)
+ : m_resource_context(resource_context), m_resource_type(resource_type), m_frame_tree_node_id(frame_tree_node_id)
+{}
+
+PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
+ content::BrowserContext *browser_context, int resource_type, int frame_tree_node_id)
+ : m_browser_context(browser_context), m_resource_type(resource_type), m_frame_tree_node_id(frame_tree_node_id)
+{}
+
+void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL &response_url,
+ network::ResourceResponseHead *response_head,
+ bool *defer)
+{
+ Q_UNUSED(defer);
+ if (content::download_utils::MustDownload(response_url, response_head->headers.get(), response_head->mime_type))
+ return;
+
+ if (m_resource_context) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ } else {
+ DCHECK(m_browser_context);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ }
+
+ std::string extension_id;
+ // FIXME: We should use extensions::InfoMap in the future:
+ if (response_head->mime_type == "application/pdf")
+ extension_id = extension_misc::kPdfExtensionId;
+ if (extension_id.empty())
+ return;
+
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&onPdfStreamIntercepted,
+ response_url,
+ extension_id,
+ m_frame_tree_node_id));
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/url_request_notification.h b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
index 673e07bf0..82384e11e 100644
--- a/src/core/net/url_request_notification.h
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
@@ -37,50 +37,40 @@
**
****************************************************************************/
-#ifndef URL_REQUEST_NOTIFIACTION_H
-#define URL_REQUEST_NOTIFIACTION_H
+#ifndef PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
+#define PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
-#include "content/public/browser/resource_request_info.h"
-#include "net/base/completion_once_callback.h"
-#include "qwebengineurlrequestinfo.h"
-#include <QPointer>
+#include "base/macros.h"
+#include "content/public/common/url_loader_throttle.h"
-class GURL;
-
-namespace net {
-class URLRequest;
+namespace content {
+class BrowserContext;
+class ResourceContext;
}
namespace QtWebEngineCore {
-class ProfileAdapter;
-class ProfileIoDataQt;
-
-// Notifies WebContentsAdapterClient of a new URLRequest.
-class URLRequestNotification
+class PluginResponseInterceptorURLLoaderThrottle : public content::URLLoaderThrottle
{
public:
- URLRequestNotification(net::URLRequest *request,
- bool isMainFrameRequest,
- GURL *newUrl,
- QWebEngineUrlRequestInfo &&requestInfo,
- content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
- net::CompletionOnceCallback callback,
- QPointer<ProfileAdapter> adapter);
- ~URLRequestNotification() = default;
- void cancel();
- void notify();
- void complete(int error);
+ PluginResponseInterceptorURLLoaderThrottle(content::ResourceContext *resource_context,
+ int resource_type, int frame_tree_node_id);
+ PluginResponseInterceptorURLLoaderThrottle(content::BrowserContext *browser_context,
+ int resource_type, int frame_tree_node_id);
+ ~PluginResponseInterceptorURLLoaderThrottle() override = default;
private:
- net::URLRequest *m_request; //used only by io thread
- bool m_isMainFrameRequest;
- GURL *m_newUrl;
- const QUrl m_originalUrl;
- QWebEngineUrlRequestInfo m_requestInfo;
- content::ResourceRequestInfo::WebContentsGetter m_webContentsGetter;
- net::CompletionOnceCallback m_callback;
- QPointer<ProfileAdapter> m_profileAdapter;
+ // content::URLLoaderThrottle overrides;
+ void WillProcessResponse(const GURL &response_url, network::ResourceResponseHead *response_head, bool *defer) override;
+
+ content::ResourceContext *m_resource_context = nullptr;
+ content::BrowserContext *m_browser_context = nullptr;
+ const int m_resource_type;
+ const int m_frame_tree_node_id;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginResponseInterceptorURLLoaderThrottle);
};
-}
-#endif
+
+} // namespace QtWebEngineCore
+
+#endif // PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
diff --git a/src/core/net/proxy_config_monitor.cpp b/src/core/net/proxy_config_monitor.cpp
new file mode 100644
index 000000000..818b6cb7f
--- /dev/null
+++ b/src/core/net/proxy_config_monitor.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// originally based on chrome/browser/net/proxy_config_monitor.cc
+// Copyright 2017 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 "profile_qt.h"
+#include "proxy_config_monitor.h"
+#include "proxy_config_service_qt.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "build/build_config.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+
+#include <utility>
+
+using content::BrowserThread;
+
+ProxyConfigMonitor::ProxyConfigMonitor(PrefService *prefs)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ proxy_config_service_.reset(
+ new ProxyConfigServiceQt(
+ prefs, base::CreateSingleThreadTaskRunnerWithTraits({ BrowserThread::UI })));
+
+ proxy_config_service_->AddObserver(this);
+}
+
+ProxyConfigMonitor::~ProxyConfigMonitor()
+{
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)
+ || !BrowserThread::IsThreadInitialized(BrowserThread::UI));
+ proxy_config_service_->RemoveObserver(this);
+}
+
+void ProxyConfigMonitor::AddToNetworkContextParams(
+ network::mojom::NetworkContextParams *network_context_params)
+{
+ network::mojom::ProxyConfigClientPtr proxy_config_client;
+ network_context_params->proxy_config_client_request = mojo::MakeRequest(&proxy_config_client);
+ proxy_config_client_set_.AddPtr(std::move(proxy_config_client));
+
+ poller_binding_set_.AddBinding(
+ this, mojo::MakeRequest(&network_context_params->proxy_config_poller_client));
+
+ net::ProxyConfigWithAnnotation proxy_config;
+ net::ProxyConfigService::ConfigAvailability availability =
+ proxy_config_service_->GetLatestProxyConfig(&proxy_config);
+ if (availability != net::ProxyConfigService::CONFIG_PENDING)
+ network_context_params->initial_proxy_config = proxy_config;
+}
+
+void ProxyConfigMonitor::OnProxyConfigChanged(
+ const net::ProxyConfigWithAnnotation &config,
+ net::ProxyConfigService::ConfigAvailability availability)
+{
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)
+ || !BrowserThread::IsThreadInitialized(BrowserThread::UI));
+ proxy_config_client_set_.ForAllPtrs(
+ [config, availability](network::mojom::ProxyConfigClient *proxy_config_client) {
+ switch (availability) {
+ case net::ProxyConfigService::CONFIG_VALID:
+ proxy_config_client->OnProxyConfigUpdated(config);
+ break;
+ case net::ProxyConfigService::CONFIG_UNSET:
+ proxy_config_client->OnProxyConfigUpdated(
+ net::ProxyConfigWithAnnotation::CreateDirect());
+ break;
+ case net::ProxyConfigService::CONFIG_PENDING:
+ NOTREACHED();
+ break;
+ }
+ });
+}
+
+void ProxyConfigMonitor::OnLazyProxyConfigPoll()
+{
+ proxy_config_service_->OnLazyPoll();
+}
diff --git a/src/core/net/proxy_config_monitor.h b/src/core/net/proxy_config_monitor.h
new file mode 100644
index 000000000..23f073a84
--- /dev/null
+++ b/src/core/net/proxy_config_monitor.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// originally based on chrome/browser/net/proxy_config_monitor.h
+// Copyright 2017 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.
+
+#ifndef PROXY_CONFIG_MONITOR_H
+#define PROXY_CONFIG_MONITOR_H
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "build/buildflag.h"
+#include "extensions/buildflags/buildflags.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "net/proxy_resolution/proxy_config_service.h"
+#include "services/network/public/mojom/network_context.mojom-forward.h"
+#include "services/network/public/mojom/network_service.mojom-forward.h"
+#include "services/network/public/mojom/proxy_config.mojom-forward.h"
+#include "services/network/public/mojom/proxy_config_with_annotation.mojom.h"
+
+namespace net {
+class ProxyConfigWithAnnotation;
+}
+
+class PrefService;
+class ProxyConfigServiceQt;
+
+// Tracks the ProxyConfig to use, and passes any updates to a NetworkContext's
+// ProxyConfigClient. This also responds to errors related to proxy settings
+// from the NetworkContext, and forwards them any listening Chrome extensions
+// associated with the profile.
+class ProxyConfigMonitor : public net::ProxyConfigService::Observer,
+ public network::mojom::ProxyConfigPollerClient
+{
+public:
+ explicit ProxyConfigMonitor(PrefService *prefs = nullptr);
+
+ ~ProxyConfigMonitor() override;
+
+ // Populates proxy-related fields of |network_context_params|. Updated
+ // ProxyConfigs will be sent to a NetworkContext created with those params
+ // whenever the configuration changes. Can be called more than once to inform
+ // multiple NetworkContexts of proxy changes.
+ void AddToNetworkContextParams(network::mojom::NetworkContextParams *network_context_params);
+
+private:
+ // net::ProxyConfigService::Observer implementation:
+ void OnProxyConfigChanged(const net::ProxyConfigWithAnnotation &config,
+ net::ProxyConfigService::ConfigAvailability availability) override;
+
+ // network::mojom::ProxyConfigPollerClient implementation:
+ void OnLazyProxyConfigPoll() override;
+
+ std::unique_ptr<ProxyConfigServiceQt> proxy_config_service_;
+
+ mojo::BindingSet<network::mojom::ProxyConfigPollerClient> poller_binding_set_;
+
+ mojo::InterfacePtrSet<network::mojom::ProxyConfigClient> proxy_config_client_set_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyConfigMonitor);
+};
+
+#endif // !PROXY_CONFIG_MONITOR_H
diff --git a/src/core/net/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp
index 8016c7e83..59884961d 100644
--- a/src/core/net/proxy_config_service_qt.cpp
+++ b/src/core/net/proxy_config_service_qt.cpp
@@ -46,8 +46,9 @@
#include "proxy_config_service_qt.h"
#include "base/bind.h"
-#include "content/public/browser/browser_thread.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
using content::BrowserThread;
@@ -69,34 +70,40 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt
}
}
-ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService,
- const net::ProxyConfigWithAnnotation &initialConfig,
- ProxyPrefs::ConfigState initialState)
- : m_baseService(baseService.release())
+ProxyConfigServiceQt::ProxyConfigServiceQt(PrefService *prefService,
+ const scoped_refptr<base::SingleThreadTaskRunner> &taskRunner)
+ : m_baseService(net::ProxyResolutionService::CreateSystemProxyConfigService(taskRunner))
, m_usesSystemConfiguration(false)
, m_registeredObserver(false)
- , m_prefConfig(initialConfig)
- , m_perfState(initialState)
-{}
+ , m_prefState(prefService
+ ? PrefProxyConfigTrackerImpl::ReadPrefConfig(prefService, &m_prefConfig)
+ : ProxyPrefs::CONFIG_UNSET)
+{
+ DETACH_FROM_SEQUENCE(m_sequenceChecker);
+}
ProxyConfigServiceQt::~ProxyConfigServiceQt()
{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(m_sequenceChecker);
if (m_registeredObserver && m_baseService.get())
m_baseService->RemoveObserver(this);
}
void ProxyConfigServiceQt::AddObserver(net::ProxyConfigService::Observer *observer)
{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(m_sequenceChecker);
m_observers.AddObserver(observer);
}
void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *observer)
{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(m_sequenceChecker);
m_observers.RemoveObserver(observer);
}
net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfigWithAnnotation *config)
{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(m_sequenceChecker);
m_usesSystemConfiguration = QNetworkProxyFactory::usesSystemConfiguration();
if (m_usesSystemConfiguration) {
// Use Chromium's base service to retrieve system settings
@@ -106,7 +113,7 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy
systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
ProxyPrefs::ConfigState configState;
systemAvailability = PrefProxyConfigTrackerImpl::GetEffectiveProxyConfig(
- m_perfState, m_prefConfig, systemAvailability, systemConfig,
+ m_prefState, m_prefConfig, systemAvailability, systemConfig,
false, &configState, config);
RegisterObserver();
return systemAvailability;
@@ -151,7 +158,7 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy
void ProxyConfigServiceQt::OnLazyPoll()
{
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CALLED_ON_VALID_SEQUENCE(m_sequenceChecker);
// We need to update if
// - setUseSystemConfiguration() was called in between
@@ -168,7 +175,7 @@ void ProxyConfigServiceQt::OnLazyPoll()
// Called when the base service changed
void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfigWithAnnotation &config, ConfigAvailability availability)
{
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CALLED_ON_VALID_SEQUENCE(m_sequenceChecker);
Q_UNUSED(config);
if (!m_usesSystemConfiguration)
@@ -180,6 +187,7 @@ void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfigWithAnnota
// Update our observers
void ProxyConfigServiceQt::Update()
{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(m_sequenceChecker);
net::ProxyConfigWithAnnotation actual_config;
ConfigAvailability availability = GetLatestProxyConfig(&actual_config);
if (availability == CONFIG_PENDING)
@@ -193,7 +201,7 @@ void ProxyConfigServiceQt::Update()
// in the constructor.
void ProxyConfigServiceQt::RegisterObserver()
{
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CALLED_ON_VALID_SEQUENCE(m_sequenceChecker);
if (!m_registeredObserver && m_baseService.get()) {
m_baseService->AddObserver(this);
m_registeredObserver = true;
diff --git a/src/core/net/proxy_config_service_qt.h b/src/core/net/proxy_config_service_qt.h
index 4d8619055..c0928bc03 100644
--- a/src/core/net/proxy_config_service_qt.h
+++ b/src/core/net/proxy_config_service_qt.h
@@ -42,6 +42,7 @@
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
+#include "base/single_thread_task_runner.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
@@ -50,6 +51,8 @@
#include <QNetworkProxy>
+class PrefService;
+
class ProxyConfigServiceQt
: public net::ProxyConfigService
, public net::ProxyConfigService::Observer
@@ -57,9 +60,8 @@ class ProxyConfigServiceQt
public:
static net::ProxyServer fromQNetworkProxy(const QNetworkProxy &);
- explicit ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService,
- const net::ProxyConfigWithAnnotation &initialConfig,
- ProxyPrefs::ConfigState initialState);
+ explicit ProxyConfigServiceQt(PrefService *prefService,
+ const scoped_refptr<base::SingleThreadTaskRunner> &taskRunner);
~ProxyConfigServiceQt() override;
// ProxyConfigService implementation:
@@ -92,7 +94,9 @@ private:
// Configuration as defined by prefs.
net::ProxyConfigWithAnnotation m_prefConfig;
- ProxyPrefs::ConfigState m_perfState;
+ ProxyPrefs::ConfigState m_prefState;
+
+ SEQUENCE_CHECKER(m_sequenceChecker);
DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt);
};
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.cpp b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
new file mode 100644
index 000000000..b6abeb567
--- /dev/null
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// originally based on android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc:
+// Copyright 2019 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 "proxying_restricted_cookie_manager_qt.h"
+
+#include "api/qwebenginecookiestore.h"
+#include "api/qwebenginecookiestore_p.h"
+#include "profile_adapter.h"
+#include "profile_qt.h"
+#include "type_conversion.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace QtWebEngineCore {
+
+class ProxyingRestrictedCookieManagerListenerQt : public network::mojom::CookieChangeListener {
+public:
+ ProxyingRestrictedCookieManagerListenerQt(const GURL &url,
+ const GURL &site_for_cookies,
+ base::WeakPtr<ProxyingRestrictedCookieManagerQt> restricted_cookie_manager,
+ network::mojom::CookieChangeListenerPtr client_listener)
+ : url_(url)
+ , site_for_cookies_(site_for_cookies)
+ , restricted_cookie_manager_(restricted_cookie_manager)
+ , client_listener_(std::move(client_listener))
+ {}
+
+ void OnCookieChange(const net::CanonicalCookie &cookie, network::mojom::CookieChangeCause cause) override
+ {
+ if (restricted_cookie_manager_ && restricted_cookie_manager_->allowCookies(url_, site_for_cookies_))
+ client_listener_->OnCookieChange(cookie, cause);
+ }
+
+private:
+ const GURL url_;
+ const GURL site_for_cookies_;
+ base::WeakPtr<ProxyingRestrictedCookieManagerQt> restricted_cookie_manager_;
+ network::mojom::CookieChangeListenerPtr client_listener_;
+};
+
+// static
+void ProxyingRestrictedCookieManagerQt::CreateAndBind(ProfileIODataQt *profileIoData,
+ network::mojom::RestrictedCookieManagerPtrInfo underlying_rcm,
+ bool is_service_worker,
+ int process_id,
+ int frame_id,
+ network::mojom::RestrictedCookieManagerRequest request)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&ProxyingRestrictedCookieManagerQt::CreateAndBindOnIoThread,
+ profileIoData,
+ std::move(underlying_rcm),
+ is_service_worker, process_id, frame_id,
+ std::move(request)));
+}
+
+
+// static
+void ProxyingRestrictedCookieManagerQt::CreateAndBindOnIoThread(ProfileIODataQt *profileIoData,
+ network::mojom::RestrictedCookieManagerPtrInfo underlying_rcm,
+ bool is_service_worker,
+ int process_id,
+ int frame_id,
+ network::mojom::RestrictedCookieManagerRequest request)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ auto wrapper = base::WrapUnique(new ProxyingRestrictedCookieManagerQt(
+ profileIoData->getWeakPtrOnIOThread(),
+ network::mojom::RestrictedCookieManagerPtr(std::move(underlying_rcm)),
+ is_service_worker, process_id, frame_id));
+ mojo::MakeStrongBinding(std::move(wrapper), std::move(request));
+}
+
+ProxyingRestrictedCookieManagerQt::ProxyingRestrictedCookieManagerQt(base::WeakPtr<ProfileIODataQt> profileIoData,
+ network::mojom::RestrictedCookieManagerPtr underlyingRestrictedCookieManager,
+ bool is_service_worker,
+ int32_t process_id,
+ int32_t frame_id)
+ : m_profileIoData(std::move(profileIoData))
+ , underlying_restricted_cookie_manager_(std::move(underlyingRestrictedCookieManager))
+ , is_service_worker_(is_service_worker)
+ , process_id_(process_id)
+ , frame_id_(frame_id)
+ , weak_factory_(this)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+}
+
+ProxyingRestrictedCookieManagerQt::~ProxyingRestrictedCookieManagerQt()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+}
+
+void ProxyingRestrictedCookieManagerQt::GetAllForUrl(const GURL &url,
+ const GURL &site_for_cookies,
+ network::mojom::CookieManagerGetOptionsPtr options,
+ GetAllForUrlCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (allowCookies(url, site_for_cookies)) {
+ underlying_restricted_cookie_manager_->GetAllForUrl(url, site_for_cookies, std::move(options), std::move(callback));
+ } else {
+ std::move(callback).Run(std::vector<net::CanonicalCookie>());
+ }
+}
+
+void ProxyingRestrictedCookieManagerQt::SetCanonicalCookie(const net::CanonicalCookie &cookie,
+ const GURL &url,
+ const GURL &site_for_cookies,
+ SetCanonicalCookieCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (allowCookies(url, site_for_cookies)) {
+ underlying_restricted_cookie_manager_->SetCanonicalCookie(cookie, url, site_for_cookies, std::move(callback));
+ } else {
+ std::move(callback).Run(false);
+ }
+}
+
+void ProxyingRestrictedCookieManagerQt::AddChangeListener(const GURL &url,
+ const GURL &site_for_cookies,
+ network::mojom::CookieChangeListenerPtr listener,
+ AddChangeListenerCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ network::mojom::CookieChangeListenerPtr proxy_listener_ptr;
+ auto proxy_listener =
+ std::make_unique<ProxyingRestrictedCookieManagerListenerQt>(
+ url, site_for_cookies, weak_factory_.GetWeakPtr(),
+ std::move(listener));
+
+ mojo::MakeStrongBinding(std::move(proxy_listener),
+ mojo::MakeRequest(&proxy_listener_ptr));
+
+ underlying_restricted_cookie_manager_->AddChangeListener(url, site_for_cookies, std::move(proxy_listener_ptr), std::move(callback));
+}
+
+void ProxyingRestrictedCookieManagerQt::SetCookieFromString(const GURL &url,
+ const GURL &site_for_cookies,
+ const std::string &cookie,
+ SetCookieFromStringCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (allowCookies(url, site_for_cookies)) {
+ underlying_restricted_cookie_manager_->SetCookieFromString(url, site_for_cookies, cookie, std::move(callback));
+ } else {
+ std::move(callback).Run();
+ }
+}
+
+void ProxyingRestrictedCookieManagerQt::GetCookiesString(const GURL &url,
+ const GURL &site_for_cookies,
+ GetCookiesStringCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (allowCookies(url, site_for_cookies)) {
+ underlying_restricted_cookie_manager_->GetCookiesString(url, site_for_cookies, std::move(callback));
+ } else {
+ std::move(callback).Run("");
+ }
+}
+
+void ProxyingRestrictedCookieManagerQt::CookiesEnabledFor(const GURL &url,
+ const GURL &site_for_cookies,
+ CookiesEnabledForCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ std::move(callback).Run(allowCookies(url, site_for_cookies));
+}
+
+bool ProxyingRestrictedCookieManagerQt::allowCookies(const GURL &url, const GURL &site_for_cookies) const
+{
+ if (!m_profileIoData)
+ return false;
+ return m_profileIoData->canGetCookies(toQt(site_for_cookies), toQt(url));
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/restricted_cookie_manager_qt.h b/src/core/net/proxying_restricted_cookie_manager_qt.h
index 9154f671d..7a9f0e3ab 100644
--- a/src/core/net/restricted_cookie_manager_qt.h
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.h
@@ -37,30 +37,30 @@
**
****************************************************************************/
-#ifndef RESTRICTED_COOKIE_MANAGER_QT_H
-#define RESTRICTED_COOKIE_MANAGER_QT_H
+#ifndef PROXYING_RESTRICTED_COOKIE_MANAGER_QT_H
+#define PROXYING_RESTRICTED_COOKIE_MANAGER_QT_H
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "services/network/restricted_cookie_manager.h"
+#include "services/network/public/mojom/restricted_cookie_manager.mojom.h"
#include "url/gurl.h"
namespace QtWebEngineCore {
class ProfileIODataQt;
-class RestrictedCookieManagerQt : public network::RestrictedCookieManager
+class ProxyingRestrictedCookieManagerQt : public network::mojom::RestrictedCookieManager
{
public:
- RestrictedCookieManagerQt(base::WeakPtr<ProfileIODataQt> profileIoData,
- network::mojom::RestrictedCookieManagerRole role,
- net::CookieStore *cookie_store,
- network::CookieSettings *cookie_settings,
- const url::Origin &origin,
+ // Expects to be called on the UI thread.
+ static void CreateAndBind(ProfileIODataQt *profileIoData,
+ network::mojom::RestrictedCookieManagerPtrInfo underlying_rcm,
bool is_service_worker,
- int32_t process_id,
- int32_t frame_id);
- ~RestrictedCookieManagerQt() override;
+ int process_id,
+ int frame_id,
+ network::mojom::RestrictedCookieManagerRequest request);
+
+ ~ProxyingRestrictedCookieManagerQt() override;
// network::mojom::RestrictedCookieManager interface:
void GetAllForUrl(const GURL &url,
@@ -75,7 +75,10 @@ public:
const GURL &site_for_cookies,
network::mojom::CookieChangeListenerPtr listener,
AddChangeListenerCallback callback) override;
-
+ void SetCookieFromString(const GURL &url,
+ const GURL &site_for_cookies,
+ const std::string &cookie,
+ SetCookieFromStringCallback callback) override;
void GetCookiesString(const GURL &url,
const GURL &site_for_cookies,
GetCookiesStringCallback callback) override;
@@ -88,13 +91,31 @@ public:
bool allowCookies(const GURL &url, const GURL &site_for_cookies) const;
private:
+ ProxyingRestrictedCookieManagerQt(base::WeakPtr<ProfileIODataQt> profileIoData,
+ network::mojom::RestrictedCookieManagerPtr underlyingRestrictedCookieManager,
+ bool is_service_worker,
+ int32_t process_id,
+ int32_t frame_id);
+
+ static void CreateAndBindOnIoThread(ProfileIODataQt *profileIoData,
+ network::mojom::RestrictedCookieManagerPtrInfo underlying_rcm,
+ bool is_service_worker,
+ int process_id,
+ int frame_id,
+ network::mojom::RestrictedCookieManagerRequest request);
+
base::WeakPtr<ProfileIODataQt> m_profileIoData;
- base::WeakPtrFactory<RestrictedCookieManagerQt> weak_factory_;
+ network::mojom::RestrictedCookieManagerPtr underlying_restricted_cookie_manager_;
+ bool is_service_worker_;
+ int process_id_;
+ int frame_id_;
+
+ base::WeakPtrFactory<ProxyingRestrictedCookieManagerQt> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(RestrictedCookieManagerQt);
+ DISALLOW_COPY_AND_ASSIGN(ProxyingRestrictedCookieManagerQt);
};
} // namespace QtWebEngineCore
-#endif // RESTRICTED_COOKIE_MANAGER_QT_H
+#endif // PROXYING_RESTRICTED_COOKIE_MANAGER_QT_H
diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
new file mode 100644
index 000000000..51a226117
--- /dev/null
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -0,0 +1,560 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "proxying_url_loader_factory_qt.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
+#include "components/safe_browsing/common/safebrowsing_constants.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_request_id.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_constants.h"
+#include "content/public/common/url_utils.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_status_code.h"
+#include "net/http/http_util.h"
+
+#include "api/qwebengineurlrequestinfo_p.h"
+#include "profile_io_data_qt.h"
+#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+#include <QVariant>
+
+// originally based on aw_proxying_url_loader_factory.cc:
+// Copyright 2018 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.
+
+namespace QtWebEngineCore {
+
+extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
+
+static QWebEngineUrlRequestInfo::ResourceType toQt(content::ResourceType resourceType)
+{
+ if (resourceType >= content::ResourceType::kMainFrame && resourceType <= content::ResourceType::kMaxValue)
+ return static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType);
+ return QWebEngineUrlRequestInfo::ResourceTypeUnknown;
+}
+
+static QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::NavigationType navigationType)
+{
+ return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
+}
+
+// Handles intercepted, in-progress requests/responses, so that they can be
+// controlled and modified accordingly.
+class InterceptedRequest : public network::mojom::URLLoader
+ , public network::mojom::URLLoaderClient
+{
+public:
+ InterceptedRequest(int process_id, uint64_t request_id, int32_t routing_id, uint32_t options,
+ const network::ResourceRequest &request,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation,
+ ProfileIODataQt *profileData,
+ network::mojom::URLLoaderRequest loader_request, network::mojom::URLLoaderClientPtr client,
+ network::mojom::URLLoaderFactoryPtr target_factory);
+ ~InterceptedRequest() override;
+
+ void Restart();
+ void InterceptOnUIThread();
+
+ // network::mojom::URLLoaderClient
+ void OnReceiveResponse(const network::ResourceResponseHead &head) override;
+ void OnReceiveRedirect(const net::RedirectInfo &redirect_info, const network::ResourceResponseHead &head) override;
+ void OnUploadProgress(int64_t current_position, int64_t total_size, OnUploadProgressCallback callback) override;
+ void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
+ void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
+ void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body) override;
+ void OnComplete(const network::URLLoaderCompletionStatus &status) override;
+
+ // network::mojom::URLLoader
+ void FollowRedirect(const std::vector<std::string> &removed_headers,
+ const net::HttpRequestHeaders &modified_headers, const base::Optional<GURL> &new_url) override;
+ void ProceedWithResponse() override;
+ void SetPriority(net::RequestPriority priority, int32_t intra_priority_value) override;
+ void PauseReadingBodyFromNet() override;
+ void ResumeReadingBodyFromNet() override;
+
+ void ContinueAfterIntercept();
+
+private:
+ // This is called when the original URLLoaderClient has a connection error.
+ void OnURLLoaderClientError();
+
+ // This is called when the original URLLoader has a connection error.
+ void OnURLLoaderError(uint32_t custom_reason, const std::string &description);
+
+ // Call OnComplete on |target_client_|. If |wait_for_loader_error| is true
+ // then this object will wait for |proxied_loader_binding_| to have a
+ // connection error before destructing.
+ void CallOnComplete(const network::URLLoaderCompletionStatus &status, bool wait_for_loader_error);
+
+ void SendErrorAndCompleteImmediately(int error_code);
+
+ const int process_id_;
+ const uint64_t request_id_;
+ const int32_t routing_id_;
+ const uint32_t options_;
+ bool input_stream_previously_failed_ = false;
+ bool request_was_redirected_ = false;
+
+ // If the |target_loader_| called OnComplete with an error this stores it.
+ // That way the destructor can send it to OnReceivedError if safe browsing
+ // error didn't occur.
+ int error_status_ = net::OK;
+ GURL m_originalUrl;
+
+ network::ResourceRequest request_;
+ network::ResourceResponseHead current_response_;
+
+ const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
+
+ ProfileIODataQt *m_profileData;
+ mojo::Binding<network::mojom::URLLoader> proxied_loader_binding_;
+ network::mojom::URLLoaderClientPtr target_client_;
+
+ mojo::Binding<network::mojom::URLLoaderClient> proxied_client_binding_;
+ network::mojom::URLLoaderPtr target_loader_;
+ network::mojom::URLLoaderFactoryPtr target_factory_;
+
+ base::WeakPtrFactory<InterceptedRequest> m_weakFactory;
+ base::WeakPtr<InterceptedRequest> m_weakPtr;
+ DISALLOW_COPY_AND_ASSIGN(InterceptedRequest);
+};
+
+InterceptedRequest::InterceptedRequest(int process_id, uint64_t request_id, int32_t routing_id, uint32_t options,
+ const network::ResourceRequest &request,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation,
+ ProfileIODataQt *profileData,
+ network::mojom::URLLoaderRequest loader_request,
+ network::mojom::URLLoaderClientPtr client,
+ network::mojom::URLLoaderFactoryPtr target_factory)
+ : process_id_(process_id)
+ , request_id_(request_id)
+ , routing_id_(routing_id)
+ , options_(options)
+ , request_(request)
+ , traffic_annotation_(traffic_annotation)
+ , m_profileData(profileData)
+ , proxied_loader_binding_(this, std::move(loader_request))
+ , target_client_(std::move(client))
+ , proxied_client_binding_(this)
+ , target_factory_(std::move(target_factory))
+ , m_weakFactory(this)
+ , m_weakPtr(m_weakFactory.GetWeakPtr())
+{
+ // If there is a client error, clean up the request.
+ target_client_.set_connection_error_handler(
+ base::BindOnce(&InterceptedRequest::OnURLLoaderClientError, m_weakFactory.GetWeakPtr()));
+ proxied_loader_binding_.set_connection_error_with_reason_handler(
+ base::BindOnce(&InterceptedRequest::OnURLLoaderError, m_weakFactory.GetWeakPtr()));
+}
+
+InterceptedRequest::~InterceptedRequest()
+{
+ m_weakFactory.InvalidateWeakPtrs();
+}
+
+void InterceptedRequest::Restart()
+{
+ // FIXME: Support deprecated interceptors here
+
+ // FIXME: unretained post?
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&InterceptedRequest::InterceptOnUIThread, base::Unretained(this)));
+}
+
+void InterceptedRequest::InterceptOnUIThread()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ content::ResourceType resourceType = content::ResourceType(request_.resource_type);
+ WebContentsAdapterClient::NavigationType navigationType =
+ pageTransitionToNavigationType(ui::PageTransition(request_.transition_type));
+
+ m_originalUrl = request_.url;
+ const QUrl qUrl = toQt(request_.url);
+
+ const QUrl initiator = request_.request_initiator.has_value() ? toQt(request_.request_initiator->GetURL()) : QUrl();
+
+ QUrl firstPartyUrl;
+ if (resourceType == content::ResourceType::kSubFrame)
+ firstPartyUrl = toQt(request_.first_party_url);
+ else
+ firstPartyUrl = toQt(request_.site_for_cookies);
+
+ QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(toQt(resourceType),
+ toQt(navigationType),
+ qUrl,
+ firstPartyUrl,
+ initiator,
+ QByteArray::fromStdString(request_.method));
+ QWebEngineUrlRequestInfo requestInfo(infoPrivate);
+
+ content::WebContents *webContents = nullptr;
+ if (process_id_) {
+ content::RenderFrameHost *frameHost = content::RenderFrameHost::FromID(process_id_, request_.render_frame_id);
+ webContents = content::WebContents::FromRenderFrameHost(frameHost);
+ } else
+ webContents = content::WebContents::FromFrameTreeNodeId(request_.render_frame_id);
+
+ if (webContents) {
+ int result = net::OK;
+ if (m_profileData) {
+ QWebEngineUrlRequestInterceptor *interceptor = m_profileData->requestInterceptor();
+ if (interceptor && !interceptor->property("deprecated").toBool())
+ interceptor->interceptRequest(requestInfo);
+ }
+
+ WebContentsAdapterClient *client =
+ WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client();
+
+ if (!requestInfo.changed()) {
+ client->interceptRequest(requestInfo);
+ }
+
+ if (requestInfo.changed()) {
+ result = requestInfo.d_ptr->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
+ // We handle the rest of the changes later when we are back in I/O thread
+ }
+
+ if (result != net::OK) {
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&InterceptedRequest::SendErrorAndCompleteImmediately, m_weakPtr, result));
+ return;
+ }
+ if (requestInfo.changed()) {
+ if (requestInfo.requestUrl() != qUrl) {
+ net::URLRequest::FirstPartyURLPolicy first_party_url_policy =
+ request_.update_first_party_url_on_redirect ? net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT
+ : net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
+ net::RedirectInfo redirectInfo = net::RedirectInfo::ComputeRedirectInfo(request_.method, request_.url,
+ request_.site_for_cookies, request_.top_frame_origin,
+ first_party_url_policy, request_.referrer_policy,
+ request_.referrer.spec(), net::HTTP_TEMPORARY_REDIRECT,
+ toGurl(requestInfo.requestUrl()), base::nullopt,
+ false /*insecure_scheme_was_upgraded*/);
+
+ // FIXME: Should probably create a new header.
+ current_response_.encoded_data_length = 0;
+ // FIXME: unretained post.
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&network::mojom::URLLoaderClientProxy::OnReceiveRedirect, base::Unretained(&(*target_client_)), redirectInfo, current_response_));
+ request_.method = redirectInfo.new_method;
+ request_.url = redirectInfo.new_url;
+ request_.site_for_cookies = redirectInfo.new_site_for_cookies;
+ request_.referrer = GURL(redirectInfo.new_referrer);
+ request_.referrer_policy = redirectInfo.new_referrer_policy;
+ if (request_.method == net::HttpRequestHeaders::kGetMethod)
+ request_.request_body = nullptr;
+ return;
+ }
+
+ if (!requestInfo.d_ptr->extraHeaders.isEmpty()) {
+ auto end = requestInfo.d_ptr->extraHeaders.constEnd();
+ for (auto header = requestInfo.d_ptr->extraHeaders.constBegin(); header != end; ++header) {
+ std::string h = header.key().toStdString();
+ if (base::LowerCaseEqualsASCII(h, "referer")) {
+ request_.referrer = GURL(header.value().toStdString());
+ } else {
+ request_.headers.SetHeader(h, header.value().toStdString());
+ }
+ }
+ }
+ }
+ }
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&InterceptedRequest::ContinueAfterIntercept, m_weakPtr));
+}
+
+void InterceptedRequest::ContinueAfterIntercept()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (!target_loader_ && target_factory_) {
+ network::mojom::URLLoaderClientPtr proxied_client;
+ proxied_client_binding_.Bind(mojo::MakeRequest(&proxied_client));
+ target_factory_->CreateLoaderAndStart(mojo::MakeRequest(&target_loader_), routing_id_, request_id_, options_,
+ request_, std::move(proxied_client), traffic_annotation_);
+ }
+}
+
+// URLLoaderClient methods.
+
+void InterceptedRequest::OnReceiveResponse(const network::ResourceResponseHead &head)
+{
+ current_response_ = head;
+
+ target_client_->OnReceiveResponse(head);
+}
+
+void InterceptedRequest::OnReceiveRedirect(const net::RedirectInfo &redirect_info, const network::ResourceResponseHead &head)
+{
+ // TODO(timvolodine): handle redirect override.
+ request_was_redirected_ = true;
+ current_response_ = head;
+ target_client_->OnReceiveRedirect(redirect_info, head);
+ request_.url = redirect_info.new_url;
+ request_.method = redirect_info.new_method;
+ request_.site_for_cookies = redirect_info.new_site_for_cookies;
+ request_.referrer = GURL(redirect_info.new_referrer);
+ request_.referrer_policy = redirect_info.new_referrer_policy;
+}
+
+void InterceptedRequest::OnUploadProgress(int64_t current_position, int64_t total_size, OnUploadProgressCallback callback)
+{
+ target_client_->OnUploadProgress(current_position, total_size, std::move(callback));
+}
+
+void InterceptedRequest::OnReceiveCachedMetadata(mojo_base::BigBuffer data)
+{
+ target_client_->OnReceiveCachedMetadata(std::move(data));
+}
+
+void InterceptedRequest::OnTransferSizeUpdated(int32_t transfer_size_diff)
+{
+ target_client_->OnTransferSizeUpdated(transfer_size_diff);
+}
+
+void InterceptedRequest::OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body)
+{
+ target_client_->OnStartLoadingResponseBody(std::move(body));
+}
+
+void InterceptedRequest::OnComplete(const network::URLLoaderCompletionStatus &status)
+{
+ // Only wait for the original loader to possibly have a custom error if the
+ // target loader succeeded. If the target loader failed, then it was a race as
+ // to whether that error or the safe browsing error would be reported.
+ CallOnComplete(status, status.error_code == net::OK);
+}
+
+// URLLoader methods.
+
+void InterceptedRequest::FollowRedirect(const std::vector<std::string> &removed_headers,
+ const net::HttpRequestHeaders &modified_headers,
+ const base::Optional<GURL> &new_url)
+{
+ if (target_loader_)
+ target_loader_->FollowRedirect(removed_headers, modified_headers, new_url);
+
+ // If |OnURLLoaderClientError| was called then we're just waiting for the
+ // connection error handler of |proxied_loader_binding_|. Don't restart the
+ // job since that'll create another URLLoader
+ if (!target_client_)
+ return;
+
+ Restart();
+}
+
+void InterceptedRequest::ProceedWithResponse()
+{
+ if (target_loader_)
+ target_loader_->ProceedWithResponse();
+}
+
+void InterceptedRequest::SetPriority(net::RequestPriority priority, int32_t intra_priority_value)
+{
+ if (target_loader_)
+ target_loader_->SetPriority(priority, intra_priority_value);
+}
+
+void InterceptedRequest::PauseReadingBodyFromNet()
+{
+ if (target_loader_)
+ target_loader_->PauseReadingBodyFromNet();
+}
+
+void InterceptedRequest::ResumeReadingBodyFromNet()
+{
+ if (target_loader_)
+ target_loader_->ResumeReadingBodyFromNet();
+}
+
+void InterceptedRequest::OnURLLoaderClientError()
+{
+ // We set |wait_for_loader_error| to true because if the loader did have a
+ // custom_reason error then the client would be reset as well and it would be
+ // a race as to which connection error we saw first.
+ CallOnComplete(network::URLLoaderCompletionStatus(net::ERR_ABORTED), true /* wait_for_loader_error */);
+}
+
+void InterceptedRequest::OnURLLoaderError(uint32_t custom_reason, const std::string &description)
+{
+ // If CallOnComplete was already called, then this object is ready to be deleted.
+ if (!target_client_)
+ delete this;
+}
+
+void InterceptedRequest::CallOnComplete(const network::URLLoaderCompletionStatus &status, bool wait_for_loader_error)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ // Save an error status so that we call onReceiveError at destruction if there
+ // was no safe browsing error.
+ if (status.error_code != net::OK)
+ error_status_ = status.error_code;
+
+ if (target_client_)
+ target_client_->OnComplete(status);
+
+ if (proxied_loader_binding_ && wait_for_loader_error) {
+ // Don't delete |this| yet, in case the |proxied_loader_binding_|'s
+ // error_handler is called with a reason to indicate an error which we want
+ // to send to the client bridge. Also reset |target_client_| so we don't
+ // get its error_handler called and then delete |this|.
+ target_client_.reset();
+
+ // Since the original client is gone no need to continue loading the
+ // request.
+ proxied_client_binding_.Close();
+ target_loader_.reset();
+
+ // In case there are pending checks as to whether this request should be
+ // intercepted, we don't want that causing |target_client_| to be used
+ // later.
+ m_weakFactory.InvalidateWeakPtrs();
+ } else {
+ delete this;
+ }
+}
+
+void InterceptedRequest::SendErrorAndCompleteImmediately(int error_code)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ auto status = network::URLLoaderCompletionStatus(error_code);
+ target_client_->OnComplete(status);
+ delete this;
+}
+
+ProxyingURLLoaderFactoryQt::ProxyingURLLoaderFactoryQt(int process_id,
+ content::ResourceContext *resourceContext,
+ network::mojom::URLLoaderFactoryRequest loader_request,
+ network::mojom::URLLoaderFactoryPtrInfo target_factory_info)
+ : m_processId(process_id), m_resourceContext(resourceContext), m_weakFactory(this)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (target_factory_info) {
+ m_targetFactory.Bind(std::move(target_factory_info));
+ m_targetFactory.set_connection_error_handler(
+ base::BindOnce(&ProxyingURLLoaderFactoryQt::OnTargetFactoryError, m_weakFactory.GetWeakPtr()));
+ }
+ m_proxyBindings.AddBinding(this, std::move(loader_request));
+ m_proxyBindings.set_connection_error_handler(
+ base::BindRepeating(&ProxyingURLLoaderFactoryQt::OnProxyBindingError, m_weakFactory.GetWeakPtr()));
+}
+
+ProxyingURLLoaderFactoryQt::~ProxyingURLLoaderFactoryQt()
+{
+ m_weakFactory.InvalidateWeakPtrs();
+}
+
+// static
+void ProxyingURLLoaderFactoryQt::CreateProxy(int process_id,
+ content::ResourceContext *resourceContext,
+ network::mojom::URLLoaderFactoryRequest loader_request,
+ network::mojom::URLLoaderFactoryPtrInfo target_factory_info)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ // Will manage its own lifetime
+ new ProxyingURLLoaderFactoryQt(process_id, resourceContext, std::move(loader_request), std::move(target_factory_info));
+}
+
+void ProxyingURLLoaderFactoryQt::CreateLoaderAndStart(network::mojom::URLLoaderRequest loader, int32_t routing_id,
+ int32_t request_id, uint32_t options,
+ const network::ResourceRequest &request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ ProfileIODataQt *profileIOData = ProfileIODataQt::FromResourceContext(m_resourceContext);
+
+ QWebEngineUrlRequestInterceptor *profileInterceptor = profileIOData ? profileIOData->requestInterceptor() : nullptr;
+ if (!profileIOData || !(profileInterceptor || profileIOData->hasPageInterceptors())) {
+ m_targetFactory->CreateLoaderAndStart(
+ std::move(loader), routing_id, request_id, options, request,
+ std::move(client), traffic_annotation);
+ return;
+ }
+
+ network::mojom::URLLoaderFactoryPtr target_factory_clone;
+ if (m_targetFactory)
+ m_targetFactory->Clone(mojo::MakeRequest(&target_factory_clone));
+
+
+ // Will manage its own lifetime
+ InterceptedRequest *req = new InterceptedRequest(m_processId, request_id, routing_id, options, request,
+ traffic_annotation, profileIOData,
+ std::move(loader), std::move(client),
+ std::move(target_factory_clone));
+ req->Restart();
+}
+
+void ProxyingURLLoaderFactoryQt::OnTargetFactoryError()
+{
+ delete this;
+}
+
+void ProxyingURLLoaderFactoryQt::OnProxyBindingError()
+{
+ if (m_proxyBindings.empty())
+ delete this;
+}
+
+void ProxyingURLLoaderFactoryQt::Clone(network::mojom::URLLoaderFactoryRequest loader_request)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ m_proxyBindings.AddBinding(this, std::move(loader_request));
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/proxying_url_loader_factory_qt.h b/src/core/net/proxying_url_loader_factory_qt.h
new file mode 100644
index 000000000..a2f175885
--- /dev/null
+++ b/src/core/net/proxying_url_loader_factory_qt.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROXYING_URL_LOADER_FACTORY_QT_H_
+#define PROXYING_URL_LOADER_FACTORY_QT_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_delete_on_sequence.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "url/gurl.h"
+
+// based on aw_proxying_url_loader_factory.h:
+// Copyright 2018 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.
+
+namespace content {
+class ResourceContext;
+}
+
+namespace QtWebEngineCore {
+
+class ProxyingURLLoaderFactoryQt : public network::mojom::URLLoaderFactory
+{
+public:
+ ProxyingURLLoaderFactoryQt(int process_id, content::ResourceContext *resourceContext,
+ network::mojom::URLLoaderFactoryRequest loader_request,
+ network::mojom::URLLoaderFactoryPtrInfo target_factory_info);
+
+ ~ProxyingURLLoaderFactoryQt() override;
+
+ // static
+ static void CreateProxy(int process_id, content::ResourceContext *resourceContext,
+ network::mojom::URLLoaderFactoryRequest loader,
+ network::mojom::URLLoaderFactoryPtrInfo target_factory_info);
+
+ void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader, int32_t routing_id, int32_t request_id,
+ uint32_t options, const network::ResourceRequest &request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation) override;
+
+ void Clone(network::mojom::URLLoaderFactoryRequest loader_request) override;
+
+private:
+ void OnTargetFactoryError();
+ void OnProxyBindingError();
+
+ const int m_processId;
+ mojo::BindingSet<network::mojom::URLLoaderFactory> m_proxyBindings;
+ network::mojom::URLLoaderFactoryPtr m_targetFactory;
+
+ content::ResourceContext *m_resourceContext;
+
+ base::WeakPtrFactory<ProxyingURLLoaderFactoryQt> m_weakFactory;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyingURLLoaderFactoryQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PROXYING_URL_LOADER_FACTORY_QT_H_
diff --git a/src/core/net/restricted_cookie_manager_qt.cpp b/src/core/net/restricted_cookie_manager_qt.cpp
deleted file mode 100644
index 7f1ca163e..000000000
--- a/src/core/net/restricted_cookie_manager_qt.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// originally based on android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc:
-// Copyright 2019 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 "restricted_cookie_manager_qt.h"
-
-#include "api/qwebenginecookiestore.h"
-#include "api/qwebenginecookiestore_p.h"
-#include "profile_adapter.h"
-#include "profile_qt.h"
-#include "type_conversion.h"
-
-#include "base/memory/ptr_util.h"
-#include "base/task/post_task.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
-namespace QtWebEngineCore {
-
-class RestrictedCookieManagerListenerQt : public network::mojom::CookieChangeListener
-{
-public:
- RestrictedCookieManagerListenerQt(const GURL &url,
- const GURL &site_for_cookies,
- base::WeakPtr<RestrictedCookieManagerQt> restricted_cookie_manager,
- network::mojom::CookieChangeListenerPtr client_listener)
- : url_(url)
- , site_for_cookies_(site_for_cookies)
- , restricted_cookie_manager_(restricted_cookie_manager)
- , client_listener_(std::move(client_listener))
- {}
-
- void OnCookieChange(const net::CanonicalCookie &cookie, network::mojom::CookieChangeCause cause) override
- {
- if (restricted_cookie_manager_ && restricted_cookie_manager_->allowCookies(url_, site_for_cookies_))
- client_listener_->OnCookieChange(cookie, cause);
- }
-
-private:
- const GURL url_;
- const GURL site_for_cookies_;
- base::WeakPtr<RestrictedCookieManagerQt> restricted_cookie_manager_;
- network::mojom::CookieChangeListenerPtr client_listener_;
-};
-
-RestrictedCookieManagerQt::RestrictedCookieManagerQt(base::WeakPtr<ProfileIODataQt> profileIoData,
- network::mojom::RestrictedCookieManagerRole role,
- net::CookieStore *cookie_store,
- network::CookieSettings *cookie_settings,
- const url::Origin &origin,
- bool is_service_worker,
- int32_t process_id,
- int32_t frame_id)
- : network::RestrictedCookieManager(role, cookie_store, cookie_settings, origin,
- nullptr, is_service_worker, process_id, frame_id)
- , m_profileIoData(profileIoData)
- , weak_factory_(this)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-}
-
-RestrictedCookieManagerQt::~RestrictedCookieManagerQt()
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-}
-
-void RestrictedCookieManagerQt::GetAllForUrl(const GURL &url,
- const GURL &site_for_cookies,
- network::mojom::CookieManagerGetOptionsPtr options,
- GetAllForUrlCallback callback)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (allowCookies(url, site_for_cookies)) {
- network::RestrictedCookieManager::GetAllForUrl(url, site_for_cookies, std::move(options), std::move(callback));
- } else {
- std::move(callback).Run(std::vector<net::CanonicalCookie>());
- }
-}
-
-void RestrictedCookieManagerQt::SetCanonicalCookie(const net::CanonicalCookie &cookie,
- const GURL &url,
- const GURL &site_for_cookies,
- SetCanonicalCookieCallback callback)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (allowCookies(url, site_for_cookies)) {
- network::RestrictedCookieManager::SetCanonicalCookie(cookie, url, site_for_cookies, std::move(callback));
- } else {
- std::move(callback).Run(false);
- }
-}
-
-void RestrictedCookieManagerQt::AddChangeListener(const GURL &url,
- const GURL &site_for_cookies,
- network::mojom::CookieChangeListenerPtr listener,
- AddChangeListenerCallback callback)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- network::mojom::CookieChangeListenerPtr proxy_listener_ptr;
- auto proxy_listener =
- std::make_unique<RestrictedCookieManagerListenerQt>(
- url, site_for_cookies, weak_factory_.GetWeakPtr(),
- std::move(listener));
-
- mojo::MakeStrongBinding(std::move(proxy_listener),
- mojo::MakeRequest(&proxy_listener_ptr));
-
- network::RestrictedCookieManager::AddChangeListener(
- url, site_for_cookies, std::move(proxy_listener_ptr),
- std::move(callback));
-}
-
-void RestrictedCookieManagerQt::GetCookiesString(const GURL &url,
- const GURL &site_for_cookies,
- GetCookiesStringCallback callback)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (allowCookies(url, site_for_cookies)) {
- network::RestrictedCookieManager::GetCookiesString(url, site_for_cookies, std::move(callback));
- } else {
- std::move(callback).Run("");
- }
-}
-
-void RestrictedCookieManagerQt::CookiesEnabledFor(const GURL &url,
- const GURL &site_for_cookies,
- CookiesEnabledForCallback callback)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- std::move(callback).Run(allowCookies(url, site_for_cookies));
-}
-
-bool RestrictedCookieManagerQt::allowCookies(const GURL &url, const GURL &site_for_cookies) const
-{
- if (!m_profileIoData)
- return false;
- return m_profileIoData->canGetCookies(toQt(site_for_cookies), toQt(url));
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/net/system_network_context_manager.cpp b/src/core/net/system_network_context_manager.cpp
new file mode 100644
index 000000000..cf84b840b
--- /dev/null
+++ b/src/core/net/system_network_context_manager.cpp
@@ -0,0 +1,351 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// based on chrome/browser/net/system_network_context_manager.cc:
+// Copyright 2017 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 "net/system_network_context_manager.h"
+
+#include <set>
+#include <unordered_map>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/feature_list.h"
+#include "base/logging.h"
+#include "base/sequence_checker.h"
+#include "base/strings/string_split.h"
+#include "base/task/post_task.h"
+#include "base/values.h"
+#include "build/build_config.h"
+#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
+#include "chrome/common/chrome_switches.h"
+#include "components/certificate_transparency/ct_known_logs.h"
+#include "components/network_session_configurator/common/network_features.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/cors_exempt_headers.h"
+#include "content/public/browser/network_service_instance.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/public/common/user_agent.h"
+#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
+#include "net/dns/public/util.h"
+#include "net/net_buildflags.h"
+#include "net/third_party/uri_template/uri_template.h"
+#include "services/network/network_service.h"
+#include "services/network/public/cpp/cross_thread_shared_url_loader_factory_info.h"
+#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/mojom/host_resolver.mojom.h"
+#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
+#include "url/gurl.h"
+
+namespace {
+
+// The global instance of the SystemNetworkContextmanager.
+SystemNetworkContextManager *g_system_network_context_manager = nullptr;
+
+network::mojom::HttpAuthStaticParamsPtr CreateHttpAuthStaticParams()
+{
+ network::mojom::HttpAuthStaticParamsPtr auth_static_params = network::mojom::HttpAuthStaticParams::New();
+
+ auth_static_params->supported_schemes = { "basic", "digest", "ntlm", "negotiate" };
+
+ return auth_static_params;
+}
+
+network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams()
+{
+ network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params = network::mojom::HttpAuthDynamicParams::New();
+
+ auto *command_line = base::CommandLine::ForCurrentProcess();
+ auth_dynamic_params->server_whitelist = command_line->GetSwitchValueASCII(switches::kAuthServerWhitelist);
+// auth_dynamic_params->delegate_whitelist = command_line->GetSwitchValueASCII(switches::kAuthNegotiateDelegateWhitelist);
+// auth_dynamic_params->enable_negotiate_port = command_line->HasSwitch(switches::kEnableAuthNegotiatePort);
+
+ return auth_dynamic_params;
+}
+
+} // namespace
+
+// SharedURLLoaderFactory backed by a SystemNetworkContextManager and its
+// network context. Transparently handles crashes.
+class SystemNetworkContextManager::URLLoaderFactoryForSystem : public network::SharedURLLoaderFactory
+{
+public:
+ explicit URLLoaderFactoryForSystem(SystemNetworkContextManager *manager) : manager_(manager)
+ {
+ DETACH_FROM_SEQUENCE(sequence_checker_);
+ }
+
+ // mojom::URLLoaderFactory implementation:
+
+ void CreateLoaderAndStart(network::mojom::URLLoaderRequest request, int32_t routing_id, int32_t request_id,
+ uint32_t options, const network::ResourceRequest &url_request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation) override
+ {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!manager_)
+ return;
+ manager_->GetURLLoaderFactory()->CreateLoaderAndStart(std::move(request), routing_id, request_id, options,
+ url_request, std::move(client), traffic_annotation);
+ }
+
+ void Clone(network::mojom::URLLoaderFactoryRequest request) override
+ {
+ if (!manager_)
+ return;
+ manager_->GetURLLoaderFactory()->Clone(std::move(request));
+ }
+
+ // SharedURLLoaderFactory implementation:
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override
+ {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return std::make_unique<network::CrossThreadSharedURLLoaderFactoryInfo>(this);
+ }
+
+ void Shutdown() { manager_ = nullptr; }
+
+private:
+ friend class base::RefCounted<URLLoaderFactoryForSystem>;
+ ~URLLoaderFactoryForSystem() override {}
+
+ SEQUENCE_CHECKER(sequence_checker_);
+ SystemNetworkContextManager *manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryForSystem);
+};
+
+network::mojom::NetworkContext *SystemNetworkContextManager::GetContext()
+{
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // SetUp should already have been called.
+ DCHECK(io_thread_network_context_);
+ return io_thread_network_context_.get();
+ }
+
+ if (!network_service_network_context_ || network_service_network_context_.encountered_error()) {
+ // This should call into OnNetworkServiceCreated(), which will re-create
+ // the network service, if needed. There's a chance that it won't be
+ // invoked, if the NetworkContext has encountered an error but the
+ // NetworkService has not yet noticed its pipe was closed. In that case,
+ // trying to create a new NetworkContext would fail, anyways, and hopefully
+ // a new NetworkContext will be created on the next GetContext() call.
+ content::GetNetworkService();
+ DCHECK(network_service_network_context_);
+ }
+ return network_service_network_context_.get();
+}
+
+network::mojom::URLLoaderFactory *SystemNetworkContextManager::GetURLLoaderFactory()
+{
+ // Create the URLLoaderFactory as needed.
+ if (url_loader_factory_ && !url_loader_factory_.encountered_error()) {
+ return url_loader_factory_.get();
+ }
+
+ network::mojom::URLLoaderFactoryParamsPtr params = network::mojom::URLLoaderFactoryParams::New();
+ params->process_id = network::mojom::kBrowserProcessId;
+ params->is_corb_enabled = false;
+ GetContext()->CreateURLLoaderFactory(mojo::MakeRequest(&url_loader_factory_), std::move(params));
+ return url_loader_factory_.get();
+}
+
+scoped_refptr<network::SharedURLLoaderFactory> SystemNetworkContextManager::GetSharedURLLoaderFactory()
+{
+ return shared_url_loader_factory_;
+}
+
+void SystemNetworkContextManager::SetUp(
+ network::mojom::NetworkContextRequest *network_context_request,
+ network::mojom::NetworkContextParamsPtr *network_context_params, bool *stub_resolver_enabled,
+ base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> *dns_over_https_servers,
+ network::mojom::HttpAuthStaticParamsPtr *http_auth_static_params,
+ network::mojom::HttpAuthDynamicParamsPtr *http_auth_dynamic_params, bool *is_quic_allowed)
+{
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ *network_context_request = mojo::MakeRequest(&io_thread_network_context_);
+ *network_context_params = CreateNetworkContextParams();
+ }
+ *is_quic_allowed = false;
+ *http_auth_static_params = CreateHttpAuthStaticParams();
+ *http_auth_dynamic_params = CreateHttpAuthDynamicParams();
+ // GetStubResolverConfig(local_state_, stub_resolver_enabled, dns_over_https_servers);
+}
+
+// static
+SystemNetworkContextManager *SystemNetworkContextManager::CreateInstance()
+{
+ DCHECK(!g_system_network_context_manager);
+ g_system_network_context_manager = new SystemNetworkContextManager();
+ return g_system_network_context_manager;
+}
+
+// static
+SystemNetworkContextManager *SystemNetworkContextManager::GetInstance()
+{
+ return g_system_network_context_manager;
+}
+
+// static
+void SystemNetworkContextManager::DeleteInstance()
+{
+ DCHECK(g_system_network_context_manager);
+ delete g_system_network_context_manager;
+}
+
+SystemNetworkContextManager::SystemNetworkContextManager()
+{
+ shared_url_loader_factory_ = new URLLoaderFactoryForSystem(this);
+}
+
+SystemNetworkContextManager::~SystemNetworkContextManager()
+{
+ shared_url_loader_factory_->Shutdown();
+}
+
+void SystemNetworkContextManager::OnNetworkServiceCreated(network::mojom::NetworkService *network_service)
+{
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
+ return;
+ // Disable QUIC globally
+ network_service->DisableQuic();
+
+ network_service->SetUpHttpAuth(CreateHttpAuthStaticParams());
+ network_service->ConfigureHttpAuthPrefs(CreateHttpAuthDynamicParams());
+
+ // The system NetworkContext must be created first, since it sets
+ // |primary_network_context| to true.
+ network_service->CreateNetworkContext(MakeRequest(&network_service_network_context_), CreateNetworkContextParams());
+
+ // Configure the stub resolver. This must be done after the system
+ // NetworkContext is created, but before anything has the chance to use it.
+ // bool stub_resolver_enabled;
+ // base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> dns_over_https_servers;
+ // GetStubResolverConfig(local_state_, &stub_resolver_enabled, &dns_over_https_servers);
+ // content::GetNetworkService()->ConfigureStubHostResolver(stub_resolver_enabled, std::move(dns_over_https_servers));
+}
+
+void SystemNetworkContextManager::AddSSLConfigToNetworkContextParams(network::mojom::NetworkContextParams *network_context_params)
+{
+ network_context_params->initial_ssl_config = network::mojom::SSLConfig::New();
+ network_context_params->initial_ssl_config->rev_checking_enabled = true;
+ network_context_params->initial_ssl_config->symantec_enforcement_disabled = true;
+}
+
+network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateDefaultNetworkContextParams()
+{
+ network::mojom::NetworkContextParamsPtr network_context_params = network::mojom::NetworkContextParams::New();
+ content::UpdateCorsExemptHeader(network_context_params.get());
+
+ network_context_params->enable_brotli = true;
+
+ // network_context_params->user_agent = GetUserAgent();
+
+ // Disable referrers by default. Any consumer that enables referrers should
+ // respect prefs::kEnableReferrers from the appropriate pref store.
+ network_context_params->enable_referrers = false;
+
+ // const base::CommandLine& command_line =
+ // *base::CommandLine::ForCurrentProcess();
+
+ // // TODO(eroman): Figure out why this doesn't work in single-process mode,
+ // // or if it does work, now.
+ // // Should be possible now that a private isolate is used.
+ // // http://crbug.com/474654
+ // if (!command_line.HasSwitch(switches::kWinHttpProxyResolver)) {
+ // if (command_line.HasSwitch(switches::kSingleProcess)) {
+ // LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode.";
+ // } else {
+ network_context_params->proxy_resolver_factory = ChromeMojoProxyResolverFactory::CreateWithSelfOwnedReceiver();
+ // }
+ // }
+
+ // network_context_params->pac_quick_check_enabled = local_state_->GetBoolean(prefs::kQuickCheckEnabled);
+
+ // Use the SystemNetworkContextManager to populate and update SSL
+ // configuration. The SystemNetworkContextManager is owned by the
+ // BrowserProcess itself, so will only be destroyed on shutdown, at which
+ // point, all NetworkContexts will be destroyed as well.
+ AddSSLConfigToNetworkContextParams(network_context_params.get());
+
+ // CT is only enabled on Desktop platforms for now.
+ network_context_params->enforce_chrome_ct_policy = true;
+ for (const auto &ct_log : certificate_transparency::GetKnownLogs()) {
+ // TODO(rsleevi): https://crbug.com/702062 - Remove this duplication.
+ network::mojom::CTLogInfoPtr log_info = network::mojom::CTLogInfo::New();
+ log_info->public_key = std::string(ct_log.log_key, ct_log.log_key_length);
+ log_info->name = ct_log.log_name;
+ network_context_params->ct_logs.push_back(std::move(log_info));
+ }
+
+ network_context_params->http_09_on_non_default_ports_enabled = false;
+
+ return network_context_params;
+}
+
+network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateNetworkContextParams()
+{
+ // TODO(mmenke): Set up parameters here (in memory cookie store, etc).
+ network::mojom::NetworkContextParamsPtr network_context_params = CreateDefaultNetworkContextParams();
+
+ network_context_params->context_name = std::string("system");
+
+ network_context_params->enable_referrers = false;
+
+ network_context_params->http_cache_enabled = false;
+
+ // These are needed for PAC scripts that use FTP URLs.
+#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
+ network_context_params->enable_ftp_url_support = true;
+#endif
+
+ network_context_params->primary_network_context = true;
+
+ proxy_config_monitor_.AddToNetworkContextParams(network_context_params.get());
+
+ return network_context_params;
+}
diff --git a/src/core/net/system_network_context_manager.h b/src/core/net/system_network_context_manager.h
new file mode 100644
index 000000000..288af5195
--- /dev/null
+++ b/src/core/net/system_network_context_manager.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// based on chrome/browser/net/system_network_context_manager.h:
+// Copyright 2017 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.
+
+#ifndef SYSTEM_NETWORK_CONTEXT_MANAGER_H_
+#define SYSTEM_NETWORK_CONTEXT_MANAGER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/optional.h"
+#include "services/network/public/mojom/host_resolver.mojom-forward.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+#include "services/network/public/mojom/network_service.mojom-forward.h"
+#include "services/network/public/mojom/ssl_config.mojom-forward.h"
+#include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
+
+#include "net/proxy_config_monitor.h"
+
+namespace network {
+namespace mojom {
+class URLLoaderFactory;
+}
+class SharedURLLoaderFactory;
+} // namespace network
+
+namespace net_log {
+class NetExportFileWriter;
+}
+
+// Responsible for creating and managing access to the system NetworkContext.
+// Lives on the UI thread. The NetworkContext this owns is intended for requests
+// not associated with a profile. It stores no data on disk, and has no HTTP
+// cache, but it does have ephemeral cookie and channel ID stores. It also does
+// not have access to HTTP proxy auth information the user has entered or that
+// comes from extensions, and similarly, has no extension-provided per-profile
+// proxy configuration information.
+//
+// This class is also responsible for configuring global NetworkService state.
+//
+// The "system" NetworkContext will either share a URLRequestContext with
+// IOThread's SystemURLRequestContext and be part of IOThread's NetworkService
+// (If the network service is disabled) or be an independent NetworkContext
+// using the actual network service.
+//
+// This class is intended to eventually replace IOThread. Handling the two cases
+// differently allows this to be used in production without breaking anything or
+// requiring two separate paths, while IOThread consumers slowly transition over
+// to being compatible with the network service.
+class SystemNetworkContextManager
+{
+public:
+ ~SystemNetworkContextManager();
+
+ // Creates the global instance of SystemNetworkContextManager. If an
+ // instance already exists, this will cause a DCHECK failure.
+ static SystemNetworkContextManager *CreateInstance();
+
+ // Gets the global SystemNetworkContextManager instance.
+ static SystemNetworkContextManager *GetInstance();
+
+ // Destroys the global SystemNetworkContextManager instance.
+ static void DeleteInstance();
+
+ // If the network service is disabled, |network_context_request| will be for
+ // the NetworkContext used by the SystemNetworkContextManager and
+ // |network_context_params| as needed to set up a system NetworkContext.
+ // Otherwise, this method can still be used to help set up the IOThread's
+ // in-process URLRequestContext.
+ //
+ // Must be called before the system NetworkContext is first used.
+ //
+ // |stub_resolver_enabled|, |dns_over_https_servers|,
+ // |http_auth_static_params|, |http_auth_dynamic_params|, and
+ // |is_quic_allowed| are used to pass initial NetworkService state to the
+ // caller, so the NetworkService can be configured appropriately. Using
+ // NetworkService's Mojo interface to set those options would lead to races
+ // with other UI->IO thread network-related tasks, since Mojo doesn't preserve
+ // execution order relative to PostTasks.
+ void SetUp(network::mojom::NetworkContextRequest *network_context_request,
+ network::mojom::NetworkContextParamsPtr *network_context_params, bool *stub_resolver_enabled,
+ base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> *dns_over_https_servers,
+ network::mojom::HttpAuthStaticParamsPtr *http_auth_static_params,
+ network::mojom::HttpAuthDynamicParamsPtr *http_auth_dynamic_params, bool *is_quic_allowed);
+
+ // Returns the System NetworkContext. May only be called after SetUp(). Does
+ // any initialization of the NetworkService that may be needed when first
+ // called.
+ network::mojom::NetworkContext *GetContext();
+
+ // Returns a URLLoaderFactory owned by the SystemNetworkContextManager that is
+ // backed by the SystemNetworkContext. Allows sharing of the URLLoaderFactory.
+ // Prefer this to creating a new one. Call Clone() on the value returned by
+ // this method to get a URLLoaderFactory that can be used on other threads.
+ network::mojom::URLLoaderFactory *GetURLLoaderFactory();
+
+ // Returns a SharedURLLoaderFactory owned by the SystemNetworkContextManager
+ // that is backed by the SystemNetworkContext.
+ scoped_refptr<network::SharedURLLoaderFactory> GetSharedURLLoaderFactory();
+
+ // Called when content creates a NetworkService. Creates the
+ // SystemNetworkContext, if the network service is enabled.
+ void OnNetworkServiceCreated(network::mojom::NetworkService *network_service);
+
+ // Populates |initial_ssl_config| and |ssl_config_client_request| members of
+ // |network_context_params|. As long as the SystemNetworkContextManager
+ // exists, any NetworkContext created with the params will continue to get
+ // SSL configuration updates.
+ void AddSSLConfigToNetworkContextParams(network::mojom::NetworkContextParams *network_context_params);
+
+ // Returns default set of parameters for configuring the network service.
+ network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams();
+
+private:
+ class URLLoaderFactoryForSystem;
+
+ explicit SystemNetworkContextManager();
+
+ // Creates parameters for the NetworkContext. May only be called once, since
+ // it initializes some class members.
+ network::mojom::NetworkContextParamsPtr CreateNetworkContextParams();
+
+ // ProxyConfigMonitor proxy_config_monitor_;
+
+ // NetworkContext using the network service, if the network service is
+ // enabled. nullptr, otherwise.
+ network::mojom::NetworkContextPtr network_service_network_context_;
+
+ // This is a NetworkContext that wraps the IOThread's SystemURLRequestContext.
+ // Always initialized in SetUp, but it's only returned by Context() when the
+ // network service is disabled.
+ network::mojom::NetworkContextPtr io_thread_network_context_;
+
+ // URLLoaderFactory backed by the NetworkContext returned by GetContext(), so
+ // consumers don't all need to create their own factory.
+ scoped_refptr<URLLoaderFactoryForSystem> shared_url_loader_factory_;
+ network::mojom::URLLoaderFactoryPtr url_loader_factory_;
+
+ ProxyConfigMonitor proxy_config_monitor_;
+
+ DISALLOW_COPY_AND_ASSIGN(SystemNetworkContextManager);
+};
+
+#endif // SYSTEM_NETWORK_CONTEXT_MANAGER_H_
diff --git a/src/core/net/url_request_context_getter_qt.cpp b/src/core/net/url_request_context_getter_qt.cpp
deleted file mode 100644
index 6081a5e9f..000000000
--- a/src/core/net/url_request_context_getter_qt.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "url_request_context_getter_qt.h"
-#include "profile_io_data_qt.h"
-
-#include "base/task/post_task.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace QtWebEngineCore {
-
-URLRequestContextGetterQt::URLRequestContextGetterQt(ProfileIODataQt *data)
- : m_profileIOData(data)
-{
-}
-
-URLRequestContextGetterQt::~URLRequestContextGetterQt()
-{
-}
-
-net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
-{
- Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- return m_profileIOData->urlRequestContext();
-}
-
-scoped_refptr<base::SingleThreadTaskRunner> URLRequestContextGetterQt::GetNetworkTaskRunner() const
-{
- return base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO});
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/net/url_request_custom_job.cpp b/src/core/net/url_request_custom_job.cpp
deleted file mode 100644
index 607e8d232..000000000
--- a/src/core/net/url_request_custom_job.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "url_request_custom_job.h"
-#include "url_request_custom_job_proxy.h"
-
-#include "api/qwebengineurlscheme.h"
-
-#include "base/strings/stringprintf.h"
-#include "base/task/post_task.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/io_buffer.h"
-#include "net/http/http_util.h"
-
-#include <QIODevice>
-
-using namespace net;
-
-namespace QtWebEngineCore {
-
-URLRequestCustomJob::URLRequestCustomJob(URLRequest *request,
- NetworkDelegate *networkDelegate,
- const std::string &scheme,
- QPointer<ProfileAdapter> profileAdapter)
- : URLRequestJob(request, networkDelegate)
- , m_proxy(new URLRequestCustomJobProxy(this, scheme, profileAdapter))
- , m_device(nullptr)
- , m_error(0)
- , m_pendingReadSize(0)
- , m_pendingReadPos(0)
- , m_pendingReadBuffer(nullptr)
- , m_corsEnabled(QWebEngineUrlScheme::schemeByName(QByteArray::fromStdString(scheme))
- .flags().testFlag(QWebEngineUrlScheme::CorsEnabled))
-{
-}
-
-URLRequestCustomJob::~URLRequestCustomJob()
-{
- m_proxy->m_job = nullptr;
- if (m_device && m_device->isOpen())
- m_device->close();
- m_device = nullptr;
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
-}
-
-void URLRequestCustomJob::Start()
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- HttpRequestHeaders requestHeaders = request()->extra_request_headers();
- std::map<std::string, std::string> headers;
- net::HttpRequestHeaders::Iterator it(requestHeaders);
- while (it.GetNext())
- headers.emplace(it.name(), it.value());
- if (!request()->referrer().empty())
- headers.emplace("Referer", request()->referrer());
-
- // TODO: handle UploadDataStream, for instance using a QIODevice wrapper.
-
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&URLRequestCustomJobProxy::initialize,
- m_proxy,
- request()->url(),
- request()->method(),
- request()->initiator(),
- std::move(headers)));
-}
-
-void URLRequestCustomJob::Kill()
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- m_proxy->m_job = nullptr;
- if (m_device && m_device->isOpen())
- m_device->close();
- if (m_pendingReadBuffer) {
- m_pendingReadBuffer->Release();
- m_pendingReadBuffer = nullptr;
- m_pendingReadSize = 0;
- m_pendingReadPos = 0;
- }
- m_device = nullptr;
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&URLRequestCustomJobProxy::release,
- m_proxy));
- URLRequestJob::Kill();
-}
-
-bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (m_mimeType.size() > 0) {
- *mimeType = m_mimeType;
- return true;
- }
- return false;
-}
-
-bool URLRequestCustomJob::GetCharset(std::string *charset)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (m_charset.size() > 0) {
- *charset = m_charset;
- return true;
- }
- return false;
-}
-
-void URLRequestCustomJob::GetResponseInfo(HttpResponseInfo *info)
-{
- // Based on net::URLRequestRedirectJob::StartAsync()
-
- if (m_error)
- return;
-
- std::string headers;
- if (m_redirect.is_valid()) {
- headers += "HTTP/1.1 303 See Other\n";
- headers += base::StringPrintf("Location: %s\n", m_redirect.spec().c_str());
- } else {
- headers += base::StringPrintf("HTTP/1.1 %i OK\n", 200);
- if (m_mimeType.size() > 0) {
- headers += base::StringPrintf("Content-Type: %s", m_mimeType.c_str());
- if (m_charset.size() > 0)
- headers += base::StringPrintf("; charset=%s", m_charset.c_str());
- headers += "\n";
- }
- }
- if (m_corsEnabled) {
- std::string origin;
- if (request_->extra_request_headers().GetHeader("Origin", &origin)) {
- headers += base::StringPrintf("Access-Control-Allow-Origin: %s\n", origin.c_str());
- headers += "Access-Control-Allow-Credentials: true\n";
- }
- }
-
- info->headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(headers));
-}
-
-bool URLRequestCustomJob::IsRedirectResponse(GURL *location, int *http_status_code, bool * /*insecure_scheme_was_upgraded*/)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (m_redirect.is_valid()) {
- *location = m_redirect;
- *http_status_code = 303;
- return true;
- }
- return false;
-}
-
-int URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (m_error)
- return m_error;
- qint64 rv = m_device ? m_device->read(buf->data(), bufSize) : -1;
- if (rv > 0) {
- return static_cast<int>(rv);
- } else if (rv == 0) {
- // Returning zero is interpreted as EOF by Chromium, so only
- // return zero if we are the end of the file.
- if (m_device->atEnd())
- return 0;
- // Otherwise return IO_PENDING and call ReadRawDataComplete when we have data
- // for them.
- buf->AddRef();
- m_pendingReadPos = 0;
- m_pendingReadSize = bufSize;
- m_pendingReadBuffer = buf;
- return ERR_IO_PENDING;
- } else {
- // QIODevice::read might have called fail on us.
- if (m_error)
- return m_error;
- if (m_device && m_device->atEnd())
- return 0;
- return ERR_FAILED;
- }
-}
-
-void URLRequestCustomJob::notifyReadyRead()
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!m_device)
- return;
- if (!m_pendingReadSize)
- return;
- Q_ASSERT(m_pendingReadBuffer);
- if (!m_pendingReadBuffer)
- return;
-
- qint64 rv = m_device->read(m_pendingReadBuffer->data() + m_pendingReadPos, m_pendingReadSize - m_pendingReadPos);
- if (rv == 0)
- return;
- if (rv < 0) {
- if (m_error)
- rv = m_error;
- else if (m_device->atEnd())
- rv = 0;
- else
- rv = ERR_FAILED;
- } else {
- m_pendingReadPos += rv;
- if (m_pendingReadPos < m_pendingReadSize && !m_device->atEnd())
- return;
- rv = m_pendingReadPos;
- }
- // killJob may be called from ReadRawDataComplete
- net::IOBuffer *buf = m_pendingReadBuffer;
- m_pendingReadBuffer = nullptr;
- m_pendingReadSize = 0;
- m_pendingReadPos = 0;
- ReadRawDataComplete(rv);
- buf->Release();
-}
-
-} // namespace
diff --git a/src/core/net/url_request_custom_job.h b/src/core/net/url_request_custom_job.h
deleted file mode 100644
index af5a6f8e0..000000000
--- a/src/core/net/url_request_custom_job.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef URL_REQUEST_CUSTOM_JOB_H_
-#define URL_REQUEST_CUSTOM_JOB_H_
-
-#include "net/url_request/url_request_job.h"
-#include "url/gurl.h"
-#include <QtCore/QPointer>
-
-QT_FORWARD_DECLARE_CLASS(QIODevice)
-
-namespace QtWebEngineCore {
-
-class ProfileAdapter;
-class URLRequestCustomJobDelegate;
-class URLRequestCustomJobProxy;
-
-// A request job that handles reading custom URL schemes
-class URLRequestCustomJob : public net::URLRequestJob
-{
-public:
- URLRequestCustomJob(net::URLRequest *request,
- net::NetworkDelegate *networkDelegate,
- const std::string &scheme,
- QPointer<ProfileAdapter> profileAdapter);
- void Start() override;
- void Kill() override;
- int ReadRawData(net::IOBuffer *buf, int buf_size) override;
- bool GetMimeType(std::string *mimeType) const override;
- bool GetCharset(std::string *charset) override;
- void GetResponseInfo(net::HttpResponseInfo *info) override;
- bool IsRedirectResponse(GURL *location, int *http_status_code, bool *insecure_scheme_was_upgraded) override;
-
-protected:
- virtual ~URLRequestCustomJob();
-
-private:
- void notifyReadyRead();
- scoped_refptr<URLRequestCustomJobProxy> m_proxy;
- std::string m_mimeType;
- std::string m_charset;
- GURL m_redirect;
- QIODevice *m_device;
- int m_error;
- int m_pendingReadSize;
- int m_pendingReadPos;
- net::IOBuffer *m_pendingReadBuffer;
- const bool m_corsEnabled;
-
- friend class URLRequestCustomJobProxy;
-
- DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob);
-};
-} // namespace QtWebEngineCore
-
-#endif // URL_REQUEST_CUSTOM_JOB_H_
diff --git a/src/core/net/url_request_custom_job_delegate.cpp b/src/core/net/url_request_custom_job_delegate.cpp
index f73296cf0..ff307bede 100644
--- a/src/core/net/url_request_custom_job_delegate.cpp
+++ b/src/core/net/url_request_custom_job_delegate.cpp
@@ -92,27 +92,27 @@ void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice
{
if (device)
QObject::connect(device, &QIODevice::readyRead, this, &URLRequestCustomJobDelegate::slotReadyRead);
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&URLRequestCustomJobProxy::reply,
- m_proxy,contentType.toStdString(),device));
+ m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::reply,
+ m_proxy, contentType.toStdString(),device));
}
void URLRequestCustomJobDelegate::slotReadyRead()
{
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&URLRequestCustomJobProxy::readyRead, m_proxy));
+ m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::readyRead, m_proxy));
}
void URLRequestCustomJobDelegate::abort()
{
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&URLRequestCustomJobProxy::abort, m_proxy));
+ m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::abort, m_proxy));
}
void URLRequestCustomJobDelegate::redirect(const QUrl &url)
{
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&URLRequestCustomJobProxy::redirect, m_proxy, toGurl(url)));
+ m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::redirect, m_proxy, toGurl(url)));
}
void URLRequestCustomJobDelegate::fail(Error error)
@@ -138,8 +138,8 @@ void URLRequestCustomJobDelegate::fail(Error error)
break;
}
if (net_error) {
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&URLRequestCustomJobProxy::fail, m_proxy, net_error));
+ m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::fail, m_proxy, net_error));
}
}
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index 72d14450e..d2df64f2f 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -38,28 +38,29 @@
****************************************************************************/
#include "url_request_custom_job_proxy.h"
-#include "url_request_custom_job.h"
#include "url_request_custom_job_delegate.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "net/base/net_errors.h"
+
#include "api/qwebengineurlrequestjob.h"
#include "profile_adapter.h"
#include "type_conversion.h"
-#include "content/public/browser/browser_thread.h"
#include "web_engine_context.h"
-using namespace net;
-
namespace QtWebEngineCore {
-URLRequestCustomJobProxy::URLRequestCustomJobProxy(URLRequestCustomJob *job,
+URLRequestCustomJobProxy::URLRequestCustomJobProxy(URLRequestCustomJobProxy::Client *client,
const std::string &scheme,
QPointer<ProfileAdapter> profileAdapter)
- : m_job(job)
+ : m_client(client)
, m_started(false)
, m_scheme(scheme)
, m_delegate(nullptr)
, m_profileAdapter(profileAdapter)
+ , m_ioTaskRunner(m_client->taskRunner())
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK(m_ioTaskRunner && m_ioTaskRunner->RunsTasksInCurrentSequence());
}
URLRequestCustomJobProxy::~URLRequestCustomJobProxy()
@@ -87,69 +88,74 @@ void URLRequestCustomJobProxy::setReplyCharset(const std::string &charset)
*/
void URLRequestCustomJobProxy::reply(std::string mimeType, QIODevice *device)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!m_job)
+ if (!m_client)
return;
- m_job->m_mimeType = mimeType;
- m_job->m_device = device;
- if (m_job->m_device && !m_job->m_device->isReadable())
- m_job->m_device->open(QIODevice::ReadOnly);
-
- qint64 size = m_job->m_device ? m_job->m_device->size() : -1;
- if (size > 0)
- m_job->set_expected_content_size(size);
- if (m_job->m_device && m_job->m_device->isReadable()) {
+ DCHECK (!m_ioTaskRunner || m_ioTaskRunner->RunsTasksInCurrentSequence());
+ m_client->m_mimeType = mimeType;
+ m_client->m_device = device;
+ if (m_client->m_device && !m_client->m_device->isReadable())
+ m_client->m_device->open(QIODevice::ReadOnly);
+
+ if (m_client->m_firstBytePosition > 0)
+ m_client->m_device->seek(m_client->m_firstBytePosition);
+
+ qint64 deviceSize = m_client->m_device ? m_client->m_device->size() : -1;
+ qint64 remainingBytes = deviceSize - m_client->m_firstBytePosition;
+ if (remainingBytes > 0)
+ m_client->notifyExpectedContentSize(remainingBytes);
+
+ if (m_client->m_device && m_client->m_device->isReadable()) {
m_started = true;
- m_job->NotifyHeadersComplete();
+ m_client->notifyHeadersComplete();
} else {
- fail(ERR_INVALID_URL);
+ fail(net::ERR_INVALID_URL);
}
}
void URLRequestCustomJobProxy::redirect(GURL url)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!m_job)
+ if (!m_client)
return;
- if (m_job->m_device || m_job->m_error)
+ DCHECK (!m_ioTaskRunner || m_ioTaskRunner->RunsTasksInCurrentSequence());
+ if (m_client->m_device || m_client->m_error)
return;
- m_job->m_redirect = url;
+ m_client->m_redirect = url;
m_started = true;
- m_job->NotifyHeadersComplete();
+ m_client->notifyHeadersComplete();
}
void URLRequestCustomJobProxy::abort()
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!m_job)
+ if (!m_client)
return;
- if (m_job->m_device && m_job->m_device->isOpen())
- m_job->m_device->close();
- m_job->m_device = nullptr;
+ DCHECK (!m_ioTaskRunner || m_ioTaskRunner->RunsTasksInCurrentSequence());
+ if (m_client->m_device && m_client->m_device->isOpen())
+ m_client->m_device->close();
+ m_client->m_device = nullptr;
if (m_started)
- m_job->NotifyCanceled();
+ m_client->notifyCanceled();
else
- m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
+ m_client->notifyAborted();
}
void URLRequestCustomJobProxy::fail(int error)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!m_job)
+ if (!m_client)
return;
- m_job->m_error = error;
- if (m_job->m_device)
- m_job->m_device->close();
+ DCHECK (m_ioTaskRunner->RunsTasksInCurrentSequence());
+ m_client->m_error = error;
+ if (m_client->m_device)
+ m_client->m_device->close();
if (!m_started)
- m_job->NotifyStartError(URLRequestStatus::FromError(error));
+ m_client->notifyStartFailure(error);
// else we fail on the next read, or the read that might already be in progress
}
void URLRequestCustomJobProxy::readyRead()
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (m_job)
- m_job->notifyReadyRead();
+ DCHECK (m_ioTaskRunner->RunsTasksInCurrentSequence());
+ if (m_client)
+ m_client->notifyReadyRead();
}
void URLRequestCustomJobProxy::initialize(GURL url, std::string method,
diff --git a/src/core/net/url_request_custom_job_proxy.h b/src/core/net/url_request_custom_job_proxy.h
index d4cd7e208..db38083dd 100644
--- a/src/core/net/url_request_custom_job_proxy.h
+++ b/src/core/net/url_request_custom_job_proxy.h
@@ -42,6 +42,7 @@
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
+#include "base/task_runner.h"
#include "url/gurl.h"
#include "url/origin.h"
#include <QtCore/QPointer>
@@ -60,7 +61,24 @@ class URLRequestCustomJobProxy : public base::RefCountedThreadSafe<URLRequestCus
{
public:
- URLRequestCustomJobProxy(URLRequestCustomJob *job,
+ class Client {
+ public:
+ std::string m_mimeType;
+ std::string m_charset;
+ GURL m_redirect;
+ QIODevice *m_device;
+ int64_t m_firstBytePosition;
+ int m_error;
+ virtual void notifyExpectedContentSize(qint64 size) = 0;
+ virtual void notifyHeadersComplete() = 0;
+ virtual void notifyCanceled() = 0;
+ virtual void notifyAborted() = 0;
+ virtual void notifyStartFailure(int) = 0;
+ virtual void notifyReadyRead() = 0;
+ virtual base::TaskRunner *taskRunner() = 0;
+ };
+
+ URLRequestCustomJobProxy(Client *client,
const std::string &scheme,
QPointer<ProfileAdapter> profileAdapter);
~URLRequestCustomJobProxy();
@@ -76,13 +94,14 @@ public:
void readyRead();
// IO thread owned:
- URLRequestCustomJob *m_job;
+ Client *m_client;
bool m_started;
// UI thread owned:
std::string m_scheme;
URLRequestCustomJobDelegate *m_delegate;
QPointer<ProfileAdapter> m_profileAdapter;
+ scoped_refptr<base::TaskRunner> m_ioTaskRunner;
};
} // namespace QtWebEngineCore
diff --git a/src/core/net/url_request_notification.cpp b/src/core/net/url_request_notification.cpp
deleted file mode 100644
index fa6d61f65..000000000
--- a/src/core/net/url_request_notification.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "url_request_notification.h"
-
-#include "base/supports_user_data.h"
-#include "base/task/post_task.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/url_request/url_request.h"
-#include "web_contents_adapter_client.h"
-#include "web_contents_view_qt.h"
-#include "profile_io_data_qt.h"
-#include "qwebengineurlrequestinfo_p.h"
-#include "type_conversion.h"
-
-namespace QtWebEngineCore {
-
-// Calls cancel() when the URLRequest is destroyed.
-class UserData : public base::SupportsUserData::Data
-{
-public:
- UserData(URLRequestNotification *ptr) : m_ptr(ptr) {}
- ~UserData() { m_ptr->cancel(); }
- static const char key[];
-
-private:
- URLRequestNotification *m_ptr;
-};
-
-const char UserData::key[] = "QtWebEngineCore::URLRequestNotification";
-
-static content::ResourceType fromQt(QWebEngineUrlRequestInfo::ResourceType resourceType)
-{
- return static_cast<content::ResourceType>(resourceType);
-}
-
-URLRequestNotification::URLRequestNotification(net::URLRequest *request, bool isMainFrameRequest, GURL *newUrl,
- QWebEngineUrlRequestInfo &&requestInfo,
- content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
- net::CompletionOnceCallback callback, QPointer<ProfileAdapter> adapter)
- : m_request(request)
- , m_isMainFrameRequest(isMainFrameRequest)
- , m_newUrl(newUrl)
- , m_originalUrl(requestInfo.requestUrl())
- , m_requestInfo(std::move(requestInfo))
- , m_webContentsGetter(webContentsGetter)
- , m_callback(std::move(callback))
- , m_profileAdapter(adapter)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- m_request->SetUserData(UserData::key, std::make_unique<UserData>(this));
-
- base::PostTaskWithTraits(
- FROM_HERE,
- {content::BrowserThread::UI},
- base::BindOnce(&URLRequestNotification::notify, base::Unretained(this)));
-}
-
-
-void URLRequestNotification::notify()
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- // May run concurrently with cancel() so no peeking at m_request here.
-
- int result = net::OK;
- content::WebContents *webContents = m_webContentsGetter.Run();
-
- if (webContents) {
-
- if (m_profileAdapter && m_profileAdapter->requestInterceptor()) {
- QWebEngineUrlRequestInterceptor *interceptor = m_profileAdapter->requestInterceptor();
- if (!interceptor->property("deprecated").toBool())
- interceptor->interceptRequest(m_requestInfo);
- }
-
- WebContentsAdapterClient *client =
- WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client();
-
- if (!m_requestInfo.changed()) {
- client->interceptRequest(m_requestInfo);
- }
-
- if (m_requestInfo.changed()) {
- result = m_requestInfo.d_ptr->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
- // We handle the rest of the changes later when we are back in I/O thread
- }
-
- // Only do navigationRequested on MAIN_FRAME and SUB_FRAME resources
- if (result == net::OK && content::IsResourceTypeFrame(fromQt(m_requestInfo.resourceType()))) {
- int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
- client->navigationRequested(m_requestInfo.navigationType(),
- m_requestInfo.requestUrl(),
- navigationRequestAction,
- m_isMainFrameRequest);
- result = net::ERR_FAILED;
- switch (static_cast<WebContentsAdapterClient::NavigationRequestAction>(navigationRequestAction)) {
- case WebContentsAdapterClient::AcceptRequest:
- result = net::OK;
- break;
- case WebContentsAdapterClient::IgnoreRequest:
- result = net::ERR_ABORTED;
- break;
- }
- DCHECK(result != net::ERR_FAILED);
- }
- }
-
- // Run the callback on the IO thread.
- base::PostTaskWithTraits(
- FROM_HERE,
- {content::BrowserThread::IO},
- base::BindOnce(&URLRequestNotification::complete, base::Unretained(this), result));
-}
-
-void URLRequestNotification::cancel()
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- // May run concurrently with notify() but we only touch m_request here.
-
- m_request = nullptr;
-}
-
-void URLRequestNotification::complete(int error)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (m_request) {
- if (m_requestInfo.changed()) {
- if (m_originalUrl != m_requestInfo.d_ptr->url)
- *m_newUrl = toGurl(m_requestInfo.d_ptr->url);
-
- if (!m_requestInfo.d_ptr->extraHeaders.isEmpty()) {
- auto end = m_requestInfo.d_ptr->extraHeaders.constEnd();
- for (auto header = m_requestInfo.d_ptr->extraHeaders.constBegin(); header != end; ++header) {
- std::string h = header.key().toStdString();
- if (base::LowerCaseEqualsASCII(h, "referer")) {
- m_request->SetReferrer(header.value().toStdString());
- } else {
- m_request->SetExtraRequestHeaderByName(h, header.value().toStdString(), /* overwrite */ true);
- }
- }
- }
- }
-
- if (m_request->status().status() != net::URLRequestStatus::CANCELED)
- std::move(m_callback).Run(error);
- m_request->RemoveUserData(UserData::key);
- }
-
- delete this;
-}
-
-}