summaryrefslogtreecommitdiffstats
path: root/src/core/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/net')
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp252
-rw-r--r--src/core/net/cookie_monster_delegate_qt.h102
-rw-r--r--src/core/net/custom_protocol_handler.cpp62
-rw-r--r--src/core/net/custom_protocol_handler.h77
-rw-r--r--src/core/net/network_delegate_qt.cpp390
-rw-r--r--src/core/net/network_delegate_qt.h95
-rw-r--r--src/core/net/proxy_config_service_qt.cpp202
-rw-r--r--src/core/net/proxy_config_service_qt.h92
-rw-r--r--src/core/net/qrc_protocol_handler_qt.cpp63
-rw-r--r--src/core/net/qrc_protocol_handler_qt.h70
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.cpp147
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.h82
-rw-r--r--src/core/net/url_request_context_getter_qt.cpp648
-rw-r--r--src/core/net/url_request_context_getter_qt.h153
-rw-r--r--src/core/net/url_request_custom_job.cpp199
-rw-r--r--src/core/net/url_request_custom_job.h90
-rw-r--r--src/core/net/url_request_custom_job_delegate.cpp138
-rw-r--r--src/core/net/url_request_custom_job_delegate.h96
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp176
-rw-r--r--src/core/net/url_request_custom_job_proxy.h90
-rw-r--r--src/core/net/url_request_qrc_job_qt.cpp133
-rw-r--r--src/core/net/url_request_qrc_job_qt.h76
-rw-r--r--src/core/net/webui_controller_factory_qt.cpp219
-rw-r--r--src/core/net/webui_controller_factory_qt.h79
24 files changed, 3731 insertions, 0 deletions
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
new file mode 100644
index 000000000..abc386204
--- /dev/null
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** 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 "cookie_monster_delegate_qt.h"
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/cookies/cookie_util.h"
+
+#include "api/qwebenginecookiestore.h"
+#include "api/qwebenginecookiestore_p.h"
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+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());
+}
+
+static void onSetCookieCallback(QWebEngineCookieStorePrivate *client, qint64 callbackId, bool success) {
+
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&QWebEngineCookieStorePrivate::onSetCallbackResult, base::Unretained(client), callbackId, success));
+}
+
+static void onDeleteCookiesCallback(QWebEngineCookieStorePrivate *client, qint64 callbackId, uint numCookies) {
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&QWebEngineCookieStorePrivate::onDeleteCallbackResult, base::Unretained(client), callbackId, numCookies));
+}
+
+static void onGetAllCookiesCallback(QWebEngineCookieStorePrivate *client, qint64 callbackId, const net::CookieList& cookies) {
+ QByteArray rawCookies;
+ for (auto&& cookie: cookies)
+ rawCookies += toQt(cookie).toRawForm() % QByteArrayLiteral("\n");
+
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&QWebEngineCookieStorePrivate::onGetAllCallbackResult, base::Unretained(client), callbackId, rawCookies));
+}
+
+CookieMonsterDelegateQt::CookieMonsterDelegateQt()
+ : m_client(0)
+ , m_cookieMonster(nullptr)
+{
+}
+
+CookieMonsterDelegateQt::~CookieMonsterDelegateQt()
+{
+
+}
+
+void CookieMonsterDelegateQt::AddStore(net::CookieStore *store)
+{
+ std::unique_ptr<net::CookieStore::CookieChangedSubscription> sub =
+ store->AddCallbackForAllChanges(
+ base::Bind(&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;
+}
+
+void CookieMonsterDelegateQt::getAllCookies(quint64 callbackId)
+{
+ net::CookieMonster::GetCookieListCallback callback = base::Bind(&onGetAllCookiesCallback, m_client->d_func(), callbackId);
+
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesOnIOThread, this, std::move(callback)));
+}
+
+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)
+{
+ Q_ASSERT(hasCookieMonster());
+ Q_ASSERT(m_client);
+
+ net::CookieStore::SetCookiesCallback callback;
+ if (callbackId != CallbackDirectory::NoCallbackId)
+ callback = base::Bind(&onSetCookieCallback, m_client->d_func(), callbackId);
+
+ GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin);
+
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ 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::CookieOptions options;
+ options.set_include_httponly();
+
+ if (m_cookieMonster)
+ m_cookieMonster->SetCookieWithOptionsAsync(url, cookie_line, options, std::move(callback));
+}
+
+void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin)
+{
+ Q_ASSERT(hasCookieMonster());
+ Q_ASSERT(m_client);
+
+ GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin);
+
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteCookieOnIOThread, this,
+ gurl, cookie.name().toStdString()));
+}
+
+void CookieMonsterDelegateQt::DeleteCookieOnIOThread(const GURL& url, const std::string& cookie_name)
+{
+ if (m_cookieMonster)
+ m_cookieMonster->DeleteCookieAsync(url, cookie_name, base::Closure());
+}
+
+void CookieMonsterDelegateQt::deleteSessionCookies(quint64 callbackId)
+{
+ Q_ASSERT(hasCookieMonster());
+ Q_ASSERT(m_client);
+
+ net::CookieMonster::DeleteCallback callback = base::Bind(&onDeleteCookiesCallback, m_client->d_func(), callbackId);
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteSessionCookiesOnIOThread, this, std::move(callback)));
+}
+
+void CookieMonsterDelegateQt::DeleteSessionCookiesOnIOThread(net::CookieMonster::DeleteCallback callback)
+{
+ if (m_cookieMonster)
+ m_cookieMonster->DeleteSessionCookiesAsync(std::move(callback));
+}
+
+void CookieMonsterDelegateQt::deleteAllCookies(quint64 callbackId)
+{
+ Q_ASSERT(hasCookieMonster());
+ Q_ASSERT(m_client);
+
+ net::CookieMonster::DeleteCallback callback = base::Bind(&onDeleteCookiesCallback, m_client->d_func(), callbackId);
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteAllOnIOThread, this, std::move(callback)));
+}
+
+void CookieMonsterDelegateQt::DeleteAllOnIOThread(net::CookieMonster::DeleteCallback callback)
+{
+ if (m_cookieMonster)
+ m_cookieMonster->DeleteAllAsync(std::move(callback));
+}
+
+void CookieMonsterDelegateQt::setCookieMonster(net::CookieMonster* monster)
+{
+ if (monster == m_cookieMonster)
+ return;
+
+ m_subscriptions.clear();
+ if (monster)
+ AddStore(monster);
+
+ m_cookieMonster = monster;
+
+ if (!m_client)
+ return;
+
+ if (monster)
+ m_client->d_func()->processPendingUserCookies();
+ else
+ m_client->d_func()->rejectPendingUserCookies();
+}
+
+void CookieMonsterDelegateQt::setClient(QWebEngineCookieStore *client)
+{
+ m_client = client;
+
+ if (!m_client)
+ return;
+
+ m_client->d_func()->delegate = this;
+
+ if (hasCookieMonster())
+ m_client->d_func()->processPendingUserCookies();
+}
+
+bool CookieMonsterDelegateQt::canSetCookie(const QUrl &firstPartyUrl, const QByteArray &/*cookieLine*/, const QUrl &url)
+{
+ if (!m_client)
+ return true;
+
+ return m_client->d_func()->canAccessCookies(firstPartyUrl, url);
+}
+
+bool CookieMonsterDelegateQt::canGetCookies(const QUrl &firstPartyUrl, const QUrl &url)
+{
+ if (!m_client)
+ return true;
+
+ return m_client->d_func()->canAccessCookies(firstPartyUrl, url);
+}
+
+void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie, net::CookieStore::ChangeCause cause)
+{
+ if (!m_client)
+ return;
+ m_client->d_func()->onCookieChanged(toQt(cookie), cause != net::CookieStore::ChangeCause::INSERTED);
+}
+
+}
diff --git a/src/core/net/cookie_monster_delegate_qt.h b/src/core/net/cookie_monster_delegate_qt.h
new file mode 100644
index 000000000..8aceca9c9
--- /dev/null
+++ b/src/core/net/cookie_monster_delegate_qt.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** 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 COOKIE_MONSTER_DELEGATE_QT_H
+#define COOKIE_MONSTER_DELEGATE_QT_H
+
+#include "qtwebenginecoreglobal.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")
+#include "base/memory/ref_counted.h"
+#include "net/cookies/cookie_monster.h"
+QT_WARNING_POP
+
+#include <QNetworkCookie>
+#include <QPointer>
+
+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 QWEBENGINE_EXPORT CookieMonsterDelegateQt : public base::RefCountedThreadSafe<CookieMonsterDelegateQt> {
+ QPointer<QWebEngineCookieStore> m_client;
+ net::CookieMonster *m_cookieMonster;
+ std::vector<std::unique_ptr<net::CookieStore::CookieChangedSubscription>> m_subscriptions;
+public:
+ CookieMonsterDelegateQt();
+ ~CookieMonsterDelegateQt();
+
+ bool hasCookieMonster();
+
+ void setCookie(quint64 callbackId, 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 setCookieMonster(net::CookieMonster* monster);
+ void setClient(QWebEngineCookieStore *client);
+
+ bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url);
+ bool canGetCookies(const QUrl &firstPartyUrl, const QUrl &url);
+
+ void AddStore(net::CookieStore *store);
+ void OnCookieChanged(const net::CanonicalCookie &cookie, net::CookieStore::ChangeCause 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);
+};
+
+}
+
+#endif // COOKIE_MONSTER_DELEGATE_QT_H
diff --git a/src/core/net/custom_protocol_handler.cpp b/src/core/net/custom_protocol_handler.cpp
new file mode 100644
index 000000000..402df04ba
--- /dev/null
+++ b/src/core/net/custom_protocol_handler.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** 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(QWeakPointer<const BrowserContextAdapter> adapter)
+ : m_adapter(adapter)
+{
+}
+
+net::URLRequestJob *CustomProtocolHandler::MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const
+{
+ if (!networkDelegate)
+ return new net::URLRequestErrorJob(request, Q_NULLPTR, net::ERR_ACCESS_DENIED);
+
+ return new URLRequestCustomJob(request, networkDelegate, request->url().scheme(), m_adapter);
+}
+
+} // namespace
diff --git a/src/core/net/custom_protocol_handler.h b/src/core/net/custom_protocol_handler.h
new file mode 100644
index 000000000..5d3838834
--- /dev/null
+++ b/src/core/net/custom_protocol_handler.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 CUSTOM_PROTOCOL_HANDLER_H_
+#define CUSTOM_PROTOCOL_HANDLER_H_
+
+#include "qtwebenginecoreglobal.h"
+#include "net/url_request/url_request_job_factory.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QObject>
+#include <QtCore/QWeakPointer>
+
+QT_FORWARD_DECLARE_CLASS(QIODevice)
+
+namespace net {
+class NetworkDelegate;
+class URLRequestJob;
+} // namespace
+
+namespace QtWebEngineCore {
+
+class BrowserContextAdapter;
+
+// Implements a ProtocolHandler for custom URL schemes.
+// If |network_delegate_| is NULL then all file requests will fail with ERR_ACCESS_DENIED.
+class QWEBENGINE_EXPORT CustomProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
+
+public:
+ CustomProtocolHandler(QWeakPointer<const BrowserContextAdapter> adapter);
+
+ net::URLRequestJob *MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
+ QWeakPointer<const BrowserContextAdapter> m_adapter;
+};
+
+} // namespace
+
+#endif // CUSTOM_PROTOCOL_HANDLER_H_
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
new file mode 100644
index 000000000..74db51d7d
--- /dev/null
+++ b/src/core/net/network_delegate_qt.cpp
@@ -0,0 +1,390 @@
+/****************************************************************************
+**
+** 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 "browser_context_adapter.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 "cookie_monster_delegate_qt.h"
+#include "ui/base/page_transition_types.h"
+#include "url_request_context_getter_qt.h"
+#include "net/base/load_flags.h"
+#include "net/url_request/url_request.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"
+
+namespace QtWebEngineCore {
+
+WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition)
+{
+ 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;
+ }
+}
+
+namespace {
+
+QWebEngineUrlRequestInfo::ResourceType toQt(content::ResourceType resourceType)
+{
+ if (resourceType >= 0 && resourceType < content::ResourceType(QWebEngineUrlRequestInfo::ResourceTypeLast))
+ return static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType);
+ return QWebEngineUrlRequestInfo::ResourceTypeUnknown;
+}
+
+QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::NavigationType navigationType)
+{
+ return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
+}
+
+// Notifies WebContentsAdapterClient of a new URLRequest.
+class URLRequestNotification {
+public:
+ URLRequestNotification(net::URLRequest *request,
+ const QUrl &url,
+ bool isMainFrameRequest,
+ int navigationType,
+ int frameTreeNodeId,
+ const net::CompletionCallback &callback)
+ : m_request(request)
+ , m_url(url)
+ , m_isMainFrameRequest(isMainFrameRequest)
+ , m_navigationType(navigationType)
+ , m_frameTreeNodeId(frameTreeNodeId)
+ , m_callback(callback)
+ {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ m_request->SetUserData(UserData::key, std::make_unique<UserData>(this));
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&URLRequestNotification::notify, base::Unretained(this)));
+ }
+
+private:
+ // 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;
+ };
+
+ void cancel()
+ {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ // May run concurrently with notify() but we only touch m_request here.
+
+ m_request = nullptr;
+ }
+
+ void notify()
+ {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ // May run concurrently with cancel() so no peeking at m_request here.
+
+ int error = net::OK;
+ content::WebContents *webContents = content::WebContents::FromFrameTreeNodeId(m_frameTreeNodeId);
+ if (webContents) {
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ WebContentsAdapterClient *client =
+ WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client();
+ client->navigationRequested(m_navigationType,
+ m_url,
+ navigationRequestAction,
+ m_isMainFrameRequest);
+ error = net::ERR_FAILED;
+ switch (static_cast<WebContentsAdapterClient::NavigationRequestAction>(navigationRequestAction)) {
+ case WebContentsAdapterClient::AcceptRequest:
+ error = net::OK;
+ break;
+ case WebContentsAdapterClient::IgnoreRequest:
+ error = net::ERR_ABORTED;
+ break;
+ }
+ DCHECK(error != net::ERR_FAILED);
+ }
+
+ // Run the callback on the IO thread.
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&URLRequestNotification::complete, base::Unretained(this), error));
+ }
+
+ void complete(int error)
+ {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (m_request) {
+ if (m_request->status().status() != net::URLRequestStatus::CANCELED)
+ m_callback.Run(error);
+ m_request->RemoveUserData(UserData::key);
+ }
+
+ delete this;
+ }
+
+ ~URLRequestNotification() {}
+
+ net::URLRequest *m_request;
+ QUrl m_url;
+ bool m_isMainFrameRequest;
+ int m_navigationType;
+ int m_frameTreeNodeId;
+ net::CompletionCallback m_callback;
+};
+
+const char URLRequestNotification::UserData::key[] = "QtWebEngineCore::URLRequestNotification";
+
+} // namespace
+
+NetworkDelegateQt::NetworkDelegateQt(URLRequestContextGetterQt *requestContext)
+ : m_requestContextGetter(requestContext)
+{
+}
+
+int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::CompletionCallback &callback, GURL *newUrl)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ Q_ASSERT(m_requestContextGetter);
+
+ const content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request);
+
+ content::ResourceType resourceType = content::RESOURCE_TYPE_LAST_TYPE;
+ WebContentsAdapterClient::NavigationType navigationType = WebContentsAdapterClient::OtherNavigation;
+
+ if (resourceInfo) {
+ resourceType = resourceInfo->GetResourceType();
+ navigationType = pageTransitionToNavigationType(resourceInfo->GetPageTransition());
+ }
+
+ const QUrl qUrl = toQt(request->url());
+
+ QWebEngineUrlRequestInterceptor* interceptor = m_requestContextGetter->m_requestInterceptor;
+ if (interceptor) {
+ QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(toQt(resourceType),
+ toQt(navigationType),
+ qUrl,
+ toQt(request->site_for_cookies()),
+ QByteArray::fromStdString(request->method()));
+ QWebEngineUrlRequestInfo requestInfo(infoPrivate);
+ interceptor->interceptRequest(requestInfo);
+ 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)
+ request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
+ }
+
+ if (result != net::OK)
+ return result;
+ }
+ }
+
+ if (!resourceInfo)
+ return net::OK;
+
+ int frameTreeNodeId = resourceInfo->GetFrameTreeNodeId();
+ // Only intercept MAIN_FRAME and SUB_FRAME with an associated render frame.
+ if (!content::IsResourceTypeFrame(resourceType) || frameTreeNodeId == -1)
+ return net::OK;
+
+ new URLRequestNotification(
+ request,
+ qUrl,
+ resourceInfo->IsMainFrame(),
+ navigationType,
+ frameTreeNodeId,
+ callback
+ );
+
+ // 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*)
+{
+ return canSetCookies(request.site_for_cookies(), request.url(), std::string());
+}
+
+bool NetworkDelegateQt::OnCanGetCookies(const net::URLRequest& request, const net::CookieList&)
+{
+ return canGetCookies(request.site_for_cookies(), request.url());
+}
+
+bool NetworkDelegateQt::OnCanEnablePrivacyMode(const GURL &url, const GURL &site_for_cookies) const
+{
+ 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_requestContextGetter);
+ return m_requestContextGetter->m_cookieDelegate->canSetCookie(toQt(first_party), QByteArray::fromStdString(cookie_line), toQt(url));
+}
+
+bool NetworkDelegateQt::canGetCookies(const GURL &first_party, const GURL &url) const
+{
+ Q_ASSERT(m_requestContextGetter);
+ return m_requestContextGetter->m_cookieDelegate->canGetCookies(toQt(first_party), toQt(url));
+}
+
+int NetworkDelegateQt::OnBeforeStartTransaction(net::URLRequest *request, const net::CompletionCallback &callback, net::HttpRequestHeaders *headers)
+{
+ 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*, const net::CompletionCallback&, 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&, const 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::OnAreExperimentalCookieFeaturesEnabled() const
+{
+ return false;
+}
+
+bool NetworkDelegateQt::OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const
+{
+ return false;
+}
+
+bool NetworkDelegateQt::OnCanQueueReportingReport(const url::Origin& origin) const
+{
+ return false;
+}
+
+bool NetworkDelegateQt::OnCanSendReportingReport(const url::Origin& origin) const
+{
+ return false;
+}
+
+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
new file mode 100644
index 000000000..b5165d229
--- /dev/null
+++ b/src/core/net/network_delegate_qt.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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 URLRequestContextGetterQt;
+
+class NetworkDelegateQt : public net::NetworkDelegate {
+ URLRequestContextGetterQt *m_requestContextGetter;
+public:
+ NetworkDelegateQt(URLRequestContextGetterQt *requestContext);
+
+ // net::NetworkDelegate implementation
+ int OnBeforeURLRequest(net::URLRequest* request, const net::CompletionCallback& callback, GURL* newUrl) override;
+ void OnURLRequestDestroyed(net::URLRequest* request) override;
+ bool OnCanSetCookie(const net::URLRequest& request, const net::CanonicalCookie& cookie, net::CookieOptions* options) override;
+ int OnBeforeStartTransaction(net::URLRequest *request, const net::CompletionCallback &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*, const net::CompletionCallback&, 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&, const AuthCallback&, net::AuthCredentials*) override;
+ bool OnCanGetCookies(const net::URLRequest&, const net::CookieList&) override;
+ bool OnCanAccessFile(const net::URLRequest&, const base::FilePath&, const base::FilePath&) const override;
+ bool OnCanEnablePrivacyMode(const GURL&, const GURL&) const override;
+ bool OnAreExperimentalCookieFeaturesEnabled() const override;
+ bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const override;
+
+ bool OnCanQueueReportingReport(const url::Origin& origin) const override;
+ bool OnCanSendReportingReport(const url::Origin& origin) 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/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp
new file mode 100644
index 000000000..7fca18eb6
--- /dev/null
+++ b/src/core/net/proxy_config_service_qt.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+
+//================ Based on ChromeProxyConfigService =======================
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE.Chromium file.
+
+#include "proxy_config_service_qt.h"
+
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qtProxy)
+{
+ net::HostPortPair hostPortPair(qtProxy.hostName().toStdString(), qtProxy.port());
+ switch (qtProxy.type()) {
+ case QNetworkProxy::Socks5Proxy:
+ return net::ProxyServer(net::ProxyServer::SCHEME_SOCKS5, hostPortPair);
+ case QNetworkProxy::HttpProxy:
+ case QNetworkProxy::HttpCachingProxy:
+ case QNetworkProxy::FtpCachingProxy:
+ return net::ProxyServer(net::ProxyServer::SCHEME_HTTP, hostPortPair);
+ 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)
+ : m_baseService(baseService.release()),
+ m_usesSystemConfiguration(false),
+ m_registeredObserver(false)
+{
+}
+
+ProxyConfigServiceQt::~ProxyConfigServiceQt()
+{
+ if (m_registeredObserver && m_baseService.get())
+ m_baseService->RemoveObserver(this);
+}
+
+void ProxyConfigServiceQt::AddObserver(net::ProxyConfigService::Observer *observer)
+{
+ m_observers.AddObserver(observer);
+}
+
+void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *observer)
+{
+ m_observers.RemoveObserver(observer);
+}
+
+net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfig *config)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
+ m_usesSystemConfiguration = QNetworkProxyFactory::usesSystemConfiguration();
+#endif
+ if (m_usesSystemConfiguration) {
+ // Use Chromium's base service to retrieve system settings
+ net::ProxyConfig systemConfig;
+ ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET;
+ if (m_baseService.get())
+ systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
+ *config = systemConfig;
+ // make sure to get updates via OnProxyConfigChanged
+ RegisterObserver();
+ return systemAvailability;
+ }
+
+ // Use QNetworkProxy::applicationProxy settings
+ const QNetworkProxy &qtProxy = QNetworkProxy::applicationProxy();
+ if (qtProxy == m_qtApplicationProxy && !m_qtProxyConfig.proxy_rules().empty()) {
+ // no changes
+ *config = m_qtProxyConfig;
+ return CONFIG_VALID;
+ }
+
+ m_qtApplicationProxy = qtProxy;
+ m_qtProxyConfig = net::ProxyConfig();
+
+ net::ProxyConfig::ProxyRules qtRules;
+ net::ProxyServer server = fromQNetworkProxy(qtProxy);
+ switch (qtProxy.type()) {
+ case QNetworkProxy::HttpProxy:
+ case QNetworkProxy::Socks5Proxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+ qtRules.single_proxies.SetSingleProxyServer(server);
+ break;
+ case QNetworkProxy::HttpCachingProxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+ qtRules.proxies_for_http.SetSingleProxyServer(server);
+ break;
+ case QNetworkProxy::FtpCachingProxy:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+ qtRules.proxies_for_ftp.SetSingleProxyServer(server);
+ break;
+ default:
+ qtRules.type = net::ProxyConfig::ProxyRules::TYPE_NO_RULES;
+ }
+
+ qtRules.bypass_rules.AddRuleToBypassLocal(); // don't use proxy for connections to localhost
+ m_qtProxyConfig.proxy_rules() = qtRules;
+ *config = m_qtProxyConfig;
+ return CONFIG_VALID;
+}
+
+void ProxyConfigServiceQt::OnLazyPoll()
+{
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
+ // We need to update if
+ // - setUseSystemConfiguration() was called in between
+ // - user changed application proxy
+ if (m_usesSystemConfiguration != QNetworkProxyFactory::usesSystemConfiguration()
+ || (!m_usesSystemConfiguration && m_qtApplicationProxy != QNetworkProxy::applicationProxy())) {
+ Update();
+ } else if (m_usesSystemConfiguration) {
+ if (m_baseService.get())
+ m_baseService->OnLazyPoll();
+ }
+#else
+ if (m_qtApplicationProxy != QNetworkProxy::applicationProxy())
+ Update();
+#endif
+}
+
+// Called when the base service changed
+void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfig &config, ConfigAvailability availability)
+{
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ Q_UNUSED(config);
+
+ if (!m_usesSystemConfiguration)
+ return;
+
+ Update();
+}
+
+// Update our observers
+void ProxyConfigServiceQt::Update()
+{
+ net::ProxyConfig actual_config;
+ ConfigAvailability availability = GetLatestProxyConfig(&actual_config);
+ if (availability == CONFIG_PENDING)
+ return;
+ for (net::ProxyConfigService::Observer &observer: m_observers)
+ observer.OnProxyConfigChanged(actual_config, availability);
+}
+
+// Register ourselves as observer of the base service.
+// This has to be done on the IO thread, and therefore cannot be done
+// in the constructor.
+void ProxyConfigServiceQt::RegisterObserver()
+{
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ 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
new file mode 100644
index 000000000..7be3289d0
--- /dev/null
+++ b/src/core/net/proxy_config_service_qt.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 PROXY_CONFIG_SERVICE_QT_H
+#define PROXY_CONFIG_SERVICE_QT_H
+
+#include "base/memory/ref_counted.h"
+#include "base/observer_list.h"
+
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service.h"
+
+#include <QNetworkProxy>
+
+class ProxyConfigServiceQt
+ : public net::ProxyConfigService,
+ public net::ProxyConfigService::Observer {
+public:
+
+ static net::ProxyServer fromQNetworkProxy(const QNetworkProxy &);
+
+ explicit ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService);
+ ~ProxyConfigServiceQt() override;
+
+ // ProxyConfigService implementation:
+ void AddObserver(net::ProxyConfigService::Observer *observer) override;
+ void RemoveObserver(net::ProxyConfigService::Observer *observer) override;
+ ConfigAvailability GetLatestProxyConfig(net::ProxyConfig *config) override;
+ void OnLazyPoll() override;
+
+private:
+ // ProxyConfigService::Observer implementation:
+ void OnProxyConfigChanged(const net::ProxyConfig& config,
+ ConfigAvailability availability) override;
+
+ // Retrieve new proxy settings and notify observers.
+ void Update();
+
+ // Makes sure that the observer registration with the base service is set up.
+ void RegisterObserver();
+
+ std::unique_ptr<net::ProxyConfigService> m_baseService;
+ base::ObserverList<net::ProxyConfigService::Observer, true> m_observers;
+
+ // Keep the last state around.
+ bool m_usesSystemConfiguration;
+ QNetworkProxy m_qtApplicationProxy;
+ net::ProxyConfig m_qtProxyConfig;
+
+ // Indicates whether the base service registration is done.
+ bool m_registeredObserver;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt);
+};
+
+#endif // PROXY_CONFIG_SERVICE_QT_H
diff --git a/src/core/net/qrc_protocol_handler_qt.cpp b/src/core/net/qrc_protocol_handler_qt.cpp
new file mode 100644
index 000000000..eb716f182
--- /dev/null
+++ b/src/core/net/qrc_protocol_handler_qt.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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 "qrc_protocol_handler_qt.h"
+#include "url_request_qrc_job_qt.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 {
+
+const char kQrcSchemeQt[] = "qrc";
+
+QrcProtocolHandlerQt::QrcProtocolHandlerQt()
+{
+}
+
+net::URLRequestJob *QrcProtocolHandlerQt::MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const
+{
+ if (!networkDelegate)
+ return new net::URLRequestErrorJob(request, Q_NULLPTR, net::ERR_ACCESS_DENIED);
+
+ return new URLRequestQrcJobQt(request, networkDelegate);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/qrc_protocol_handler_qt.h b/src/core/net/qrc_protocol_handler_qt.h
new file mode 100644
index 000000000..f2849c1ef
--- /dev/null
+++ b/src/core/net/qrc_protocol_handler_qt.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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 QRC_PROTOCOL_HANDLER_QT_H_
+#define QRC_PROTOCOL_HANDLER_QT_H_
+
+#include "net/url_request/url_request_job_factory.h"
+
+namespace net {
+
+class NetworkDelegate;
+class URLRequestJob;
+
+} // namespace
+
+namespace QtWebEngineCore {
+
+extern const char kQrcSchemeQt[];
+
+// Implements a ProtocolHandler for qrc file jobs. If |network_delegate_| is NULL,
+// then all file requests will fail with ERR_ACCESS_DENIED.
+class QrcProtocolHandlerQt : public net::URLRequestJobFactory::ProtocolHandler {
+
+public:
+ QrcProtocolHandlerQt();
+ net::URLRequestJob *MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(QrcProtocolHandlerQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // QRC_PROTOCOL_HANDLER_QT_H_
diff --git a/src/core/net/ssl_host_state_delegate_qt.cpp b/src/core/net/ssl_host_state_delegate_qt.cpp
new file mode 100644
index 000000000..d8f73abda
--- /dev/null
+++ b/src/core/net/ssl_host_state_delegate_qt.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** 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"
+
+#include "ssl_host_state_delegate_qt.h"
+
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+// Mirrors implementation in aw_ssl_host_state_delegate.cc
+
+CertPolicy::CertPolicy()
+{
+}
+
+CertPolicy::~CertPolicy()
+{
+}
+
+// For an allowance, we consider a given |cert| to be a match to a saved
+// allowed cert if the |error| is an exact match to or subset of the errors
+// in the saved CertStatus.
+bool CertPolicy::Check(const net::X509Certificate &cert, net::CertStatus error) const
+{
+ net::SHA256HashValue fingerprint = cert.CalculateChainFingerprint256();
+ auto allowed_iter = m_allowed.find(fingerprint);
+ if ((allowed_iter != m_allowed.end()) && (allowed_iter->second & error) && ((allowed_iter->second & error) == error))
+ return true;
+ return false;
+}
+
+void CertPolicy::Allow(const net::X509Certificate& cert, net::CertStatus error)
+{
+ net::SHA256HashValue fingerprint = cert.CalculateChainFingerprint256();
+ m_allowed[fingerprint] |= error;
+}
+
+SSLHostStateDelegateQt::SSLHostStateDelegateQt()
+{
+}
+
+SSLHostStateDelegateQt::~SSLHostStateDelegateQt()
+{
+}
+
+void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509Certificate &cert, net::CertStatus error)
+{
+ m_certPolicyforHost[host].Allow(cert, error);
+}
+
+// Clear all allow preferences.
+void SSLHostStateDelegateQt::Clear(const base::Callback<bool(const std::string&)>& host_filter)
+{
+ if (host_filter.is_null()) {
+ m_certPolicyforHost.clear();
+ return;
+ }
+
+ for (auto it = m_certPolicyforHost.begin(); it != m_certPolicyforHost.end();) {
+ auto next_it = std::next(it);
+
+ if (host_filter.Run(it->first))
+ m_certPolicyforHost.erase(it);
+
+ it = next_it;
+ }
+}
+
+// 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,
+ net::CertStatus error,bool *expired_previous_decision)
+{
+ return m_certPolicyforHost[host].Check(cert, error) ? SSLHostStateDelegate::ALLOWED : SSLHostStateDelegate::DENIED;
+}
+
+// Records that a host has run insecure content.
+void SSLHostStateDelegateQt::HostRanInsecureContent(const std::string &host, int pid, InsecureContentType content_type)
+{
+}
+
+// Returns whether the specified host ran insecure content.
+bool SSLHostStateDelegateQt::DidHostRunInsecureContent(const std::string &host, int pid, InsecureContentType content_type) const
+{
+ return false;
+}
+
+// Revokes all SSL certificate error allow exceptions made by the user for
+// |host|.
+void SSLHostStateDelegateQt::RevokeUserAllowExceptions(const std::string &host)
+{
+ m_certPolicyforHost.erase(host);
+}
+
+// Returns whether the user has allowed a certificate error exception for
+// |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
+{
+ auto policy_iterator = m_certPolicyforHost.find(host);
+ return policy_iterator != m_certPolicyforHost.end() &&
+ policy_iterator->second.HasAllowException();
+}
+
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/ssl_host_state_delegate_qt.h b/src/core/net/ssl_host_state_delegate_qt.h
new file mode 100644
index 000000000..3ebabb601
--- /dev/null
+++ b/src/core/net/ssl_host_state_delegate_qt.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** 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 SSL_HOST_STATE_DELEGATE_QT_H
+#define SSL_HOST_STATE_DELEGATE_QT_H
+
+#include "content/public/browser/ssl_host_state_delegate.h"
+#include "browser_context_adapter.h"
+
+namespace QtWebEngineCore {
+
+class CertPolicy {
+public:
+ CertPolicy();
+ ~CertPolicy();
+ bool Check(const net::X509Certificate& cert, net::CertStatus error) const;
+ void Allow(const net::X509Certificate& cert, net::CertStatus error);
+ bool HasAllowException() const { return m_allowed.size() > 0; }
+
+private:
+ std::map<net::SHA256HashValue, net::CertStatus> m_allowed;
+};
+
+class SSLHostStateDelegateQt : public content::SSLHostStateDelegate {
+
+public:
+ SSLHostStateDelegateQt();
+ ~SSLHostStateDelegateQt();
+
+ // content::SSLHostStateDelegate implementation:
+ void AllowCert(const std::string &, const net::X509Certificate &cert, net::CertStatus error) override;
+ void Clear(const base::Callback<bool(const std::string&)>& host_filter) override;
+ virtual CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert,
+ net::CertStatus 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 RevokeUserAllowExceptions(const std::string &host) override;
+ bool HasAllowException(const std::string &host) const override;
+
+private:
+ std::map<std::string, CertPolicy> m_certPolicyforHost;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // SSL_HOST_STATE_DELEGATE_QT_H
diff --git a/src/core/net/url_request_context_getter_qt.cpp b/src/core/net/url_request_context_getter_qt.cpp
new file mode 100644
index 000000000..3b041639e
--- /dev/null
+++ b/src/core/net/url_request_context_getter_qt.cpp
@@ -0,0 +1,648 @@
+/****************************************************************************
+**
+** 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 "base/command_line.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_util.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
+#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
+#include "content/network/proxy_service_mojo.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/browsing_data_remover.h"
+#include "content/public/browser/cookie_store_factory.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "net/base/cache_type.h"
+#include "net/cert/cert_verifier.h"
+#include "net/cert/ct_known_logs.h"
+#include "net/cert/ct_log_verifier.h"
+#include "net/cert/ct_policy_enforcer.h"
+#include "net/cert/multi_log_ct_verifier.h"
+#include "net/dns/host_resolver.h"
+#include "net/dns/mapped_host_resolver.h"
+#include "net/extras/sqlite/sqlite_channel_id_store.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_auth_preferences.h"
+#include "net/http/http_auth_scheme.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_server_properties_impl.h"
+#include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
+#include "net/proxy/proxy_script_fetcher_impl.h"
+#include "net/proxy/proxy_service.h"
+#include "net/ssl/channel_id_service.h"
+#include "net/ssl/default_channel_id_store.h"
+#include "net/ssl/ssl_config_service_defaults.h"
+#include "net/url_request/static_http_user_agent_settings.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/data_protocol_handler.h"
+#include "net/url_request/file_protocol_handler.h"
+#include "net/url_request/ftp_protocol_handler.h"
+#include "net/url_request/url_request_intercepting_job_factory.h"
+#include "net/ftp/ftp_network_layer.h"
+#include "services/proxy_resolver/public/interfaces/proxy_resolver.mojom.h"
+
+#include "api/qwebengineurlschemehandler.h"
+#include "browser_context_adapter.h"
+#include "browser_context_qt.h"
+#include "custom_protocol_handler.h"
+#include "cookie_monster_delegate_qt.h"
+#include "content_client_qt.h"
+#include "network_delegate_qt.h"
+#include "proxy_config_service_qt.h"
+#include "qrc_protocol_handler_qt.h"
+#include "qwebenginecookiestore.h"
+#include "qwebenginecookiestore_p.h"
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+using content::BrowserThread;
+
+URLRequestContextGetterQt::URLRequestContextGetterQt(QSharedPointer<BrowserContextAdapter> browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors)
+ : m_ignoreCertificateErrors(false)
+ , m_mutex(QMutex::Recursive)
+ , m_contextInitialized(false)
+ , m_updateAllStorage(false)
+ , m_updateCookieStore(false)
+ , m_updateHttpCache(false)
+ , m_updateJobFactory(true)
+ , m_updateUserAgent(false)
+ , m_browserContext(browserContext)
+ , m_baseJobFactory(0)
+ , m_cookieDelegate(new CookieMonsterDelegateQt())
+ , m_requestInterceptors(std::move(request_interceptors))
+{
+ std::swap(m_protocolHandlers, *protocolHandlers);
+
+ // The ProtocolHandlerRegistry and it's JobInterceptorFactory need to be
+ // created on the UI thread:
+ ProtocolHandlerRegistry* protocolHandlerRegistry =
+ ProtocolHandlerRegistryFactory::GetForBrowserContext(browserContext->browserContext());
+ DCHECK(protocolHandlerRegistry);
+ m_protocolHandlerInterceptor =
+ protocolHandlerRegistry->CreateJobInterceptorFactory();
+
+ QMutexLocker lock(&m_mutex);
+ m_cookieDelegate->setClient(browserContext->cookieStore());
+ setFullConfiguration(browserContext);
+ updateStorageSettings();
+}
+
+URLRequestContextGetterQt::~URLRequestContextGetterQt()
+{
+ m_cookieDelegate->setCookieMonster(0); // this will let CookieMonsterDelegateQt be deleted
+ delete m_proxyConfigService.fetchAndStoreAcquire(0);
+}
+
+
+void URLRequestContextGetterQt::setFullConfiguration(QSharedPointer<BrowserContextAdapter> browserContext)
+{
+ if (!browserContext)
+ return;
+
+ m_requestInterceptor = browserContext->requestInterceptor();
+ m_persistentCookiesPolicy = browserContext->persistentCookiesPolicy();
+ m_cookiesPath = browserContext->cookiesPath();
+ m_channelIdPath = browserContext->channelIdPath();
+ m_httpAcceptLanguage = browserContext->httpAcceptLanguage();
+ m_httpUserAgent = browserContext->httpUserAgent();
+ m_httpCacheType = browserContext->httpCacheType();
+ m_httpCachePath = browserContext->httpCachePath();
+ m_httpCacheMaxSize = browserContext->httpCacheMaxSize();
+ m_customUrlSchemes = browserContext->customUrlSchemes();
+}
+
+net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ if (!m_urlRequestContext) {
+ m_urlRequestContext.reset(new net::URLRequestContext());
+
+ m_networkDelegate.reset(new NetworkDelegateQt(this));
+ m_urlRequestContext->set_network_delegate(m_networkDelegate.get());
+ m_urlRequestContext->set_enable_brotli(base::FeatureList::IsEnabled(features::kBrotliEncoding));
+
+ QMutexLocker lock(&m_mutex);
+ generateAllStorage();
+ generateJobFactory();
+ m_contextInitialized = true;
+ }
+
+ return m_urlRequestContext.get();
+}
+
+void URLRequestContextGetterQt::updateStorageSettings()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ QMutexLocker lock(&m_mutex);
+ setFullConfiguration(m_browserContext.toStrongRef());
+
+ if (!m_updateAllStorage) {
+ m_updateAllStorage = true;
+ // We must create the proxy config service on the UI loop on Linux because it
+ // must synchronously run on the glib message loop. This will be passed to
+ // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
+ Q_ASSERT(m_proxyConfigService == 0);
+ m_proxyConfigService =
+ new ProxyConfigServiceQt(
+ net::ProxyService::CreateSystemProxyConfigService(
+ content::BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
+ m_proxyResolverFactory = ChromeMojoProxyResolverFactory::CreateWithStrongBinding();
+
+ if (m_contextInitialized)
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::generateAllStorage, this));
+ }
+}
+
+void URLRequestContextGetterQt::cancelAllUrlRequests()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ Q_ASSERT(m_urlRequestContext);
+
+ const std::set<const net::URLRequest*> *url_requests = m_urlRequestContext->url_requests();
+ std::set<const net::URLRequest*>::const_iterator it = url_requests->begin();
+ std::set<const net::URLRequest*>::const_iterator end = url_requests->end();
+ for ( ; it != end; ++it) {
+ net::URLRequest* request = const_cast<net::URLRequest*>(*it);
+ if (request)
+ request->Cancel();
+ }
+
+}
+
+void URLRequestContextGetterQt::generateAllStorage()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ QMutexLocker lock(&m_mutex);
+ generateStorage();
+ generateCookieStore();
+ generateUserAgent();
+ generateHttpCache();
+ m_updateAllStorage = false;
+}
+
+static const char* const kDefaultAuthSchemes[] = { net::kBasicAuthScheme,
+ net::kDigestAuthScheme,
+#if defined(USE_KERBEROS) && !defined(OS_ANDROID)
+ net::kNegotiateAuthScheme,
+#endif
+ net::kNtlmAuthScheme };
+
+void URLRequestContextGetterQt::generateStorage()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ Q_ASSERT(m_urlRequestContext);
+
+ // We must stop all requests before deleting their backends.
+ if (m_storage) {
+ m_cookieDelegate->setCookieMonster(0);
+ m_storage->set_cookie_store(0);
+ cancelAllUrlRequests();
+ // we need to get rid of dangling pointer due to coming storage deletion
+ m_urlRequestContext->set_http_transaction_factory(0);
+ m_httpNetworkSession.reset();
+ }
+
+
+ m_storage.reset(new net::URLRequestContextStorage(m_urlRequestContext.get()));
+
+ net::ProxyConfigService *proxyConfigService = m_proxyConfigService.fetchAndStoreAcquire(0);
+ Q_ASSERT(proxyConfigService);
+
+ m_storage->set_cert_verifier(net::CertVerifier::CreateDefault());
+ std::unique_ptr<net::MultiLogCTVerifier> ct_verifier(new net::MultiLogCTVerifier());
+ ct_verifier->AddLogs(net::ct::CreateLogVerifiersForKnownLogs());
+ m_storage->set_cert_transparency_verifier(std::move(ct_verifier));
+ m_storage->set_ct_policy_enforcer(base::WrapUnique(new net::CTPolicyEnforcer));
+
+ std::unique_ptr<net::HostResolver> host_resolver(net::HostResolver::CreateDefaultResolver(NULL));
+
+ // The System Proxy Resolver has issues on Windows with unconfigured network cards,
+ // which is why we want to use the v8 one
+ if (!m_dhcpProxyScriptFetcherFactory)
+ m_dhcpProxyScriptFetcherFactory.reset(new net::DhcpProxyScriptFetcherFactory);
+
+ m_storage->set_proxy_service(content::CreateProxyServiceUsingMojoFactory(
+ std::move(m_proxyResolverFactory),
+ std::unique_ptr<net::ProxyConfigService>(proxyConfigService),
+ std::make_unique<net::ProxyScriptFetcherImpl>(m_urlRequestContext.get()),
+ m_dhcpProxyScriptFetcherFactory->Create(m_urlRequestContext.get()),
+ host_resolver.get(),
+ nullptr /* NetLog */,
+ m_networkDelegate.get()));
+
+ m_storage->set_ssl_config_service(new net::SSLConfigServiceDefaults);
+ m_storage->set_transport_security_state(std::unique_ptr<net::TransportSecurityState>(new net::TransportSecurityState()));
+
+ if (!m_httpAuthPreferences) {
+ std::vector<std::string> auth_types(std::begin(kDefaultAuthSchemes), std::end(kDefaultAuthSchemes));
+ m_httpAuthPreferences.reset(new net::HttpAuthPreferences(auth_types
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ , std::string() /* gssapi library name */
+#endif
+ ));
+ }
+ m_storage->set_http_auth_handler_factory(net::HttpAuthHandlerRegistryFactory::Create(m_httpAuthPreferences.get(), host_resolver.get()));
+ m_storage->set_http_server_properties(std::unique_ptr<net::HttpServerProperties>(new net::HttpServerPropertiesImpl));
+
+ // Give |m_storage| ownership at the end in case it's |mapped_host_resolver|.
+ m_storage->set_host_resolver(std::move(host_resolver));
+}
+
+void URLRequestContextGetterQt::updateCookieStore()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ m_persistentCookiesPolicy = m_browserContext.data()->persistentCookiesPolicy();
+ m_cookiesPath = m_browserContext.data()->cookiesPath();
+ m_channelIdPath = m_browserContext.data()->channelIdPath();
+
+ if (m_contextInitialized && !m_updateAllStorage && !m_updateCookieStore) {
+ m_updateCookieStore = true;
+ m_updateHttpCache = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::generateCookieStore, this));
+ }
+}
+
+void URLRequestContextGetterQt::generateCookieStore()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
+
+ QMutexLocker lock(&m_mutex);
+ m_updateCookieStore = false;
+
+ scoped_refptr<net::SQLiteChannelIDStore> channel_id_db;
+ if (!m_channelIdPath.isEmpty() && m_persistentCookiesPolicy != BrowserContextAdapter::NoPersistentCookies) {
+ channel_id_db = new net::SQLiteChannelIDStore(
+ toFilePath(m_channelIdPath),
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND}));
+ }
+
+ m_storage->set_channel_id_service(
+ base::WrapUnique(new net::ChannelIDService(
+ new net::DefaultChannelIDStore(channel_id_db.get()))));
+
+ // Unset it first to get a chance to destroy and flush the old cookie store before opening a new on possibly the same file.
+ m_cookieDelegate->setCookieMonster(0);
+ m_storage->set_cookie_store(0);
+
+ std::unique_ptr<net::CookieStore> cookieStore;
+ switch (m_persistentCookiesPolicy) {
+ case BrowserContextAdapter::NoPersistentCookies:
+ cookieStore = content::CreateCookieStore(
+ content::CookieStoreConfig(
+ base::FilePath(),
+ false,
+ false,
+ nullptr)
+ );
+ break;
+ case BrowserContextAdapter::AllowPersistentCookies:
+ cookieStore = content::CreateCookieStore(
+ content::CookieStoreConfig(
+ toFilePath(m_cookiesPath),
+ false,
+ true,
+ nullptr)
+ );
+ break;
+ case BrowserContextAdapter::ForcePersistentCookies:
+ cookieStore = content::CreateCookieStore(
+ content::CookieStoreConfig(
+ toFilePath(m_cookiesPath),
+ true,
+ true,
+ nullptr)
+ );
+ break;
+ }
+
+ net::CookieMonster * const cookieMonster = static_cast<net::CookieMonster*>(cookieStore.get());
+ cookieStore->SetChannelIDServiceID(m_urlRequestContext->channel_id_service()->GetUniqueID());
+ m_cookieDelegate->setCookieMonster(cookieMonster);
+ m_storage->set_cookie_store(std::move(cookieStore));
+
+ const std::vector<std::string> cookieableSchemes(kCookieableSchemes, kCookieableSchemes + arraysize(kCookieableSchemes));
+ cookieMonster->SetCookieableSchemes(cookieableSchemes);
+
+ if (!m_updateAllStorage && m_updateHttpCache) {
+ // HttpCache needs to be regenerated when we generate a new channel id service
+ generateHttpCache();
+ }
+}
+
+void URLRequestContextGetterQt::updateUserAgent()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ m_httpAcceptLanguage = m_browserContext.data()->httpAcceptLanguage();
+ m_httpUserAgent = m_browserContext.data()->httpUserAgent();
+
+ if (m_contextInitialized && !m_updateAllStorage && !m_updateUserAgent) {
+ m_updateUserAgent = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::generateUserAgent, this));
+ }
+}
+
+void URLRequestContextGetterQt::generateUserAgent()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
+
+ QMutexLocker lock(&m_mutex);
+ m_updateUserAgent = false;
+
+ m_storage->set_http_user_agent_settings(std::unique_ptr<net::HttpUserAgentSettings>(
+ new net::StaticHttpUserAgentSettings(m_httpAcceptLanguage.toStdString(), m_httpUserAgent.toStdString())));
+}
+
+void URLRequestContextGetterQt::updateHttpCache()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ m_httpCacheType = m_browserContext.data()->httpCacheType();
+ m_httpCachePath = m_browserContext.data()->httpCachePath();
+ m_httpCacheMaxSize = m_browserContext.data()->httpCacheMaxSize();
+
+ if (m_httpCacheType == BrowserContextAdapter::NoCache) {
+ content::BrowsingDataRemover *remover = content::BrowserContext::GetBrowsingDataRemover(m_browserContext.data()->browserContext());
+ remover->Remove(base::Time(), base::Time::Max(),
+ content::BrowsingDataRemover::DATA_TYPE_CACHE,
+ content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB);
+ }
+
+ if (m_contextInitialized && !m_updateAllStorage && !m_updateHttpCache) {
+ m_updateHttpCache = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::generateHttpCache, this));
+ }
+}
+
+void URLRequestContextGetterQt::updateJobFactory()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ m_customUrlSchemes = m_browserContext.data()->customUrlSchemes();
+
+ if (m_contextInitialized && !m_updateJobFactory) {
+ m_updateJobFactory = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::regenerateJobFactory, this));
+ }
+}
+
+void URLRequestContextGetterQt::updateRequestInterceptor()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ m_requestInterceptor = m_browserContext.data()->requestInterceptor();
+
+ // We in this case do not need to regenerate any Chromium classes.
+}
+
+static bool doNetworkSessionContextMatch(const net::HttpNetworkSession::Context &first, const net::HttpNetworkSession::Context &second)
+{
+ if (first.transport_security_state != second.transport_security_state)
+ return false;
+ if (first.cert_verifier != second.cert_verifier)
+ return false;
+ if (first.channel_id_service != second.channel_id_service)
+ return false;
+ if (first.proxy_service != second.proxy_service)
+ return false;
+ if (first.ssl_config_service != second.ssl_config_service)
+ return false;
+ if (first.http_auth_handler_factory != second.http_auth_handler_factory)
+ return false;
+ if (first.http_server_properties != second.http_server_properties)
+ return false;
+ if (first.host_resolver != second.host_resolver)
+ return false;
+ if (first.cert_transparency_verifier != second.cert_transparency_verifier)
+ return false;
+ if (first.ct_policy_enforcer != second.ct_policy_enforcer)
+ return false;
+
+ return true;
+}
+
+static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, const net::HttpNetworkSession::Params &second)
+{
+ if (first.ignore_certificate_errors != second.ignore_certificate_errors)
+ return false;
+
+ return true;
+}
+
+net::HttpNetworkSession::Context URLRequestContextGetterQt::generateNetworkSessionContext()
+{
+ Q_ASSERT(m_urlRequestContext);
+
+ net::HttpNetworkSession::Context network_session_context;
+
+ network_session_context.transport_security_state = m_urlRequestContext->transport_security_state();
+ network_session_context.cert_verifier = m_urlRequestContext->cert_verifier();
+ network_session_context.channel_id_service = m_urlRequestContext->channel_id_service();
+ network_session_context.proxy_service = m_urlRequestContext->proxy_service();
+ network_session_context.ssl_config_service = m_urlRequestContext->ssl_config_service();
+ network_session_context.http_auth_handler_factory = m_urlRequestContext->http_auth_handler_factory();
+ network_session_context.http_server_properties = m_urlRequestContext->http_server_properties();
+ network_session_context.host_resolver = m_urlRequestContext->host_resolver();
+ network_session_context.cert_transparency_verifier = m_urlRequestContext->cert_transparency_verifier();
+ network_session_context.ct_policy_enforcer = m_urlRequestContext->ct_policy_enforcer();
+
+ return network_session_context;
+}
+
+net::HttpNetworkSession::Params URLRequestContextGetterQt::generateNetworkSessionParams()
+{
+ Q_ASSERT(m_urlRequestContext);
+
+ net::HttpNetworkSession::Params network_session_params;
+
+ network_session_params.ignore_certificate_errors = m_ignoreCertificateErrors;
+
+ return network_session_params;
+}
+
+void URLRequestContextGetterQt::generateHttpCache()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_storage);
+
+ QMutexLocker lock(&m_mutex);
+ m_updateHttpCache = false;
+
+ if (m_updateCookieStore)
+ generateCookieStore();
+
+ net::HttpCache::DefaultBackend* main_backend = 0;
+ switch (m_httpCacheType) {
+ case BrowserContextAdapter::MemoryHttpCache:
+ main_backend =
+ new net::HttpCache::DefaultBackend(
+ net::MEMORY_CACHE,
+ net::CACHE_BACKEND_DEFAULT,
+ base::FilePath(),
+ m_httpCacheMaxSize
+ );
+ break;
+ case BrowserContextAdapter::DiskHttpCache:
+ main_backend =
+ new net::HttpCache::DefaultBackend(
+ net::DISK_CACHE,
+ net::CACHE_BACKEND_DEFAULT,
+ toFilePath(m_httpCachePath),
+ m_httpCacheMaxSize
+ );
+ break;
+ case BrowserContextAdapter::NoCache:
+ // It's safe to not create BackendFactory.
+ break;
+ }
+
+ net::HttpCache *cache = 0;
+ net::HttpNetworkSession::Context network_session_context = generateNetworkSessionContext();
+ net::HttpNetworkSession::Params network_session_params = generateNetworkSessionParams();
+
+ if (!m_httpNetworkSession
+ || !doNetworkSessionParamsMatch(network_session_params, m_httpNetworkSession->params())
+ || !doNetworkSessionContextMatch(network_session_context, m_httpNetworkSession->context())) {
+ cancelAllUrlRequests();
+ m_httpNetworkSession.reset(new net::HttpNetworkSession(network_session_params, network_session_context));
+ }
+
+ cache = new net::HttpCache(m_httpNetworkSession.get(), std::unique_ptr<net::HttpCache::DefaultBackend>(main_backend), false);
+
+ m_storage->set_http_transaction_factory(std::unique_ptr<net::HttpCache>(cache));
+}
+
+void URLRequestContextGetterQt::generateJobFactory()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(!m_jobFactory);
+
+ QMutexLocker lock(&m_mutex);
+ m_updateJobFactory = false;
+
+ std::unique_ptr<net::URLRequestJobFactoryImpl> jobFactory(new net::URLRequestJobFactoryImpl());
+ for (auto &it : m_protocolHandlers)
+ jobFactory->SetProtocolHandler(it.first, base::WrapUnique(it.second.release()));
+ m_protocolHandlers.clear();
+
+ jobFactory->SetProtocolHandler(url::kDataScheme, std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::DataProtocolHandler()));
+ jobFactory->SetProtocolHandler(url::kFileScheme,
+ std::make_unique<net::FileProtocolHandler>(
+ base::CreateTaskRunnerWithTraits({base::MayBlock(),
+ base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})));
+ jobFactory->SetProtocolHandler(kQrcSchemeQt, std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>(new QrcProtocolHandlerQt()));
+ jobFactory->SetProtocolHandler(url::kFtpScheme,
+ net::FtpProtocolHandler::Create(m_urlRequestContext->host_resolver()));
+
+ m_installedCustomSchemes = m_customUrlSchemes;
+ Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) {
+ jobFactory->SetProtocolHandler(scheme.toStdString(), std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>(new CustomProtocolHandler(m_browserContext)));
+ }
+
+ m_baseJobFactory = jobFactory.get();
+
+ // Set up interceptors in the reverse order.
+ std::unique_ptr<net::URLRequestJobFactory> topJobFactory = std::move(jobFactory);
+
+ for (content::URLRequestInterceptorScopedVector::reverse_iterator i = m_requestInterceptors.rbegin(); i != m_requestInterceptors.rend(); ++i) {
+ topJobFactory.reset(new net::URLRequestInterceptingJobFactory(std::move(topJobFactory), std::move(*i)));
+ }
+
+ m_requestInterceptors.clear();
+
+ if (m_protocolHandlerInterceptor) {
+ m_protocolHandlerInterceptor->Chain(std::move(topJobFactory));
+ topJobFactory = std::move(m_protocolHandlerInterceptor);
+ }
+
+ m_jobFactory = std::move(topJobFactory);
+
+ m_urlRequestContext->set_job_factory(m_jobFactory.get());
+}
+
+void URLRequestContextGetterQt::regenerateJobFactory()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ Q_ASSERT(m_urlRequestContext);
+ Q_ASSERT(m_jobFactory);
+ Q_ASSERT(m_baseJobFactory);
+
+ QMutexLocker lock(&m_mutex);
+ m_updateJobFactory = false;
+
+ if (m_customUrlSchemes == m_installedCustomSchemes)
+ return;
+
+ Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) {
+ m_baseJobFactory->SetProtocolHandler(scheme.toStdString(), nullptr);
+ }
+
+ m_installedCustomSchemes = m_customUrlSchemes;
+ Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) {
+ m_baseJobFactory->SetProtocolHandler(scheme.toStdString(), std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>(new CustomProtocolHandler(m_browserContext)));
+ }
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> URLRequestContextGetterQt::GetNetworkTaskRunner() const
+{
+ return content::BrowserThread::GetTaskRunnerForThread(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
new file mode 100644
index 000000000..809e4190d
--- /dev/null
+++ b/src/core/net/url_request_context_getter_qt.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** 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"
+
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/url_constants.h"
+#include "net/http/http_network_session.h"
+#include "net/url_request/url_request_context_storage.h"
+#include "net/url_request/url_request_job_factory_impl.h"
+#include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
+
+#include "cookie_monster_delegate_qt.h"
+#include "network_delegate_qt.h"
+#include "browser_context_adapter.h"
+
+#include <QtCore/qatomic.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qsharedpointer.h>
+
+namespace net {
+class HttpAuthPreferences;
+class MappedHostResolver;
+class ProxyConfigService;
+}
+
+namespace QtWebEngineCore {
+
+// FIXME: This class should be split into a URLRequestContextGetter and a ProfileIOData, similar to what chrome does.
+class URLRequestContextGetterQt : public net::URLRequestContextGetter {
+public:
+ URLRequestContextGetterQt(QSharedPointer<BrowserContextAdapter> browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors);
+
+ net::URLRequestContext *GetURLRequestContext() override;
+ scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const override;
+
+ // Called on the UI thread:
+ void updateStorageSettings();
+ void updateUserAgent();
+ void updateCookieStore();
+ void updateHttpCache();
+ void updateJobFactory();
+ void updateRequestInterceptor();
+
+private:
+ virtual ~URLRequestContextGetterQt();
+
+ // Called on the IO thread:
+ void generateAllStorage();
+ void generateStorage();
+ void generateCookieStore();
+ void generateHttpCache();
+ void generateUserAgent();
+ void generateJobFactory();
+ void regenerateJobFactory();
+ void cancelAllUrlRequests();
+ net::HttpNetworkSession::Params generateNetworkSessionParams();
+ net::HttpNetworkSession::Context generateNetworkSessionContext();
+
+ void setFullConfiguration(QSharedPointer<BrowserContextAdapter> browserContext);
+
+ bool m_ignoreCertificateErrors;
+
+ QMutex m_mutex;
+ bool m_contextInitialized;
+ bool m_updateAllStorage;
+ bool m_updateCookieStore;
+ bool m_updateHttpCache;
+ bool m_updateJobFactory;
+ bool m_updateUserAgent;
+
+ QWeakPointer<BrowserContextAdapter> m_browserContext;
+ content::ProtocolHandlerMap m_protocolHandlers;
+
+ QAtomicPointer<net::ProxyConfigService> m_proxyConfigService;
+ std::unique_ptr<net::URLRequestContext> m_urlRequestContext;
+ std::unique_ptr<NetworkDelegateQt> m_networkDelegate;
+ std::unique_ptr<net::URLRequestContextStorage> m_storage;
+ std::unique_ptr<net::URLRequestJobFactory> m_jobFactory;
+ std::unique_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> m_protocolHandlerInterceptor;
+ net::URLRequestJobFactoryImpl *m_baseJobFactory;
+ std::unique_ptr<net::DhcpProxyScriptFetcherFactory> m_dhcpProxyScriptFetcherFactory;
+ scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate;
+ content::URLRequestInterceptorScopedVector m_requestInterceptors;
+ std::unique_ptr<net::HttpNetworkSession> m_httpNetworkSession;
+ std::unique_ptr<net::HttpAuthPreferences> m_httpAuthPreferences;
+ proxy_resolver::mojom::ProxyResolverFactoryPtr m_proxyResolverFactory;
+
+ QList<QByteArray> m_installedCustomSchemes;
+ QWebEngineUrlRequestInterceptor* m_requestInterceptor;
+
+ // Configuration values to setup URLRequestContext in IO thread, copied from browserContext
+ // FIXME: Should later be moved to a separate ProfileIOData class.
+ BrowserContextAdapter::PersistentCookiesPolicy m_persistentCookiesPolicy;
+ QString m_cookiesPath;
+ QString m_channelIdPath;
+ QString m_httpAcceptLanguage;
+ QString m_httpUserAgent;
+ BrowserContextAdapter::HttpCacheType m_httpCacheType;
+ QString m_httpCachePath;
+ int m_httpCacheMaxSize;
+ QList<QByteArray> m_customUrlSchemes;
+
+ friend class NetworkDelegateQt;
+};
+
+} // 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
new file mode 100644
index 000000000..cf96cd6d9
--- /dev/null
+++ b/src/core/net/url_request_custom_job.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** 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 "content/public/browser/browser_thread.h"
+#include "net/base/io_buffer.h"
+
+#include <QIODevice>
+
+using namespace net;
+
+namespace QtWebEngineCore {
+
+URLRequestCustomJob::URLRequestCustomJob(URLRequest *request,
+ NetworkDelegate *networkDelegate,
+ const std::string &scheme,
+ QWeakPointer<const BrowserContextAdapter> adapter)
+ : URLRequestJob(request, networkDelegate)
+ , m_proxy(new URLRequestCustomJobProxy(this, scheme, adapter))
+ , m_device(nullptr)
+ , m_error(0)
+ , m_pendingReadSize(0)
+ , m_pendingReadPos(0)
+ , m_pendingReadBuffer(nullptr)
+{
+}
+
+URLRequestCustomJob::~URLRequestCustomJob()
+{
+ m_proxy->m_job = nullptr;
+ if (m_device && m_device->isOpen())
+ m_device->close();
+ m_device = nullptr;
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&URLRequestCustomJobProxy::release,
+ m_proxy));
+}
+
+void URLRequestCustomJob::Start()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&URLRequestCustomJobProxy::initialize,
+ m_proxy, request()->url(), request()->method(), request()->initiator()));
+}
+
+void URLRequestCustomJob::Kill()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ 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;
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&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;
+}
+
+bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_code)
+{
+ 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
new file mode 100644
index 000000000..021cf3204
--- /dev/null
+++ b/src/core/net/url_request_custom_job.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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/QWeakPointer>
+
+QT_FORWARD_DECLARE_CLASS(QIODevice)
+
+namespace QtWebEngineCore {
+
+class BrowserContextAdapter;
+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,
+ QWeakPointer<const BrowserContextAdapter> adapter);
+ 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;
+ bool IsRedirectResponse(GURL* location, int* http_status_code) 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;
+
+ 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
new file mode 100644
index 000000000..338bd7137
--- /dev/null
+++ b/src/core/net/url_request_custom_job_delegate.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** 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_delegate.h"
+#include "url_request_custom_job_proxy.h"
+
+#include "type_conversion.h"
+#include "net/base/net_errors.h"
+#include "content/public/browser/browser_thread.h"
+
+#include <QByteArray>
+
+namespace QtWebEngineCore {
+
+URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
+ const QUrl &url,
+ const QByteArray &method,
+ const QUrl &initiatorOrigin)
+ : m_proxy(proxy),
+ m_request(url),
+ m_method(method),
+ m_initiatorOrigin(initiatorOrigin)
+{
+}
+
+URLRequestCustomJobDelegate::~URLRequestCustomJobDelegate()
+{
+}
+
+QUrl URLRequestCustomJobDelegate::url() const
+{
+ return m_request;
+}
+
+QByteArray URLRequestCustomJobDelegate::method() const
+{
+ return m_method;
+}
+
+QUrl URLRequestCustomJobDelegate::initiator() const
+{
+ return m_initiatorOrigin;
+}
+
+void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice *device)
+{
+ if (device)
+ QObject::connect(device, &QIODevice::readyRead, this, &URLRequestCustomJobDelegate::slotReadyRead);
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestCustomJobProxy::reply,
+ m_proxy,contentType.toStdString(),device));
+}
+
+void URLRequestCustomJobDelegate::slotReadyRead()
+{
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestCustomJobProxy::readyRead, m_proxy));
+}
+
+void URLRequestCustomJobDelegate::abort()
+{
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestCustomJobProxy::abort, m_proxy));
+}
+
+void URLRequestCustomJobDelegate::redirect(const QUrl &url)
+{
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestCustomJobProxy::redirect,
+ m_proxy, toGurl(url)));
+}
+
+void URLRequestCustomJobDelegate::fail(Error error)
+{
+ int net_error = 0;
+ switch (error) {
+ case NoError:
+ break;
+ case UrlInvalid:
+ net_error = net::ERR_INVALID_URL;
+ break;
+ case UrlNotFound:
+ net_error = net::ERR_FILE_NOT_FOUND;
+ break;
+ case RequestAborted:
+ net_error = net::ERR_ABORTED;
+ break;
+ case RequestDenied:
+ net_error = net::ERR_ACCESS_DENIED;
+ break;
+ case RequestFailed:
+ net_error = net::ERR_FAILED;
+ break;
+ }
+ if (net_error) {
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestCustomJobProxy::fail,
+ m_proxy, net_error));
+ }
+}
+
+} // namespace
diff --git a/src/core/net/url_request_custom_job_delegate.h b/src/core/net/url_request_custom_job_delegate.h
new file mode 100644
index 000000000..6bbd10909
--- /dev/null
+++ b/src/core/net/url_request_custom_job_delegate.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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_DELEGATE_H_
+#define URL_REQUEST_CUSTOM_JOB_DELEGATE_H_
+
+#include "base/memory/ref_counted.h"
+#include "qtwebenginecoreglobal.h"
+
+#include <QObject>
+#include <QUrl>
+
+QT_FORWARD_DECLARE_CLASS(QIODevice)
+
+namespace QtWebEngineCore {
+
+class URLRequestCustomJobProxy;
+
+class QWEBENGINE_EXPORT URLRequestCustomJobDelegate : public QObject {
+ Q_OBJECT
+public:
+ ~URLRequestCustomJobDelegate();
+
+ enum Error {
+ NoError = 0,
+ UrlNotFound,
+ UrlInvalid,
+ RequestAborted,
+ RequestDenied,
+ RequestFailed
+ };
+
+ QUrl url() const;
+ QByteArray method() const;
+ QUrl initiator() const;
+
+ void reply(const QByteArray &contentType, QIODevice *device);
+ void redirect(const QUrl& url);
+ void abort();
+ void fail(Error);
+
+private Q_SLOTS:
+ void slotReadyRead();
+
+private:
+ URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
+ const QUrl &url,
+ const QByteArray &method,
+ const QUrl &initiatorOrigin);
+
+ friend class URLRequestCustomJobProxy;
+ scoped_refptr<URLRequestCustomJobProxy> m_proxy;
+ QUrl m_request;
+ QByteArray m_method;
+ QUrl m_initiatorOrigin;
+};
+
+} // namespace
+
+#endif // URL_REQUEST_CUSTOM_JOB_DELEGATE_H_
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
new file mode 100644
index 000000000..6c9824bb9
--- /dev/null
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "url_request_custom_job_proxy.h"
+#include "url_request_custom_job.h"
+#include "url_request_custom_job_delegate.h"
+#include "api/qwebengineurlrequestjob.h"
+#include "browser_context_adapter.h"
+#include "type_conversion.h"
+#include "content/public/browser/browser_thread.h"
+
+using namespace net;
+
+namespace QtWebEngineCore {
+
+URLRequestCustomJobProxy::URLRequestCustomJobProxy(URLRequestCustomJob *job,
+ const std::string &scheme,
+ QWeakPointer<const BrowserContextAdapter> adapter)
+ : m_job(job)
+ , m_started(false)
+ , m_scheme(scheme)
+ , m_delegate(nullptr)
+ , m_adapter(adapter)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+}
+
+URLRequestCustomJobProxy::~URLRequestCustomJobProxy()
+{
+}
+
+void URLRequestCustomJobProxy::release()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (m_delegate) {
+ m_delegate->deleteLater();
+ m_delegate = nullptr;
+ }
+}
+
+// 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)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (!m_job)
+ 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()) {
+ m_started = true;
+ m_job->NotifyHeadersComplete();
+ } else {
+ fail(ERR_INVALID_URL);
+ }
+}
+
+void URLRequestCustomJobProxy::redirect(GURL url)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (!m_job)
+ return;
+ if (m_job->m_device || m_job->m_error)
+ return;
+ m_job->m_redirect = url;
+ m_started = true;
+ m_job->NotifyHeadersComplete();
+}
+
+void URLRequestCustomJobProxy::abort()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (!m_job)
+ return;
+ if (m_job->m_device && m_job->m_device->isOpen())
+ m_job->m_device->close();
+ m_job->m_device = nullptr;
+ if (m_started)
+ m_job->NotifyCanceled();
+ else
+ m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
+}
+
+void URLRequestCustomJobProxy::fail(int error)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (!m_job)
+ return;
+ m_job->m_error = error;
+ if (m_job->m_device)
+ m_job->m_device->close();
+ if (!m_started)
+ m_job->NotifyStartError(URLRequestStatus::FromError(error));
+ // else we fail on the next read, or the read that might already be in progress
+}
+
+void URLRequestCustomJobProxy::readyRead()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (m_job)
+ m_job->notifyReadyRead();
+}
+
+void URLRequestCustomJobProxy::initialize(GURL url, std::string method, base::Optional<url::Origin> initiator)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ Q_ASSERT(!m_delegate);
+
+ QUrl initiatorOrigin;
+ if (initiator.has_value())
+ initiatorOrigin = toQt(initiator.value().GetURL());
+
+ QWebEngineUrlSchemeHandler *schemeHandler = 0;
+ QSharedPointer<const BrowserContextAdapter> browserContext = m_adapter.toStrongRef();
+ if (browserContext)
+ schemeHandler = browserContext->customUrlSchemeHandlers()[toQByteArray(m_scheme)];
+ if (schemeHandler) {
+ m_delegate = new URLRequestCustomJobDelegate(this, toQt(url),
+ QByteArray::fromStdString(method),
+ initiatorOrigin);
+ QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate);
+ schemeHandler->requestStarted(requestJob);
+ }
+}
+
+} // namespace
diff --git a/src/core/net/url_request_custom_job_proxy.h b/src/core/net/url_request_custom_job_proxy.h
new file mode 100644
index 000000000..603ad5840
--- /dev/null
+++ b/src/core/net/url_request_custom_job_proxy.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#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 "url/gurl.h"
+#include "url/origin.h"
+#include <QtCore/QWeakPointer>
+
+QT_FORWARD_DECLARE_CLASS(QIODevice)
+
+namespace QtWebEngineCore {
+
+class URLRequestCustomJob;
+class URLRequestCustomJobDelegate;
+class BrowserContextAdapter;
+
+// Used to comunicate between URLRequestCustomJob living on the IO thread
+// and URLRequestCustomJobDelegate living on the UI thread.
+class URLRequestCustomJobProxy
+ : public base::RefCountedThreadSafe<URLRequestCustomJobProxy> {
+
+public:
+ URLRequestCustomJobProxy(URLRequestCustomJob *job,
+ const std::string &scheme,
+ QWeakPointer<const BrowserContextAdapter> adapter);
+ ~URLRequestCustomJobProxy();
+
+ // Called from URLRequestCustomJobDelegate via post:
+ //void setReplyCharset(const std::string &);
+ void reply(std::string mimeType, QIODevice *device);
+ void redirect(GURL url);
+ void abort();
+ void fail(int error);
+ void release();
+ void initialize(GURL url, std::string method, base::Optional<url::Origin> initiatorOrigin);
+ void readyRead();
+
+ // IO thread owned:
+ URLRequestCustomJob *m_job;
+ bool m_started;
+
+ // UI thread owned:
+ std::string m_scheme;
+ URLRequestCustomJobDelegate *m_delegate;
+ QWeakPointer<const BrowserContextAdapter> m_adapter;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // URL_REQUEST_CUSTOM_JOB_PROXY_H_
diff --git a/src/core/net/url_request_qrc_job_qt.cpp b/src/core/net/url_request_qrc_job_qt.cpp
new file mode 100644
index 000000000..a2712653d
--- /dev/null
+++ b/src/core/net/url_request_qrc_job_qt.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** 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_qrc_job_qt.h"
+
+#include "type_conversion.h"
+
+#include "base/pending_task.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "net/base/net_errors.h"
+#include "net/base/io_buffer.h"
+
+#include <QUrl>
+#include <QFileInfo>
+#include <QMimeDatabase>
+#include <QMimeType>
+
+using namespace net;
+namespace QtWebEngineCore {
+
+URLRequestQrcJobQt::URLRequestQrcJobQt(URLRequest *request, NetworkDelegate *networkDelegate)
+ : URLRequestJob(request, networkDelegate)
+ , m_remainingBytes(0)
+ , m_weakFactory(this)
+{
+}
+
+URLRequestQrcJobQt::~URLRequestQrcJobQt()
+{
+ if (m_file.isOpen())
+ m_file.close();
+}
+
+void URLRequestQrcJobQt::Start()
+{
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&URLRequestQrcJobQt::startGetHead, m_weakFactory.GetWeakPtr()));
+}
+
+void URLRequestQrcJobQt::Kill()
+{
+ if (m_file.isOpen())
+ m_file.close();
+ m_weakFactory.InvalidateWeakPtrs();
+
+ URLRequestJob::Kill();
+}
+
+bool URLRequestQrcJobQt::GetMimeType(std::string *mimeType) const
+{
+ DCHECK(request_);
+ if (m_mimeType.size() > 0) {
+ *mimeType = m_mimeType;
+ return true;
+ }
+ return false;
+}
+
+int URLRequestQrcJobQt::ReadRawData(IOBuffer *buf, int bufSize)
+{
+ DCHECK_GE(m_remainingBytes, 0);
+ // File has been read finished.
+ if (!m_remainingBytes || !bufSize) {
+ return 0;
+ }
+ if (m_remainingBytes < bufSize)
+ bufSize = static_cast<int>(m_remainingBytes);
+ qint64 rv = m_file.read(buf->data(), bufSize);
+ if (rv >= 0) {
+ m_remainingBytes -= rv;
+ DCHECK_GE(m_remainingBytes, 0);
+ return static_cast<int>(rv);
+ }
+ return static_cast<int>(rv);
+}
+
+void URLRequestQrcJobQt::startGetHead()
+{
+ // Get qrc file path.
+ QString qrcFilePath = ':' + toQt(request_->url()).path();
+ m_file.setFileName(qrcFilePath);
+ QFileInfo qrcFileInfo(m_file);
+ // Get qrc file mime type.
+ QMimeDatabase mimeDatabase;
+ QMimeType mimeType = mimeDatabase.mimeTypeForFile(qrcFileInfo);
+ m_mimeType = mimeType.name().toStdString();
+ // Open file
+ if (m_file.open(QIODevice::ReadOnly)) {
+ m_remainingBytes = m_file.size();
+ set_expected_content_size(m_remainingBytes);
+ // Notify that the headers are complete
+ NotifyHeadersComplete();
+ } else {
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, ERR_INVALID_URL));
+ }
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/url_request_qrc_job_qt.h b/src/core/net/url_request_qrc_job_qt.h
new file mode 100644
index 000000000..11c130693
--- /dev/null
+++ b/src/core/net/url_request_qrc_job_qt.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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_QRC_JOB_QT_H_
+#define URL_REQUEST_QRC_JOB_QT_H_
+
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_job.h"
+
+#include <QFile>
+
+namespace QtWebEngineCore {
+
+// A request job that handles reading qrc file URLs
+class URLRequestQrcJobQt : public net::URLRequestJob {
+
+public:
+ URLRequestQrcJobQt(net::URLRequest *request, net::NetworkDelegate *networkDelegate);
+ void Start() override;
+ void Kill() override;
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override;;
+ bool GetMimeType(std::string *mimeType) const override;
+
+protected:
+ virtual ~URLRequestQrcJobQt();
+ // Get file mime type and try open file on a background thread.
+ void startGetHead();
+
+private:
+ qint64 m_remainingBytes;
+ QFile m_file;
+ std::string m_mimeType;
+ base::WeakPtrFactory<URLRequestQrcJobQt> m_weakFactory;
+
+ DISALLOW_COPY_AND_ASSIGN(URLRequestQrcJobQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // URL_REQUEST_QRC_JOB_QT_H_
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
new file mode 100644
index 000000000..3b13f03b8
--- /dev/null
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+// Based on chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc:
+// Copyright (c) 2012 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 "webui_controller_factory_qt.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.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/task_scheduler_internals/task_scheduler_internals_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/features/features.h"
+#include "media/media_features.h"
+#include "ppapi/features/features.h"
+#include "printing/features/features.h"
+#include "ui/web_dialogs/web_dialog_ui.h"
+#include "url/gurl.h"
+
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+#include "chrome/browser/ui/webui/sandbox_internals_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"
+// #endif
+
+// #if defined(USE_NSS_CERTS) && defined(USE_AURA)
+// #include "chrome/browser/ui/webui/certificate_viewer_ui.h"
+// #endif
+
+// #if BUILDFLAG(ENABLE_EXTENSIONS)
+// #include "chrome/browser/extensions/extension_web_ui.h"
+// #include "chrome/browser/ui/webui/extensions/extensions_ui.h"
+// #include "chrome/common/extensions/extension_constants.h"
+// #include "extensions/browser/extension_registry.h"
+// #include "extensions/browser/extension_system.h"
+// #include "extensions/common/constants.h"
+// #include "extensions/common/extension.h"
+// #include "extensions/common/feature_switch.h"
+// #include "extensions/common/manifest.h"
+// #endif
+
+using content::WebUI;
+using content::WebUIController;
+
+namespace {
+
+// A function for creating a new WebUI. The caller owns the return value, which
+// may be NULL (for example, if the URL refers to an non-existent extension).
+typedef WebUIController* (*WebUIFactoryFunction)(WebUI *web_ui, const GURL &url);
+
+// Template for defining WebUIFactoryFunction.
+template<class T>
+WebUIController *NewWebUI(WebUI *web_ui, const GURL &/*url*/)
+{
+ return new T(web_ui);
+}
+
+// Returns a function that can be used to create the right type of WebUI for a
+// tab, based on its URL. Returns NULL if the URL doesn't have WebUI associated
+// with it.
+WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, const GURL &url)
+{
+ // 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;
+
+ // 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::kChromeUITaskSchedulerInternalsHost)
+ return &NewWebUI<TaskSchedulerInternalsUI>;
+
+ if (url.SchemeIs(content::kChromeDevToolsScheme)) {
+// if (!DevToolsUIBindings::IsValidFrontendURL(url))
+// return nullptr;
+ return &NewWebUI<DevToolsUI>;
+ }
+
+// if (url.host_piece() == chrome::kChromeUIUserActionsHost)
+// return &NewWebUI<UserActionsUI>;
+// if (url.host_piece() == chrome::kChromeUIInspectHost)
+// return &NewWebUI<InspectUI>;
+//
+//#if defined(USE_NSS_CERTS) && defined(USE_AURA)
+// if (url.host_piece() == chrome::kChromeUICertificateViewerHost)
+// return &NewWebUI<CertificateViewerUI>;
+//#endif // USE_NSS_CERTS && USE_AURA
+//#if BUILDFLAG(ENABLE_EXTENSIONS)
+// 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 (url.host_piece() == chrome::kChromeUISandboxHost)
+ return &NewWebUI<SandboxInternalsUI>;
+#endif
+ return nullptr;
+}
+
+} // namespace
+
+namespace QtWebEngineCore {
+
+WebUI::TypeID WebUIControllerFactoryQt::GetWebUIType(content::BrowserContext *browser_context, const GURL &url) const
+{
+ 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
+{
+ return GetWebUIType(browser_context, url) != WebUI::kNoWebUI;
+}
+
+bool WebUIControllerFactoryQt::UseWebUIBindingsForURL(content::BrowserContext *browser_context, const GURL &url) const
+{
+ return UseWebUIForURL(browser_context, url);
+}
+
+WebUIController *WebUIControllerFactoryQt::CreateWebUIControllerForURL(WebUI *web_ui, const GURL &url) const
+{
+ Profile *profile = Profile::FromWebUI(web_ui);
+ WebUIFactoryFunction function = GetWebUIFactoryFunction(web_ui, profile, url);
+ if (!function)
+ return nullptr;
+
+ return (*function)(web_ui, url);
+}
+
+// static
+WebUIControllerFactoryQt *WebUIControllerFactoryQt::GetInstance()
+{
+ return base::Singleton<WebUIControllerFactoryQt>::get();
+}
+
+WebUIControllerFactoryQt::WebUIControllerFactoryQt()
+{
+}
+
+WebUIControllerFactoryQt::~WebUIControllerFactoryQt()
+{
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/webui_controller_factory_qt.h b/src/core/net/webui_controller_factory_qt.h
new file mode 100644
index 000000000..440dd5a13
--- /dev/null
+++ b/src/core/net/webui_controller_factory_qt.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#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 {
+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;
+ content::WebUIController *CreateWebUIControllerForURL(content::WebUI *webUi, const GURL &url) const override;
+
+ static WebUIControllerFactoryQt *GetInstance();
+
+protected:
+ WebUIControllerFactoryQt();
+ ~WebUIControllerFactoryQt() override;
+
+private:
+ friend struct base::DefaultSingletonTraits<WebUIControllerFactoryQt>;
+
+ DISALLOW_COPY_AND_ASSIGN(WebUIControllerFactoryQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // WEB_UI_CONTROLLER_FACTORY_QT_H_