diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-03-12 12:55:30 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-03-20 00:35:30 +0000 |
commit | 831d20bfb1bd677245c1fbdd5ded0fc757c44541 (patch) | |
tree | cee7be7e1339515100d0b525363682a87a91e50a /src/core/net/network_delegate_qt.cpp | |
parent | ff2cccda960027744e63392a6b6ef6ef8a4657ba (diff) |
Cleanup file locations
Move printing and network specific classes to subdirectories so we have
fewer files in the main dir.
Change-Id: I675b1b8b8fd1588061104cec181087f305b44f98
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
Diffstat (limited to 'src/core/net/network_delegate_qt.cpp')
-rw-r--r-- | src/core/net/network_delegate_qt.cpp | 390 |
1 files changed, 390 insertions, 0 deletions
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 |