summaryrefslogtreecommitdiffstats
path: root/src/core/network_delegate_qt.cpp
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@digia.com>2014-07-25 15:53:07 +0200
committerAndras Becsi <andras.becsi@digia.com>2014-08-06 17:20:17 +0200
commitca30d0374020752d3ac367fdffef88a5c1fe4a48 (patch)
treed93bb8ca51657febaee379e86c422d91b905a68b /src/core/network_delegate_qt.cpp
parent7d90b44187cfa8f93df6a6341da41cf8192d18ad (diff)
Add QQuick API for intercepting navigation requests
Add missing navigationRequested API to be able to intercept navigation requests. This is useful for ignoring requests for example in kiosk-like applications that want to restrinct navigation to a specific url or domain, or want to disable specific types of navigation requests (e.g. reloading, clicking links, form submissions). Change-Id: Ie375e635a3c3566527972d05f5d99b39489c5ca8 Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'src/core/network_delegate_qt.cpp')
-rw-r--r--src/core/network_delegate_qt.cpp140
1 files changed, 139 insertions, 1 deletions
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp
index 27807c499..424d0e631 100644
--- a/src/core/network_delegate_qt.cpp
+++ b/src/core/network_delegate_qt.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -40,3 +40,141 @@
****************************************************************************/
#include "network_delegate_qt.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/resource_request_details.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/common/page_transition_types.h"
+#include "net/base/load_flags.h"
+#include "net/url_request/url_request.h"
+#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+
+namespace {
+
+int pageTransitionToNavigationType(content::PageTransition transition)
+{
+ int32 qualifier = content::PageTransitionGetQualifier(transition);
+
+ if (qualifier & content::PAGE_TRANSITION_FORWARD_BACK)
+ return WebContentsAdapterClient::BackForwardNavigation;
+
+ content::PageTransition stippedTransition = content::PageTransitionStripQualifier(transition);
+
+ switch (stippedTransition) {
+ case content::PAGE_TRANSITION_LINK:
+ return WebContentsAdapterClient::LinkClickedNavigation;
+ case content::PAGE_TRANSITION_TYPED:
+ return WebContentsAdapterClient::TypedNavigation;
+ case content::PAGE_TRANSITION_FORM_SUBMIT:
+ return WebContentsAdapterClient::FormSubmittedNavigation;
+ case content::PAGE_TRANSITION_RELOAD:
+ return WebContentsAdapterClient::ReloadNavigation;
+ default:
+ return WebContentsAdapterClient::OtherNavigation;
+ }
+}
+
+}
+
+int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::CompletionCallback &callback, GURL *)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ const content::ResourceRequestInfo *info = content::ResourceRequestInfo::ForRequest(request);
+ int renderProcessId;
+ int renderViewId;
+ if (!info || !info->GetRenderViewForRequest(request, &renderProcessId, &renderViewId))
+ // Abort the request if it has no associated render info / render view.
+ return net::ERR_ABORTED;
+
+ ResourceType::Type resourceType = info->GetResourceType();
+ // Only intercept MAIN_FRAME and SUB_FRAME.
+ if (!ResourceType::IsFrame(resourceType))
+ return net::OK;
+
+ // Track active requests since |callback| and |new_url| are valid
+ // only until OnURLRequestDestroyed is called for this request.
+ m_activeRequests.insert(request);
+
+ int navigationType = pageTransitionToNavigationType(info->GetPageTransition());
+
+ RequestParams params = {
+ toQt(request->url()),
+ resourceType == ResourceType::MAIN_FRAME,
+ navigationType,
+ renderProcessId,
+ renderViewId
+ };
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&NetworkDelegateQt::NotifyNavigationRequestedOnUIThread,
+ base::Unretained(this),
+ request,
+ params,
+ callback)
+ );
+
+ // We'll run the callback after we notified the UI thread.
+ return net::ERR_IO_PENDING;
+}
+
+void NetworkDelegateQt::OnURLRequestDestroyed(net::URLRequest* request)
+{
+ m_activeRequests.remove(request);
+}
+
+void NetworkDelegateQt::CompleteURLRequestOnIOThread(net::URLRequest *request,
+ int navigationRequestAction,
+ const net::CompletionCallback &callback)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ if (!m_activeRequests.contains(request))
+ return;
+
+ int error = net::OK;
+ switch (navigationRequestAction) {
+ case WebContentsAdapterClient::AcceptRequest:
+ error = net::OK;
+ break;
+ case WebContentsAdapterClient::IgnoreRequest:
+ error = net::OK;
+ // We can cancel the request here since we are on the IO thread.
+ request->Cancel();
+ break;
+ default:
+ error = net::ERR_FAILED;
+ Q_UNREACHABLE();
+ }
+ callback.Run(error);
+}
+
+void NetworkDelegateQt::NotifyNavigationRequestedOnUIThread(net::URLRequest *request,
+ RequestParams params,
+ const net::CompletionCallback &callback)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ content::RenderViewHost *rvh = content::RenderViewHost::FromID(params.renderProcessId, params.renderViewId);
+
+ if (rvh) {
+ content::WebContents *webContents = content::WebContents::FromRenderViewHost(rvh);
+ WebContentsAdapterClient *client = WebContentsViewQt::from(webContents->GetView())->client();
+ client->navigationRequested(params.navigationType, params.url, navigationRequestAction, params.isMainFrameRequest);
+ }
+
+ // Run the callback on the IO thread.
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&NetworkDelegateQt::CompleteURLRequestOnIOThread,
+ base::Unretained(this),
+ request,
+ navigationRequestAction,
+ callback)
+ );
+}