summaryrefslogtreecommitdiffstats
path: root/src/core/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/net')
-rw-r--r--src/core/net/client_cert_override.cpp176
-rw-r--r--src/core/net/client_cert_override.h75
-rw-r--r--src/core/net/client_cert_qt.cpp148
-rw-r--r--src/core/net/client_cert_qt.h37
-rw-r--r--src/core/net/client_cert_store_data.cpp63
-rw-r--r--src/core/net/client_cert_store_data.h54
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp300
-rw-r--r--src/core/net/cookie_monster_delegate_qt.h112
-rw-r--r--src/core/net/custom_protocol_handler.cpp62
-rw-r--r--src/core/net/custom_protocol_handler.h88
-rw-r--r--src/core/net/custom_url_loader_factory.cpp536
-rw-r--r--src/core/net/custom_url_loader_factory.h36
-rw-r--r--src/core/net/network_delegate_qt.cpp316
-rw-r--r--src/core/net/network_delegate_qt.h94
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp199
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.h41
-rw-r--r--src/core/net/proxy_config_monitor.cpp82
-rw-r--r--src/core/net/proxy_config_monitor.h59
-rw-r--r--src/core/net/proxy_config_service_qt.cpp82
-rw-r--r--src/core/net/proxy_config_service_qt.h60
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.cpp165
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.h86
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp603
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.h57
-rw-r--r--src/core/net/qrc_url_scheme_handler.cpp49
-rw-r--r--src/core/net/qrc_url_scheme_handler.h43
-rw-r--r--src/core/net/resource_request_body_qt.cpp181
-rw-r--r--src/core/net/resource_request_body_qt.h70
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.cpp99
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.h74
-rw-r--r--src/core/net/system_network_context_manager.cpp356
-rw-r--r--src/core/net/system_network_context_manager.h121
-rw-r--r--src/core/net/url_request_context_getter_qt.cpp69
-rw-r--r--src/core/net/url_request_context_getter_qt.h61
-rw-r--r--src/core/net/url_request_custom_job.cpp242
-rw-r--r--src/core/net/url_request_custom_job.h93
-rw-r--r--src/core/net/url_request_custom_job_delegate.cpp103
-rw-r--r--src/core/net/url_request_custom_job_delegate.h64
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp173
-rw-r--r--src/core/net/url_request_custom_job_proxy.h86
-rw-r--r--src/core/net/url_request_notification.cpp194
-rw-r--r--src/core/net/url_request_notification.h85
-rw-r--r--src/core/net/version_ui_qt.cpp56
-rw-r--r--src/core/net/version_ui_qt.h32
-rw-r--r--src/core/net/webui_controller_factory_qt.cpp122
-rw-r--r--src/core/net/webui_controller_factory_qt.h63
46 files changed, 3376 insertions, 2591 deletions
diff --git a/src/core/net/client_cert_override.cpp b/src/core/net/client_cert_override.cpp
deleted file mode 100644
index afb7ab5af..000000000
--- a/src/core/net/client_cert_override.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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 "client_cert_override.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/task/post_task.h"
-#include "base/callback_forward.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "net/ssl/client_cert_store.h"
-#include "net/ssl/ssl_cert_request_info.h"
-#include "net/ssl/ssl_private_key.h"
-#include "net/cert/x509_certificate.h"
-#include "third_party/boringssl/src/include/openssl/pem.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-#include "client_cert_store_data.h"
-#include "profile_io_data_qt.h"
-
-#include <QtNetwork/qtnetworkglobal.h>
-
-#if defined(USE_NSS_CERTS)
-#include "net/ssl/client_cert_store_nss.h"
-#endif
-
-#if defined(OS_WIN)
-#include "net/ssl/client_cert_store_win.h"
-#endif
-
-#if defined(OS_MACOSX)
-#include "net/ssl/client_cert_store_mac.h"
-#endif
-
-namespace {
-
-class ClientCertIdentityOverride : public net::ClientCertIdentity
-{
-public:
- ClientCertIdentityOverride(scoped_refptr<net::X509Certificate> cert, scoped_refptr<net::SSLPrivateKey> key)
- : net::ClientCertIdentity(std::move(cert)), m_key(std::move(key)) {}
- ~ClientCertIdentityOverride() override = default;
-
- void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)> private_key_callback) override
- {
- std::move(private_key_callback).Run(m_key);
- }
-
-#if defined(OS_MACOSX)
- SecIdentityRef sec_identity_ref() const override
- {
- return nullptr;
- }
-#endif
-
-private:
- scoped_refptr<net::SSLPrivateKey> m_key;
-};
-
-} // namespace
-
-namespace QtWebEngineCore {
-
-ClientCertOverrideStore::ClientCertOverrideStore(ClientCertificateStoreData *storeData)
- : ClientCertStore()
- , m_storeData(storeData)
- , m_nativeStore(createNativeStore())
-{
-}
-
-ClientCertOverrideStore::~ClientCertOverrideStore() = default;
-
-#if QT_CONFIG(ssl)
-net::ClientCertIdentityList ClientCertOverrideStore::GetClientCertsOnUIThread(const net::SSLCertRequestInfo &cert_request_info)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- const auto &clientCertOverrideData = m_storeData->extraCerts;
- // Look for certificates in memory store
- for (int i = 0; i < clientCertOverrideData.length(); i++) {
- scoped_refptr<net::X509Certificate> cert = clientCertOverrideData[i]->certPtr;
- if (cert != NULL && cert->IsIssuedByEncoded(cert_request_info.cert_authorities)) {
- net::ClientCertIdentityList selected_identities;
- selected_identities.push_back(std::make_unique<ClientCertIdentityOverride>(cert, clientCertOverrideData[i]->keyPtr));
- return selected_identities;
- }
- }
- return net::ClientCertIdentityList();
-}
-
-void ClientCertOverrideStore::GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
- ClientCertListCallback callback,
- net::ClientCertIdentityList &&result)
-{
- // Continue with native cert store if matching certificatse were not found in memory
- if (result.empty() && m_nativeStore)
- m_nativeStore->GetClientCerts(cert_request_info, std::move(callback));
- else
- std::move(callback).Run(std::move(result));
-}
-
-#endif // QT_CONFIG(ssl)
-
-void ClientCertOverrideStore::GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
- ClientCertListCallback callback)
-{
-#if QT_CONFIG(ssl)
- // Access the user-provided data from the UI thread, but return on whatever thread this is.
- if (base::PostTaskWithTraitsAndReplyWithResult(
- FROM_HERE, { content::BrowserThread::UI },
- base::BindOnce(&ClientCertOverrideStore::GetClientCertsOnUIThread,
- base::Unretained(this), std::cref(cert_request_info)),
- base::BindOnce(&ClientCertOverrideStore::GetClientCertsReturn,
- base::Unretained(this), std::cref(cert_request_info), std::move(callback)))
- ) {
- return;
- }
-#endif // QT_CONFIG(ssl)
-
- // Continue with native cert store if we failed to post task
- if (m_nativeStore)
- m_nativeStore->GetClientCerts(cert_request_info, std::move(callback));
- else
- std::move(callback).Run(net::ClientCertIdentityList());
-}
-
-// static
-std::unique_ptr<net::ClientCertStore> ClientCertOverrideStore::createNativeStore()
-{
-#if defined(USE_NSS_CERTS)
- return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory()));
-#elif defined(OS_WIN)
- return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
-#elif defined(OS_MACOSX)
- return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
-#else
- return nullptr;
-#endif
-}
-} // namespace QtWebEngineCore
diff --git a/src/core/net/client_cert_override.h b/src/core/net/client_cert_override.h
deleted file mode 100644
index 4f2734485..000000000
--- a/src/core/net/client_cert_override.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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 CLIENT_CERT_OVERRIDE_P_H
-#define CLIENT_CERT_OVERRIDE_P_H
-
-#include "net/ssl/client_cert_store.h"
-#include "base/callback_forward.h"
-#include "net/cert/x509_certificate.h"
-
-namespace net {
-class SSLCertRequestInfo;
-} // namespace net
-
-namespace QtWebEngineCore {
-struct ClientCertificateStoreData;
-
-class ClientCertOverrideStore : public net::ClientCertStore
-{
-public:
- ClientCertOverrideStore(ClientCertificateStoreData *storeData);
- virtual ~ClientCertOverrideStore() override;
- void GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
- ClientCertListCallback callback) override;
-private:
- static std::unique_ptr<net::ClientCertStore> createNativeStore();
- net::ClientCertIdentityList GetClientCertsOnUIThread(const net::SSLCertRequestInfo &request);
- void GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
- ClientCertListCallback callback,
- net::ClientCertIdentityList &&result);
- ClientCertificateStoreData *m_storeData;
- std::unique_ptr<net::ClientCertStore> m_nativeStore;
-};
-
-} // QtWebEngineCore
-
-#endif
-
-
diff --git a/src/core/net/client_cert_qt.cpp b/src/core/net/client_cert_qt.cpp
new file mode 100644
index 000000000..044e5618e
--- /dev/null
+++ b/src/core/net/client_cert_qt.cpp
@@ -0,0 +1,148 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "client_cert_qt.h"
+
+#include "base/functional/bind.h"
+#include "base/functional/callback_forward.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "crypto/crypto_buildflags.h"
+#include "net/ssl/client_cert_store.h"
+#include "net/ssl/ssl_cert_request_info.h"
+#include "net/ssl/ssl_private_key.h"
+#include "net/cert/x509_certificate.h"
+#include "third_party/boringssl/src/include/openssl/pem.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+#include "client_cert_store_data.h"
+
+#include <QtNetwork/qtnetworkglobal.h>
+
+#if BUILDFLAG(USE_NSS_CERTS)
+#include "net/ssl/client_cert_store_nss.h"
+#endif
+
+#if defined(Q_OS_WIN)
+#include "net/ssl/client_cert_store_win.h"
+#endif
+
+#if BUILDFLAG(IS_MAC)
+#include "net/ssl/client_cert_store_mac.h"
+#endif
+
+namespace {
+
+class ClientCertIdentityQt : public net::ClientCertIdentity
+{
+public:
+ ClientCertIdentityQt(scoped_refptr<net::X509Certificate> cert, scoped_refptr<net::SSLPrivateKey> key)
+ : net::ClientCertIdentity(std::move(cert)), m_key(std::move(key)) {}
+ ~ClientCertIdentityQt() override = default;
+
+ void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)> private_key_callback) override
+ {
+ std::move(private_key_callback).Run(m_key);
+ }
+
+private:
+ scoped_refptr<net::SSLPrivateKey> m_key;
+};
+
+} // namespace
+
+namespace QtWebEngineCore {
+
+ClientCertStoreQt::ClientCertStoreQt(ClientCertificateStoreData *storeData)
+ : ClientCertStore()
+ , m_storeData(storeData)
+ , m_nativeStore(createNativeStore())
+{
+}
+
+ClientCertStoreQt::~ClientCertStoreQt() = default;
+
+#if QT_CONFIG(ssl)
+net::ClientCertIdentityList ClientCertStoreQt::GetClientCertsOnUIThread(const net::SSLCertRequestInfo &cert_request_info)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ const auto &clientCertOverrideData = m_storeData->extraCerts;
+
+ // Look for certificates in memory store
+ net::ClientCertIdentityList selected_identities;
+ for (int i = 0; i < clientCertOverrideData.length(); i++) {
+ scoped_refptr<net::X509Certificate> cert = clientCertOverrideData[i]->certPtr;
+ if (cert) {
+ if (cert->HasExpired()) {
+ qWarning() << "Expired certificate" << clientCertOverrideData[i];
+ continue;
+ }
+ if (cert_request_info.cert_authorities.empty()
+ || cert->IsIssuedByEncoded(cert_request_info.cert_authorities)) {
+ selected_identities.push_back(std::make_unique<ClientCertIdentityQt>(
+ cert, clientCertOverrideData[i]->keyPtr));
+ }
+ }
+ }
+ return selected_identities;
+}
+
+void ClientCertStoreQt::GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
+ ClientCertListCallback callback,
+ net::ClientCertIdentityList &&result)
+{
+ // Continue with native cert store and append them after memory certificates
+ if (m_nativeStore) {
+ ClientCertListCallback callback2 = base::BindOnce(
+ [](ClientCertStoreQt::ClientCertListCallback callback,
+ net::ClientCertIdentityList result1, net::ClientCertIdentityList result2) {
+ while (!result2.empty()) {
+ result1.push_back(std::move(result2.back()));
+ result2.pop_back();
+ }
+ std::move(callback).Run(std::move(result1));
+ },
+ std::move(callback), std::move(result));
+ m_nativeStore->GetClientCerts(cert_request_info, std::move(callback2));
+ } else {
+ std::move(callback).Run(std::move(result));
+ }
+}
+
+#endif // QT_CONFIG(ssl)
+
+void ClientCertStoreQt::GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
+ ClientCertListCallback callback)
+{
+#if QT_CONFIG(ssl)
+ // Access the user-provided data from the UI thread, but return on whatever thread this is.
+ bool ok = content::GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
+ base::BindOnce(&ClientCertStoreQt::GetClientCertsOnUIThread,
+ base::Unretained(this), std::cref(cert_request_info)),
+ base::BindOnce(&ClientCertStoreQt::GetClientCertsReturn,
+ base::Unretained(this), std::cref(cert_request_info), std::move(callback)));
+ DCHECK(ok); // callback is already moved and we can't really recover here.
+#else
+ if (m_nativeStore)
+ m_nativeStore->GetClientCerts(cert_request_info, std::move(callback));
+ else
+ std::move(callback).Run(net::ClientCertIdentityList());
+#endif // QT_CONFIG(ssl)
+}
+
+// static
+std::unique_ptr<net::ClientCertStore> ClientCertStoreQt::createNativeStore()
+{
+#if BUILDFLAG(USE_NSS_CERTS)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory()));
+#elif defined(Q_OS_WIN)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
+#elif BUILDFLAG(IS_MAC)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
+#else
+ return nullptr;
+#endif
+}
+} // namespace QtWebEngineCore
diff --git a/src/core/net/client_cert_qt.h b/src/core/net/client_cert_qt.h
new file mode 100644
index 000000000..96579fae6
--- /dev/null
+++ b/src/core/net/client_cert_qt.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef CLIENT_CERT_QT_P_H
+#define CLIENT_CERT_QT_P_H
+
+#include "base/functional/callback_forward.h"
+#include "net/cert/x509_certificate.h"
+#include "net/ssl/client_cert_store.h"
+
+namespace net {
+class SSLCertRequestInfo;
+} // namespace net
+
+namespace QtWebEngineCore {
+struct ClientCertificateStoreData;
+
+class ClientCertStoreQt : public net::ClientCertStore
+{
+public:
+ ClientCertStoreQt(ClientCertificateStoreData *storeData);
+ virtual ~ClientCertStoreQt() override;
+ void GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
+ ClientCertListCallback callback) override;
+private:
+ static std::unique_ptr<net::ClientCertStore> createNativeStore();
+ net::ClientCertIdentityList GetClientCertsOnUIThread(const net::SSLCertRequestInfo &request);
+ void GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
+ ClientCertListCallback callback,
+ net::ClientCertIdentityList &&result);
+ ClientCertificateStoreData *m_storeData;
+ std::unique_ptr<net::ClientCertStore> m_nativeStore;
+};
+
+} // QtWebEngineCore
+
+#endif
diff --git a/src/core/net/client_cert_store_data.cpp b/src/core/net/client_cert_store_data.cpp
index 5a62cb6fe..0de6885df 100644
--- a/src/core/net/client_cert_store_data.cpp
+++ b/src/core/net/client_cert_store_data.cpp
@@ -1,48 +1,9 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "net/client_cert_store_data.h"
#if QT_CONFIG(ssl)
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_platform_key_util.h"
@@ -59,15 +20,16 @@
namespace {
-class SSLPlatformKeyOverride : public net::ThreadedSSLPrivateKey::Delegate {
+class SSLPlatformKeyQt : public net::ThreadedSSLPrivateKey::Delegate
+{
public:
- SSLPlatformKeyOverride(const QByteArray &sslKeyInBytes)
+ SSLPlatformKeyQt(const QByteArray &sslKeyInBytes)
{
m_mem = BIO_new_mem_buf(sslKeyInBytes, -1);
m_key = PEM_read_bio_PrivateKey(m_mem, nullptr, nullptr, nullptr);
}
- ~SSLPlatformKeyOverride() override
+ ~SSLPlatformKeyQt() override
{
if (m_key)
EVP_PKEY_free(m_key);
@@ -103,8 +65,8 @@ public:
std::vector<uint16_t> GetAlgorithmPreferences() override
{
- return { SSL_SIGN_RSA_PKCS1_SHA1, SSL_SIGN_RSA_PKCS1_SHA512
- , SSL_SIGN_RSA_PKCS1_SHA384, SSL_SIGN_RSA_PKCS1_SHA256 };
+ return net::SSLPrivateKey::DefaultAlgorithmPreferences(EVP_PKEY_id(m_key),
+ /* supports pss */ true);
}
std::string GetProviderName() override {
return "qtwebengine";
@@ -112,8 +74,6 @@ public:
private:
EVP_PKEY *m_key;
BIO *m_mem;
-
- DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyOverride);
};
scoped_refptr<net::SSLPrivateKey> wrapOpenSSLPrivateKey(const QByteArray &sslKeyInBytes)
@@ -122,11 +82,11 @@ scoped_refptr<net::SSLPrivateKey> wrapOpenSSLPrivateKey(const QByteArray &sslKey
return nullptr;
return base::MakeRefCounted<net::ThreadedSSLPrivateKey>(
- std::make_unique<SSLPlatformKeyOverride>(sslKeyInBytes),
+ std::make_unique<SSLPlatformKeyQt>(sslKeyInBytes),
net::GetSSLPlatformKeyTaskRunner());
}
-} // namespace
+} // namespace
namespace QtWebEngineCore {
@@ -137,7 +97,8 @@ void ClientCertificateStoreData::add(const QSslCertificate &certificate, const Q
Entry *data = new Entry;
data->keyPtr = wrapOpenSSLPrivateKey(sslKeyInBytes);
- data->certPtr = net::X509Certificate::CreateFromBytes(certInBytes.data(), certInBytes.length());
+ data->certPtr = net::X509Certificate::CreateFromBytes(base::make_span((const unsigned char *)certInBytes.data(),
+ (unsigned long)certInBytes.length()));
data->key = privateKey;
data->certificate = certificate;
extraCerts.append(data);
diff --git a/src/core/net/client_cert_store_data.h b/src/core/net/client_cert_store_data.h
index 7f83f4b60..c2e28ac18 100644
--- a/src/core/net/client_cert_store_data.h
+++ b/src/core/net/client_cert_store_data.h
@@ -1,52 +1,16 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CLIENT_CERT_STORE_DATA_H
#define CLIENT_CERT_STORE_DATA_H
-#include "qtwebenginecoreglobal.h"
-#include "qtnetworkglobal.h"
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtNetwork/qtnetworkglobal.h>
#if QT_CONFIG(ssl)
#include "base/memory/ref_counted.h"
-#include <QtCore/qvector.h>
+#include <QtCore/qlist.h>
#include <QtNetwork/qsslcertificate.h>
#include <QtNetwork/qsslkey.h>
@@ -57,8 +21,10 @@ class X509Certificate;
namespace QtWebEngineCore {
-struct ClientCertificateStoreData {
- struct Entry {
+struct ClientCertificateStoreData
+{
+ struct Entry
+ {
QSslKey key;
QSslCertificate certificate;
scoped_refptr<net::X509Certificate> certPtr;
@@ -69,7 +35,7 @@ struct ClientCertificateStoreData {
void remove(const QSslCertificate &certificate);
void clear();
- QVector<Entry*> extraCerts;
+ QList<Entry *> extraCerts;
};
} // namespace QtWebEngineCore
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index 5f7b75f57..d107c520c 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -1,129 +1,112 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "cookie_monster_delegate_qt.h"
-#include "base/bind.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 "base/functional/bind.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"
#include "type_conversion.h"
+#include <QNetworkCookie>
+
namespace QtWebEngineCore {
-static GURL sourceUrlForCookie(const QNetworkCookie &cookie) {
+class CookieChangeListener : public network::mojom::CookieChangeListener
+{
+public:
+ CookieChangeListener(CookieMonsterDelegateQt *delegate) : m_delegate(delegate) { }
+ ~CookieChangeListener() override = default;
+
+ // network::mojom::CookieChangeListener:
+ void OnCookieChange(const net::CookieChangeInfo &change) override
+ {
+ m_delegate->OnCookieChanged(change);
+ }
+
+private:
+ CookieMonsterDelegateQt *m_delegate;
+};
+
+class CookieAccessFilter : public network::mojom::CookieRemoteAccessFilter
+{
+public:
+ CookieAccessFilter(CookieMonsterDelegateQt *delegate) : m_delegate(delegate) { }
+ ~CookieAccessFilter() override = default;
+
+ void AllowedAccess(const GURL &url, const net::SiteForCookies &site_for_cookies, AllowedAccessCallback callback) override
+ {
+ bool allow = m_delegate->canGetCookies(toQt(site_for_cookies.first_party_url()), toQt(url));
+ std::move(callback).Run(allow);
+ }
+
+private:
+ CookieMonsterDelegateQt *m_delegate;
+};
+
+
+static GURL sourceUrlForCookie(const QNetworkCookie &cookie)
+{
QString urlFragment = QStringLiteral("%1%2").arg(cookie.domain()).arg(cookie.path());
return net::cookie_util::CookieOriginToURL(urlFragment.toStdString(), /* is_https */ cookie.isSecure());
}
CookieMonsterDelegateQt::CookieMonsterDelegateQt()
- : m_client(0)
- , m_cookieMonster(nullptr)
+ : m_client(nullptr)
+ , m_listener(new CookieChangeListener(this))
+ , m_filter(new CookieAccessFilter(this))
+ , m_receiver(m_listener.get())
+ , m_filterReceiver(m_filter.get())
+ , m_hasFilter(false)
{
}
CookieMonsterDelegateQt::~CookieMonsterDelegateQt()
{
-
}
void CookieMonsterDelegateQt::AddStore(net::CookieStore *store)
{
- std::unique_ptr<net::CookieChangeSubscription> sub =
- store->GetChangeDispatcher().AddCallbackForAllChanges(
- base::Bind(&CookieMonsterDelegateQt::OnCookieChanged,
- // this object's destruction will deregister the subscription.
- base::Unretained(this)));
+ std::unique_ptr<net::CookieChangeSubscription> sub = store->GetChangeDispatcher().AddCallbackForAllChanges(
+ base::BindRepeating(&CookieMonsterDelegateQt::OnCookieChanged,
+ // this object's destruction will deregister the subscription.
+ base::Unretained(this)));
m_subscriptions.push_back(std::move(sub));
}
bool CookieMonsterDelegateQt::hasCookieMonster()
{
- return m_cookieMonster;
+ return m_mojoCookieManager.is_bound();
}
-void CookieMonsterDelegateQt::getAllCookies(quint64 callbackId)
+void CookieMonsterDelegateQt::getAllCookies()
{
- 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)));
+ m_mojoCookieManager->GetAllCookies(net::CookieStore::GetAllCookiesCallback());
}
-void CookieMonsterDelegateQt::GetAllCookiesOnIOThread(net::CookieMonster::GetCookieListCallback callback)
-{
- if (m_cookieMonster)
- m_cookieMonster->GetAllCookiesAsync(std::move(callback));
-}
-
-void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie &cookie, const QUrl &origin)
+void CookieMonsterDelegateQt::setCookie(const QNetworkCookie &cookie, const QUrl &origin)
{
Q_ASSERT(hasCookieMonster());
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)
-{
+ net::CookieInclusionStatus inclusion;
+ auto canonCookie = net::CanonicalCookie::Create(gurl, cookie_line, base::Time::Now(),
+ absl::nullopt, absl::nullopt, true, &inclusion);
+ if (!canonCookie || !inclusion.IsInclude()) {
+ LOG(WARNING) << "QWebEngineCookieStore::setCookie() - Tried to set invalid cookie";
+ return;
+ }
net::CookieOptions options;
options.set_include_httponly();
-
- if (m_cookieMonster)
- m_cookieMonster->SetCookieWithOptionsAsync(url, cookie_line, options, std::move(callback));
+ options.set_same_site_cookie_context(net::CookieOptions::SameSiteCookieContext::MakeInclusiveForSet());
+ m_mojoCookieManager->SetCanonicalCookie(*canonCookie.get(), gurl, options, net::CookieStore::SetCookiesCallback());
}
void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin)
@@ -132,89 +115,69 @@ 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()));
+ 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::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());
-}
-
-
-void CookieMonsterDelegateQt::deleteSessionCookies(quint64 callbackId)
+void CookieMonsterDelegateQt::deleteSessionCookies()
{
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)));
+ auto filter = network::mojom::CookieDeletionFilter::New();
+ filter->session_control = network::mojom::CookieDeletionSessionControl::SESSION_COOKIES;
+ m_mojoCookieManager->DeleteCookies(std::move(filter), network::mojom::CookieManager::DeleteCookiesCallback());
}
-void CookieMonsterDelegateQt::DeleteSessionCookiesOnIOThread(net::CookieMonster::DeleteCallback callback)
-{
- if (m_cookieMonster)
- m_cookieMonster->DeleteSessionCookiesAsync(std::move(callback));
-}
-
-void CookieMonsterDelegateQt::deleteAllCookies(quint64 callbackId)
+void CookieMonsterDelegateQt::deleteAllCookies()
{
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)));
+ auto filter = network::mojom::CookieDeletionFilter::New();
+ m_mojoCookieManager->DeleteCookies(std::move(filter), network::mojom::CookieManager::DeleteCookiesCallback());
}
-void CookieMonsterDelegateQt::DeleteAllOnIOThread(net::CookieMonster::DeleteCallback callback)
+void CookieMonsterDelegateQt::setMojoCookieManager(mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_info)
{
- if (m_cookieMonster)
- m_cookieMonster->DeleteAllAsync(std::move(callback));
-}
+ if (m_mojoCookieManager.is_bound())
+ unsetMojoCookieManager();
-void CookieMonsterDelegateQt::setCookieMonster(net::CookieMonster* monster)
-{
- if (monster == m_cookieMonster)
- return;
+ Q_ASSERT(!m_mojoCookieManager.is_bound());
+ Q_ASSERT(!m_receiver.is_bound());
- m_subscriptions.clear();
- if (monster)
- AddStore(monster);
+ m_mojoCookieManager.Bind(std::move(cookie_manager_info));
- m_cookieMonster = monster;
+ m_mojoCookieManager->AddGlobalChangeListener(m_receiver.BindNewPipeAndPassRemote());
+ if (m_hasFilter)
+ m_mojoCookieManager->SetRemoteFilter(m_filterReceiver.BindNewPipeAndPassRemote());
- if (!m_client)
+ if (m_client)
+ m_client->d_func()->processPendingUserCookies();
+}
+
+void CookieMonsterDelegateQt::setHasFilter(bool hasFilter)
+{
+ m_hasFilter = hasFilter;
+ if (!m_mojoCookieManager.is_bound())
return;
+ if (m_hasFilter) {
+ if (!m_filterReceiver.is_bound())
+ m_mojoCookieManager->SetRemoteFilter(m_filterReceiver.BindNewPipeAndPassRemote());
+ } else {
+ if (m_filterReceiver.is_bound())
+ m_filterReceiver.reset();
+ }
+}
- if (monster)
- m_client->d_func()->processPendingUserCookies();
- else
- m_client->d_func()->rejectPendingUserCookies();
+void CookieMonsterDelegateQt::unsetMojoCookieManager()
+{
+ m_receiver.reset();
+ m_filterReceiver.reset();
+ m_mojoCookieManager.reset();
}
void CookieMonsterDelegateQt::setClient(QWebEngineCookieStore *client)
@@ -246,54 +209,11 @@ bool CookieMonsterDelegateQt::canGetCookies(const QUrl &firstPartyUrl, const QUr
return m_client->d_func()->canAccessCookies(firstPartyUrl, url);
}
-void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie, net::CookieChangeCause cause)
+void CookieMonsterDelegateQt::OnCookieChanged(const net::CookieChangeInfo &change)
{
if (!m_client)
return;
- m_client->d_func()->onCookieChanged(toQt(cookie), cause != net::CookieChangeCause::INSERTED);
-}
-
-void CookieMonsterDelegateQt::GetAllCookiesCallbackOnIOThread(qint64 callbackId, const net::CookieList &cookies, const net::CookieStatusList &statusList)
-{
- 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));
+ m_client->d_func()->onCookieChanged(toQt(change.cookie), change.cause != net::CookieChangeCause::INSERTED);
}
-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));
-}
-
-void CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread(qint64 callbackId, const QByteArray &cookies)
-{
- if (m_client)
- m_client->d_func()->onGetAllCallbackResult(callbackId, cookies);
-}
-
-void CookieMonsterDelegateQt::SetCookieCallbackOnUIThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status)
-{
- if (m_client)
- m_client->d_func()->onSetCallbackResult(callbackId,
- status == net::CanonicalCookie::CookieInclusionStatus::INCLUDE);
-}
-
-void CookieMonsterDelegateQt::DeleteCookiesCallbackOnUIThread(qint64 callbackId, uint numCookies)
-{
- if (m_client)
- m_client->d_func()->onDeleteCallbackResult(callbackId, numCookies);
-}
-}
+} // namespace QtWebEngineCore
diff --git a/src/core/net/cookie_monster_delegate_qt.h b/src/core/net/cookie_monster_delegate_qt.h
index 2ac04acb4..f6872323d 100644
--- a/src/core/net/cookie_monster_delegate_qt.h
+++ b/src/core/net/cookie_monster_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -53,70 +17,66 @@
#include "qtwebenginecoreglobal_p.h"
-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"
-QT_WARNING_POP
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.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
-#include <QNetworkCookie>
#include <QPointer>
+QT_FORWARD_DECLARE_CLASS(QNetworkCookie)
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> {
+class Q_WEBENGINECORE_EXPORT CookieMonsterDelegateQt : public base::RefCountedThreadSafe<CookieMonsterDelegateQt>
+{
QPointer<QWebEngineCookieStore> m_client;
- net::CookieMonster *m_cookieMonster;
std::vector<std::unique_ptr<net::CookieChangeSubscription>> m_subscriptions;
+
+ mojo::Remote<network::mojom::CookieManager> m_mojoCookieManager;
+ std::unique_ptr<network::mojom::CookieChangeListener> m_listener;
+ std::unique_ptr<network::mojom::CookieRemoteAccessFilter> m_filter;
+ mojo::Receiver<network::mojom::CookieChangeListener> m_receiver;
+ mojo::Receiver<network::mojom::CookieRemoteAccessFilter> m_filterReceiver;
+ bool m_hasFilter;
public:
CookieMonsterDelegateQt();
~CookieMonsterDelegateQt();
bool hasCookieMonster();
- void setCookie(quint64 callbackId, const QNetworkCookie &cookie, const QUrl &origin);
+ void setCookie(const QNetworkCookie &cookie, const QUrl &origin);
void deleteCookie(const QNetworkCookie &cookie, const QUrl &origin);
- void getAllCookies(quint64 callbackId);
- void deleteSessionCookies(quint64 callbackId);
- void deleteAllCookies(quint64 callbackId);
+ void getAllCookies();
+ void deleteSessionCookies();
+ void deleteAllCookies();
- void setCookieMonster(net::CookieMonster* monster);
void setClient(QWebEngineCookieStore *client);
+ void setMojoCookieManager(mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_info);
+ void unsetMojoCookieManager();
+ void setHasFilter(bool b);
bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url) const;
bool canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) const;
void AddStore(net::CookieStore *store);
- 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 SetCookieCallbackOnUIThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status);
- void DeleteCookiesCallbackOnUIThread(qint64 callbackId, uint numCookies);
+ void OnCookieChanged(const net::CookieChangeInfo &change);
};
-}
+} // namespace QtWebEngineCore
#endif // COOKIE_MONSTER_DELEGATE_QT_H
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 7b189763c..000000000
--- a/src/core/net/custom_protocol_handler.h
+++ /dev/null
@@ -1,88 +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..b91a1289b
--- /dev/null
+++ b/src/core/net/custom_url_loader_factory.cpp
@@ -0,0 +1,536 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "custom_url_loader_factory.h"
+
+#include "base/strings/stringprintf.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 "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_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/cpp/cors/cors.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
+#include "url/url_util.h"
+#include "url/url_util_qt.h"
+
+#include "api/qwebengineurlscheme.h"
+#include "net/url_request_custom_job_proxy.h"
+#include "profile_adapter.h"
+#include "qwebengineloadinginfo.h"
+#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_delegate_qt.h"
+#include "web_contents_view_qt.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/qpointer.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,
+ mojo::PendingReceiver<network::mojom::URLLoader> loader,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote,
+ QPointer<ProfileAdapter> profileAdapter,
+ content::WebContents *webContents)
+ {
+ // 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_remote), profileAdapter, webContents);
+ customUrlLoader->Start();
+ }
+
+ // network::mojom::URLLoader:
+ void FollowRedirect(const std::vector<std::string> &removed_headers,
+ const net::HttpRequestHeaders &modified_headers,
+ const net::HttpRequestHeaders &modified_cors_exempt_headers, // FIXME: do something with this?
+ const absl::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));
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ 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 { }
+
+private:
+ CustomURLLoader(const network::ResourceRequest &request,
+ mojo::PendingReceiver<network::mojom::URLLoader> loader,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote,
+ QPointer<ProfileAdapter> profileAdapter,
+ content::WebContents *webContents)
+ // ### We can opt to run the url-loader on the UI thread instead
+ : m_taskRunner(content::GetIOThreadTaskRunner({}))
+ , m_proxy(new URLRequestCustomJobProxy(this, request.url.scheme(), profileAdapter))
+ , m_webContents(webContents)
+ , m_receiver(this, std::move(loader))
+ , m_client(std::move(client_remote))
+ , m_request(request)
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_receiver.set_disconnect_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);
+ m_isLocal = scheme.flags().testFlag(QWebEngineUrlScheme::LocalScheme);
+ }
+
+ ~CustomURLLoader() override = default;
+
+ void Start()
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+
+ if (network::cors::IsCorsEnabledRequestMode(m_request.mode)) {
+ // CORS mode requires a valid request_initiator.
+ if (!m_request.request_initiator)
+ return CompleteWithFailure(net::ERR_INVALID_ARGUMENT);
+
+ if (m_isLocal) {
+ std::string fromScheme = m_request.request_initiator->GetTupleOrPrecursorTupleIfOpaque().scheme();
+ const std::vector<std::string> &localSchemes = url::GetLocalSchemes();
+ bool fromLocal = base::Contains(localSchemes, fromScheme);
+ bool hasLocalAccess = fromLocal;
+ if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(fromScheme))
+ hasLocalAccess = cs->flags & (url::CustomScheme::LocalAccessAllowed | url::CustomScheme::Local);
+ if (!hasLocalAccess)
+ return CompleteWithFailure(net::ERR_ACCESS_DENIED);
+ } else if (!m_corsEnabled && !m_request.request_initiator->IsSameOriginWith(url::Origin::Create(m_request.url))) {
+ // Custom schemes are not covered by CorsURLLoader, so we need to reject CORS requests manually.
+ return CompleteWithFailure(network::CorsErrorStatus(network::mojom::CorsError::kCorsDisabledScheme));
+ }
+ }
+
+ if (mojo::CreateDataPipe(nullptr, m_pipeProducerHandle, m_pipeConsumerHandle) != MOJO_RESULT_OK)
+ return CompleteWithFailure(net::ERR_FAILED);
+
+ m_head = network::mojom::URLResponseHead::New();
+ m_head->request_start = base::TimeTicks::Now();
+
+ if (!m_pipeConsumerHandle.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 (ParseRange(m_request.headers))
+ m_firstBytePosition = m_byteRange.first_byte_position();
+
+// m_taskRunner->PostTask(FROM_HERE,
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::initialize, m_proxy, m_request.url,
+ m_request.method, m_request.request_initiator, std::move(headers),
+ m_request.request_body));
+ }
+
+ void CompleteWithFailure(network::CorsErrorStatus cors_error)
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_client->OnComplete(network::URLLoaderCompletionStatus(cors_error));
+ ClearProxyAndClient(false);
+ }
+
+ 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_receiver.reset();
+ 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_headerBytesRead;
+ 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));
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
+ if (!wait_for_loader_error || !m_receiver.is_bound())
+ delete this;
+ }
+
+ // URLRequestCustomJobProxy::Client:
+ void notifyExpectedContentSize(qint64 size) override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ m_totalSize = size;
+ if (m_byteRange.IsValid()) {
+ if (!m_byteRange.ComputeBounds(size)) {
+ CompleteWithFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE);
+ } else {
+ m_maxBytesToRead = m_byteRange.last_byte_position() - m_byteRange.first_byte_position() + 1;
+ m_head->content_length = m_maxBytesToRead;
+ }
+ } else {
+ 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 {
+ if (m_byteRange.IsValid() && m_totalSize > 0) {
+ headers += "HTTP/1.1 206 Partial Content\n";
+ headers += net::HttpResponseHeaders::kContentRange;
+ headers += base::StringPrintf(": bytes %lld-%lld/%lld",
+ qlonglong{m_byteRange.first_byte_position()},
+ qlonglong{m_byteRange.last_byte_position()},
+ qlonglong{m_totalSize});
+ headers += "\n";
+ } else {
+ headers += "HTTP/1.1 200 OK\n";
+ }
+ if (m_mimeType.size() > 0) {
+ headers += net::HttpRequestHeaders::kContentType;
+ headers += base::StringPrintf(": %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";
+ }
+ }
+ for (auto it = m_additionalResponseHeaders.cbegin();
+ it != m_additionalResponseHeaders.cend(); ++it) {
+ headers += it.key().toLower().toStdString() + ": " + it.value().toLower().toStdString()
+ + "\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 = {};
+ net::RedirectInfo::FirstPartyURLPolicy first_party_url_policy =
+ m_request.update_first_party_url_on_redirect ? net::RedirectInfo::FirstPartyURLPolicy::UPDATE_URL_ON_REDIRECT
+ : net::RedirectInfo::FirstPartyURLPolicy::NEVER_CHANGE_URL;
+ net::RedirectInfo redirectInfo = net::RedirectInfo::ComputeRedirectInfo(
+ m_request.method, m_request.url,
+ m_request.site_for_cookies,
+ first_party_url_policy, m_request.referrer_policy,
+ m_request.referrer.spec(), net::HTTP_SEE_OTHER,
+ m_redirect, absl::nullopt, false /*insecure_scheme_was_upgraded*/);
+ m_client->OnReceiveRedirect(redirectInfo, std::move(m_head));
+ m_head = nullptr;
+ // ### 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_headerBytesRead = m_head->headers->raw_headers().length();
+ m_client->OnReceiveResponse(std::move(m_head), std::move(m_pipeConsumerHandle), absl::nullopt);
+ m_head = nullptr;
+
+ m_watcher = std::make_unique<mojo::SimpleWatcher>(
+ FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, m_taskRunner);
+ m_watcher->Watch(m_pipeProducerHandle.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ MOJO_WATCH_CONDITION_SATISFIED,
+ base::BindRepeating(&CustomURLLoader::notifyReadyWrite,
+ m_weakPtrFactory.GetWeakPtr()));
+
+ readAvailableData(); // May delete this
+ }
+ 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 = {};
+ m_client->OnReceiveResponse(std::move(m_head), mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
+ CompleteWithFailure(net::Error(error));
+ }
+ void notifySuccess() override
+ {
+ if (m_webContents) {
+ WebContentsDelegateQt *delegate =
+ static_cast<WebContentsDelegateQt *>(m_webContents->GetDelegate());
+ delegate->emitLoadSucceeded(toQt(m_request.url));
+ }
+ }
+ 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();
+ }
+ bool readAvailableData()
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ for (;;) {
+ if (m_error || !m_device)
+ break;
+
+ void *buffer = nullptr;
+ uint32_t bufferSize = 0;
+ MojoResult beginResult = m_pipeProducerHandle->BeginWriteData(
+ &buffer, &bufferSize, MOJO_BEGIN_WRITE_DATA_FLAG_NONE);
+ if (beginResult == MOJO_RESULT_SHOULD_WAIT) {
+ m_watcher->ArmOrNotify();
+ return false; // Wait for pipe watcher
+ }
+ if (beginResult != MOJO_RESULT_OK)
+ break;
+ if (m_maxBytesToRead > 0 && m_maxBytesToRead <= int64_t{std::numeric_limits<uint32_t>::max()})
+ bufferSize = std::min(bufferSize, uint32_t(m_maxBytesToRead));
+
+ int readResult = m_device->read(static_cast<char *>(buffer), bufferSize);
+ uint32_t bytesRead = std::max(readResult, 0);
+ m_pipeProducerHandle->EndWriteData(bytesRead);
+ m_totalBytesRead += bytesRead;
+ m_client->OnTransferSizeUpdated(m_totalBytesRead);
+
+ const bool deviceAtEnd = m_device->atEnd();
+ if ((deviceAtEnd && !m_device->isSequential())
+ || (m_maxBytesToRead > 0 && m_totalBytesRead >= m_maxBytesToRead)) {
+ OnTransferComplete(MOJO_RESULT_OK);
+ return true; // Done with reading
+ }
+
+ if (readResult == 0)
+ return false; // Wait for readyRead
+ if (readResult < 0 && deviceAtEnd && m_device->isSequential()) {
+ // Failure on read, and sequential device claiming to be at end, so treat it as a successful end-of-data.
+ OnTransferComplete(MOJO_RESULT_OK);
+ return true; // Done with reading
+ }
+ if (readResult < 0)
+ break;
+ }
+
+ CompleteWithFailure(m_error ? net::Error(m_error) : net::ERR_FAILED);
+ return true; // Done with reading
+ }
+ bool ParseRange(const net::HttpRequestHeaders &headers)
+ {
+ std::string range_header;
+ if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) {
+ std::vector<net::HttpByteRange> ranges;
+ if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
+ // Chromium doesn't support multirange requests.
+ if (ranges.size() == 1) {
+ m_byteRange = ranges[0];
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ base::SequencedTaskRunner *taskRunner() override
+ {
+ DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
+ return m_taskRunner.get();
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> m_taskRunner;
+ scoped_refptr<URLRequestCustomJobProxy> m_proxy;
+ content::WebContents *m_webContents;
+
+ mojo::Receiver<network::mojom::URLLoader> m_receiver;
+ mojo::Remote<network::mojom::URLLoaderClient> m_client;
+ mojo::ScopedDataPipeProducerHandle m_pipeProducerHandle;
+ mojo::ScopedDataPipeConsumerHandle m_pipeConsumerHandle;
+ std::unique_ptr<mojo::SimpleWatcher> m_watcher;
+
+ net::HttpByteRange m_byteRange;
+ int64_t m_totalSize = 0;
+ int64_t m_maxBytesToRead = -1;
+ network::ResourceRequest m_request;
+ network::mojom::URLResponseHeadPtr m_head;
+ qint64 m_headerBytesRead = 0;
+ qint64 m_totalBytesRead = 0;
+ bool m_corsEnabled;
+ bool m_isLocal;
+
+ base::WeakPtrFactory<CustomURLLoader> m_weakPtrFactory{this};
+};
+
+class CustomURLLoaderFactory : public network::mojom::URLLoaderFactory {
+public:
+ CustomURLLoaderFactory(ProfileAdapter *profileAdapter, content::WebContents *webContents, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+ : m_taskRunner(content::GetIOThreadTaskRunner({}))
+ , m_profileAdapter(profileAdapter)
+ , m_webContents(webContents)
+ {
+ m_receivers.set_disconnect_handler(base::BindRepeating(
+ &CustomURLLoaderFactory::OnDisconnect, base::Unretained(this)));
+ m_receivers.Add(this, std::move(receiver));
+ }
+ ~CustomURLLoaderFactory() override = default;
+
+ // network::mojom::URLLoaderFactory:
+ void CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> loader,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest &request,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation) override
+ {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ Q_UNUSED(request_id);
+ Q_UNUSED(options);
+ Q_UNUSED(traffic_annotation);
+
+ m_taskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&CustomURLLoader::CreateAndStart, request,
+ std::move(loader), std::move(client),
+ m_profileAdapter, m_webContents));
+
+ }
+
+ void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) override
+ {
+ m_receivers.Add(this, std::move(receiver));
+ }
+
+ void OnDisconnect()
+ {
+ if (m_receivers.empty())
+ delete this;
+ }
+
+ static mojo::PendingRemote<network::mojom::URLLoaderFactory> Create(ProfileAdapter *profileAdapter, content::WebContents *webContents)
+ {
+ mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_remote;
+ new CustomURLLoaderFactory(profileAdapter, webContents, pending_remote.InitWithNewPipeAndPassReceiver());
+ return pending_remote;
+ }
+
+ const scoped_refptr<base::SequencedTaskRunner> m_taskRunner;
+ mojo::ReceiverSet<network::mojom::URLLoaderFactory> m_receivers;
+ QPointer<ProfileAdapter> m_profileAdapter;
+ content::WebContents *m_webContents;
+};
+
+} // namespace
+
+mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter, content::WebContents *webContents)
+{
+ return CustomURLLoaderFactory::Create(profileAdapter, webContents);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/custom_url_loader_factory.h b/src/core/net/custom_url_loader_factory.h
new file mode 100644
index 000000000..e4a767c85
--- /dev/null
+++ b/src/core/net/custom_url_loader_factory.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+//
+// 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_URL_LOADER_FACTORY_H_
+#define CUSTOM_URL_LOADER_FACTORY_H_
+
+#include "mojo/public/cpp/bindings/pending_remote.h"
+
+namespace content {
+class WebContents;
+}
+namespace network {
+namespace mojom {
+class URLLoaderFactory;
+} // namespace mojom
+} // namespace network
+
+namespace QtWebEngineCore {
+class ProfileAdapter;
+
+mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter, content::WebContents *webContents);
+
+} // namespace QtWebEngineCore
+
+#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 68bf34d31..000000000
--- a/src/core/net/network_delegate_qt.cpp
+++ /dev/null
@@ -1,316 +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
- QWebEngineUrlRequestInterceptor* profileInterceptor = m_profileIOData->requestInterceptor();
- if (profileInterceptor && profileInterceptor->property("deprecated").toBool()) {
- profileInterceptor = nullptr;
- if (QWebEngineUrlRequestInterceptor* interceptor = m_profileIOData->acquireInterceptor()) {
- interceptor->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;
-
- if (!m_profileIOData->hasPageInterceptors() && !profileInterceptor && !content::IsResourceTypeFrame(resourceType))
- return net::OK;
-
- auto webContentsGetter = resourceInfo->GetWebContentsGetterForRequest();
- new URLRequestNotification(
- request,
- resourceInfo->IsMainFrame(),
- newUrl,
- std::move(requestInfo),
- webContentsGetter,
- std::move(callback),
- profileInterceptor ? m_profileIOData->profileAdapter() : nullptr
- );
-
- // 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 53debadcd..000000000
--- a/src/core/net/network_delegate_qt.h
+++ /dev/null
@@ -1,94 +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..319d3a566
--- /dev/null
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -0,0 +1,199 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.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.
+
+#include "plugin_response_interceptor_url_loader_throttle.h"
+
+#include "base/functional/bind.h"
+#include "base/uuid.h"
+#include "chrome/browser/extensions/api/streams_private/streams_private_api.h"
+#include "content/public/browser/browser_context.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 "extensions/browser/guest_view/mime_handler_view/mime_handler_view_attach_helper.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/manifest_handlers/mime_types_handler.h"
+#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h"
+
+#include "extensions/extension_system_qt.h"
+#include "web_contents_delegate_qt.h"
+#include "web_engine_settings.h"
+
+#include <string>
+#include <tuple>
+
+namespace {
+
+constexpr uint32_t kFullPageMimeHandlerDataPipeSize = 512U;
+
+void ClearAllButFrameAncestors(network::mojom::URLResponseHead *response_head)
+{
+ response_head->headers->RemoveHeader("Content-Security-Policy");
+ response_head->headers->RemoveHeader("Content-Security-Policy-Report-Only");
+
+ if (!response_head->parsed_headers)
+ return;
+
+ std::vector<network::mojom::ContentSecurityPolicyPtr> &csp =
+ response_head->parsed_headers->content_security_policy;
+ std::vector<network::mojom::ContentSecurityPolicyPtr> cleared;
+
+ for (auto &policy : csp) {
+ auto frame_ancestors = policy->directives.find(network::mojom::CSPDirectiveName::FrameAncestors);
+ if (frame_ancestors == policy->directives.end())
+ continue;
+
+ auto cleared_policy = network::mojom::ContentSecurityPolicy::New();
+ cleared_policy->self_origin = std::move(policy->self_origin);
+ cleared_policy->header = std::move(policy->header);
+ cleared_policy->header->header_value = "";
+ cleared_policy->directives[network::mojom::CSPDirectiveName::FrameAncestors] = std::move(frame_ancestors->second);
+
+ auto raw_frame_ancestors = policy->raw_directives.find(network::mojom::CSPDirectiveName::FrameAncestors);
+ DCHECK(raw_frame_ancestors != policy->raw_directives.end());
+
+ cleared_policy->header->header_value = "frame-ancestors " + raw_frame_ancestors->second;
+ response_head->headers->AddHeader(
+ cleared_policy->header->type == network::mojom::ContentSecurityPolicyType::kEnforce
+ ? "Content-Security-Policy"
+ : "Content-Security-Policy-Report-Only",
+ cleared_policy->header->header_value);
+ cleared_policy->raw_directives[network::mojom::CSPDirectiveName::FrameAncestors] =
+ std::move(raw_frame_ancestors->second);
+
+ cleared.push_back(std::move(cleared_policy));
+ }
+
+ csp.swap(cleared);
+}
+} // namespace
+
+
+namespace QtWebEngineCore {
+
+PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
+ network::mojom::RequestDestination request_destination,
+ int frame_tree_node_id)
+ : m_request_destination(request_destination), m_frame_tree_node_id(frame_tree_node_id)
+{}
+
+void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL &response_url,
+ network::mojom::URLResponseHead *response_head,
+ bool *defer)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(m_frame_tree_node_id);
+ if (!web_contents)
+ return;
+
+ if (content::download_utils::MustDownload(
+ web_contents->GetBrowserContext(),
+ response_url, response_head->headers.get(), response_head->mime_type))
+ return;
+
+ std::string extension_id;
+ if (response_head->mime_type == "application/pdf")
+ extension_id = extension_misc::kPdfExtensionId;
+ if (extension_id.empty())
+ return;
+
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate());
+ if (!contentsDelegate)
+ return;
+
+ WebEngineSettings *settings = contentsDelegate->webEngineSettings();
+ if (!settings->testAttribute(QWebEngineSettings::PdfViewerEnabled)
+ || !settings->testAttribute(QWebEngineSettings::PluginsEnabled)) {
+ // PluginServiceFilterQt will inform the URLLoader about the disabled state of plugins
+ // and we can expect the download to be triggered automatically. It's unnecessary to
+ // go further and start the guest view embedding process.
+ return;
+ }
+
+ // Chrome's PDF Extension does not work properly in the face of a restrictive
+ // Content-Security-Policy, and does not currently respect the policy anyway.
+ // Ignore CSP served on a PDF response. https://crbug.com/271452
+ if (extension_id == extension_misc::kPdfExtensionId && response_head->headers)
+ ClearAllButFrameAncestors(response_head);
+
+ const std::string stream_id = base::Uuid::GenerateRandomV4().AsLowercaseString();
+
+ mojo::PendingRemote<network::mojom::URLLoader> dummy_new_loader;
+ std::ignore = dummy_new_loader.InitWithNewPipeAndPassReceiver();
+ mojo::Remote<network::mojom::URLLoaderClient> new_client;
+ mojo::PendingReceiver<network::mojom::URLLoaderClient> new_client_receiver =
+ new_client.BindNewPipeAndPassReceiver();
+
+ const std::string internal_id = base::UnguessableToken::Create().ToString();
+ // Provide the MimeHandlerView code a chance to override the payload. This is
+ // the case where the resource is handled by frame-based MimeHandlerView.
+ const std::string payload =
+ extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
+ m_frame_tree_node_id, response_url, response_head->mime_type, stream_id,
+ internal_id,
+ base::BindOnce(&PluginResponseInterceptorURLLoaderThrottle::ResumeLoad,
+ weak_factory_.GetWeakPtr()));
+ *defer = true;
+
+ mojo::ScopedDataPipeProducerHandle producer_handle;
+ mojo::ScopedDataPipeConsumerHandle consumer_handle;
+ CHECK_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(kFullPageMimeHandlerDataPipeSize, producer_handle, consumer_handle));
+
+ uint32_t len = static_cast<uint32_t>(payload.size());
+ CHECK_EQ(MOJO_RESULT_OK,
+ producer_handle->WriteData(
+ payload.c_str(), &len, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
+
+ network::URLLoaderCompletionStatus status(net::OK);
+ status.decoded_body_length = len;
+ new_client->OnComplete(status);
+
+ mojo::PendingRemote<network::mojom::URLLoader> original_loader;
+ mojo::PendingReceiver<network::mojom::URLLoaderClient> original_client;
+ mojo::ScopedDataPipeConsumerHandle body = std::move(consumer_handle);
+ delegate_->InterceptResponse(std::move(dummy_new_loader),
+ std::move(new_client_receiver),
+ &original_loader, &original_client,
+ &body);
+
+ // Make a deep copy of URLResponseHead before passing it cross-thread.
+ auto deep_copied_response = response_head->Clone();
+ if (response_head->headers) {
+ deep_copied_response->headers =
+ base::MakeRefCounted<net::HttpResponseHeaders>(
+ response_head->headers->raw_headers());
+ }
+
+ auto transferrable_loader = blink::mojom::TransferrableURLLoader::New();
+ transferrable_loader->url = GURL(
+ extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() +
+ base::Uuid::GenerateRandomV4().AsLowercaseString());
+ transferrable_loader->url_loader = std::move(original_loader);
+ transferrable_loader->url_loader_client = std::move(original_client);
+ transferrable_loader->head = std::move(deep_copied_response);
+ transferrable_loader->head->intercepted_by_plugin = true;
+ transferrable_loader->body = std::move(body);
+
+ bool embedded = m_request_destination !=
+ network::mojom::RequestDestination::kDocument;
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent,
+ extension_id, stream_id, embedded, m_frame_tree_node_id,
+ std::move(transferrable_loader), response_url, internal_id));
+}
+
+void PluginResponseInterceptorURLLoaderThrottle::ResumeLoad()
+{
+ delegate_->Resume();
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.h b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
new file mode 100644
index 000000000..fb3918c45
--- /dev/null
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
+#define PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
+
+#include "base/memory/weak_ptr.h"
+#include "services/network/public/mojom/fetch_api.mojom-shared.h"
+#include "third_party/blink/public/common/loader/url_loader_throttle.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace QtWebEngineCore {
+
+class PluginResponseInterceptorURLLoaderThrottle : public blink::URLLoaderThrottle
+{
+public:
+ PluginResponseInterceptorURLLoaderThrottle(network::mojom::RequestDestination request_destination,
+ int frame_tree_node_id);
+ ~PluginResponseInterceptorURLLoaderThrottle() override = default;
+
+private:
+ // content::URLLoaderThrottle overrides;
+ void WillProcessResponse(const GURL &response_url, network::mojom::URLResponseHead *response_head, bool *defer) override;
+
+ // Resumes loading for an intercepted response. This would give the extension
+ // layer chance to initialize its browser side state.
+ void ResumeLoad();
+
+ const network::mojom::RequestDestination m_request_destination;
+ const int m_frame_tree_node_id;
+
+ base::WeakPtrFactory<PluginResponseInterceptorURLLoaderThrottle>
+ weak_factory_{this};
+};
+
+} // 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..8315b7bf2
--- /dev/null
+++ b/src/core/net/proxy_config_monitor.cpp
@@ -0,0 +1,82 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// 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 "content/public/browser/browser_task_traits.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.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, content::GetUIThreadTaskRunner({})));
+
+ 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)
+{
+ mojo::PendingRemote<network::mojom::ProxyConfigClient> proxy_config_client;
+ network_context_params->proxy_config_client_receiver =
+ proxy_config_client.InitWithNewPipeAndPassReceiver();
+ proxy_config_client_set_.Add(std::move(proxy_config_client));
+
+ poller_receiver_set_.Add(this,
+ network_context_params->proxy_config_poller_client.InitWithNewPipeAndPassReceiver());
+
+ 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));
+ for (const auto &proxy_config_client : proxy_config_client_set_) {
+ 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..585e4b7ed
--- /dev/null
+++ b/src/core/net/proxy_config_monitor.h
@@ -0,0 +1,59 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// 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 "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote_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/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::ReceiverSet<network::mojom::ProxyConfigPollerClient> poller_receiver_set_;
+ mojo::RemoteSet<network::mojom::ProxyConfigClient> proxy_config_client_set_;
+};
+
+#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 00ff1c54d..d74ec699d 100644
--- a/src/core/net/proxy_config_service_qt.cpp
+++ b/src/core/net/proxy_config_service_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//================ Based on ChromeProxyConfigService =======================
@@ -45,58 +9,63 @@
#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 "net/base/proxy_server.h"
-using content::BrowserThread;
+#include <QNetworkProxy>
net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qtProxy)
{
- net::HostPortPair hostPortPair(qtProxy.hostName().toStdString(), qtProxy.port());
+ std::string host = qtProxy.hostName().toStdString();
+ uint16_t port = qtProxy.port();
switch (qtProxy.type()) {
case QNetworkProxy::Socks5Proxy:
- return net::ProxyServer(net::ProxyServer::SCHEME_SOCKS5, hostPortPair);
+ return net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_SOCKS5, host, port);
case QNetworkProxy::HttpProxy:
case QNetworkProxy::HttpCachingProxy:
case QNetworkProxy::FtpCachingProxy:
- return net::ProxyServer(net::ProxyServer::SCHEME_HTTP, hostPortPair);
+ return net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTP, host, port);
case QNetworkProxy::NoProxy:
case QNetworkProxy::DefaultProxy:
- return net::ProxyServer(net::ProxyServer::SCHEME_DIRECT, net::HostPortPair());
default:
return net::ProxyServer(net::ProxyServer::SCHEME_INVALID, net::HostPortPair());
}
}
-ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService,
- const net::ProxyConfigWithAnnotation& initialConfig, ProxyPrefs::ConfigState initialState)
- : m_baseService(baseService.release()),
- m_usesSystemConfiguration(false),
- m_registeredObserver(false),
- m_prefConfig(initialConfig),
- m_perfState(initialState)
+ProxyConfigServiceQt::ProxyConfigServiceQt(PrefService *prefService,
+ const scoped_refptr<base::SequencedTaskRunner> &taskRunner)
+ : m_baseService(net::ProxyConfigService::CreateSystemProxyConfigService(taskRunner))
+ , m_usesSystemConfiguration(false)
+ , m_registeredObserver(false)
+ , 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 +75,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 +120,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 +137,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 +149,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 +163,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 09e88d445..49c9877a5 100644
--- a/src/core/net/proxy_config_service_qt.h
+++ b/src/core/net/proxy_config_service_qt.h
@@ -1,48 +1,11 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PROXY_CONFIG_SERVICE_QT_H
#define PROXY_CONFIG_SERVICE_QT_H
-#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
-
+#include "base/task/sequenced_task_runner.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
@@ -50,16 +13,17 @@
#include <QNetworkProxy>
+class PrefService;
+
class ProxyConfigServiceQt
- : public net::ProxyConfigService
- , public net::ProxyConfigService::Observer {
+ : public net::ProxyConfigService
+ , public net::ProxyConfigService::Observer
+{
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::SequencedTaskRunner> &taskRunner);
~ProxyConfigServiceQt() override;
// ProxyConfigService implementation:
@@ -92,9 +56,9 @@ private:
// Configuration as defined by prefs.
net::ProxyConfigWithAnnotation m_prefConfig;
- ProxyPrefs::ConfigState m_perfState;
+ ProxyPrefs::ConfigState m_prefState;
- DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt);
+ SEQUENCE_CHECKER(m_sequenceChecker);
};
#endif // PROXY_CONFIG_SERVICE_QT_H
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..29e6de968
--- /dev/null
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
@@ -0,0 +1,165 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// 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_io_data_qt.h"
+#include "type_conversion.h"
+
+#include "base/memory/ptr_util.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
+
+namespace QtWebEngineCore {
+
+// static
+void ProxyingRestrictedCookieManagerQt::CreateAndBind(ProfileIODataQt *profileIoData,
+ mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
+ mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(&ProxyingRestrictedCookieManagerQt::CreateAndBindOnIoThread,
+ profileIoData,
+ std::move(underlying_rcm),
+ std::move(receiver)));
+}
+
+
+// static
+void ProxyingRestrictedCookieManagerQt::CreateAndBindOnIoThread(ProfileIODataQt *profileIoData,
+ mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
+ mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ auto wrapper = base::WrapUnique(new ProxyingRestrictedCookieManagerQt(
+ profileIoData->getWeakPtrOnIOThread(),
+ std::move(underlying_rcm)));
+ mojo::MakeSelfOwnedReceiver(std::move(wrapper), std::move(receiver));
+}
+
+ProxyingRestrictedCookieManagerQt::ProxyingRestrictedCookieManagerQt(
+ base::WeakPtr<ProfileIODataQt> profileIoData,
+ mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlyingRestrictedCookieManager)
+ : m_profileIoData(std::move(profileIoData))
+ , underlying_restricted_cookie_manager_(std::move(underlyingRestrictedCookieManager))
+ , weak_factory_(this)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+}
+
+ProxyingRestrictedCookieManagerQt::~ProxyingRestrictedCookieManagerQt()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+}
+
+void ProxyingRestrictedCookieManagerQt::GetAllForUrl(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin, bool has_storage_access,
+ network::mojom::CookieManagerGetOptionsPtr options,
+ bool is_ad_tagged,
+ GetAllForUrlCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (allowCookies(url, site_for_cookies)) {
+ underlying_restricted_cookie_manager_->GetAllForUrl(url, site_for_cookies, top_frame_origin, has_storage_access,
+ std::move(options), is_ad_tagged, std::move(callback));
+ } else {
+ std::move(callback).Run(std::vector<net::CookieWithAccessResult>());
+ }
+}
+
+void ProxyingRestrictedCookieManagerQt::SetCanonicalCookie(const net::CanonicalCookie &cookie,
+ const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ net::CookieInclusionStatus status,
+ SetCanonicalCookieCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (allowCookies(url, site_for_cookies)) {
+ underlying_restricted_cookie_manager_->SetCanonicalCookie(cookie, url, site_for_cookies, top_frame_origin,
+ has_storage_access, status, std::move(callback));
+ } else {
+ std::move(callback).Run(false);
+ }
+}
+
+void ProxyingRestrictedCookieManagerQt::AddChangeListener(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ mojo::PendingRemote<network::mojom::CookieChangeListener> listener,
+ AddChangeListenerCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ underlying_restricted_cookie_manager_->AddChangeListener(url, site_for_cookies, top_frame_origin, has_storage_access,
+ std::move(listener), std::move(callback));
+}
+
+void ProxyingRestrictedCookieManagerQt::SetCookieFromString(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin, bool has_storage_access,
+ 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, top_frame_origin, has_storage_access,
+ cookie, std::move(callback));
+ } else {
+ std::move(callback).Run();
+ }
+}
+
+void ProxyingRestrictedCookieManagerQt::GetCookiesString(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access, bool get_version_shared_memory,
+ bool is_ad_tagged,
+ GetCookiesStringCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (allowCookies(url, site_for_cookies)) {
+ underlying_restricted_cookie_manager_->GetCookiesString(url, site_for_cookies, top_frame_origin,
+ has_storage_access, get_version_shared_memory,
+ is_ad_tagged,
+ std::move(callback));
+ } else {
+ std::move(callback).Run(network::mojom::kInvalidCookieVersion, base::ReadOnlySharedMemoryRegion(), "");
+ }
+}
+
+void ProxyingRestrictedCookieManagerQt::CookiesEnabledFor(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin & /*top_frame_origin*/,
+ bool /*has_storage_access*/,
+ CookiesEnabledForCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ std::move(callback).Run(allowCookies(url, site_for_cookies));
+}
+
+bool ProxyingRestrictedCookieManagerQt::allowCookies(const GURL &url, const net::SiteForCookies &site_for_cookies) const
+{
+ if (!m_profileIoData)
+ return false;
+ return m_profileIoData->canGetCookies(toQt(site_for_cookies.first_party_url()), toQt(url));
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.h b/src/core/net/proxying_restricted_cookie_manager_qt.h
new file mode 100644
index 000000000..ba30a448e
--- /dev/null
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.h
@@ -0,0 +1,86 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PROXYING_RESTRICTED_COOKIE_MANAGER_QT_H
+#define PROXYING_RESTRICTED_COOKIE_MANAGER_QT_H
+
+#include "base/memory/weak_ptr.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/network/public/mojom/restricted_cookie_manager.mojom.h"
+#include "url/gurl.h"
+
+namespace QtWebEngineCore {
+
+class ProfileIODataQt;
+
+class ProxyingRestrictedCookieManagerQt : public network::mojom::RestrictedCookieManager
+{
+public:
+ // Expects to be called on the UI thread.
+ static void CreateAndBind(ProfileIODataQt *profileIoData,
+ mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
+ mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver);
+
+ ~ProxyingRestrictedCookieManagerQt() override;
+
+ // network::mojom::RestrictedCookieManager interface:
+ void GetAllForUrl(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ network::mojom::CookieManagerGetOptionsPtr options,
+ bool is_ad_tagged,
+ GetAllForUrlCallback callback) override;
+
+ void SetCanonicalCookie(const net::CanonicalCookie& cookie,
+ const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ net::CookieInclusionStatus status,
+ SetCanonicalCookieCallback callback) override;
+ void AddChangeListener(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ mojo::PendingRemote<network::mojom::CookieChangeListener> listener,
+ AddChangeListenerCallback callback) override;
+ void SetCookieFromString(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ const std::string &cookie,
+ SetCookieFromStringCallback callback) override;
+ void GetCookiesString(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access, bool get_version_shared_memory,
+ bool is_ad_tagged,
+ GetCookiesStringCallback callback) override;
+ void CookiesEnabledFor(const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ CookiesEnabledForCallback callback) override;
+
+ // Internal:
+ bool allowCookies(const GURL &url, const net::SiteForCookies &site_for_cookies) const;
+
+private:
+ ProxyingRestrictedCookieManagerQt(base::WeakPtr<ProfileIODataQt> profileIoData,
+ mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm);
+
+ static void CreateAndBindOnIoThread(ProfileIODataQt *profileIoData,
+ mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
+ mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver);
+
+ base::WeakPtr<ProfileIODataQt> m_profileIoData;
+
+ mojo::Remote<network::mojom::RestrictedCookieManager> underlying_restricted_cookie_manager_;
+
+ base::WeakPtrFactory<ProxyingRestrictedCookieManagerQt> weak_factory_;
+};
+
+} // namespace QtWebEngineCore
+
+#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..220f44023
--- /dev/null
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -0,0 +1,603 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "proxying_url_loader_factory_qt.h"
+
+#include <utility>
+
+#include "base/functional/bind.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
+#include "net/base/filename_util.h"
+#include "net/http/http_status_code.h"
+#include "services/network/public/cpp/cors/cors.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/mojom/early_hints.mojom.h"
+#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
+#include "url/url_util.h"
+#include "url/url_util_qt.h"
+
+#include "api/qwebengineurlrequestinfo_p.h"
+#include "type_conversion.h"
+#include "web_contents_adapter.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+#include "net/resource_request_body_qt.h"
+
+// 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 {
+ network::mojom::URLResponseHeadPtr createResponse(const network::ResourceRequest &request) {
+ const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity);
+ network::mojom::URLResponseHeadPtr response = network::mojom::URLResponseHead::New();
+ response->response_type = network::cors::CalculateResponseType(
+ request.mode, disable_web_security || (
+ request.request_initiator && request.request_initiator->IsSameOriginWith(url::Origin::Create(request.url))));
+
+ return response;
+ }
+}
+
+namespace QtWebEngineCore {
+
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMainFrame, blink::mojom::ResourceType::kMainFrame)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubFrame, blink::mojom::ResourceType::kSubFrame)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeStylesheet, blink::mojom::ResourceType::kStylesheet)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeScript, blink::mojom::ResourceType::kScript)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeImage, blink::mojom::ResourceType::kImage)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFontResource, blink::mojom::ResourceType::kFontResource)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubResource, blink::mojom::ResourceType::kSubResource)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeObject, blink::mojom::ResourceType::kObject)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMedia, blink::mojom::ResourceType::kMedia)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeWorker, blink::mojom::ResourceType::kWorker)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSharedWorker, blink::mojom::ResourceType::kSharedWorker)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePrefetch, blink::mojom::ResourceType::kPrefetch)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFavicon, blink::mojom::ResourceType::kFavicon)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeXhr, blink::mojom::ResourceType::kXhr)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePing, blink::mojom::ResourceType::kPing)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker, blink::mojom::ResourceType::kServiceWorker)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeCspReport, blink::mojom::ResourceType::kCspReport)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePluginResource, blink::mojom::ResourceType::kPluginResource)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadMainFrame, blink::mojom::ResourceType::kNavigationPreloadMainFrame)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadSubFrame, blink::mojom::ResourceType::kNavigationPreloadSubFrame)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeJson, blink::mojom::ResourceType::kJson)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeLast, blink::mojom::ResourceType::kMaxValue)
+
+extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
+
+static QWebEngineUrlRequestInfo::ResourceType toQt(blink::mojom::ResourceType resourceType)
+{
+ if (resourceType >= blink::mojom::ResourceType::kMinValue && resourceType <= blink::mojom::ResourceType::kMaxValue)
+ return static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType);
+ return QWebEngineUrlRequestInfo::ResourceTypeUnknown;
+}
+
+static QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::NavigationType navigationType)
+{
+ return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
+}
+
+static QHash<QByteArray, QByteArray> toQt(const net::HttpRequestHeaders &headers)
+{
+ const auto vector = headers.GetHeaderVector();
+ QHash<QByteArray, QByteArray> hash;
+
+ for (const auto &header : vector) {
+ hash.insert(QByteArray::fromStdString(header.key), QByteArray::fromStdString(header.value));
+ }
+
+ return hash;
+}
+
+// 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(ProfileAdapter *profile_adapter,
+ int frame_tree_node_id, int32_t request_id, uint32_t options,
+ const network::ResourceRequest &request,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation,
+ mojo::PendingReceiver<network::mojom::URLLoader> loader,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client,
+ mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory);
+ ~InterceptedRequest() override;
+
+ void Restart();
+
+ // network::mojom::URLLoaderClient
+ void OnReceiveResponse(network::mojom::URLResponseHeadPtr head, mojo::ScopedDataPipeConsumerHandle, absl::optional<mojo_base::BigBuffer>) override;
+ void OnReceiveRedirect(const net::RedirectInfo &redirect_info, network::mojom::URLResponseHeadPtr head) override;
+ void OnUploadProgress(int64_t current_position, int64_t total_size, OnUploadProgressCallback callback) override;
+ void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
+ void OnComplete(const network::URLLoaderCompletionStatus &status) override;
+ void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr) override {}
+
+ // network::mojom::URLLoader
+ void FollowRedirect(const std::vector<std::string> &removed_headers,
+ const net::HttpRequestHeaders &modified_headers,
+ const net::HttpRequestHeaders &modified_cors_exempt_headers,
+ const absl::optional<GURL> &new_url) override;
+ void SetPriority(net::RequestPriority priority, int32_t intra_priority_value) override;
+ void PauseReadingBodyFromNet() override;
+ void ResumeReadingBodyFromNet() override;
+
+private:
+ void InterceptOnUIThread();
+ void ContinueAfterIntercept();
+
+ // 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);
+
+ content::WebContents* webContents();
+ QWebEngineUrlRequestInterceptor* getProfileInterceptor();
+ QWebEngineUrlRequestInterceptor* getPageInterceptor();
+
+ QPointer<ProfileAdapter> profile_adapter_;
+ const int frame_tree_node_id_;
+ const int32_t request_id_;
+ const uint32_t options_;
+ bool allow_local_ = false;
+ bool allow_remote_ = true;
+ bool local_access_ = false;
+ bool remote_access_ = true;
+
+ bool loader_error_seen_ = 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;
+ network::ResourceRequest request_;
+ ResourceRequestBody request_body_;
+ network::mojom::URLResponseHeadPtr current_response_;
+
+ const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
+
+ struct RequestInfoDeleter
+ {
+ void operator()(QWebEngineUrlRequestInfo *ptr) const
+ { delete ptr; }
+ };
+
+ std::unique_ptr<QWebEngineUrlRequestInfo, RequestInfoDeleter> request_info_;
+
+ mojo::Receiver<network::mojom::URLLoader> proxied_loader_receiver_;
+ mojo::Remote<network::mojom::URLLoaderClient> target_client_;
+ mojo::Receiver<network::mojom::URLLoaderClient> proxied_client_receiver_{this};
+ mojo::Remote<network::mojom::URLLoader> target_loader_;
+ mojo::Remote<network::mojom::URLLoaderFactory> target_factory_;
+
+ base::WeakPtrFactory<InterceptedRequest> weak_factory_;
+};
+
+InterceptedRequest::InterceptedRequest(ProfileAdapter *profile_adapter,
+ int frame_tree_node_id, int32_t request_id, uint32_t options,
+ const network::ResourceRequest &request,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation,
+ mojo::PendingReceiver<network::mojom::URLLoader> loader_receiver,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client,
+ mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory)
+ : profile_adapter_(profile_adapter)
+ , frame_tree_node_id_(frame_tree_node_id)
+ , request_id_(request_id)
+ , options_(options)
+ , request_(request)
+ , request_body_(ResourceRequestBody(request_.request_body.get()))
+ , traffic_annotation_(traffic_annotation)
+ , proxied_loader_receiver_(this, std::move(loader_receiver))
+ , target_client_(std::move(client))
+ , target_factory_(std::move(target_factory))
+ , weak_factory_(this)
+{
+ const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity);
+ current_response_ = createResponse(request_);
+ // If there is a client error, clean up the request.
+ target_client_.set_disconnect_handler(
+ base::BindOnce(&InterceptedRequest::OnURLLoaderClientError, base::Unretained(this)));
+ proxied_loader_receiver_.set_disconnect_with_reason_handler(
+ base::BindOnce(&InterceptedRequest::OnURLLoaderError, base::Unretained(this)));
+ if (!disable_web_security && request_.request_initiator) {
+ const std::vector<std::string> &localSchemes = url::GetLocalSchemes();
+ const std::string fromScheme = request_.request_initiator->GetTupleOrPrecursorTupleIfOpaque().scheme();
+ const std::string toScheme = request_.url.scheme();
+ const bool fromLocal = base::Contains(localSchemes, fromScheme);
+ const bool toLocal = base::Contains(localSchemes, toScheme);
+ bool hasLocalAccess = false;
+ local_access_ = toLocal;
+ remote_access_ = !toLocal && (toScheme != "data") && (toScheme != "qrc");
+ if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(fromScheme))
+ hasLocalAccess = cs->flags & url::CustomScheme::LocalAccessAllowed;
+ if (fromLocal || toLocal) {
+ content::WebContents *wc = webContents();
+ // local schemes must have universal access, or be accessing something local and have local access.
+ allow_local_ = hasLocalAccess || (fromLocal && wc && wc->GetOrCreateWebPreferences().allow_file_access_from_file_urls);
+ allow_remote_ = !fromLocal || (wc && wc->GetOrCreateWebPreferences().allow_remote_access_from_local_urls);
+ }
+ }
+}
+
+InterceptedRequest::~InterceptedRequest()
+{
+ weak_factory_.InvalidateWeakPtrs();
+}
+
+content::WebContents* InterceptedRequest::webContents()
+{
+ if (frame_tree_node_id_ == content::RenderFrameHost::kNoFrameTreeNodeId)
+ return nullptr;
+ return content::WebContents::FromFrameTreeNodeId(frame_tree_node_id_);
+}
+
+QWebEngineUrlRequestInterceptor* InterceptedRequest::getProfileInterceptor()
+{
+ return profile_adapter_ ? profile_adapter_->requestInterceptor() : nullptr;
+}
+
+QWebEngineUrlRequestInterceptor* InterceptedRequest::getPageInterceptor()
+{
+ if (auto wc = webContents()) {
+ auto view = static_cast<content::WebContentsImpl *>(wc)->GetView();
+ if (WebContentsAdapterClient *client = WebContentsViewQt::from(view)->client())
+ return client->webContentsAdapter()->requestInterceptor();
+ }
+ return nullptr;
+}
+
+void InterceptedRequest::Restart()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ bool granted_special_access = false;
+ auto navigationType = toQt(pageTransitionToNavigationType(ui::PageTransition(request_.transition_type)));
+ switch (navigationType) {
+ case QWebEngineUrlRequestInfo::NavigationTypeLink:
+ case QWebEngineUrlRequestInfo::NavigationTypeTyped:
+ if (blink::mojom::ResourceType(request_.resource_type) == blink::mojom::ResourceType::kMainFrame && request_.has_user_gesture)
+ granted_special_access = true; // allow normal explicit navigation
+ break;
+ case QWebEngineUrlRequestInfo::NavigationTypeBackForward:
+ case QWebEngineUrlRequestInfo::NavigationTypeReload:
+ if (blink::mojom::ResourceType(request_.resource_type) == blink::mojom::ResourceType::kMainFrame)
+ granted_special_access = true;
+ break;
+ default:
+ break;
+ }
+
+ // Check if non-local access is allowed
+ if (!allow_remote_ && remote_access_) {
+ if (!granted_special_access) {
+ target_client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_NETWORK_ACCESS_DENIED));
+ delete this;
+ return;
+ }
+ }
+
+ // Check if local access is allowed
+ if (!allow_local_ && local_access_) {
+ // Check for specifically granted file access:
+ if (auto *frame_tree = content::FrameTreeNode::GloballyFindByID(frame_tree_node_id_)) {
+ const int renderer_id = frame_tree->current_frame_host()->GetProcess()->GetID();
+ base::FilePath file_path;
+ if (net::FileURLToFilePath(request_.url, &file_path)) {
+ if (content::ChildProcessSecurityPolicy::GetInstance()->CanReadFile(renderer_id, file_path))
+ granted_special_access = true;
+ }
+ }
+ if (!granted_special_access) {
+ target_client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
+ delete this;
+ return;
+ }
+ }
+
+ // MEMO since all codepatch leading to Restart scheduled and executed as asynchronous tasks in main thread,
+ // interceptors may change in meantime and also during intercept call, so they should be resolved anew.
+ // Set here only profile's interceptor since it runs first without going to user code.
+ auto profileInterceptor = getProfileInterceptor();
+ if (!profileInterceptor && !getPageInterceptor()) {
+ ContinueAfterIntercept();
+ return;
+ }
+
+ auto resourceType = toQt(blink::mojom::ResourceType(request_.resource_type));
+ const QUrl originalUrl = toQt(request_.url);
+ const QUrl initiator = request_.request_initiator.has_value() ? toQt(request_.request_initiator->GetURL()) : QUrl();
+
+ auto wc = webContents();
+ GURL top_document_url = wc ? wc->GetVisibleURL() : GURL();
+ QUrl firstPartyUrl;
+ if (!top_document_url.is_empty())
+ firstPartyUrl = toQt(top_document_url);
+ else
+ firstPartyUrl = toQt(request_.site_for_cookies.first_party_url()); // m_topDocumentUrl can be empty for the main-frame.
+
+ QHash<QByteArray, QByteArray> headers = toQt(request_.headers);
+
+ if (!request_.referrer.is_empty())
+ headers.insert("Referer", toQt(request_.referrer).toEncoded());
+
+ auto info = new QWebEngineUrlRequestInfoPrivate(
+ resourceType, navigationType, originalUrl, firstPartyUrl, initiator,
+ QByteArray::fromStdString(request_.method), &request_body_, headers);
+ Q_ASSERT(!request_info_);
+ request_info_.reset(new QWebEngineUrlRequestInfo(info));
+
+ InterceptOnUIThread();
+ ContinueAfterIntercept();
+}
+
+void InterceptedRequest::InterceptOnUIThread()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (auto interceptor = getProfileInterceptor())
+ interceptor->interceptRequest(*request_info_);
+
+ if (!request_info_->changed()) {
+ if (auto interceptor = getPageInterceptor())
+ interceptor->interceptRequest(*request_info_);
+ }
+}
+
+void InterceptedRequest::ContinueAfterIntercept()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (request_info_) {
+ // cleanup in scope because of delete this and it's not needed else where after
+ const auto scoped_request_info = std::move(request_info_);
+ QWebEngineUrlRequestInfoPrivate &info = *scoped_request_info->d_ptr;
+
+ for (auto header = info.extraHeaders.constBegin(); header != info.extraHeaders.constEnd(); ++header) {
+ std::string h = header.key().toStdString();
+ if (base::EqualsCaseInsensitiveASCII(h, "referer"))
+ request_.referrer = GURL(header.value().toStdString());
+ else
+ request_.headers.SetHeader(h, header.value().toStdString());
+ }
+
+ if (info.changed) {
+ if (info.shouldBlockRequest)
+ return SendErrorAndCompleteImmediately(net::ERR_BLOCKED_BY_CLIENT);
+
+ if (info.shouldRedirectRequest) {
+ net::RedirectInfo::FirstPartyURLPolicy first_party_url_policy =
+ request_.update_first_party_url_on_redirect ? net::RedirectInfo::FirstPartyURLPolicy::UPDATE_URL_ON_REDIRECT
+ : net::RedirectInfo::FirstPartyURLPolicy::NEVER_CHANGE_URL;
+ net::RedirectInfo redirectInfo = net::RedirectInfo::ComputeRedirectInfo(
+ request_.method, request_.url, request_.site_for_cookies,
+ first_party_url_policy, request_.referrer_policy, request_.referrer.spec(),
+ net::HTTP_TEMPORARY_REDIRECT, toGurl(info.url), absl::nullopt,
+ false /*insecure_scheme_was_upgraded*/);
+ 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;
+ // In case of multiple sequential rediredts, current_response_ has previously been moved to target_client_
+ // so we create a new one using the redirect url.
+ if (!current_response_)
+ current_response_ = createResponse(request_);
+ current_response_->encoded_data_length = 0;
+ target_client_->OnReceiveRedirect(redirectInfo, std::move(current_response_));
+ return;
+ }
+ }
+ }
+
+ if (!target_loader_ && target_factory_) {
+ loader_error_seen_ = false;
+ target_factory_->CreateLoaderAndStart(target_loader_.BindNewPipeAndPassReceiver(), request_id_,
+ options_, request_, proxied_client_receiver_.BindNewPipeAndPassRemote(),
+ traffic_annotation_);
+ }
+}
+
+// URLLoaderClient methods.
+
+void InterceptedRequest::OnReceiveResponse(network::mojom::URLResponseHeadPtr head, mojo::ScopedDataPipeConsumerHandle handle, absl::optional<mojo_base::BigBuffer> buffer)
+{
+ current_response_ = head.Clone();
+
+ target_client_->OnReceiveResponse(std::move(head), std::move(handle), std::move(buffer));
+}
+
+void InterceptedRequest::OnReceiveRedirect(const net::RedirectInfo &redirect_info, network::mojom::URLResponseHeadPtr head)
+{
+ // TODO(timvolodine): handle redirect override.
+ current_response_ = head.Clone();
+ target_client_->OnReceiveRedirect(redirect_info, std::move(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::OnTransferSizeUpdated(int32_t transfer_size_diff)
+{
+ target_client_->OnTransferSizeUpdated(transfer_size_diff);
+}
+
+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 net::HttpRequestHeaders &modified_cors_exempt_headers,
+ const absl::optional<GURL> &new_url)
+{
+ if (target_loader_)
+ target_loader_->FollowRedirect(removed_headers, modified_headers, modified_cors_exempt_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::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;
+ else
+ loader_error_seen_ = true;
+}
+
+void InterceptedRequest::CallOnComplete(const network::URLLoaderCompletionStatus &status, bool wait_for_loader_error)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ // 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_receiver_.is_bound() && wait_for_loader_error && !loader_error_seen_) {
+ // Since the original client is gone no need to continue loading the
+ // request.
+ proxied_client_receiver_.reset();
+ target_loader_.reset();
+
+ // Don't delete |this| yet, in case the |proxied_loader_receiver_|'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();
+
+ // 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.
+ weak_factory_.InvalidateWeakPtrs();
+ } else {
+ delete this;
+ }
+}
+
+void InterceptedRequest::SendErrorAndCompleteImmediately(int error_code)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ auto status = network::URLLoaderCompletionStatus(error_code);
+ target_client_->OnComplete(status);
+ delete this;
+}
+
+ProxyingURLLoaderFactoryQt::ProxyingURLLoaderFactoryQt(ProfileAdapter *adapter, int frame_tree_node_id,
+ mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
+ mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_info)
+ : m_profileAdapter(adapter), m_frameTreeNodeId(frame_tree_node_id), m_weakFactory(this)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (target_factory_info) {
+ m_targetFactory.Bind(std::move(target_factory_info));
+ m_targetFactory.set_disconnect_handler(
+ base::BindOnce(&ProxyingURLLoaderFactoryQt::OnTargetFactoryError, m_weakFactory.GetWeakPtr()));
+ }
+ m_proxyReceivers.Add(this, std::move(loader_receiver));
+ m_proxyReceivers.set_disconnect_handler(
+ base::BindRepeating(&ProxyingURLLoaderFactoryQt::OnProxyBindingError, m_weakFactory.GetWeakPtr()));
+}
+
+ProxyingURLLoaderFactoryQt::~ProxyingURLLoaderFactoryQt()
+{
+ m_weakFactory.InvalidateWeakPtrs();
+}
+
+void ProxyingURLLoaderFactoryQt::CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> loader, int32_t request_id,
+ uint32_t options, const network::ResourceRequest &request,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> url_loader_client,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_clone;
+ if (m_targetFactory)
+ m_targetFactory->Clone(target_factory_clone.InitWithNewPipeAndPassReceiver());
+
+ // Will manage its own lifetime
+ InterceptedRequest *req = new InterceptedRequest(m_profileAdapter, m_frameTreeNodeId, request_id, options,
+ request, traffic_annotation, std::move(loader),
+ std::move(url_loader_client), std::move(target_factory_clone));
+ req->Restart();
+}
+
+void ProxyingURLLoaderFactoryQt::OnTargetFactoryError()
+{
+ delete this;
+}
+
+void ProxyingURLLoaderFactoryQt::OnProxyBindingError()
+{
+ if (m_proxyReceivers.empty())
+ delete this;
+}
+
+void ProxyingURLLoaderFactoryQt::Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ m_proxyReceivers.Add(this, std::move(receiver));
+}
+
+} // 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..904a40c2d
--- /dev/null
+++ b/src/core/net/proxying_url_loader_factory_qt.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PROXYING_URL_LOADER_FACTORY_QT_H_
+#define PROXYING_URL_LOADER_FACTORY_QT_H_
+
+#include "base/memory/weak_ptr.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+
+#include <QPointer>
+// 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 network {
+struct ResourceRequest;
+}
+
+namespace QtWebEngineCore {
+
+class ProfileAdapter;
+
+class ProxyingURLLoaderFactoryQt : public network::mojom::URLLoaderFactory
+{
+public:
+ ProxyingURLLoaderFactoryQt(ProfileAdapter *adapter, int frameTreeNodeId,
+ mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
+ mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_target_factory_remote);
+
+ ~ProxyingURLLoaderFactoryQt() override;
+
+ void CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> loader,
+ int32_t request_id,
+ uint32_t options, const network::ResourceRequest &request,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation) override;
+
+ void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) override;
+
+private:
+ void OnTargetFactoryError();
+ void OnProxyBindingError();
+
+ QPointer<ProfileAdapter> m_profileAdapter;
+ int m_frameTreeNodeId;
+ mojo::ReceiverSet<network::mojom::URLLoaderFactory> m_proxyReceivers;
+ mojo::Remote<network::mojom::URLLoaderFactory> m_targetFactory;
+ base::WeakPtrFactory<ProxyingURLLoaderFactoryQt> m_weakFactory;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PROXYING_URL_LOADER_FACTORY_QT_H_
diff --git a/src/core/net/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp
index 73bf24f1d..a8b4e4388 100644
--- a/src/core/net/qrc_url_scheme_handler.cpp
+++ b/src/core/net/qrc_url_scheme_handler.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qrc_url_scheme_handler.h"
@@ -46,6 +10,8 @@
#include <QMimeDatabase>
#include <QMimeType>
+#include <memory>
+
namespace QtWebEngineCore {
void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
@@ -58,7 +24,7 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
QUrl requestUrl = job->requestUrl();
QString requestPath = requestUrl.path();
- QScopedPointer<QFile> file(new QFile(':' + requestPath, job));
+ auto file = std::make_unique<QFile>(':' + requestPath, job);
if (!file->exists() || file->size() == 0) {
qWarning("QResource '%s' not found or is empty", qUtf8Printable(requestPath));
job->fail(QWebEngineUrlRequestJob::UrlNotFound);
@@ -67,7 +33,10 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
QFileInfo fileInfo(*file);
QMimeDatabase mimeDatabase;
QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo);
- job->reply(mimeType.name().toUtf8(), file.take());
+ if (mimeType.name() == QStringLiteral("application/x-extension-html"))
+ job->reply("text/html", file.release());
+ else
+ job->reply(mimeType.name().toUtf8(), file.release());
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/qrc_url_scheme_handler.h b/src/core/net/qrc_url_scheme_handler.h
index f6ca92879..96155b05b 100644
--- a/src/core/net/qrc_url_scheme_handler.h
+++ b/src/core/net/qrc_url_scheme_handler.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QRC_URL_SCHEME_HANDLER_H
#define QRC_URL_SCHEME_HANDLER_H
@@ -45,7 +9,8 @@
namespace QtWebEngineCore {
-class QrcUrlSchemeHandler final : public QWebEngineUrlSchemeHandler {
+class QrcUrlSchemeHandler final : public QWebEngineUrlSchemeHandler
+{
public:
void requestStarted(QWebEngineUrlRequestJob *) override;
};
diff --git a/src/core/net/resource_request_body_qt.cpp b/src/core/net/resource_request_body_qt.cpp
new file mode 100644
index 000000000..d0d54784d
--- /dev/null
+++ b/src/core/net/resource_request_body_qt.cpp
@@ -0,0 +1,181 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "resource_request_body_qt.h"
+#include "type_conversion.h"
+
+#include "services/network/public/cpp/resource_request_body.h"
+#include "services/network/public/mojom/data_pipe_getter.mojom.h"
+#include "services/network/public/mojom/url_request.mojom-shared.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace QtWebEngineCore {
+
+ResourceRequestBody::ResourceRequestBody(network::ResourceRequestBody *requestBody, QObject *parent)
+ : QIODevice(parent)
+ , m_requestBody(requestBody)
+ , m_dataElementsIdx(0)
+ , m_dataElementBytesIdx(0)
+ , m_dataElementFileIdx(0)
+{};
+
+ResourceRequestBody::~ResourceRequestBody(){};
+
+qint64 ResourceRequestBody::readData(char *data, qint64 maxSize)
+{
+ if (!m_requestBody)
+ return -1;
+
+ const std::size_t dataElementsSize = m_requestBody->elements()->size();
+ if (m_dataElementsIdx == dataElementsSize)
+ return -1;
+
+ qint64 bytesRead = 0;
+ const std::vector<network::DataElement> *elements = m_requestBody->elements();
+ while (bytesRead < maxSize && m_dataElementsIdx < dataElementsSize) {
+ const network::DataElement &currentDataElement = elements->at(m_dataElementsIdx);
+
+ switch (currentDataElement.type()) {
+ case network::mojom::DataElementDataView::Tag::kBytes: {
+ readDataElementBytes(currentDataElement.As<network::DataElementBytes>().bytes(),
+ bytesRead, maxSize, &data);
+ break;
+ }
+ case network::mojom::DataElementDataView::Tag::kFile: {
+ const network::DataElementFile file = currentDataElement.As<network::DataElementFile>();
+ const qint64 offset = file.offset();
+ const qint64 length = file.length();
+ readDataElementFile(file.path(), offset, length, bytesRead, maxSize, &data);
+ break;
+ }
+ case network::mojom::DataElementDataView::Tag::kDataPipe: {
+ mojo::Remote<network::mojom::DataPipeGetter> pipeGetter;
+ pipeGetter.Bind(
+ currentDataElement.As<network::DataElementDataPipe>().CloneDataPipeGetter());
+ const mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle> consumerHandle =
+ getConsumerHandleFromPipeGetter(pipeGetter);
+ readDataElementPipe(consumerHandle, bytesRead, maxSize, &data);
+ break;
+ }
+ case network::mojom::DataElementDataView::Tag::kChunkedDataPipe: {
+ setErrorString(QStringLiteral("Chunked data pipe is used in request body upload, which "
+ "is currently not supported"));
+ // Nothing should come before or after DataElementChunkedDataPipe
+ return -1;
+ }
+ }
+
+ if (bytesRead == maxSize || m_dataElementsIdx == dataElementsSize)
+ break;
+ }
+
+ return bytesRead;
+}
+
+// We don't want to write, ever
+qint64 ResourceRequestBody::writeData(const char *data, qint64 maxSize)
+{
+ return -1;
+}
+
+bool ResourceRequestBody::isSequential() const
+{
+ return true;
+}
+
+void ResourceRequestBody::readDataElementBytes(const std::vector<uint8_t> &dataElement,
+ qint64 &bytesRead, const qint64 &maxSize,
+ char **data)
+{
+ const std::size_t dataElementSize = dataElement.size();
+ const std::size_t bytesToRead = std::min(dataElementSize, static_cast<std::size_t>(maxSize));
+
+ std::memcpy(*data, dataElement.data(), bytesToRead);
+ *data += bytesToRead;
+ m_dataElementBytesIdx += bytesToRead;
+ bytesRead += bytesToRead;
+
+ if (m_dataElementBytesIdx == dataElementSize) {
+ m_dataElementsIdx++;
+ m_dataElementBytesIdx = 0;
+ }
+}
+
+void ResourceRequestBody::readDataElementFile(const base::FilePath &filePath, const qint64 &offset,
+ const qint64 &length, qint64 &bytesRead,
+ const qint64 &maxSize, char **data)
+{
+ QFile file(toQt(filePath.value()));
+ const qint64 realOffset = offset + m_dataElementFileIdx;
+ const std::size_t fileSize = std::min(file.size(), length) - realOffset;
+ const std::size_t bytesToRead = std::min(fileSize, static_cast<std::size_t>(maxSize));
+
+ file.open(QFile::ReadOnly);
+ file.seek(realOffset);
+
+ std::memcpy(*data, file.read(bytesToRead).data(), bytesToRead);
+ *data += bytesToRead;
+ m_dataElementFileIdx += bytesToRead;
+ bytesRead += bytesToRead;
+
+ file.close();
+
+ if (m_dataElementFileIdx == fileSize) {
+ m_dataElementsIdx++;
+ m_dataElementFileIdx = 0;
+ }
+}
+
+mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle>
+ResourceRequestBody::getConsumerHandleFromPipeGetter(
+ mojo::Remote<network::mojom::DataPipeGetter> &pipeGetter)
+{
+ mojo::ScopedHandleBase<mojo::DataPipeProducerHandle> producerHandle;
+ mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle> consumerHandle;
+ mojo::CreateDataPipe(nullptr, producerHandle, consumerHandle);
+ base::WeakPtrFactory<ResourceRequestBody> weakPtrFactory{ this };
+ pipeGetter->Read(std::move(producerHandle),
+ base::BindOnce(&ResourceRequestBody::pipeGetterOnReadComplete,
+ weakPtrFactory.GetWeakPtr()));
+
+ return consumerHandle;
+}
+
+void ResourceRequestBody::readDataElementPipe(
+ const mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle> &consumerHandle,
+ qint64 &bytesRead, const qint64 &maxSize, char **data)
+{
+ MojoResult result;
+ do {
+ uint32_t bytesToRead = 1;
+ result = consumerHandle->ReadData(*data, &bytesToRead, MOJO_READ_DATA_FLAG_NONE);
+
+ if (result == MOJO_RESULT_OK) {
+ *data += bytesToRead;
+ bytesRead += bytesToRead;
+ } else if (result != MOJO_RESULT_SHOULD_WAIT && result != MOJO_RESULT_FAILED_PRECONDITION) {
+ setErrorString(QString::fromLatin1("Error while reading from data pipe, skipping"
+ "remaining content of data pipe. Mojo error code: ")
+ + QString::number(result));
+ }
+ } while ((result == MOJO_RESULT_SHOULD_WAIT || result == MOJO_RESULT_OK)
+ && bytesRead < maxSize);
+
+ m_dataElementsIdx++;
+}
+
+void ResourceRequestBody::pipeGetterOnReadComplete(int32_t status, uint64_t size) { }
+
+void ResourceRequestBody::appendFilesForTest(const QString &path)
+{
+ if (!m_requestBody)
+ return;
+
+ base::FilePath filePath = toFilePath(path);
+ m_requestBody->elements_mutable()->push_back(static_cast<network::DataElement>(
+ network::DataElementFile(filePath, 0, 23, base::Time())));
+ m_requestBody->elements_mutable()->push_back(static_cast<network::DataElement>(
+ network::DataElementFile(filePath, 10, 23, base::Time())));
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/resource_request_body_qt.h b/src/core/net/resource_request_body_qt.h
new file mode 100644
index 000000000..717885d7d
--- /dev/null
+++ b/src/core/net/resource_request_body_qt.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef RESOURCEREQUESTBODY_QT_H
+#define RESOURCEREQUESTBODY_QT_H
+
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+#include <QtCore/QIODevice>
+#include <QtCore/QFile>
+#include <QtCore/QUrl>
+
+namespace network {
+class ResourceRequestBody;
+namespace mojom {
+class DataPipeGetter;
+class ChunkedDataPipeGetter;
+}
+}
+
+namespace base {
+class FilePath;
+}
+
+namespace mojo {
+template<typename T>
+class Remote;
+template<typename T>
+class ScopedHandleBase;
+class DataPipeConsumerHandle;
+}
+
+namespace QtWebEngineCore {
+
+class Q_WEBENGINECORE_EXPORT ResourceRequestBody : public QIODevice
+{
+ Q_OBJECT
+public:
+ explicit ResourceRequestBody(network::ResourceRequestBody *requestBody,
+ QObject *parent = nullptr);
+ ~ResourceRequestBody();
+
+ qint64 readData(char *data, qint64 maxSize) override;
+ qint64 writeData(const char *data, qint64 maxSize) override;
+ bool isSequential() const override;
+
+ void appendFilesForTest(const QString &path);
+
+private:
+ network::ResourceRequestBody *const m_requestBody;
+
+ std::size_t m_dataElementsIdx;
+ std::size_t m_dataElementBytesIdx;
+ std::size_t m_dataElementFileIdx;
+
+ void readDataElementBytes(const std::vector<uint8_t> &dataElement, qint64 &bytesRead,
+ const qint64 &maxSize, char **data);
+ void readDataElementFile(const base::FilePath &filePath, const qint64 &offset,
+ const qint64 &length, qint64 &bytesRead, const qint64 &maxSize,
+ char **data);
+ mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle>
+ getConsumerHandleFromPipeGetter(mojo::Remote<network::mojom::DataPipeGetter> &pipeGetter);
+ void
+ readDataElementPipe(const mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle> &consumerHandle,
+ qint64 &bytesRead, const qint64 &maxSize, char **data);
+ void pipeGetterOnReadComplete(int32_t status, uint64_t size);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // RESOURCEREQUESTBODY_QT_H
diff --git a/src/core/net/ssl_host_state_delegate_qt.cpp b/src/core/net/ssl_host_state_delegate_qt.cpp
index ecc3c681e..809a95c8d 100644
--- a/src/core/net/ssl_host_state_delegate_qt.cpp
+++ b/src/core/net/ssl_host_state_delegate_qt.cpp
@@ -1,47 +1,9 @@
-/****************************************************************************
-**
-** 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 "base/callback.h"
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "ssl_host_state_delegate_qt.h"
-#include "type_conversion.h"
+#include "base/functional/callback.h"
namespace QtWebEngineCore {
@@ -67,27 +29,23 @@ bool CertPolicy::Check(const net::X509Certificate &cert, int error) const
return false;
}
-void CertPolicy::Allow(const net::X509Certificate& cert, int error)
+void CertPolicy::Allow(const net::X509Certificate &cert, int error)
{
net::SHA256HashValue fingerprint = cert.CalculateChainFingerprint256();
m_allowed[fingerprint] |= error;
}
-SSLHostStateDelegateQt::SSLHostStateDelegateQt()
-{
-}
+SSLHostStateDelegateQt::SSLHostStateDelegateQt() {}
-SSLHostStateDelegateQt::~SSLHostStateDelegateQt()
-{
-}
+SSLHostStateDelegateQt::~SSLHostStateDelegateQt() {}
-void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509Certificate &cert, int error)
+void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509Certificate &cert, int error, content::StoragePartition *)
{
m_certPolicyforHost[host].Allow(cert, error);
}
// Clear all allow preferences.
-void SSLHostStateDelegateQt::Clear(const base::Callback<bool(const std::string&)>& host_filter)
+void SSLHostStateDelegateQt::Clear(base::RepeatingCallback<bool(const std::string&)> host_filter)
{
if (host_filter.is_null()) {
m_certPolicyforHost.clear();
@@ -107,9 +65,9 @@ void SSLHostStateDelegateQt::Clear(const base::Callback<bool(const std::string&)
// Queries whether |cert| is allowed for |host| and |error|. Returns true in
// |expired_previous_decision| if a previous user decision expired immediately
// prior to this query, otherwise false.
-content::SSLHostStateDelegate::CertJudgment SSLHostStateDelegateQt::QueryPolicy(
- const std::string &host, const net::X509Certificate &cert,
- int error, bool */*expired_previous_decision*/)
+content::SSLHostStateDelegate::CertJudgment SSLHostStateDelegateQt::QueryPolicy(const std::string &host,
+ const net::X509Certificate &cert,
+ int error, content::StoragePartition *)
{
return m_certPolicyforHost[host].Check(cert, error) ? SSLHostStateDelegate::ALLOWED : SSLHostStateDelegate::DENIED;
}
@@ -120,7 +78,17 @@ void SSLHostStateDelegateQt::HostRanInsecureContent(const std::string &host, int
}
// Returns whether the specified host ran insecure content.
-bool SSLHostStateDelegateQt::DidHostRunInsecureContent(const std::string &host, int pid, InsecureContentType content_type) const
+bool SSLHostStateDelegateQt::DidHostRunInsecureContent(const std::string &host, int pid, InsecureContentType content_type)
+{
+ return false;
+}
+
+void SSLHostStateDelegateQt::AllowHttpForHost(const std::string &host, content::StoragePartition *web_contents)
+{
+ // Intentional no-op see aw_ssl_host_state_delegate
+}
+
+bool SSLHostStateDelegateQt::IsHttpAllowedForHost(const std::string &host, content::StoragePartition *web_contents)
{
return false;
}
@@ -136,12 +104,33 @@ void SSLHostStateDelegateQt::RevokeUserAllowExceptions(const std::string &host)
// |host|. This does not mean that *all* certificate errors are allowed, just
// that there exists an exception. To see if a particular certificate and
// error combination exception is allowed, use QueryPolicy().
-bool SSLHostStateDelegateQt::HasAllowException(const std::string &host) const
+bool SSLHostStateDelegateQt::HasAllowException(const std::string &host, content::StoragePartition *)
{
auto policy_iterator = m_certPolicyforHost.find(host);
return policy_iterator != m_certPolicyforHost.end() &&
policy_iterator->second.HasAllowException();
}
+bool SSLHostStateDelegateQt::HasAllowExceptionForAnyHost(content::StoragePartition *storage_partition)
+{
+ for (auto const &it : m_certPolicyforHost) {
+ if (it.second.HasAllowException()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void SSLHostStateDelegateQt::SetHttpsEnforcementForHost(const std::string &host, bool enforce,
+ content::StoragePartition *storage_partition)
+{
+ // Intentional no-op see aw_ssl_host_state_delegate
+}
+
+bool SSLHostStateDelegateQt::IsHttpsEnforcedForUrl(const GURL &url,
+ content::StoragePartition *storage_partition)
+{
+ return false;
+}
} // namespace QtWebEngineCore
diff --git a/src/core/net/ssl_host_state_delegate_qt.h b/src/core/net/ssl_host_state_delegate_qt.h
index b1b49bcf3..f210f028a 100644
--- a/src/core/net/ssl_host_state_delegate_qt.h
+++ b/src/core/net/ssl_host_state_delegate_qt.h
@@ -1,77 +1,51 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef SSL_HOST_STATE_DELEGATE_QT_H
#define SSL_HOST_STATE_DELEGATE_QT_H
#include "content/public/browser/ssl_host_state_delegate.h"
-#include "profile_adapter.h"
+
+#include <map>
+#include <string>
namespace QtWebEngineCore {
-class CertPolicy {
+class CertPolicy
+{
public:
CertPolicy();
~CertPolicy();
- bool Check(const net::X509Certificate& cert, int error) const;
- void Allow(const net::X509Certificate& cert, int error);
+ bool Check(const net::X509Certificate &cert, int error) const;
+ void Allow(const net::X509Certificate &cert, int error);
bool HasAllowException() const { return m_allowed.size() > 0; }
private:
std::map<net::SHA256HashValue, int> m_allowed;
};
-class SSLHostStateDelegateQt : public content::SSLHostStateDelegate {
+class SSLHostStateDelegateQt : public content::SSLHostStateDelegate
+{
public:
SSLHostStateDelegateQt();
~SSLHostStateDelegateQt();
// content::SSLHostStateDelegate implementation:
- void AllowCert(const std::string &, const net::X509Certificate &cert, int error) override;
- void Clear(const base::Callback<bool(const std::string&)>& host_filter) override;
- CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert,
- int error, bool *expired_previous_decision) override;
- void HostRanInsecureContent(const std::string& host, int child_id, InsecureContentType content_type) override;
- bool DidHostRunInsecureContent(const std::string& host, int child_id, InsecureContentType content_type) const override;
+ void AllowCert(const std::string &, const net::X509Certificate &cert, int error, content::StoragePartition *storage_partition) override;
+ void Clear(base::RepeatingCallback<bool(const std::string&)> host_filter) override;
+ CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert, int error, content::StoragePartition *web_contents) override;
+ void HostRanInsecureContent(const std::string &host, int child_id, InsecureContentType content_type) override;
+ bool DidHostRunInsecureContent(const std::string &host, int child_id, InsecureContentType content_type) override;
+ void AllowHttpForHost(const std::string &host, content::StoragePartition *web_contents) override;
+ bool IsHttpAllowedForHost(const std::string &host, content::StoragePartition *web_contents) override;
+ void SetHttpsEnforcementForHost(const std::string &host, bool enforce,
+ content::StoragePartition *storage_partition) override;
void RevokeUserAllowExceptions(const std::string &host) override;
- bool HasAllowException(const std::string &host) const override;
+ bool HasAllowException(const std::string &host, content::StoragePartition *web_contents) override;
+ bool HasAllowExceptionForAnyHost(content::StoragePartition *storage_partition) override;
+ bool IsHttpsEnforcedForUrl(const GURL &url,
+ content::StoragePartition *storage_partition) override;
private:
std::map<std::string, CertPolicy> m_certPolicyforHost;
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..78098529d
--- /dev/null
+++ b/src/core/net/system_network_context_manager.cpp
@@ -0,0 +1,356 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// 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 "base/command_line.h"
+#include "base/functional/bind.h"
+#include "base/strings/string_split.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_switches.h"
+#include "content/public/browser/network_service_instance.h"
+#include "content/public/common/content_switches.h"
+#include "crypto/sha2.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "net/base/port_util.h"
+#include "net/net_buildflags.h"
+#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
+#include "services/network/network_service.h"
+#include "services/network/public/cpp/cross_thread_pending_shared_url_loader_factory.h"
+#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/mojom/cert_verifier_service.mojom.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
+#include "api/qwebengineglobalsettings.h"
+#include "api/qwebengineglobalsettings_p.h"
+
+#if BUILDFLAG(IS_WIN)
+#include "chrome/browser/net/chrome_mojo_proxy_resolver_win.h"
+#include "components/os_crypt/sync/os_crypt.h"
+#include "content/public/browser/network_service_util.h"
+#endif
+
+ASSERT_ENUMS_MATCH(net::SecureDnsMode::kSecure, QWebEngineGlobalSettings::SecureDnsMode::SecureOnly)
+ASSERT_ENUMS_MATCH(net::SecureDnsMode::kAutomatic,
+ QWebEngineGlobalSettings::SecureDnsMode::SecureWithFallback)
+ASSERT_ENUMS_MATCH(net::SecureDnsMode::kOff, QWebEngineGlobalSettings::SecureDnsMode::SystemOnly)
+
+namespace {
+
+network::mojom::HttpAuthStaticParamsPtr CreateHttpAuthStaticParams()
+{
+ network::mojom::HttpAuthStaticParamsPtr auth_static_params =
+ network::mojom::HttpAuthStaticParams::New();
+
+ return auth_static_params;
+}
+
+network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams()
+{
+ network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params = network::mojom::HttpAuthDynamicParams::New();
+
+ auth_dynamic_params->allowed_schemes = { "basic", "digest", "ntlm", "negotiate" };
+
+ auto *command_line = base::CommandLine::ForCurrentProcess();
+ auth_dynamic_params->server_allowlist = command_line->GetSwitchValueASCII(switches::kAuthServerAllowlist);
+// auth_dynamic_params->delegate_allowlist = command_line->GetSwitchValueASCII(switches::kAuthNegotiateDelegateWhitelist);
+// auth_dynamic_params->enable_negotiate_port = command_line->HasSwitch(switches::kEnableAuthNegotiatePort);
+
+ return auth_dynamic_params;
+}
+
+} // namespace
+
+namespace QtWebEngineCore {
+
+// The global instance of the SystemNetworkContextmanager.
+SystemNetworkContextManager *g_system_network_context_manager = nullptr;
+
+// 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(mojo::PendingReceiver<network::mojom::URLLoader> receiver,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest &url_request,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client,
+ const net::MutableNetworkTrafficAnnotationTag &traffic_annotation) override
+ {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!manager_)
+ return;
+ manager_->GetURLLoaderFactory()->CreateLoaderAndStart(
+ std::move(receiver), request_id, options, url_request,
+ std::move(client), traffic_annotation);
+ }
+
+ void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) override
+ {
+ if (!manager_)
+ return;
+ manager_->GetURLLoaderFactory()->Clone(std::move(receiver));
+ }
+
+ // SharedURLLoaderFactory implementation:
+ std::unique_ptr<network::PendingSharedURLLoaderFactory> Clone() override
+ {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return std::make_unique<network::CrossThreadPendingSharedURLLoaderFactory>(this);
+ }
+
+ void Shutdown() { manager_ = nullptr; }
+
+private:
+ friend class base::RefCounted<URLLoaderFactoryForSystem>;
+ ~URLLoaderFactoryForSystem() override {}
+
+ SEQUENCE_CHECKER(sequence_checker_);
+ SystemNetworkContextManager *manager_;
+};
+
+network::mojom::NetworkContext *SystemNetworkContextManager::GetContext()
+{
+ if (!network_service_network_context_ ||
+ !network_service_network_context_.is_connected()) {
+ // 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_.is_connected()) {
+ 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(url_loader_factory_.BindNewPipeAndPassReceiver(), std::move(params));
+ return url_loader_factory_.get();
+}
+
+scoped_refptr<network::SharedURLLoaderFactory> SystemNetworkContextManager::GetSharedURLLoaderFactory()
+{
+ return shared_url_loader_factory_;
+}
+
+// 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)
+{
+ bool is_quic_force_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableQuic);
+ // Disable QUIC globally
+ if (!is_quic_force_enabled)
+ network_service->DisableQuic();
+
+ network_service->SetUpHttpAuth(CreateHttpAuthStaticParams());
+ network_service->ConfigureHttpAuthPrefs(CreateHttpAuthDynamicParams());
+
+#if BUILDFLAG(IS_WIN)
+ if (content::IsOutOfProcessNetworkService())
+ network_service->SetEncryptionKey(OSCrypt::GetRawEncryptionKey());
+#endif
+
+ // Configure the Certificate Transparency logs.
+ std::vector<std::pair<std::string, base::Time>> disqualified_logs =
+ certificate_transparency::GetDisqualifiedLogs();
+ std::vector<network::mojom::CTLogInfoPtr> log_list_mojo;
+ for (const auto &ct_log : certificate_transparency::GetKnownLogs()) {
+ 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->id = crypto::SHA256HashString(log_info->public_key);
+ log_info->name = ct_log.log_name;
+ log_info->current_operator = ct_log.current_operator;
+
+ auto it = std::lower_bound(
+ std::begin(disqualified_logs), std::end(disqualified_logs), log_info->id,
+ [](const auto& disqualified_log, const std::string& log_id) {
+ return disqualified_log.first < log_id;
+ });
+ if (it != std::end(disqualified_logs) && it->first == log_info->id)
+ log_info->disqualified_at = it->second;
+
+ for (size_t i = 0; i < ct_log.previous_operators_length; i++) {
+ const auto& op = ct_log.previous_operators[i];
+ network::mojom::PreviousOperatorEntryPtr previous_operator =
+ network::mojom::PreviousOperatorEntry::New();
+ previous_operator->name = op.name;
+ previous_operator->end_time = op.end_time;
+ log_info->previous_operators.push_back(std::move(previous_operator));
+ }
+
+ log_list_mojo.push_back(std::move(log_info));
+ }
+ network_service->UpdateCtLogList(std::move(log_list_mojo), base::DoNothing());
+
+ // The system NetworkContext is created first
+ network_service_network_context_.reset();
+ network_service->CreateNetworkContext(
+ network_service_network_context_.BindNewPipeAndPassReceiver(),
+ CreateNetworkContextParams());
+
+ // Handle --explicitly-allowed-ports
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kExplicitlyAllowedPorts)) {
+ std::vector<uint16_t> explicitly_allowed_network_ports;
+ std::string switch_value =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
+ const auto split = base::SplitStringPiece(switch_value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const auto &piece : split) {
+ int port;
+ if (!base::StringToInt(piece, &port))
+ continue;
+ if (!net::IsPortValid(port))
+ continue;
+ explicitly_allowed_network_ports.push_back(static_cast<uint16_t>(port));
+ }
+
+ network_service->SetExplicitlyAllowedPorts(explicitly_allowed_network_ports);
+ }
+
+ // The network service is a singleton that can be reinstantiated for different reasons,
+ // e.g., when the network service crashes. Therefore, we configure the stub host
+ // resolver of the network service here, each time it is instantiated, with our global
+ // DNS-Over-HTTPS settings. This ensures that the global settings don't get lost
+ // on reinstantiation and are in effect upon initial instantiation.
+ QWebEngineGlobalSettingsPrivate::instance()->configureStubHostResolver();
+}
+
+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->symantec_enforcement_disabled = true;
+}
+
+void SystemNetworkContextManager::ConfigureDefaultNetworkContextParams(network::mojom::NetworkContextParams *network_context_params,
+ cert_verifier::mojom::CertVerifierCreationParams *cert_verifier_creation_params)
+{
+ network_context_params->enable_brotli = true;
+
+ // 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();
+
+ 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();
+ }
+ }
+#if BUILDFLAG(IS_WIN)
+ if (command_line.HasSwitch(switches::kUseSystemProxyResolver)) {
+ network_context_params->windows_system_proxy_resolver =
+ ChromeMojoProxyResolverWin::CreateWithSelfOwnedReceiver();
+ }
+#endif
+ // 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);
+}
+
+network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateNetworkContextParams()
+{
+ // TODO(mmenke): Set up parameters here (in memory cookie store, etc).
+ network::mojom::NetworkContextParamsPtr network_context_params = network::mojom::NetworkContextParams::New();
+ cert_verifier::mojom::CertVerifierCreationParamsPtr
+ cert_verifier_creation_params = cert_verifier::mojom::CertVerifierCreationParams::New();
+ ConfigureDefaultNetworkContextParams(network_context_params.get(), cert_verifier_creation_params.get());
+
+ network_context_params->enable_referrers = false;
+
+ network_context_params->http_cache_enabled = false;
+
+ proxy_config_monitor_.AddToNetworkContextParams(network_context_params.get());
+
+ network_context_params->cert_verifier_params =
+ content::GetCertVerifierParams(std::move(cert_verifier_creation_params));
+ return network_context_params;
+}
+
+bool isValidTemplates(std::string templates)
+{
+ absl::optional<net::DnsOverHttpsConfig> dnsOverHttpsConfig =
+ net::DnsOverHttpsConfig::FromString(templates);
+ return dnsOverHttpsConfig.has_value();
+}
+
+
+void configureStubHostResolver(QWebEngineGlobalSettings::SecureDnsMode dnsMode,
+ std::string dnsOverHttpsTemplates, bool insecureDnsClientEnabled,
+ bool additionalInsecureDnsTypesEnabled)
+{
+ if (content::IsNetworkServiceCreated()) {
+ network::mojom::NetworkService *networkService = content::GetNetworkService();
+ if (networkService) {
+ absl::optional<net::DnsOverHttpsConfig> dohConfig = dnsOverHttpsTemplates.empty()
+ ? net::DnsOverHttpsConfig()
+ : net::DnsOverHttpsConfig::FromString(dnsOverHttpsTemplates);
+ networkService->ConfigureStubHostResolver(insecureDnsClientEnabled,
+ net::SecureDnsMode(dnsMode), *dohConfig,
+ additionalInsecureDnsTypesEnabled);
+ }
+ }
+}
+
+} // namespace QtWebEngineCore
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..d56bdab78
--- /dev/null
+++ b/src/core/net/system_network_context_manager.h
@@ -0,0 +1,121 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// 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 "services/network/public/mojom/network_context.mojom.h"
+#include "services/network/public/mojom/network_service.mojom-forward.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "net/proxy_config_monitor.h"
+
+namespace cert_verifier {
+namespace mojom {
+class CertVerifierCreationParams;
+}}
+
+namespace network {
+namespace mojom {
+class URLLoaderFactory;
+}
+class SharedURLLoaderFactory;
+} // namespace network
+
+namespace QtWebEngineCore {
+
+// 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();
+
+ // 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);
+
+ // Configures the default set of parameters for the network context.
+ void ConfigureDefaultNetworkContextParams(network::mojom::NetworkContextParams *,
+ cert_verifier::mojom::CertVerifierCreationParams *);
+
+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.
+ mojo::Remote<network::mojom::NetworkContext> network_service_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_;
+ mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_;
+
+ ProxyConfigMonitor proxy_config_monitor_;
+};
+
+} // namespace QtWebEngineCore
+
+#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_context_getter_qt.h b/src/core/net/url_request_context_getter_qt.h
deleted file mode 100644
index b6135cb16..000000000
--- a/src/core/net/url_request_context_getter_qt.h
+++ /dev/null
@@ -1,61 +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_CONTEXT_GETTER_QT_H
-#define URL_REQUEST_CONTEXT_GETTER_QT_H
-
-#include "net/url_request/url_request_context_getter.h"
-
-namespace QtWebEngineCore {
-
-class ProfileIODataQt;
-
-class URLRequestContextGetterQt : public net::URLRequestContextGetter {
-public:
- URLRequestContextGetterQt(ProfileIODataQt *data);
- net::URLRequestContext *GetURLRequestContext() override;
- scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const override;
-private:
- virtual ~URLRequestContextGetterQt();
- ProfileIODataQt *m_profileIOData;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // URL_REQUEST_CONTEXT_GETTER_QT_H
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 dd213d4f8..000000000
--- a/src/core/net/url_request_custom_job.cpp
+++ /dev/null
@@ -1,242 +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))
- , m_httpStatusCode(500)
-{
-}
-
-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_corsEnabled)
- return;
-
- std::string headers;
- headers += base::StringPrintf("HTTP/1.1 %i OK\n", m_httpStatusCode);
- if (m_redirect.is_valid())
- headers += base::StringPrintf("Location: %s\n", m_redirect.spec().c_str());
- 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.c_str(), headers.size()));
-}
-
-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 e1e8e9fba..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;
- int m_httpStatusCode;
-
- 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 b5a7a55a7..fb6b605a4 100644
--- a/src/core/net/url_request_custom_job_delegate.cpp
+++ b/src/core/net/url_request_custom_job_delegate.cpp
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "url_request_custom_job_delegate.h"
#include "url_request_custom_job_proxy.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/net_errors.h"
@@ -51,16 +14,16 @@
namespace QtWebEngineCore {
-URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
- const QUrl &url,
- const QByteArray &method,
- const QUrl &initiatorOrigin,
- const QMap<QByteArray, QByteArray> &headers)
- : m_proxy(proxy),
- m_request(url),
- m_method(method),
- m_initiatorOrigin(initiatorOrigin),
- m_requestHeaders(headers)
+URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(
+ URLRequestCustomJobProxy *proxy, const QUrl &url, const QByteArray &method,
+ const QUrl &initiatorOrigin, const QMap<QByteArray, QByteArray> &headers,
+ network::ResourceRequestBody *requestBody)
+ : m_proxy(proxy)
+ , m_request(url)
+ , m_method(method)
+ , m_initiatorOrigin(initiatorOrigin)
+ , m_requestHeaders(headers)
+ , m_resourceRequestBody(ResourceRequestBody(requestBody))
{
}
@@ -88,36 +51,52 @@ QMap<QByteArray, QByteArray> URLRequestCustomJobDelegate::requestHeaders() const
return m_requestHeaders;
}
+QIODevice *URLRequestCustomJobDelegate::requestBody()
+{
+ return &m_resourceRequestBody;
+}
+
+void URLRequestCustomJobDelegate::setAdditionalResponseHeaders(
+ const QMultiMap<QByteArray, QByteArray> &additionalResponseHeaders)
+{
+ m_additionalResponseHeaders = additionalResponseHeaders;
+}
+
void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice *device)
{
- if (device)
+ if (!device)
+ m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::succeed, m_proxy));
+ else {
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,
+ std::move(m_additionalResponseHeaders)));
+ }
}
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)
{
- int net_error = 0;
+ int net_error = 0;
switch (error) {
case NoError:
break;
@@ -138,8 +117,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_delegate.h b/src/core/net/url_request_custom_job_delegate.h
index 0ab1a82c7..63db46464 100644
--- a/src/core/net/url_request_custom_job_delegate.h
+++ b/src/core/net/url_request_custom_job_delegate.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -53,6 +17,7 @@
#include "base/memory/ref_counted.h"
#include "qtwebenginecoreglobal_p.h"
+#include "resource_request_body_qt.h"
#include <QMap>
#include <QObject>
@@ -60,11 +25,16 @@
QT_FORWARD_DECLARE_CLASS(QIODevice)
+namespace network {
+class ResourceRequestBody;
+}
+
namespace QtWebEngineCore {
class URLRequestCustomJobProxy;
-class Q_WEBENGINECORE_PRIVATE_EXPORT URLRequestCustomJobDelegate : public QObject {
+class Q_WEBENGINECORE_EXPORT URLRequestCustomJobDelegate : public QObject
+{
Q_OBJECT
public:
~URLRequestCustomJobDelegate();
@@ -82,9 +52,12 @@ public:
QByteArray method() const;
QUrl initiator() const;
QMap<QByteArray, QByteArray> requestHeaders() const;
+ QIODevice *requestBody();
+ void
+ setAdditionalResponseHeaders(const QMultiMap<QByteArray, QByteArray> &additionalResponseHeaders);
void reply(const QByteArray &contentType, QIODevice *device);
- void redirect(const QUrl& url);
+ void redirect(const QUrl &url);
void abort();
void fail(Error);
@@ -92,11 +65,10 @@ private Q_SLOTS:
void slotReadyRead();
private:
- URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
- const QUrl &url,
- const QByteArray &method,
- const QUrl &initiatorOrigin,
- const QMap<QByteArray, QByteArray> &requestHeaders);
+ URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy, const QUrl &url,
+ const QByteArray &method, const QUrl &initiatorOrigin,
+ const QMap<QByteArray, QByteArray> &requestHeaders,
+ network::ResourceRequestBody *requestBody);
friend class URLRequestCustomJobProxy;
scoped_refptr<URLRequestCustomJobProxy> m_proxy;
@@ -104,6 +76,8 @@ private:
QByteArray m_method;
QUrl m_initiatorOrigin;
const QMap<QByteArray, QByteArray> m_requestHeaders;
+ QMultiMap<QByteArray, QByteArray> m_additionalResponseHeaders;
+ ResourceRequestBody m_resourceRequestBody;
};
} // namespace
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index b9ccf7ea4..54faddc62 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -1,65 +1,31 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#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 "services/network/public/cpp/resource_request_body.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()
@@ -75,89 +41,99 @@ void URLRequestCustomJobProxy::release()
}
}
-// Fix me: this is never used
-/*
-void URLRequestCustomJobProxy::setReplyCharset(const std::string &charset)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!m_job)
- return;
- m_job->m_charset = charset;
-}
-*/
-void URLRequestCustomJobProxy::reply(std::string mimeType, QIODevice *device)
+void URLRequestCustomJobProxy::reply(std::string contentType, QIODevice *device,
+ QMultiMap<QByteArray, QByteArray> additionalResponseHeaders)
{
- 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());
+ QByteArray qcontentType = QByteArray::fromStdString(contentType).toLower();
+ const int sidx = qcontentType.indexOf(';');
+ if (sidx > 0) {
+ const int cidx = qcontentType.indexOf("charset=", sidx);
+ if (cidx > 0) {
+ m_client->m_charset = qcontentType.mid(cidx + 8).trimmed().toStdString();
+ qcontentType = qcontentType.first(sidx);
+ } else {
+ qWarning() << "QWebEngineUrlRequestJob::reply(): Unrecognized content-type format with ';'" << qcontentType;
+ }
+ }
+ m_client->m_mimeType = qcontentType.trimmed().toStdString();
+ m_client->m_device = device;
+ m_client->m_additionalResponseHeaders = std::move(additionalResponseHeaders);
+ if (m_client->m_device && !m_client->m_device->isReadable())
+ m_client->m_device->open(QIODevice::ReadOnly);
+
+ if (m_client->m_device && 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;
+ if (deviceSize > 0)
+ m_client->notifyExpectedContentSize(deviceSize);
+
+ if (m_client->m_device && m_client->m_device->isReadable()) {
m_started = true;
- m_job->m_httpStatusCode = 200;
- 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_job->m_httpStatusCode = 303;
+ 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;
- m_job->m_httpStatusCode = 500;
- 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::succeed()
+{
+ m_client->notifySuccess();
+}
+
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,
- base::Optional<url::Origin> initiator,
- std::map<std::string, std::string> headers)
+ absl::optional<url::Origin> initiator,
+ std::map<std::string, std::string> headers,
+ scoped_refptr<network::ResourceRequestBody> requestBody)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Q_ASSERT(!m_delegate);
@@ -175,10 +151,9 @@ void URLRequestCustomJobProxy::initialize(GURL url, std::string method,
qHeaders.insert(toQByteArray(it->first), toQByteArray(it->second));
if (schemeHandler) {
- m_delegate = new URLRequestCustomJobDelegate(this, toQt(url),
- QByteArray::fromStdString(method),
- initiatorOrigin,
- qHeaders);
+ m_delegate =
+ new URLRequestCustomJobDelegate(this, toQt(url), QByteArray::fromStdString(method),
+ initiatorOrigin, qHeaders, requestBody.get());
QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate);
schemeHandler->requestStarted(requestJob);
}
diff --git a/src/core/net/url_request_custom_job_proxy.h b/src/core/net/url_request_custom_job_proxy.h
index aa55db07c..c03992411 100644
--- a/src/core/net/url_request_custom_job_proxy.h
+++ b/src/core/net/url_request_custom_job_proxy.h
@@ -1,53 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef URL_REQUEST_CUSTOM_JOB_PROXY_H_
#define URL_REQUEST_CUSTOM_JOB_PROXY_H_
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
+#include "base/task/sequenced_task_runner.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
#include "url/origin.h"
#include <QtCore/QPointer>
+#include <QMap>
+#include <QByteArray>
QT_FORWARD_DECLARE_CLASS(QIODevice)
+namespace network {
+class ResourceRequestBody;
+}
+
namespace QtWebEngineCore {
class URLRequestCustomJob;
@@ -56,33 +26,57 @@ class ProfileAdapter;
// Used to comunicate between URLRequestCustomJob living on the IO thread
// and URLRequestCustomJobDelegate living on the UI thread.
-class URLRequestCustomJobProxy
- : public base::RefCountedThreadSafe<URLRequestCustomJobProxy> {
+class URLRequestCustomJobProxy : public base::RefCountedThreadSafe<URLRequestCustomJobProxy>
+{
public:
- URLRequestCustomJobProxy(URLRequestCustomJob *job,
+ class Client {
+ public:
+ std::string m_mimeType;
+ std::string m_charset;
+ QMultiMap<QByteArray, QByteArray> m_additionalResponseHeaders;
+ 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 notifySuccess() = 0;
+ virtual void notifyReadyRead() = 0;
+ virtual base::SequencedTaskRunner *taskRunner() = 0;
+ };
+
+ URLRequestCustomJobProxy(Client *client,
const std::string &scheme,
QPointer<ProfileAdapter> profileAdapter);
~URLRequestCustomJobProxy();
// Called from URLRequestCustomJobDelegate via post:
//void setReplyCharset(const std::string &);
- void reply(std::string mimeType, QIODevice *device);
+ void reply(std::string mimeType, QIODevice *device,
+ QMultiMap<QByteArray, QByteArray> additionalResponseHeaders);
void redirect(GURL url);
void abort();
void fail(int error);
+ void succeed();
void release();
- void initialize(GURL url, std::string method, base::Optional<url::Origin> initiatorOrigin, std::map<std::string, std::string> headers);
+ void initialize(GURL url, std::string method, absl::optional<url::Origin> initiatorOrigin,
+ std::map<std::string, std::string> headers,
+ scoped_refptr<network::ResourceRequestBody> requestBody);
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::SequencedTaskRunner> 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 e37ad35bc..000000000
--- a/src/core/net/url_request_notification.cpp
+++ /dev/null
@@ -1,194 +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) {
- 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;
-}
-
-}
diff --git a/src/core/net/url_request_notification.h b/src/core/net/url_request_notification.h
deleted file mode 100644
index 1d9acf12f..000000000
--- a/src/core/net/url_request_notification.h
+++ /dev/null
@@ -1,85 +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$
-**
-****************************************************************************/
-
-#ifndef URL_REQUEST_NOTIFIACTION_H
-#define URL_REQUEST_NOTIFIACTION_H
-
-#include "content/public/browser/resource_request_info.h"
-#include "net/base/completion_once_callback.h"
-#include "qwebengineurlrequestinfo.h"
-#include <QPointer>
-
-class GURL;
-
-namespace net {
-class URLRequest;
-}
-
-namespace QtWebEngineCore {
-
-class ProfileAdapter;
-class ProfileIoDataQt;
-
-// Notifies WebContentsAdapterClient of a new URLRequest.
-class URLRequestNotification {
-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);
-
-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;
-};
-}
-#endif
diff --git a/src/core/net/version_ui_qt.cpp b/src/core/net/version_ui_qt.cpp
new file mode 100644
index 000000000..61a89596a
--- /dev/null
+++ b/src/core/net/version_ui_qt.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "version_ui_qt.h"
+#include "api/qtwebenginecoreglobal.h"
+#include "build/build_config.h"
+#include "base/command_line.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/browser/profiles/profile.h"
+#include "qtwebengine/grit/qt_webengine_resources.h"
+#include "services/network/public/cpp/content_security_policy/content_security_policy.h"
+
+namespace {
+const char kQtWebEngineVersion[] = "qtwebengine_version";
+const char kQtWebEngineChromiumVersion[] = "qtwebengine_chromium_version";
+const char kQtWebEngineChromiumSecurityPatchVersion[] =
+ "qtwebengine_chromium_security_patch_version";
+const char kCommandLine[] = "command_line";
+const char kQtVersionCSS[] = "qt_version.css";
+const char kQtLogo[] = "images/qt.png";
+const char kQtWebEngineLogo[] = "images/qtwebengine.png";
+}
+
+VersionUIQt::VersionUIQt(content::WebUI *web_ui) : content::WebUIController(web_ui)
+{
+
+ Profile *profile = Profile::FromWebUI(web_ui);
+ content::WebUIDataSource *html_source =
+ content::WebUIDataSource::CreateAndAdd(profile, chrome::kChromeUIVersionQtHost);
+ html_source->OverrideContentSecurityPolicy(
+ network::mojom::CSPDirectiveName::ScriptSrc,
+ "script-src chrome://resources 'self' 'unsafe-inline';");
+ html_source->SetDefaultResource(IDR_VERSION_UI_QT_HTML);
+ html_source->AddResourcePath(kQtVersionCSS, IDR_VERSION_UI_QT_CSS);
+ html_source->AddResourcePath(kQtLogo, IDR_QT_LOGO);
+ html_source->AddResourcePath(kQtWebEngineLogo, IDR_QTWEBENGINE_LOGO);
+
+ html_source->AddString(kQtWebEngineVersion, qWebEngineVersion());
+ html_source->AddString(kQtWebEngineChromiumVersion, qWebEngineChromiumVersion());
+ html_source->AddString(kQtWebEngineChromiumSecurityPatchVersion,
+ qWebEngineChromiumSecurityPatchVersion());
+#if BUILDFLAG(IS_WIN)
+ html_source->AddString(
+ kCommandLine,
+ base::AsString16(base::CommandLine::ForCurrentProcess()->GetCommandLineString()));
+#else
+ std::string command_line;
+ typedef std::vector<std::string> ArgvList;
+ const ArgvList &argv = base::CommandLine::ForCurrentProcess()->argv();
+ for (auto iter = argv.begin(); iter != argv.end(); iter++)
+ command_line += " " + *iter;
+ html_source->AddString(kCommandLine, command_line);
+#endif
+}
+
+VersionUIQt::~VersionUIQt() { }
diff --git a/src/core/net/version_ui_qt.h b/src/core/net/version_ui_qt.h
new file mode 100644
index 000000000..1fe8ef9e0
--- /dev/null
+++ b/src/core/net/version_ui_qt.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+//
+// 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 VERSION_UI_QT_H_
+#define VERSION_UI_QT_H_
+
+#include "build/build_config.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+class VersionUIQt : public content::WebUIController
+{
+public:
+ explicit VersionUIQt(content::WebUI *web_ui);
+ ~VersionUIQt() override;
+
+ VersionUIQt(const VersionUIQt &) = delete;
+ VersionUIQt &operator=(const VersionUIQt &) = delete;
+};
+
+#endif // VERSION_UI_QT_H
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index 92bb8854f..2acd05cae 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Based on chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
@@ -44,39 +8,37 @@
#include "webui_controller_factory_qt.h"
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "build_config_qt.h"
+#include "devtools_frontend_qt.h"
+#include "base/functional/bind.h"
#include "build/build_config.h"
#include "chrome/browser/accessibility/accessibility_ui.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/devtools_ui.h"
-#include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
+#include "chrome/browser/ui/webui/device_log/device_log_ui.h"
+#include "chrome/browser/ui/webui/devtools/devtools_ui.h"
+#include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
+#include "chrome/browser/ui/webui/user_actions/user_actions_ui.h"
#include "chrome/common/url_constants.h"
-#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
-#include "content/public/common/content_client.h"
#include "content/public/common/url_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "media/media_buildflags.h"
-#include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
-#include "ui/web_dialogs/web_dialog_ui.h"
#include "url/gurl.h"
+#include "version_ui_qt.h"
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-#include "chrome/browser/ui/webui/sandbox_internals_ui.h"
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
+#include "chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h"
+#endif
+
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+#include "chrome/browser/ui/webui/media/webrtc_logs_ui.h"
#endif
// The Following WebUIs are disabled because they currently doesn't build
// or doesn't work, but would be interesting for us if they did:
// #include "chrome/browser/ui/webui/inspect_ui.h"
-// #include "chrome/browser/ui/webui/user_actions/user_actions_ui.h"
-
-// #if BUILDFLAG(ENABLE_WEBRTC)
-// #include "chrome/browser/ui/webui/media/webrtc_logs_ui.h"
-// #endif
// #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
// #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
@@ -109,7 +71,7 @@ typedef std::unique_ptr<WebUIController> (*WebUIFactoryFunction)(WebUI *web_ui,
// Template for defining WebUIFactoryFunction.
template<class T>
-std::unique_ptr<WebUIController> NewWebUI(WebUI *web_ui, const GURL &/*url*/)
+std::unique_ptr<WebUIController> NewWebUI(WebUI *web_ui, const GURL & /*url*/)
{
return std::unique_ptr<WebUIController>(new T(web_ui));
}
@@ -119,26 +81,35 @@ std::unique_ptr<WebUIController> NewWebUI(WebUI *web_ui, const GURL &/*url*/)
// with it.
WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, const GURL &url)
{
+ Q_UNUSED(web_ui);
+ Q_UNUSED(profile);
// This will get called a lot to check all URLs, so do a quick check of other
// schemes to filter out most URLs.
if (!content::HasWebUIScheme(url))
- return NULL;
+ return nullptr;
// We must compare hosts only since some of the Web UIs append extra stuff
// after the host name.
- if (url.host() == chrome::kChromeUIQuotaInternalsHost)
- return &NewWebUI<QuotaInternalsUI>;
+ if (url.host_piece() == chrome::kChromeUINetInternalsHost)
+ return &NewWebUI<NetInternalsUI>;
if (url.SchemeIs(content::kChromeDevToolsScheme)) {
-// if (!DevToolsUIBindings::IsValidFrontendURL(url))
-// return nullptr;
+ if (!QtWebEngineCore::DevToolsFrontendQt::IsValidFrontendURL(url))
+ return nullptr;
return &NewWebUI<DevToolsUI>;
}
- if (url.host() == chrome::kChromeUIAccessibilityHost)
+ if (url.host_piece() == chrome::kChromeUIAccessibilityHost)
return &NewWebUI<AccessibilityUI>;
-// if (url.host_piece() == chrome::kChromeUIUserActionsHost)
-// return &NewWebUI<UserActionsUI>;
+ if (url.host_piece() == chrome::kChromeUIUserActionsHost)
+ return &NewWebUI<UserActionsUI>;
+
+ if (url.host_piece() == chrome::kChromeUIDeviceLogHost)
+ return &NewWebUI<chromeos::DeviceLogUI>;
+
+ if (url.host_piece() == chrome::kChromeUIVersionQtHost)
+ return &NewWebUI<VersionUIQt>;
+
// if (url.host_piece() == chrome::kChromeUIInspectHost)
// return &NewWebUI<InspectUI>;
//
@@ -150,21 +121,17 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
// if (url.host_piece() == chrome::kChromeUIExtensionsFrameHost)
// return &NewWebUI<extensions::ExtensionsUI>;
//#endif
-//#if BUILDFLAG(ENABLE_PLUGINS)
-// if (url.host_piece() == chrome::kChromeUIFlashHost)
-// return &NewWebUI<FlashUI>;
-//#endif
//#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
// if (url.host_piece() == chrome::kChromeUIPrintHost &&
// !profile->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled)) {
// return &NewWebUI<PrintPreviewUI>;
// }
//#endif
-//#if BUILDFLAG(ENABLE_WEBRTC)
-// if (url.host_piece() == chrome::kChromeUIWebRtcLogsHost)
-// return &NewWebUI<WebRtcLogsUI>;
-//#endif
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ if (url.host_piece() == chrome::kChromeUIWebRtcLogsHost)
+ return &NewWebUI<WebRtcLogsUI>;
+#endif
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
if (url.host_piece() == chrome::kChromeUISandboxHost)
return &NewWebUI<SandboxInternalsUI>;
#endif
@@ -175,24 +142,19 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
namespace QtWebEngineCore {
-WebUI::TypeID WebUIControllerFactoryQt::GetWebUIType(content::BrowserContext *browser_context, const GURL &url) const
+WebUI::TypeID WebUIControllerFactoryQt::GetWebUIType(content::BrowserContext *browser_context, const GURL &url)
{
Profile *profile = Profile::FromBrowserContext(browser_context);
WebUIFactoryFunction function = GetWebUIFactoryFunction(nullptr, profile, url);
return function ? reinterpret_cast<WebUI::TypeID>(function) : WebUI::kNoWebUI;
}
-bool WebUIControllerFactoryQt::UseWebUIForURL(content::BrowserContext *browser_context, const GURL &url) const
+bool WebUIControllerFactoryQt::UseWebUIForURL(content::BrowserContext *browser_context, const GURL &url)
{
return GetWebUIType(browser_context, url) != WebUI::kNoWebUI;
}
-bool WebUIControllerFactoryQt::UseWebUIBindingsForURL(content::BrowserContext *browser_context, const GURL &url) const
-{
- return UseWebUIForURL(browser_context, url);
-}
-
-std::unique_ptr<WebUIController> WebUIControllerFactoryQt::CreateWebUIControllerForURL(WebUI *web_ui, const GURL &url) const
+std::unique_ptr<WebUIController> WebUIControllerFactoryQt::CreateWebUIControllerForURL(WebUI *web_ui, const GURL &url)
{
Profile *profile = Profile::FromWebUI(web_ui);
WebUIFactoryFunction function = GetWebUIFactoryFunction(web_ui, profile, url);
diff --git a/src/core/net/webui_controller_factory_qt.h b/src/core/net/webui_controller_factory_qt.h
index 4038e6538..22219dd5a 100644
--- a/src/core/net/webui_controller_factory_qt.h
+++ b/src/core/net/webui_controller_factory_qt.h
@@ -1,66 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_UI_CONTROLLER_FACTORY_QT_H_
#define WEB_UI_CONTROLLER_FACTORY_QT_H_
-#include "base/macros.h"
#include "base/memory/singleton.h"
-#include "components/favicon_base/favicon_callback.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_controller_factory.h"
-#include "ui/base/layout.h"
-
-class Profile;
-
-namespace base {
-class RefCountedMemory;
-}
namespace QtWebEngineCore {
-class WebUIControllerFactoryQt : public content::WebUIControllerFactory {
+class WebUIControllerFactoryQt : public content::WebUIControllerFactory
+{
public:
- content::WebUI::TypeID GetWebUIType(content::BrowserContext *browserContext, const GURL &url) const override;
- bool UseWebUIForURL(content::BrowserContext *browserContext, const GURL &url) const override;
- bool UseWebUIBindingsForURL(content::BrowserContext *browserContext, const GURL &url) const override;
- std::unique_ptr<content::WebUIController> CreateWebUIControllerForURL(content::WebUI *webUi, const GURL &url) const override;
+ content::WebUI::TypeID GetWebUIType(content::BrowserContext *browserContext, const GURL &url) override;
+ bool UseWebUIForURL(content::BrowserContext *browserContext, const GURL &url) override;
+ std::unique_ptr<content::WebUIController> CreateWebUIControllerForURL(content::WebUI *webUi, const GURL &url) override;
static WebUIControllerFactoryQt *GetInstance();
@@ -70,10 +25,8 @@ protected:
private:
friend struct base::DefaultSingletonTraits<WebUIControllerFactoryQt>;
-
- DISALLOW_COPY_AND_ASSIGN(WebUIControllerFactoryQt);
};
} // namespace QtWebEngineCore
-#endif // WEB_UI_CONTROLLER_FACTORY_QT_H_
+#endif // WEB_UI_CONTROLLER_FACTORY_QT_H_