diff options
author | Andras Becsi <andras.becsi@theqtcompany.com> | 2015-07-10 17:27:45 +0200 |
---|---|---|
committer | Andras Becsi <andras.becsi@theqtcompany.com> | 2015-08-03 20:46:55 +0000 |
commit | e11cd75ff506e8dcbfc990d70baeec821f1f0563 (patch) | |
tree | db4e58d9b0c66656e5eccb368dd61cdb36034c75 /src/core/network_delegate_qt.cpp | |
parent | 853d5867644fd53f2d779c3c7b39a34803a3e566 (diff) |
Add API for intercepting url requests
This patch is adding a QWebEngineUrlRequestInterceptor interface
that can be subclassed to observe or intercept all resource requests
making it possible to implement browser features like adblocking
and setting custom request headers for url requests.
The interceptRequest virtual function is executed on the IO thread.
This patch also includes a unit test for the testable API parts.
Change-Id: Ibe740fc55551a9a5da40794088ccb6d03d913631
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Reviewed-by: Martin Rotter <rotter.martinos@gmail.com>
Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'src/core/network_delegate_qt.cpp')
-rw-r--r-- | src/core/network_delegate_qt.cpp | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp index 0d1b2b558..5af781007 100644 --- a/src/core/network_delegate_qt.cpp +++ b/src/core/network_delegate_qt.cpp @@ -36,31 +36,37 @@ #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_details.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 { -int pageTransitionToNavigationType(ui::PageTransition transition) +static int pageTransitionToNavigationType(ui::PageTransition transition) { int32 qualifier = ui::PageTransitionGetQualifier(transition); if (qualifier & ui::PAGE_TRANSITION_FORWARD_BACK) return WebContentsAdapterClient::BackForwardNavigation; - ui::PageTransition stippedTransition = ui::PageTransitionStripQualifier(transition); + ui::PageTransition strippedTransition = ui::PageTransitionStripQualifier(transition); - switch (stippedTransition) { + switch (strippedTransition) { case ui::PAGE_TRANSITION_LINK: - return WebContentsAdapterClient::LinkClickedNavigation; + return WebContentsAdapterClient::LinkNavigation; case ui::PAGE_TRANSITION_TYPED: return WebContentsAdapterClient::TypedNavigation; case ui::PAGE_TRANSITION_FORM_SUBMIT: @@ -72,29 +78,68 @@ int pageTransitionToNavigationType(ui::PageTransition transition) } } -int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::CompletionCallback &callback, GURL *) +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)); - const content::ResourceRequestInfo *info = content::ResourceRequestInfo::ForRequest(request); - if (!info) + Q_ASSERT(m_requestContextGetter); + Q_ASSERT(m_requestContextGetter->m_browserContext); + + const content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request); + + content::ResourceType resourceType = content::RESOURCE_TYPE_LAST_TYPE; + int navigationType = QWebEngineUrlRequestInfo::NavigationTypeOther; + + if (resourceInfo) { + resourceType = resourceInfo->GetResourceType(); + navigationType = pageTransitionToNavigationType(resourceInfo->GetPageTransition()); + } + + const QUrl qUrl = toQt(request->url()); + + QWebEngineUrlRequestInterceptor* interceptor = m_requestContextGetter->m_browserContext->requestInterceptor(); + if (interceptor) { + QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType) + , static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType) + , qUrl + , QByteArray::fromStdString(request->method())); + QWebEngineUrlRequestInfo requestInfo(infoPrivate); + if (interceptor->interceptRequest(requestInfo)) { + int result = infoPrivate->shouldBlockRequest ? net::ERR_ABORTED : 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); + } + + return result; + } + } + + if (!resourceInfo) return net::OK; - content::ResourceType resourceType = info->GetResourceType(); int renderProcessId; int renderFrameId; // Only intercept MAIN_FRAME and SUB_FRAME with an associated render frame. - if (!content::IsResourceTypeFrame(resourceType) || !info->GetRenderFrameForRequest(request, &renderProcessId, &renderFrameId)) + if (!content::IsResourceTypeFrame(resourceType) || !resourceInfo->GetRenderFrameForRequest(request, &renderProcessId, &renderFrameId)) 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()), - info->IsMainFrame(), + qUrl, + resourceInfo->IsMainFrame(), navigationType, renderProcessId, renderFrameId |