diff options
author | huangs <huangs@chromium.org> | 2015-09-22 08:31:17 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-22 15:31:46 +0000 |
commit | 2ad8595f7a925851acd3ae733f359fafe6223ff5 (patch) | |
tree | fce8d86113ac940ca73aa60b64c69a2b86c3de01 | |
parent | 289e7a8ecb6208275d28f6f5651f22943f85af49 (diff) | |
download | chromium_src-2ad8595f7a925851acd3ae733f359fafe6223ff5.zip chromium_src-2ad8595f7a925851acd3ae733f359fafe6223ff5.tar.gz chromium_src-2ad8595f7a925851acd3ae733f359fafe6223ff5.tar.bz2 |
Revert of Add a NavigationThrottle to the public content/ interface (patchset #18 id:350001 of https://codereview.chromium.org/1269813002/ )
Reason for revert:
linux_chromiium_chromeos_rel_ng => browser_test => SelectFileDialogExtensionBrowserTest seems to faile a lot, testing.
Original issue's description:
> Add a NavigationThrottle to the public content/ interface
>
> This CL adds a NavigationThrottle class to the public content/ interface. A NavigationThrottle is used to control the flow of navigations. It lives entirely on the UI thread. Eventually, all components that want the functionality of a ResourceThrottle for navigations should transition to a NavigationThrottle: the new architecture for navigations (browser-side navigation) will not support ResourceThrottles for main resources load. See https://docs.google.com/document/d/1ICLLQoC9EsZ-bWH4ZKRhPCIoZKn6pOj02SlGl6SKH6Y/edit?pli=1#heading=h.fmxjmgvbgg7x for the design doc.
>
> This Cl also transition the InterceptNavigationresourceThrottle to the Navigationthrottle model.
> BUG=504347
>
> Committed: https://crrev.com/394057986ff5d00a841a976f3bd8d599603acaa1
> Cr-Commit-Position: refs/heads/master@{#350092}
TBR=nasko@chromium.org,davidben@chromium.org,carlosk@chromium.org,fdegans@chromium.org,avi@chromium.org,creis@chromium.org,nick@chromium.org,asargent@chromium.org,sky@chromium.org,mnaganov@chromium.org,clamy@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=504347
Review URL: https://codereview.chromium.org/1350913008
Cr-Commit-Position: refs/heads/master@{#350157}
36 files changed, 820 insertions, 1025 deletions
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index ab14d49..759c844 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc @@ -25,13 +25,10 @@ #include "base/command_line.h" #include "base/path_service.h" #include "components/cdm/browser/cdm_message_filter_android.h" -#include "components/navigation_interception/intercept_navigation_delegate.h" #include "content/public/browser/access_token_store.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/client_certificate_delegate.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/navigation_throttle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -490,22 +487,6 @@ void AwContentBrowserClient::OverrideWebkitPrefs( content::WebContents::FromRenderViewHost(rvh), web_prefs); } -ScopedVector<content::NavigationThrottle> -AwContentBrowserClient::CreateThrottlesForNavigation( - content::NavigationHandle* navigation_handle) { - ScopedVector<content::NavigationThrottle> throttles; - if (navigation_handle->IsInMainFrame() || - (!navigation_handle->GetURL().SchemeIs(url::kHttpScheme) && - !navigation_handle->GetURL().SchemeIs(url::kHttpsScheme) && - !navigation_handle->GetURL().SchemeIs(url::kAboutScheme))) { - throttles.push_back( - navigation_interception::InterceptNavigationDelegate::CreateThrottleFor( - navigation_handle) - .Pass()); - } - return throttles.Pass(); -} - #if defined(VIDEO_HOLE) content::ExternalVideoSurfaceContainer* AwContentBrowserClient::OverrideCreateExternalVideoSurfaceContainer( diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index a3a814e..d811cf2 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h @@ -142,8 +142,6 @@ class AwContentBrowserClient : public content::ContentBrowserClient { std::map<int, base::MemoryMappedFile::Region>* regions) override; void OverrideWebkitPrefs(content::RenderViewHost* rvh, content::WebPreferences* web_prefs) override; - ScopedVector<content::NavigationThrottle> CreateThrottlesForNavigation( - content::NavigationHandle* navigation_handle) override; #if defined(VIDEO_HOLE) content::ExternalVideoSurfaceContainer* OverrideCreateExternalVideoSurfaceContainer( diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc index ed7c52b..1d9e585 100644 --- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc @@ -221,6 +221,14 @@ void AwResourceDispatcherHostDelegate::RequestBeginning( throttles->push_back(new IoThreadClientThrottle( request_info->GetChildID(), request_info->GetRenderFrameID(), request)); + if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME || + (resource_type == content::RESOURCE_TYPE_SUB_FRAME && + !request->url().SchemeIs(url::kHttpScheme) && + !request->url().SchemeIs(url::kHttpsScheme) && + !request->url().SchemeIs(url::kAboutScheme))) { + throttles->push_back(InterceptNavigationDelegate::CreateThrottleFor( + request)); + } if (resource_type != content::RESOURCE_TYPE_MAIN_FRAME) InterceptNavigationDelegate::UpdateUserGestureCarryoverInfo(request); } diff --git a/chrome/browser/apps/app_url_redirector.cc b/chrome/browser/apps/app_url_redirector.cc index 6396293..cf15169 100644 --- a/chrome/browser/apps/app_url_redirector.cc +++ b/chrome/browser/apps/app_url_redirector.cc @@ -9,18 +9,22 @@ #include "base/logging.h" #include "chrome/browser/prerender/prerender_contents.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_io_data.h" #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" -#include "components/navigation_interception/intercept_navigation_throttle.h" +#include "components/navigation_interception/intercept_navigation_resource_throttle.h" #include "components/navigation_interception/navigation_params.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/resource_request_info.h" +#include "content/public/browser/resource_throttle.h" #include "content/public/browser/web_contents.h" -#include "extensions/browser/extension_registry.h" +#include "extensions/browser/info_map.h" #include "extensions/common/extension.h" #include "extensions/common/extension_set.h" #include "net/url_request/url_request.h" using content::BrowserThread; +using content::ResourceRequestInfo; using content::WebContents; using extensions::Extension; using extensions::UrlHandlers; @@ -51,8 +55,8 @@ bool LaunchAppWithUrl( } // These are guaranteed by CreateThrottleFor below. - DCHECK(UrlHandlers::CanExtensionHandleUrl(app.get(), params.url())); DCHECK(!params.is_post()); + DCHECK(UrlHandlers::CanExtensionHandleUrl(app.get(), params.url())); Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); @@ -69,54 +73,57 @@ bool LaunchAppWithUrl( } // namespace // static -scoped_ptr<content::NavigationThrottle> -AppUrlRedirector::MaybeCreateThrottleFor(content::NavigationHandle* handle) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DVLOG(1) << "Considering URL for redirection: " << handle->GetURL().spec(); - - content::BrowserContext* browser_context = - handle->GetWebContents()->GetBrowserContext(); - DCHECK(browser_context); +content::ResourceThrottle* +AppUrlRedirector::MaybeCreateThrottleFor(net::URLRequest* request, + ProfileIOData* profile_io_data) { + DVLOG(1) << "Considering URL for redirection: " + << request->method() << " " << request->url().spec(); // Support only GET for now. - if (handle->IsPost()) { + if (request->method() != "GET") { DVLOG(1) << "Skip redirection: method is not GET"; - return nullptr; + return NULL; } - if (!handle->GetURL().SchemeIsHTTPOrHTTPS()) { + if (!request->url().SchemeIsHTTPOrHTTPS()) { DVLOG(1) << "Skip redirection: scheme is not HTTP or HTTPS"; - return nullptr; + return NULL; + } + + // The user has indicated that a URL should be force downloaded. Turn off + // URL redirection in this case. + if (ResourceRequestInfo::ForRequest(request)->IsDownload()) { + DVLOG(1) << "Skip redirection: request is a forced download"; + return NULL; } // Never redirect URLs to apps in incognito. Technically, apps are not // supported in incognito, but that may change in future. // See crbug.com/240879, which tracks incognito support for v2 apps. - Profile* profile = Profile::FromBrowserContext(browser_context); - if (profile->GetProfileType() == Profile::INCOGNITO_PROFILE) { + if (profile_io_data->IsOffTheRecord()) { DVLOG(1) << "Skip redirection: unsupported in incognito"; - return nullptr; + return NULL; } - const extensions::ExtensionSet& enabled_extensions = - extensions::ExtensionRegistry::Get(browser_context)->enabled_extensions(); - for (extensions::ExtensionSet::const_iterator iter = - enabled_extensions.begin(); - iter != enabled_extensions.end(); ++iter) { + const extensions::ExtensionSet& extensions = + profile_io_data->GetExtensionInfoMap()->extensions(); + for (extensions::ExtensionSet::const_iterator iter = extensions.begin(); + iter != extensions.end(); + ++iter) { const UrlHandlerInfo* handler = - UrlHandlers::FindMatchingUrlHandler(iter->get(), handle->GetURL()); + UrlHandlers::FindMatchingUrlHandler(iter->get(), request->url()); if (handler) { DVLOG(1) << "Found matching app handler for redirection: " << (*iter)->name() << "(" << (*iter)->id() << "):" << handler->id; - return scoped_ptr<content::NavigationThrottle>( - new navigation_interception::InterceptNavigationThrottle( - handle, - base::Bind(&LaunchAppWithUrl, - scoped_refptr<const Extension>(*iter), handler->id))); + return new navigation_interception::InterceptNavigationResourceThrottle( + request, + base::Bind(&LaunchAppWithUrl, + scoped_refptr<const Extension>(*iter), + handler->id)); } } DVLOG(1) << "Skipping redirection: no matching app handler found"; - return nullptr; + return NULL; } diff --git a/chrome/browser/apps/app_url_redirector.h b/chrome/browser/apps/app_url_redirector.h index 629af37..331d7b4 100644 --- a/chrome/browser/apps/app_url_redirector.h +++ b/chrome/browser/apps/app_url_redirector.h @@ -6,22 +6,24 @@ #define CHROME_BROWSER_APPS_APP_URL_REDIRECTOR_H_ #include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "content/public/browser/navigation_throttle.h" namespace content { -class NavigationHandle; -class NavigationThrottle; -class WebContents; +class ResourceThrottle; } -// This class creates navigation throttles that redirect URLs to apps that have -// a matching URL handler in the 'url_handlers' manifest key. Note that this is -// a UI thread class. +namespace net { +class URLRequest; +} + +class ProfileIOData; + +// This class creates resource throttles that redirect URLs to apps that +// have a matching URL handler in the 'url_handlers' manifest key. class AppUrlRedirector { public: - static scoped_ptr<content::NavigationThrottle> MaybeCreateThrottleFor( - content::NavigationHandle* handle); + static content::ResourceThrottle* MaybeCreateThrottleFor( + net::URLRequest* request, + ProfileIOData* profile_io_data); private: DISALLOW_COPY_AND_ASSIGN(AppUrlRedirector); diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index bbe1c07..25f4aa4 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -24,7 +24,6 @@ #include "base/thread_task_runner_handle.h" #include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/after_startup_task_utils.h" -#include "chrome/browser/apps/app_url_redirector.h" #include "chrome/browser/browser_about_handler.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_shutdown.h" @@ -121,8 +120,6 @@ #include "content/public/browser/child_process_data.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/client_certificate_delegate.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/navigation_throttle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -176,7 +173,6 @@ #include "chrome/browser/chrome_browser_main_android.h" #include "chrome/common/descriptors_android.h" #include "components/crash/content/browser/crash_dump_manager_android.h" -#include "components/navigation_interception/intercept_navigation_delegate.h" #include "components/service_tab_launcher/browser/android/service_tab_launcher.h" #include "ui/base/resource/resource_bundle_android.h" #elif defined(OS_POSIX) @@ -2602,34 +2598,6 @@ void ChromeContentBrowserClient::RecordURLMetric(const std::string& metric, } } -ScopedVector<content::NavigationThrottle> -ChromeContentBrowserClient::CreateThrottlesForNavigation( - content::NavigationHandle* handle) { - ScopedVector<content::NavigationThrottle> throttles; -#if defined(OS_ANDROID) - // TODO(davidben): This is insufficient to integrate with prerender properly. - // https://crbug.com/370595 - prerender::PrerenderContents* prerender_contents = - prerender::PrerenderContents::FromWebContents(handle->GetWebContents()); - if (!prerender_contents && handle->IsInMainFrame()) { - throttles.push_back( - navigation_interception::InterceptNavigationDelegate::CreateThrottleFor( - handle) - .Pass()); - } -#else - if (handle->IsInMainFrame()) { - // Redirect some navigations to apps that have registered matching URL - // handlers ('url_handlers' in the manifest). - scoped_ptr<content::NavigationThrottle> url_to_app_throttle = - AppUrlRedirector::MaybeCreateThrottleFor(handle); - if (url_to_app_throttle) - throttles.push_back(url_to_app_throttle.Pass()); - } -#endif - return throttles.Pass(); -} - content::DevToolsManagerDelegate* ChromeContentBrowserClient::GetDevToolsManagerDelegate() { return new ChromeDevToolsManagerDelegate(); diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 1e2e97f..a8b6270 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -285,8 +285,6 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { content::WebContents* web_contents) override; void RecordURLMetric(const std::string& metric, const GURL& url) override; - ScopedVector<content::NavigationThrottle> CreateThrottlesForNavigation( - content::NavigationHandle* handle) override; private: friend class DisableWebRtcEncryptionFlagTest; diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc index b28332e..aa4705e 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc @@ -339,8 +339,25 @@ void ChromeResourceDispatcherHostDelegate::RequestBeginning( resource_context); #if defined(OS_ANDROID) - if (resource_type != content::RESOURCE_TYPE_MAIN_FRAME) - InterceptNavigationDelegate::UpdateUserGestureCarryoverInfo(request); + // TODO(davidben): This is insufficient to integrate with prerender properly. + // https://crbug.com/370595 + if (!is_prerendering) { + if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) { + throttles->push_back( + InterceptNavigationDelegate::CreateThrottleFor(request)); + } else { + InterceptNavigationDelegate::UpdateUserGestureCarryoverInfo(request); + } + } +#else + if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) { + // Redirect some navigations to apps that have registered matching URL + // handlers ('url_handlers' in the manifest). + content::ResourceThrottle* url_to_app_throttle = + AppUrlRedirector::MaybeCreateThrottleFor(request, io_data); + if (url_to_app_throttle) + throttles->push_back(url_to_app_throttle); + } #endif #if defined(OS_CHROMEOS) diff --git a/components/components_tests.gyp b/components/components_tests.gyp index f2917db..c3dd97c 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp @@ -354,7 +354,7 @@ 'nacl/zygote/nacl_fork_delegate_linux_unittest.cc', ], 'navigation_interception_unittest_sources': [ - 'navigation_interception/intercept_navigation_throttle_unittest.cc', + 'navigation_interception/intercept_navigation_resource_throttle_unittest.cc', ], 'network_hints_unittest_sources': [ 'network_hints/renderer/dns_prefetch_queue_unittest.cc', diff --git a/components/navigation_interception.gypi b/components/navigation_interception.gypi index 7ccc4cd..3511201 100644 --- a/components/navigation_interception.gypi +++ b/components/navigation_interception.gypi @@ -23,8 +23,8 @@ ], 'sources': [ # Note: sources list duplicated in GN build. - 'navigation_interception/intercept_navigation_throttle.cc', - 'navigation_interception/intercept_navigation_throttle.h', + 'navigation_interception/intercept_navigation_resource_throttle.cc', + 'navigation_interception/intercept_navigation_resource_throttle.h', 'navigation_interception/navigation_params.cc', 'navigation_interception/navigation_params.h', ], diff --git a/components/navigation_interception/BUILD.gn b/components/navigation_interception/BUILD.gn index f268510..12456ff 100644 --- a/components/navigation_interception/BUILD.gn +++ b/components/navigation_interception/BUILD.gn @@ -8,8 +8,8 @@ if (is_android) { source_set("navigation_interception") { sources = [ - "intercept_navigation_throttle.cc", - "intercept_navigation_throttle.h", + "intercept_navigation_resource_throttle.cc", + "intercept_navigation_resource_throttle.h", "navigation_params.cc", "navigation_params.h", ] @@ -49,7 +49,7 @@ if (is_android) { source_set("unit_tests") { testonly = true sources = [ - "intercept_navigation_throttle_unittest.cc", + "intercept_navigation_resource_throttle_unittest.cc", ] deps = [ ":navigation_interception", diff --git a/components/navigation_interception/intercept_navigation_delegate.cc b/components/navigation_interception/intercept_navigation_delegate.cc index 11017f3b..ba9053d 100644 --- a/components/navigation_interception/intercept_navigation_delegate.cc +++ b/components/navigation_interception/intercept_navigation_delegate.cc @@ -7,10 +7,9 @@ #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/callback.h" -#include "components/navigation_interception/intercept_navigation_throttle.h" +#include "components/navigation_interception/intercept_navigation_resource_throttle.h" #include "components/navigation_interception/navigation_params_android.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/navigation_throttle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_request_info.h" @@ -84,12 +83,10 @@ InterceptNavigationDelegate* InterceptNavigationDelegate::Get( } // static -scoped_ptr<content::NavigationThrottle> -InterceptNavigationDelegate::CreateThrottleFor( - content::NavigationHandle* handle) { - return scoped_ptr<content::NavigationThrottle>( - new InterceptNavigationThrottle( - handle, base::Bind(&CheckIfShouldIgnoreNavigationOnUIThread))); +content::ResourceThrottle* InterceptNavigationDelegate::CreateThrottleFor( + net::URLRequest* request) { + return new InterceptNavigationResourceThrottle( + request, base::Bind(&CheckIfShouldIgnoreNavigationOnUIThread)); } // static diff --git a/components/navigation_interception/intercept_navigation_delegate.h b/components/navigation_interception/intercept_navigation_delegate.h index 57858fd..d84969f 100644 --- a/components/navigation_interception/intercept_navigation_delegate.h +++ b/components/navigation_interception/intercept_navigation_delegate.h @@ -12,8 +12,7 @@ class GURL; namespace content { -class NavigationHandle; -class NavigationThrottle; +class ResourceThrottle; class WebContents; } @@ -33,8 +32,9 @@ class NavigationParams; // 1) the Java-side interface implementation must be associated (via the // Associate method) with a WebContents for which URLRequests are to be // intercepted, -// 2) the NavigationThrottle obtained via CreateThrottleFor must be associated -// with the NavigationHandle in the ContentBrowserClient implementation. +// 2) the ResourceThrottle obtained via CreateThrottleFor must be associated +// with the URLRequests in the ResourceDispatcherHostDelegate +// implementation. class InterceptNavigationDelegate : public base::SupportsUserData::Data { public: InterceptNavigationDelegate(JNIEnv* env, jobject jdelegate); @@ -50,10 +50,10 @@ class InterceptNavigationDelegate : public base::SupportsUserData::Data { // can be null. static InterceptNavigationDelegate* Get(content::WebContents* web_contents); - // Creates a InterceptNavigationThrottle that will direct all callbacks to - // the InterceptNavigationDelegate. - static scoped_ptr<content::NavigationThrottle> CreateThrottleFor( - content::NavigationHandle* handle); + // Creates a InterceptNavigationResourceThrottle that will direct all + // callbacks to the InterceptNavigationDelegate. + static content::ResourceThrottle* CreateThrottleFor( + net::URLRequest* request); // Updates information to determine whether to have user gesture carryover or // not. diff --git a/components/navigation_interception/intercept_navigation_resource_throttle.cc b/components/navigation_interception/intercept_navigation_resource_throttle.cc new file mode 100644 index 0000000..1b0b89f --- /dev/null +++ b/components/navigation_interception/intercept_navigation_resource_throttle.cc @@ -0,0 +1,146 @@ +// 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 "components/navigation_interception/intercept_navigation_resource_throttle.h" + +#include "components/navigation_interception/navigation_params.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/resource_context.h" +#include "content/public/browser/resource_controller.h" +#include "content/public/browser/resource_request_info.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/referrer.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/redirect_info.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_job_factory.h" +#include "net/url_request/url_request.h" +#include "ui/base/page_transition_types.h" + +using content::BrowserThread; +using content::ChildProcessSecurityPolicy; +using ui::PageTransition; +using content::Referrer; +using content::RenderProcessHost; +using content::ResourceRequestInfo; + +namespace navigation_interception { + +namespace { + +void CheckIfShouldIgnoreNavigationOnUIThread( + int render_process_id, + int render_frame_id, + const NavigationParams& navigation_params, + InterceptNavigationResourceThrottle::CheckOnUIThreadCallback + should_ignore_callback, + base::Callback<void(bool)> callback) { + bool should_ignore_navigation = false; + RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id); + if (rph) { + NavigationParams validated_params(navigation_params); + rph->FilterURL(false, &validated_params.url()); + + content::RenderFrameHost* render_frame_host = + content::RenderFrameHost::FromID(render_process_id, render_frame_id); + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(render_frame_host); + + if (web_contents) { + should_ignore_navigation = should_ignore_callback.Run(web_contents, + validated_params); + } + } + + BrowserThread::PostTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(callback, should_ignore_navigation)); +} + +} // namespace + +InterceptNavigationResourceThrottle::InterceptNavigationResourceThrottle( + net::URLRequest* request, + CheckOnUIThreadCallback should_ignore_callback) + : request_(request), + should_ignore_callback_(should_ignore_callback), + weak_ptr_factory_(this) { +} + +InterceptNavigationResourceThrottle::~InterceptNavigationResourceThrottle() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); +} + +void InterceptNavigationResourceThrottle::WillStartRequest(bool* defer) { + *defer = + CheckIfShouldIgnoreNavigation(request_->url(), request_->method(), false); +} + +void InterceptNavigationResourceThrottle::WillRedirectRequest( + const net::RedirectInfo& redirect_info, + bool* defer) { + *defer = CheckIfShouldIgnoreNavigation(redirect_info.new_url, + redirect_info.new_method, true); +} + +const char* InterceptNavigationResourceThrottle::GetNameForLogging() const { + return "InterceptNavigationResourceThrottle"; +} + +bool InterceptNavigationResourceThrottle::CheckIfShouldIgnoreNavigation( + const GURL& url, + const std::string& method, + bool is_redirect) { + const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); + if (!info) + return false; + + int render_process_id, render_frame_id; + if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) + return false; + + bool is_external_protocol = + !info->GetContext()->GetRequestContext()->job_factory()->IsHandledURL( + url); + NavigationParams navigation_params( + url, + Referrer::SanitizeForRequest( + url, Referrer(GURL(request_->referrer()), info->GetReferrerPolicy())), + info->HasUserGesture(), method == "POST", info->GetPageTransition(), + is_redirect, is_external_protocol, true); + + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind( + &CheckIfShouldIgnoreNavigationOnUIThread, + render_process_id, + render_frame_id, + navigation_params, + should_ignore_callback_, + base::Bind( + &InterceptNavigationResourceThrottle::OnResultObtained, + weak_ptr_factory_.GetWeakPtr()))); + + // Defer request while we wait for the UI thread to check if the navigation + // should be ignored. + return true; +} + +void InterceptNavigationResourceThrottle::OnResultObtained( + bool should_ignore_navigation) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (should_ignore_navigation) { + controller()->CancelAndIgnore(); + } else { + controller()->Resume(); + } +} + +} // namespace navigation_interception diff --git a/components/navigation_interception/intercept_navigation_resource_throttle.h b/components/navigation_interception/intercept_navigation_resource_throttle.h new file mode 100644 index 0000000..db3a714 --- /dev/null +++ b/components/navigation_interception/intercept_navigation_resource_throttle.h @@ -0,0 +1,63 @@ +// 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. + +#ifndef COMPONENTS_NAVIGATION_INTERCEPTION_INTERCEPT_NAVIGATION_RESOURCE_THROTTLE_H_ +#define COMPONENTS_NAVIGATION_INTERCEPTION_INTERCEPT_NAVIGATION_RESOURCE_THROTTLE_H_ + +#include <string> + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "content/public/browser/resource_throttle.h" + +class GURL; + +namespace content { +class WebContents; +} + +namespace net { +class URLRequest; +} + +namespace navigation_interception { + +class NavigationParams; + +// This class allows the provider of the Callback to selectively ignore top +// level navigations. +class InterceptNavigationResourceThrottle : public content::ResourceThrottle { + public: + typedef base::Callback<bool( + content::WebContents* /* source */, + const NavigationParams& /* navigation_params */)> + CheckOnUIThreadCallback; + + InterceptNavigationResourceThrottle( + net::URLRequest* request, + CheckOnUIThreadCallback should_ignore_callback); + ~InterceptNavigationResourceThrottle() override; + + // content::ResourceThrottle implementation: + void WillStartRequest(bool* defer) override; + void WillRedirectRequest(const net::RedirectInfo& redirect_info, + bool* defer) override; + const char* GetNameForLogging() const override; + + private: + bool CheckIfShouldIgnoreNavigation(const GURL& url, + const std::string& method, + bool is_redirect); + void OnResultObtained(bool should_ignore_navigation); + + net::URLRequest* request_; + CheckOnUIThreadCallback should_ignore_callback_; + base::WeakPtrFactory<InterceptNavigationResourceThrottle> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(InterceptNavigationResourceThrottle); +}; + +} // namespace navigation_interception + +#endif // COMPONENTS_NAVIGATION_INTERCEPTION_INTERCEPT_NAVIGATION_RESOURCE_THROTTLE_H_ diff --git a/components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc b/components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc new file mode 100644 index 0000000..8855f42 --- /dev/null +++ b/components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc @@ -0,0 +1,481 @@ +// 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 "base/bind.h" +#include "base/bind_helpers.h" +#include "base/memory/scoped_ptr.h" +#include "base/run_loop.h" +#include "base/synchronization/waitable_event.h" +#include "components/navigation_interception/intercept_navigation_resource_throttle.h" +#include "components/navigation_interception/navigation_params.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/resource_context.h" +#include "content/public/browser/resource_controller.h" +#include "content/public/browser/resource_dispatcher_host.h" +#include "content/public/browser/resource_dispatcher_host_delegate.h" +#include "content/public/browser/resource_request_info.h" +#include "content/public/browser/resource_throttle.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/test/mock_resource_context.h" +#include "content/public/test/test_renderer_host.h" +#include "net/base/request_priority.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_response_info.h" +#include "net/url_request/redirect_info.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using content::ResourceType; +using testing::_; +using testing::Eq; +using testing::Ne; +using testing::Property; +using testing::Return; + +namespace navigation_interception { + +namespace { + +const char kTestUrl[] = "http://www.test.com/"; +const char kUnsafeTestUrl[] = "about:crash"; + +// The MS C++ compiler complains about not being able to resolve which url() +// method (const or non-const) to use if we use the Property matcher to check +// the return value of the NavigationParams::url() method. +// It is possible to suppress the error by specifying the types directly but +// that results in very ugly syntax, which is why these custom matchers are +// used instead. +MATCHER(NavigationParamsUrlIsTest, "") { + return arg.url() == GURL(kTestUrl); +} + +MATCHER(NavigationParamsUrlIsSafe, "") { + return arg.url() != GURL(kUnsafeTestUrl); +} + +} // namespace + + +// MockInterceptCallbackReceiver ---------------------------------------------- + +class MockInterceptCallbackReceiver { + public: + MOCK_METHOD2(ShouldIgnoreNavigation, + bool(content::WebContents* source, + const NavigationParams& navigation_params)); +}; + +// MockResourceController ----------------------------------------------------- +class MockResourceController : public content::ResourceController { + public: + enum Status { + UNKNOWN, + RESUMED, + CANCELLED + }; + + MockResourceController() + : status_(UNKNOWN) { + } + + Status status() const { return status_; } + + // ResourceController: + void Cancel() override { NOTREACHED(); } + void CancelAndIgnore() override { status_ = CANCELLED; } + void CancelWithError(int error_code) override { NOTREACHED(); } + void Resume() override { + DCHECK(status_ == UNKNOWN); + status_ = RESUMED; + } + + private: + Status status_; +}; + +// TestIOThreadState ---------------------------------------------------------- + +enum RedirectMode { + REDIRECT_MODE_NO_REDIRECT, + REDIRECT_MODE_302, +}; + +class TestIOThreadState { + public: + TestIOThreadState(const GURL& url, + int render_process_id, + int render_frame_id, + const std::string& request_method, + RedirectMode redirect_mode, + MockInterceptCallbackReceiver* callback_receiver) + : resource_context_(&test_url_request_context_), + request_(resource_context_.GetRequestContext()->CreateRequest( + url, + net::DEFAULT_PRIORITY, + NULL /* delegate */)) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (render_process_id != MSG_ROUTING_NONE && + render_frame_id != MSG_ROUTING_NONE) { + content::ResourceRequestInfo::AllocateForTesting( + request_.get(), + content::RESOURCE_TYPE_MAIN_FRAME, + &resource_context_, + render_process_id, + MSG_ROUTING_NONE, + render_frame_id, + true, // is_main_frame + false, // parent_is_main_frame + true, // allow_download + false); // is_async + } + throttle_.reset(new InterceptNavigationResourceThrottle( + request_.get(), + base::Bind(&MockInterceptCallbackReceiver::ShouldIgnoreNavigation, + base::Unretained(callback_receiver)))); + throttle_->set_controller_for_testing(&throttle_controller_); + request_->set_method(request_method); + + if (redirect_mode == REDIRECT_MODE_302) { + net::HttpResponseInfo& response_info = + const_cast<net::HttpResponseInfo&>(request_->response_info()); + response_info.headers = new net::HttpResponseHeaders( + "Status: 302 Found\0\0"); + } + } + + void ThrottleWillStartRequest(bool* defer) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + throttle_->WillStartRequest(defer); + } + + void ThrottleWillRedirectRequest(const net::RedirectInfo& redirect_info, + bool* defer) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + throttle_->WillRedirectRequest(redirect_info, defer); + } + + bool request_resumed() const { + return throttle_controller_.status() == + MockResourceController::RESUMED; + } + + bool request_cancelled() const { + return throttle_controller_.status() == + MockResourceController::CANCELLED; + } + + private: + net::TestURLRequestContext test_url_request_context_; + content::MockResourceContext resource_context_; + scoped_ptr<net::URLRequest> request_; + scoped_ptr<InterceptNavigationResourceThrottle> throttle_; + MockResourceController throttle_controller_; +}; + +// InterceptNavigationResourceThrottleTest ------------------------------------ + +class InterceptNavigationResourceThrottleTest + : public content::RenderViewHostTestHarness { + public: + InterceptNavigationResourceThrottleTest() + : mock_callback_receiver_(new MockInterceptCallbackReceiver()), + io_thread_state_(NULL) { + } + + void SetUp() override { RenderViewHostTestHarness::SetUp(); } + + void TearDown() override { + if (web_contents()) + web_contents()->SetDelegate(NULL); + + content::BrowserThread::DeleteSoon( + content::BrowserThread::IO, FROM_HERE, io_thread_state_); + + RenderViewHostTestHarness::TearDown(); + } + + void SetIOThreadState(TestIOThreadState* io_thread_state) { + io_thread_state_ = io_thread_state; + } + + void RunThrottleWillStartRequestOnIOThread( + const GURL& url, + const std::string& request_method, + RedirectMode redirect_mode, + int render_process_id, + int render_frame_id, + bool* defer) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + TestIOThreadState* io_thread_state = + new TestIOThreadState(url, render_process_id, render_frame_id, + request_method, redirect_mode, + mock_callback_receiver_.get()); + + SetIOThreadState(io_thread_state); + + if (redirect_mode == REDIRECT_MODE_NO_REDIRECT) { + io_thread_state->ThrottleWillStartRequest(defer); + } else { + // 302 redirects convert POSTs to gets. + net::RedirectInfo redirect_info; + redirect_info.new_url = url; + redirect_info.new_method = "GET"; + io_thread_state->ThrottleWillRedirectRequest(redirect_info, defer); + } + } + + protected: + enum ShouldIgnoreNavigationCallbackAction { + IgnoreNavigation, + DontIgnoreNavigation + }; + + void SetUpWebContentsDelegateAndDrainRunLoop( + ShouldIgnoreNavigationCallbackAction callback_action, + bool* defer) { + ON_CALL(*mock_callback_receiver_, ShouldIgnoreNavigation(_, _)) + .WillByDefault(Return(callback_action == IgnoreNavigation)); + EXPECT_CALL(*mock_callback_receiver_, + ShouldIgnoreNavigation(web_contents(), + NavigationParamsUrlIsTest())) + .Times(1); + + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &InterceptNavigationResourceThrottleTest:: + RunThrottleWillStartRequestOnIOThread, + base::Unretained(this), + GURL(kTestUrl), + "GET", + REDIRECT_MODE_NO_REDIRECT, + web_contents()->GetRenderViewHost()->GetProcess()->GetID(), + web_contents()->GetMainFrame()->GetRoutingID(), + base::Unretained(defer))); + + // Wait for the request to finish processing. + base::RunLoop().RunUntilIdle(); + } + + void WaitForPreviouslyScheduledIoThreadWork() { + base::WaitableEvent io_thread_work_done(true, false); + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &base::WaitableEvent::Signal, + base::Unretained(&io_thread_work_done))); + io_thread_work_done.Wait(); + } + + scoped_ptr<MockInterceptCallbackReceiver> mock_callback_receiver_; + TestIOThreadState* io_thread_state_; +}; + +TEST_F(InterceptNavigationResourceThrottleTest, + RequestDeferredAndResumedIfNavigationNotIgnored) { + bool defer = false; + SetUpWebContentsDelegateAndDrainRunLoop(DontIgnoreNavigation, &defer); + + EXPECT_TRUE(defer); + ASSERT_TRUE(io_thread_state_); + EXPECT_TRUE(io_thread_state_->request_resumed()); +} + +TEST_F(InterceptNavigationResourceThrottleTest, + RequestDeferredAndCancelledIfNavigationIgnored) { + bool defer = false; + SetUpWebContentsDelegateAndDrainRunLoop(IgnoreNavigation, &defer); + + EXPECT_TRUE(defer); + ASSERT_TRUE(io_thread_state_); + EXPECT_TRUE(io_thread_state_->request_cancelled()); +} + +TEST_F(InterceptNavigationResourceThrottleTest, + NoCallbackMadeIfContentsDeletedWhileThrottleRunning) { + bool defer = false; + + // The tested scenario is when the WebContents is deleted after the + // ResourceThrottle has finished processing on the IO thread but before the + // UI thread callback has been processed. Since both threads in this test + // are serviced by one message loop, the post order is the execution order. + EXPECT_CALL(*mock_callback_receiver_, + ShouldIgnoreNavigation(_, _)) + .Times(0); + + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &InterceptNavigationResourceThrottleTest:: + RunThrottleWillStartRequestOnIOThread, + base::Unretained(this), + GURL(kTestUrl), + "GET", + REDIRECT_MODE_NO_REDIRECT, + web_contents()->GetRenderViewHost()->GetProcess()->GetID(), + web_contents()->GetMainFrame()->GetRoutingID(), + base::Unretained(&defer))); + + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind( + &RenderViewHostTestHarness::DeleteContents, + base::Unretained(this))); + + // The WebContents will now be deleted and only after that will the UI-thread + // callback posted by the ResourceThrottle be executed. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(defer); + ASSERT_TRUE(io_thread_state_); + EXPECT_TRUE(io_thread_state_->request_resumed()); +} + +TEST_F(InterceptNavigationResourceThrottleTest, + RequestNotDeferredForRequestNotAssociatedWithARenderView) { + bool defer = false; + + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &InterceptNavigationResourceThrottleTest:: + RunThrottleWillStartRequestOnIOThread, + base::Unretained(this), + GURL(kTestUrl), + "GET", + REDIRECT_MODE_NO_REDIRECT, + MSG_ROUTING_NONE, + MSG_ROUTING_NONE, + base::Unretained(&defer))); + + // Wait for the request to finish processing. + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(defer); +} + +TEST_F(InterceptNavigationResourceThrottleTest, + CallbackCalledWithFilteredUrl) { + bool defer = false; + + ON_CALL(*mock_callback_receiver_, + ShouldIgnoreNavigation(_, NavigationParamsUrlIsSafe())) + .WillByDefault(Return(false)); + EXPECT_CALL(*mock_callback_receiver_, + ShouldIgnoreNavigation(_, NavigationParamsUrlIsSafe())) + .Times(1); + + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &InterceptNavigationResourceThrottleTest:: + RunThrottleWillStartRequestOnIOThread, + base::Unretained(this), + GURL(kUnsafeTestUrl), + "GET", + REDIRECT_MODE_NO_REDIRECT, + web_contents()->GetRenderViewHost()->GetProcess()->GetID(), + web_contents()->GetMainFrame()->GetRoutingID(), + base::Unretained(&defer))); + + // Wait for the request to finish processing. + base::RunLoop().RunUntilIdle(); +} + +TEST_F(InterceptNavigationResourceThrottleTest, + CallbackIsPostFalseForGet) { + bool defer = false; + + EXPECT_CALL(*mock_callback_receiver_, + ShouldIgnoreNavigation(_, AllOf( + NavigationParamsUrlIsSafe(), + Property(&NavigationParams::is_post, Eq(false))))) + .WillOnce(Return(false)); + + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &InterceptNavigationResourceThrottleTest:: + RunThrottleWillStartRequestOnIOThread, + base::Unretained(this), + GURL(kTestUrl), + "GET", + REDIRECT_MODE_NO_REDIRECT, + web_contents()->GetRenderViewHost()->GetProcess()->GetID(), + web_contents()->GetMainFrame()->GetRoutingID(), + base::Unretained(&defer))); + + // Wait for the request to finish processing. + base::RunLoop().RunUntilIdle(); +} + +TEST_F(InterceptNavigationResourceThrottleTest, + CallbackIsPostTrueForPost) { + bool defer = false; + + EXPECT_CALL(*mock_callback_receiver_, + ShouldIgnoreNavigation(_, AllOf( + NavigationParamsUrlIsSafe(), + Property(&NavigationParams::is_post, Eq(true))))) + .WillOnce(Return(false)); + + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &InterceptNavigationResourceThrottleTest:: + RunThrottleWillStartRequestOnIOThread, + base::Unretained(this), + GURL(kTestUrl), + "POST", + REDIRECT_MODE_NO_REDIRECT, + web_contents()->GetRenderViewHost()->GetProcess()->GetID(), + web_contents()->GetMainFrame()->GetRoutingID(), + base::Unretained(&defer))); + + // Wait for the request to finish processing. + base::RunLoop().RunUntilIdle(); +} + +TEST_F(InterceptNavigationResourceThrottleTest, + CallbackIsPostFalseForPostConvertedToGetBy302) { + bool defer = false; + + EXPECT_CALL(*mock_callback_receiver_, + ShouldIgnoreNavigation(_, AllOf( + NavigationParamsUrlIsSafe(), + Property(&NavigationParams::is_post, Eq(false))))) + .WillOnce(Return(false)); + + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &InterceptNavigationResourceThrottleTest:: + RunThrottleWillStartRequestOnIOThread, + base::Unretained(this), + GURL(kTestUrl), + "POST", + REDIRECT_MODE_302, + web_contents()->GetRenderViewHost()->GetProcess()->GetID(), + web_contents()->GetMainFrame()->GetRoutingID(), + base::Unretained(&defer))); + + // Wait for the request to finish processing. + base::RunLoop().RunUntilIdle(); +} + +} // namespace navigation_interception diff --git a/components/navigation_interception/intercept_navigation_throttle.cc b/components/navigation_interception/intercept_navigation_throttle.cc deleted file mode 100644 index cc256a1..0000000 --- a/components/navigation_interception/intercept_navigation_throttle.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015 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 "components/navigation_interception/intercept_navigation_throttle.h" - -#include "components/navigation_interception/navigation_params.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/navigation_handle.h" - -namespace navigation_interception { - -InterceptNavigationThrottle::InterceptNavigationThrottle( - content::NavigationHandle* navigation_handle, - CheckCallback should_ignore_callback) - : content::NavigationThrottle(navigation_handle), - should_ignore_callback_(should_ignore_callback) {} - -InterceptNavigationThrottle::~InterceptNavigationThrottle() {} - -content::NavigationThrottle::ThrottleCheckResult -InterceptNavigationThrottle::WillStartRequest() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - return CheckIfShouldIgnoreNavigation(false); -} - -content::NavigationThrottle::ThrottleCheckResult -InterceptNavigationThrottle::WillRedirectRequest() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - return CheckIfShouldIgnoreNavigation(true); -} - -content::NavigationThrottle::ThrottleCheckResult -InterceptNavigationThrottle::CheckIfShouldIgnoreNavigation(bool is_redirect) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - NavigationParams navigation_params( - navigation_handle()->GetURL(), navigation_handle()->GetReferrer(), - navigation_handle()->HasUserGesture(), navigation_handle()->IsPost(), - navigation_handle()->GetPageTransition(), is_redirect, - navigation_handle()->IsExternalProtocol(), true); - - bool should_ignore_navigation = should_ignore_callback_.Run( - navigation_handle()->GetWebContents(), navigation_params); - return should_ignore_navigation - ? content::NavigationThrottle::CANCEL_AND_IGNORE - : content::NavigationThrottle::PROCEED; -} - -} // namespace navigation_interception diff --git a/components/navigation_interception/intercept_navigation_throttle.h b/components/navigation_interception/intercept_navigation_throttle.h deleted file mode 100644 index 0b7f746..0000000 --- a/components/navigation_interception/intercept_navigation_throttle.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NAVIGATION_INTERCEPTION_INTERCEPT_NAVIGATION_THROTTLE_H_ -#define COMPONENTS_NAVIGATION_INTERCEPTION_INTERCEPT_NAVIGATION_THROTTLE_H_ - -#include <string> - -#include "base/callback.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/navigation_throttle.h" - -class GURL; - -namespace content { -class NavigationHandle; -class WebContents; -} - -namespace navigation_interception { - -class NavigationParams; - -// This class allows the provider of the Callback to selectively ignore top -// level navigations. This is a UI thread class. -class InterceptNavigationThrottle : public content::NavigationThrottle { - public: - typedef base::Callback<bool(content::WebContents* /* source */, - const NavigationParams& /* navigation_params */)> - CheckCallback; - - InterceptNavigationThrottle(content::NavigationHandle* navigation_handle, - CheckCallback should_ignore_callback); - ~InterceptNavigationThrottle() override; - - // content::NavigationThrottle implementation: - ThrottleCheckResult WillStartRequest() override; - ThrottleCheckResult WillRedirectRequest() override; - - private: - ThrottleCheckResult CheckIfShouldIgnoreNavigation(bool is_redirect); - - CheckCallback should_ignore_callback_; - - DISALLOW_COPY_AND_ASSIGN(InterceptNavigationThrottle); -}; - -} // namespace navigation_interception - -#endif // COMPONENTS_NAVIGATION_INTERCEPTION_INTERCEPT_NAVIGATION_THROTTLE_H_ diff --git a/components/navigation_interception/intercept_navigation_throttle_unittest.cc b/components/navigation_interception/intercept_navigation_throttle_unittest.cc deleted file mode 100644 index 15e05ef..0000000 --- a/components/navigation_interception/intercept_navigation_throttle_unittest.cc +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2015 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 "base/bind.h" -#include "base/bind_helpers.h" -#include "base/memory/scoped_ptr.h" -#include "components/navigation_interception/intercept_navigation_throttle.h" -#include "components/navigation_interception/navigation_params.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/navigation_throttle.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/test_renderer_host.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using content::NavigationThrottle; -using testing::_; -using testing::Eq; -using testing::Ne; -using testing::Property; -using testing::Return; - -namespace navigation_interception { - -namespace { - -const char kTestUrl[] = "http://www.test.com/"; - -// The MS C++ compiler complains about not being able to resolve which url() -// method (const or non-const) to use if we use the Property matcher to check -// the return value of the NavigationParams::url() method. -// It is possible to suppress the error by specifying the types directly but -// that results in very ugly syntax, which is why these custom matchers are -// used instead. -MATCHER(NavigationParamsUrlIsTest, "") { - return arg.url() == GURL(kTestUrl); -} - -} // namespace - -// MockInterceptCallbackReceiver ---------------------------------------------- - -class MockInterceptCallbackReceiver { - public: - MOCK_METHOD2(ShouldIgnoreNavigation, - bool(content::WebContents* source, - const NavigationParams& navigation_params)); -}; - -// InterceptNavigationThrottleTest ------------------------------------ - -class InterceptNavigationThrottleTest - : public content::RenderViewHostTestHarness { - public: - InterceptNavigationThrottleTest() - : mock_callback_receiver_(new MockInterceptCallbackReceiver()) {} - - NavigationThrottle::ThrottleCheckResult - SimulateWillStart(const GURL& url, const GURL& sanitized_url, bool is_post) { - scoped_ptr<content::NavigationHandle> test_handle = - content::NavigationHandle::CreateNavigationHandleForTesting( - url, true, web_contents()); - test_handle->RegisterThrottleForTesting( - scoped_ptr<NavigationThrottle>( - new InterceptNavigationThrottle( - test_handle.get(), - base::Bind( - &MockInterceptCallbackReceiver::ShouldIgnoreNavigation, - base::Unretained(mock_callback_receiver_.get())))) - .Pass()); - return test_handle->CallWillStartRequestForTesting( - is_post, content::Referrer(), false, ui::PAGE_TRANSITION_LINK, false); - } - - NavigationThrottle::ThrottleCheckResult Simulate302() { - scoped_ptr<content::NavigationHandle> test_handle = - content::NavigationHandle::CreateNavigationHandleForTesting( - GURL(kTestUrl), true, web_contents()); - test_handle->RegisterThrottleForTesting( - scoped_ptr<NavigationThrottle>( - new InterceptNavigationThrottle( - test_handle.get(), - base::Bind( - &MockInterceptCallbackReceiver::ShouldIgnoreNavigation, - base::Unretained(mock_callback_receiver_.get())))) - .Pass()); - test_handle->CallWillStartRequestForTesting( - true, content::Referrer(), false, ui::PAGE_TRANSITION_LINK, false); - return test_handle->CallWillRedirectRequestForTesting(GURL(kTestUrl), false, - GURL(), false); - } - - scoped_ptr<MockInterceptCallbackReceiver> mock_callback_receiver_; -}; - -TEST_F(InterceptNavigationThrottleTest, - RequestDeferredAndResumedIfNavigationNotIgnored) { - ON_CALL(*mock_callback_receiver_, ShouldIgnoreNavigation(_, _)) - .WillByDefault(Return(false)); - EXPECT_CALL( - *mock_callback_receiver_, - ShouldIgnoreNavigation(web_contents(), NavigationParamsUrlIsTest())); - NavigationThrottle::ThrottleCheckResult result = - SimulateWillStart(GURL(kTestUrl), GURL(kTestUrl), false); - - EXPECT_EQ(NavigationThrottle::PROCEED, result); -} - -TEST_F(InterceptNavigationThrottleTest, - RequestDeferredAndCancelledIfNavigationIgnored) { - ON_CALL(*mock_callback_receiver_, ShouldIgnoreNavigation(_, _)) - .WillByDefault(Return(true)); - EXPECT_CALL( - *mock_callback_receiver_, - ShouldIgnoreNavigation(web_contents(), NavigationParamsUrlIsTest())); - NavigationThrottle::ThrottleCheckResult result = - SimulateWillStart(GURL(kTestUrl), GURL(kTestUrl), false); - - EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, result); -} - -TEST_F(InterceptNavigationThrottleTest, CallbackIsPostFalseForGet) { - EXPECT_CALL(*mock_callback_receiver_, - ShouldIgnoreNavigation( - _, AllOf(NavigationParamsUrlIsTest(), - Property(&NavigationParams::is_post, Eq(false))))) - .WillOnce(Return(false)); - - NavigationThrottle::ThrottleCheckResult result = - SimulateWillStart(GURL(kTestUrl), GURL(kTestUrl), false); - - EXPECT_EQ(NavigationThrottle::PROCEED, result); -} - -TEST_F(InterceptNavigationThrottleTest, CallbackIsPostTrueForPost) { - EXPECT_CALL(*mock_callback_receiver_, - ShouldIgnoreNavigation( - _, AllOf(NavigationParamsUrlIsTest(), - Property(&NavigationParams::is_post, Eq(true))))) - .WillOnce(Return(false)); - NavigationThrottle::ThrottleCheckResult result = - SimulateWillStart(GURL(kTestUrl), GURL(kTestUrl), true); - - EXPECT_EQ(NavigationThrottle::PROCEED, result); -} - -TEST_F(InterceptNavigationThrottleTest, - CallbackIsPostFalseForPostConvertedToGetBy302) { - EXPECT_CALL(*mock_callback_receiver_, - ShouldIgnoreNavigation( - _, AllOf(NavigationParamsUrlIsTest(), - Property(&NavigationParams::is_post, Eq(true))))) - .WillOnce(Return(false)); - EXPECT_CALL(*mock_callback_receiver_, - ShouldIgnoreNavigation( - _, AllOf(NavigationParamsUrlIsTest(), - Property(&NavigationParams::is_post, Eq(false))))) - .WillOnce(Return(false)); - NavigationThrottle::ThrottleCheckResult result = Simulate302(); - - EXPECT_EQ(NavigationThrottle::PROCEED, result); -} - -} // namespace navigation_interception diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 994a2fc..2c5e773 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc @@ -5,8 +5,6 @@ #include "content/browser/frame_host/navigation_handle_impl.h" #include "content/browser/frame_host/navigator_delegate.h" -#include "content/public/browser/content_browser_client.h" -#include "content/public/common/content_client.h" #include "net/url_request/redirect_info.h" namespace content { @@ -14,7 +12,7 @@ namespace content { // static scoped_ptr<NavigationHandleImpl> NavigationHandleImpl::Create( const GURL& url, - bool is_main_frame, + const bool is_main_frame, NavigatorDelegate* delegate) { return scoped_ptr<NavigationHandleImpl>( new NavigationHandleImpl(url, is_main_frame, delegate)); @@ -24,14 +22,10 @@ NavigationHandleImpl::NavigationHandleImpl(const GURL& url, const bool is_main_frame, NavigatorDelegate* delegate) : url_(url), - is_main_frame_(is_main_frame), - is_post_(false), - has_user_gesture_(false), - transition_(ui::PAGE_TRANSITION_LINK), - is_external_protocol_(false), net_error_code_(net::OK), + state_(DID_START), + is_main_frame_(is_main_frame), is_same_page_(false), - state_(INITIAL), is_transferring_(false), delegate_(delegate) { delegate_->DidStartNavigation(this); @@ -41,46 +35,16 @@ NavigationHandleImpl::~NavigationHandleImpl() { delegate_->DidFinishNavigation(this); } -const GURL& NavigationHandleImpl::GetURL() { +const GURL& NavigationHandleImpl::GetURL() const { return url_; } -bool NavigationHandleImpl::IsInMainFrame() { - return is_main_frame_; -} - -bool NavigationHandleImpl::IsPost() { - CHECK_NE(INITIAL, state_) - << "This accessor should not be called before the request is started."; - return is_post_; -} - -const Referrer& NavigationHandleImpl::GetReferrer() { - CHECK_NE(INITIAL, state_) - << "This accessor should not be called before the request is started."; - return sanitized_referrer_; -} - -bool NavigationHandleImpl::HasUserGesture() { - CHECK_NE(INITIAL, state_) - << "This accessor should not be called before the request is started."; - return has_user_gesture_; -} - -ui::PageTransition NavigationHandleImpl::GetPageTransition() { - CHECK_NE(INITIAL, state_) - << "This accessor should not be called before the request is started."; - return transition_; -} - -bool NavigationHandleImpl::IsExternalProtocol() { - CHECK_NE(INITIAL, state_) - << "This accessor should not be called before the request is started."; - return is_external_protocol_; +net::Error NavigationHandleImpl::GetNetErrorCode() const { + return net_error_code_; } -net::Error NavigationHandleImpl::GetNetErrorCode() { - return net_error_code_; +bool NavigationHandleImpl::IsInMainFrame() const { + return is_main_frame_; } bool NavigationHandleImpl::IsSamePage() { @@ -90,99 +54,14 @@ bool NavigationHandleImpl::IsSamePage() { return is_same_page_; } -bool NavigationHandleImpl::HasCommittedDocument() { +bool NavigationHandleImpl::HasCommittedDocument() const { return state_ == DID_COMMIT; } -bool NavigationHandleImpl::HasCommittedErrorPage() { +bool NavigationHandleImpl::HasCommittedErrorPage() const { return state_ == DID_COMMIT_ERROR_PAGE; } -void NavigationHandleImpl::RegisterThrottleForTesting( - scoped_ptr<NavigationThrottle> navigation_throttle) { - throttles_.push_back(navigation_throttle.Pass()); -} - -NavigationThrottle::ThrottleCheckResult -NavigationHandleImpl::CallWillStartRequestForTesting( - bool is_post, - const Referrer& sanitized_referrer, - bool has_user_gesture, - ui::PageTransition transition, - bool is_external_protocol) { - return WillStartRequest(is_post, sanitized_referrer, has_user_gesture, - transition, is_external_protocol); -} - -NavigationThrottle::ThrottleCheckResult -NavigationHandleImpl::CallWillRedirectRequestForTesting( - const GURL& new_url, - bool new_method_is_post, - const GURL& new_referrer_url, - bool new_is_external_protocol) { - return WillRedirectRequest(new_url, new_method_is_post, new_referrer_url, - new_is_external_protocol); -} - -NavigationThrottle::ThrottleCheckResult NavigationHandleImpl::WillStartRequest( - bool is_post, - const Referrer& sanitized_referrer, - bool has_user_gesture, - ui::PageTransition transition, - bool is_external_protocol) { - // Update the navigation parameters. - is_post_ = is_post; - sanitized_referrer_ = sanitized_referrer; - has_user_gesture_ = has_user_gesture; - transition_ = transition; - is_external_protocol_ = is_external_protocol; - - state_ = WILL_SEND_REQUEST; - - // Register the navigation throttles. The ScopedVector returned by - // GetNavigationThrottles is not assigned to throttles_ directly because it - // would overwrite any throttle previously added with - // RegisterThrottleForTesting. - ScopedVector<NavigationThrottle> throttles_to_register = - GetContentClient()->browser()->CreateThrottlesForNavigation(this); - if (throttles_to_register.size() > 0) { - throttles_.insert(throttles_.end(), throttles_to_register.begin(), - throttles_to_register.end()); - throttles_to_register.weak_clear(); - } - - // Notify each throttle of the request. - for (NavigationThrottle* throttle : throttles_) { - NavigationThrottle::ThrottleCheckResult result = - throttle->WillStartRequest(); - if (result == NavigationThrottle::CANCEL_AND_IGNORE) - return NavigationThrottle::CANCEL_AND_IGNORE; - } - return NavigationThrottle::PROCEED; -} - -NavigationThrottle::ThrottleCheckResult -NavigationHandleImpl::WillRedirectRequest(const GURL& new_url, - bool new_method_is_post, - const GURL& new_referrer_url, - bool new_is_external_protocol) { - // Update the navigation parameters. - url_ = new_url; - is_post_ = new_method_is_post; - sanitized_referrer_.url = new_referrer_url; - sanitized_referrer_ = Referrer::SanitizeForRequest(url_, sanitized_referrer_); - is_external_protocol_ = new_is_external_protocol; - - // Have each throttle be notified of the request. - for (NavigationThrottle* throttle : throttles_) { - NavigationThrottle::ThrottleCheckResult result = - throttle->WillRedirectRequest(); - if (result == NavigationThrottle::CANCEL_AND_IGNORE) - return NavigationThrottle::CANCEL_AND_IGNORE; - } - return NavigationThrottle::PROCEED; -} - void NavigationHandleImpl::DidRedirectNavigation(const GURL& new_url) { url_ = new_url; delegate_->DidRedirectNavigation(this); diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index aebb929..861adb0 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h @@ -9,9 +9,7 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" #include "content/common/content_export.h" -#include "content/public/browser/navigation_throttle.h" #include "url/gurl.h" namespace content { @@ -55,37 +53,18 @@ struct NavigationRequestInfo; class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle { public: static scoped_ptr<NavigationHandleImpl> Create(const GURL& url, - bool is_main_frame, + const bool is_main_frame, NavigatorDelegate* delegate); + ~NavigationHandleImpl() override; // NavigationHandle implementation: - const GURL& GetURL() override; - bool IsInMainFrame() override; - bool IsPost() override; - const Referrer& GetReferrer() override; - bool HasUserGesture() override; - ui::PageTransition GetPageTransition() override; - bool IsExternalProtocol() override; - net::Error GetNetErrorCode() override; + const GURL& GetURL() const override; + net::Error GetNetErrorCode() const override; + bool IsInMainFrame() const override; bool IsSamePage() override; - bool HasCommittedDocument() override; - bool HasCommittedErrorPage() override; - void RegisterThrottleForTesting( - scoped_ptr<NavigationThrottle> navigation_throttle) override; - NavigationThrottle::ThrottleCheckResult CallWillStartRequestForTesting( - bool is_post, - const Referrer& sanitized_referrer, - bool has_user_gesture, - ui::PageTransition transition, - bool is_external_protocol) override; - NavigationThrottle::ThrottleCheckResult CallWillRedirectRequestForTesting( - const GURL& new_url, - bool new_method_is_post, - const GURL& new_referrer_url, - bool new_is_external_protocol) override; - - NavigatorDelegate* delegate() const { return delegate_; } + bool HasCommittedDocument() const override; + bool HasCommittedErrorPage() const override; void set_net_error_code(net::Error net_error_code) { net_error_code_ = net_error_code; @@ -100,21 +79,6 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle { is_transferring_ = is_transferring; } - // Called when the URLRequest will start in the network stack. - NavigationThrottle::ThrottleCheckResult WillStartRequest( - bool is_post, - const Referrer& sanitized_referrer, - bool has_user_gesture, - ui::PageTransition transition, - bool is_external_protocol); - - // Called when the URLRequest will be redirected in the network stack. - NavigationThrottle::ThrottleCheckResult WillRedirectRequest( - const GURL& new_url, - bool new_method_is_post, - const GURL& new_referrer_url, - bool new_is_external_protocol); - // Called when the navigation was redirected. This will update the |url_| and // inform the delegate. void DidRedirectNavigation(const GURL& new_url); @@ -126,8 +90,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle { private: // Used to track the state the navigation is currently in. enum State { - INITIAL = 0, - WILL_SEND_REQUEST, + DID_START = 0, DID_COMMIT, DID_COMMIT_ERROR_PAGE, }; @@ -138,17 +101,10 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle { // See NavigationHandle for a description of those member variables. GURL url_; - const bool is_main_frame_; - bool is_post_; - Referrer sanitized_referrer_; - bool has_user_gesture_; - ui::PageTransition transition_; - bool is_external_protocol_; net::Error net_error_code_; - bool is_same_page_; - - // The state the navigation is in. State state_; + const bool is_main_frame_; + bool is_same_page_; // Whether the navigation is in the middle of a transfer. Set to false when // the DidStartProvisionalLoad is received from the new renderer. @@ -158,9 +114,6 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle { // navigation. NavigatorDelegate* delegate_; - // A list of Throttles registered for this navigation. - ScopedVector<NavigationThrottle> throttles_; - DISALLOW_COPY_AND_ASSIGN(NavigationHandleImpl); }; diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 8247f35..a99074f 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc @@ -14,7 +14,6 @@ #include "content/browser/site_instance_impl.h" #include "content/common/resource_request_body.h" #include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_throttle.h" #include "content/public/browser/stream_handle.h" #include "content/public/common/content_client.h" #include "net/base/load_flags.h" @@ -180,20 +179,6 @@ bool NavigationRequest::BeginNavigation() { state_ = STARTED; if (ShouldMakeNetworkRequestForURL(common_params_.url)) { - // TODO(clamy): pass the real value for |is_external_protocol| if needed. - NavigationThrottle::ThrottleCheckResult result = - navigation_handle_->WillStartRequest( - begin_params_.method == "POST", - Referrer::SanitizeForRequest(common_params_.url, - common_params_.referrer), - begin_params_.has_user_gesture, common_params_.transition, false); - - // Abort the request if needed. This will destroy the NavigationRequest. - if (result == NavigationThrottle::CANCEL_AND_IGNORE) { - frame_tree_node_->ResetNavigationRequest(false); - return false; - } - loader_ = NavigationURLLoader::Create( frame_tree_node_->navigator()->GetController()->GetBrowserContext(), frame_tree_node_->frame_tree_node_id(), info_.Pass(), this); @@ -224,24 +209,12 @@ void NavigationRequest::TransferNavigationHandleOwnership( void NavigationRequest::OnRequestRedirected( const net::RedirectInfo& redirect_info, const scoped_refptr<ResourceResponse>& response) { + // TODO(davidben): Track other changes from redirects. These are important + // for, e.g., reloads. common_params_.url = redirect_info.new_url; - begin_params_.method = redirect_info.new_method; - common_params_.referrer.url = GURL(redirect_info.new_referrer); - - // TODO(clamy): Have CSP + security upgrade checks here. - // TODO(clamy): Kill the renderer if FilterURL fails? - // TODO(clamy): pass the real value for |is_external_protocol| if needed. - NavigationThrottle::ThrottleCheckResult result = - navigation_handle_->WillRedirectRequest( - common_params_.url, begin_params_.method == "POST", - common_params_.referrer.url, false); - - // Abort the request if needed. This will destroy the NavigationRequest. - if (result == NavigationThrottle::CANCEL_AND_IGNORE) { - frame_tree_node_->ResetNavigationRequest(false); - return; - } + // TODO(davidben): This where prerender and navigation_interceptor should be + // integrated. For now, just always follow all redirects. loader_->FollowRedirect(); navigation_handle_->DidRedirectNavigation(redirect_info.new_url); diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index b711278..a1530b4 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h @@ -164,10 +164,8 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate { // Note: When the navigation is ready to commit, the url in |common_params| // will be set to the final navigation url, obtained after following all // redirects. - // Note: |common_params_| and |begin_params_| are not const as they can be - // modified during redirects. CommonNavigationParams common_params_; - BeginNavigationParams begin_params_; + const BeginNavigationParams begin_params_; const RequestNavigationParams request_params_; const bool browser_initiated_; diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index fa0c049..b03e232 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc @@ -159,7 +159,7 @@ void NavigatorImpl::DidStartProvisionalLoad( } render_frame_host->SetNavigationHandle( - NavigationHandleImpl::Create(validated_url, is_main_frame, delegate_)); + NavigationHandleImpl::Create(url, is_main_frame, delegate_)); } void NavigatorImpl::DidFailProvisionalLoadWithError( diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index aed2daa..8f6c99c 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc @@ -1359,10 +1359,8 @@ void RenderFrameHostImpl::OnBeginNavigation( scoped_refptr<ResourceRequestBody> body) { CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)); - CommonNavigationParams validated_params = common_params; - GetProcess()->FilterURL(false, &validated_params.url); frame_tree_node()->navigator()->OnBeginNavigation( - frame_tree_node(), validated_params, begin_params, body); + frame_tree_node(), common_params, begin_params, body); } void RenderFrameHostImpl::OnDispatchLoad() { diff --git a/content/browser/loader/navigation_resource_throttle.cc b/content/browser/loader/navigation_resource_throttle.cc deleted file mode 100644 index 8dd143c..0000000 --- a/content/browser/loader/navigation_resource_throttle.cc +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2015 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 "content/browser/loader/navigation_resource_throttle.h" - -#include "base/callback.h" -#include "content/browser/frame_host/navigation_handle_impl.h" -#include "content/browser/frame_host/render_frame_host_impl.h" -#include "content/public/browser/resource_context.h" -#include "content/public/browser/resource_controller.h" -#include "content/public/browser/resource_request_info.h" -#include "content/public/common/referrer.h" -#include "net/url_request/redirect_info.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_job_factory.h" -#include "ui/base/page_transition_types.h" - -namespace content { - -namespace { -typedef base::Callback<void(NavigationThrottle::ThrottleCheckResult)> - UIChecksPerformedCallback; - -void CheckWillStartRequestOnUIThread(UIChecksPerformedCallback callback, - int render_process_id, - int render_frame_host_id, - bool is_post, - const Referrer& sanitized_referrer, - bool has_user_gesture, - ui::PageTransition transition, - bool is_external_protocol) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::PROCEED; - RenderFrameHostImpl* render_frame_host = - RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id); - if (render_frame_host) { - NavigationHandleImpl* navigation_handle = - render_frame_host->navigation_handle(); - if (navigation_handle) { - result = navigation_handle->WillStartRequest(is_post, sanitized_referrer, - has_user_gesture, transition, - is_external_protocol); - } - } - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(callback, result)); -} - -void CheckWillRedirectRequestOnUIThread(UIChecksPerformedCallback callback, - int render_process_id, - int render_frame_host_id, - const GURL& new_url, - bool new_method_is_post, - const GURL& new_referrer_url, - bool new_is_external_protocol) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::PROCEED; - RenderFrameHostImpl* render_frame_host = - RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id); - if (render_frame_host) { - NavigationHandleImpl* navigation_handle = - render_frame_host->navigation_handle(); - if (navigation_handle) { - RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id); - GURL new_validated_url = new_url; - rph->FilterURL(false, &new_validated_url); - result = navigation_handle->WillRedirectRequest( - new_validated_url, new_method_is_post, new_referrer_url, - new_is_external_protocol); - } - } - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(callback, result)); -} -} // namespace - -NavigationResourceThrottle::NavigationResourceThrottle(net::URLRequest* request) - : request_(request), weak_ptr_factory_(this) {} - -NavigationResourceThrottle::~NavigationResourceThrottle() {} - -void NavigationResourceThrottle::WillStartRequest(bool* defer) { - const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); - if (!info) - return; - - int render_process_id, render_frame_id; - if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) - return; - - bool is_external_protocol = - !info->GetContext()->GetRequestContext()->job_factory()->IsHandledURL( - request_->url()); - UIChecksPerformedCallback callback = - base::Bind(&NavigationResourceThrottle::OnUIChecksPerformed, - weak_ptr_factory_.GetWeakPtr()); - DCHECK(request_->method() == "POST" || request_->method() == "GET"); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&CheckWillStartRequestOnUIThread, callback, render_process_id, - render_frame_id, request_->method() == "POST", - Referrer::SanitizeForRequest( - request_->url(), Referrer(GURL(request_->referrer()), - info->GetReferrerPolicy())), - info->HasUserGesture(), info->GetPageTransition(), - is_external_protocol)); - *defer = true; -} - -void NavigationResourceThrottle::WillRedirectRequest( - const net::RedirectInfo& redirect_info, - bool* defer) { - const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); - if (!info) - return; - - int render_process_id, render_frame_id; - if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) - return; - - bool new_is_external_protocol = - !info->GetContext()->GetRequestContext()->job_factory()->IsHandledURL( - request_->url()); - DCHECK(redirect_info.new_method == "POST" || - redirect_info.new_method == "GET"); - UIChecksPerformedCallback callback = - base::Bind(&NavigationResourceThrottle::OnUIChecksPerformed, - weak_ptr_factory_.GetWeakPtr()); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&CheckWillRedirectRequestOnUIThread, callback, - render_process_id, render_frame_id, redirect_info.new_url, - redirect_info.new_method == "POST", - GURL(redirect_info.new_referrer), new_is_external_protocol)); - *defer = true; -} - -const char* NavigationResourceThrottle::GetNameForLogging() const { - return "NavigationResourceThrottle"; -} - -void NavigationResourceThrottle::OnUIChecksPerformed( - NavigationThrottle::ThrottleCheckResult result) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (result == NavigationThrottle::CANCEL_AND_IGNORE) { - controller()->CancelAndIgnore(); - } else { - controller()->Resume(); - } -} - -} // namespace content diff --git a/content/browser/loader/navigation_resource_throttle.h b/content/browser/loader/navigation_resource_throttle.h deleted file mode 100644 index e46b59d..0000000 --- a/content/browser/loader/navigation_resource_throttle.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_LOADER_NAVIGATION_RESOURCE_THROTTLE_H_ -#define CONTENT_BROWSER_LOADER_NAVIGATION_RESOURCE_THROTTLE_H_ - -#include "base/basictypes.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/navigation_throttle.h" -#include "content/public/browser/resource_throttle.h" - -namespace net { -class URLRequest; -} - -namespace content { - -// This ResourceThrottle is used to convey throttling information to the UI -// thread during navigations. The UI thread can then use its NavigationThrottle -// mechanism to interact with the navigation. -class NavigationResourceThrottle : public ResourceThrottle { - public: - NavigationResourceThrottle(net::URLRequest* request); - ~NavigationResourceThrottle() override; - - // ResourceThrottle overrides: - void WillStartRequest(bool* defer) override; - void WillRedirectRequest(const net::RedirectInfo& redirect_info, - bool* defer) override; - const char* GetNameForLogging() const override; - - private: - void OnUIChecksPerformed(NavigationThrottle::ThrottleCheckResult result); - - net::URLRequest* request_; - base::WeakPtrFactory<NavigationResourceThrottle> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(NavigationResourceThrottle); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_LOADER_NAVIGATION_RESOURCE_THROTTLE_H_ diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 81cbf8a..c5c6796 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc @@ -41,7 +41,6 @@ #include "content/browser/loader/detachable_resource_handler.h" #include "content/browser/loader/mime_type_resource_handler.h" #include "content/browser/loader/navigation_resource_handler.h" -#include "content/browser/loader/navigation_resource_throttle.h" #include "content/browser/loader/navigation_url_loader_impl_core.h" #include "content/browser/loader/power_save_block_resource_throttle.h" #include "content/browser/loader/redirect_to_file_resource_handler.h" @@ -1482,16 +1481,6 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers( plugin_service, request)); ScopedVector<ResourceThrottle> throttles; - - // Add a NavigationResourceThrottle for navigations. - // PlzNavigate: the throttle is unnecessary as communication with the UI - // thread is handled by the NavigationURLloader. - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableBrowserSideNavigation) && - IsResourceTypeFrame(resource_type)) { - throttles.push_back(new NavigationResourceThrottle(request)); - } - if (delegate_) { delegate_->RequestBeginning(request, resource_context, diff --git a/content/content_browser.gypi b/content/content_browser.gypi index f562da9..182628e 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -182,10 +182,7 @@ 'public/browser/navigation_details.cc', 'public/browser/navigation_details.h', 'public/browser/navigation_entry.h', - 'public/browser/navigation_handle.cc', 'public/browser/navigation_handle.h', - 'public/browser/navigation_throttle.cc', - 'public/browser/navigation_throttle.h', 'public/browser/navigation_type.h', 'public/browser/navigator_connect_context.h', 'public/browser/navigator_connect_service_factory.h', @@ -975,8 +972,6 @@ 'browser/loader/mime_type_resource_handler.h', 'browser/loader/navigation_resource_handler.cc', 'browser/loader/navigation_resource_handler.h', - 'browser/loader/navigation_resource_throttle.cc', - 'browser/loader/navigation_resource_throttle.h', 'browser/loader/navigation_url_loader.cc', 'browser/loader/navigation_url_loader.h', 'browser/loader/navigation_url_loader_delegate.h', diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index f25c84a..01b58bd 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc @@ -359,12 +359,6 @@ void ContentBrowserClient::OpenURL( callback.Run(nullptr); } -ScopedVector<NavigationThrottle> -ContentBrowserClient::CreateThrottlesForNavigation( - NavigationHandle* navigation_handle) { - return ScopedVector<NavigationThrottle>(); -} - #if defined(OS_WIN) const wchar_t* ContentBrowserClient::GetResourceDllName() { return nullptr; diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 55569fb..2c6734c 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -16,7 +16,6 @@ #include "base/memory/scoped_vector.h" #include "base/values.h" #include "content/public/browser/certificate_request_result_type.h" -#include "content/public/browser/navigation_throttle.h" #include "content/public/common/content_client.h" #include "content/public/common/media_stream_request.h" #include "content/public/common/resource_type.h" @@ -97,7 +96,6 @@ class DevToolsManagerDelegate; class ExternalVideoSurfaceContainer; class LocationProvider; class MediaObserver; -class NavigationHandle; class NavigatorConnectContext; class NavigatorConnectServiceFactory; class PlatformNotificationService; @@ -671,14 +669,6 @@ class CONTENT_EXPORT ContentBrowserClient { // Allows the embedder to record |metric| for a specific |url|. virtual void RecordURLMetric(const std::string& metric, const GURL& url) {} - // Allows the embedder to register one or more NavigationThrottles for the - // navigation indicated by |navigation_handle|. A NavigationThrottle is used - // to control the flow of a navigation on the UI thread. The embedder is - // guaranteed that the throttles will be executed in the order they were - // provided. - virtual ScopedVector<NavigationThrottle> CreateThrottlesForNavigation( - NavigationHandle* navigation_handle); - // Populates |mappings| with all files that need to be mapped before launching // a child process. #if defined(OS_ANDROID) diff --git a/content/public/browser/navigation_handle.cc b/content/public/browser/navigation_handle.cc deleted file mode 100644 index f5eaa11..0000000 --- a/content/public/browser/navigation_handle.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015 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 "content/public/browser/navigation_handle.h" - -#include "content/browser/frame_host/navigation_handle_impl.h" -#include "content/browser/frame_host/navigator.h" -#include "content/browser/web_contents/web_contents_impl.h" - -namespace content { - -WebContents* NavigationHandle::GetWebContents() { - // The NavigationHandleImpl cannot access the WebContentsImpl as it would be - // a layering violation, hence the cast here. - return static_cast<WebContentsImpl*>( - static_cast<NavigationHandleImpl*>(this)->delegate()); -} - -// static -scoped_ptr<NavigationHandle> NavigationHandle::CreateNavigationHandleForTesting( - const GURL& url, - bool is_main_frame, - WebContents* web_contents) { - scoped_ptr<NavigationHandleImpl> handle_impl = NavigationHandleImpl::Create( - url, is_main_frame, static_cast<WebContentsImpl*>(web_contents)); - return scoped_ptr<NavigationHandle>(handle_impl.Pass()); -} - -} // namespace content diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h index 033aca2..c60baba 100644 --- a/content/public/browser/navigation_handle.h +++ b/content/public/browser/navigation_handle.h @@ -6,70 +6,27 @@ #define CONTENT_PUBLIC_BROWSER_NAVIGATION_HANDLE_H_ #include "content/common/content_export.h" -#include "content/public/browser/navigation_throttle.h" -#include "content/public/common/referrer.h" #include "net/base/net_errors.h" -#include "ui/base/page_transition_types.h" class GURL; namespace content { -class NavigationThrottle; -class WebContents; // A NavigationHandle tracks information related to a single navigation. class CONTENT_EXPORT NavigationHandle { public: virtual ~NavigationHandle() {} - // Parameters available at navigation start time ----------------------------- - // - // These parameters are always available during the navigation. Note that - // some may change during navigation (e.g. due to server redirects). - // The URL the frame is navigating to. This may change during the navigation // when encountering a server redirect. - virtual const GURL& GetURL() = 0; - - // Whether the navigation is taking place in the main frame or in a subframe. - // This remains constant over the navigation lifetime. - virtual bool IsInMainFrame() = 0; - - // The WebContents the navigation is taking place in. - WebContents* GetWebContents(); - - // Parameters available at network request start time ------------------------ - // - // The following parameters are only available when the network request is - // made for the navigation (or at commit time if no network request is made). - // This corresponds to NavigationThrottle::WillSendRequest. They should not - // be queried before that. - - // Whether the navigation is a POST or a GET. This may change during the - // navigation when encountering a server redirect. - virtual bool IsPost() = 0; - - // Returns a sanitized version of the referrer for this request. - virtual const Referrer& GetReferrer() = 0; - - // Whether the navigation was initiated by a user gesture. Note that this - // will return false for browser-initiated navigations. - // TODO(clamy): when PlzNavigate launches, this should return true for - // browser-initiated navigations. - virtual bool HasUserGesture() = 0; - - // Returns the page transition type. - virtual ui::PageTransition GetPageTransition() = 0; - - // Whether the target URL cannot be handled by the browser's internal protocol - // handlers. - virtual bool IsExternalProtocol() = 0; - - // Navigation control flow -------------------------------------------------- + virtual const GURL& GetURL() const = 0; // The net error code if an error happened prior to commit. Otherwise it will // be net::OK. - virtual net::Error GetNetErrorCode() = 0; + virtual net::Error GetNetErrorCode() const = 0; + + // Whether the navigation is taking place in the main frame or in a subframe. + virtual bool IsInMainFrame() const = 0; // Whether the navigation happened in the same page. This is only known // after the navigation has committed. It is an error to call this method @@ -77,44 +34,10 @@ class CONTENT_EXPORT NavigationHandle { virtual bool IsSamePage() = 0; // Whether the navigation has successfully committed a document. - virtual bool HasCommittedDocument() = 0; + virtual bool HasCommittedDocument() const = 0; // Whether an error page has committed for the navigation. - virtual bool HasCommittedErrorPage() = 0; - - // Testing methods ---------------------------------------------------------- - // - // The following methods should be used exclusively for writing unit tests. - - static scoped_ptr<NavigationHandle> CreateNavigationHandleForTesting( - const GURL& url, - bool is_main_frame, - WebContents* web_contents); - - // Registers a NavigationThrottle for tests. The throttle can - // modify the request, pause the request or cancel the request. This will - // take ownership of the NavigationThrottle. - // Note: in non-test cases, NavigationThrottles should not be added directly - // but returned by the implementation of - // ContentBrowserClient::CreateThrottlesForNavigation. This ensures proper - // ordering of the throttles. - virtual void RegisterThrottleForTesting( - scoped_ptr<NavigationThrottle> navigation_throttle) = 0; - - // Simulates the network request starting. - virtual NavigationThrottle::ThrottleCheckResult - CallWillStartRequestForTesting(bool is_post, - const Referrer& sanitized_referrer, - bool has_user_gesture, - ui::PageTransition transition, - bool is_external_protocol) = 0; - - // Simulates the network request being redirected. - virtual NavigationThrottle::ThrottleCheckResult - CallWillRedirectRequestForTesting(const GURL& new_url, - bool new_method_is_post, - const GURL& new_referrer_url, - bool new_is_external_protocol) = 0; + virtual bool HasCommittedErrorPage() const = 0; }; } // namespace content diff --git a/content/public/browser/navigation_throttle.cc b/content/public/browser/navigation_throttle.cc deleted file mode 100644 index ac3b3aa..0000000 --- a/content/public/browser/navigation_throttle.cc +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 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 "content/public/browser/navigation_throttle.h" - -namespace content { - -NavigationThrottle::NavigationThrottle(NavigationHandle* navigation_handle) - : navigation_handle_(navigation_handle) {} - -NavigationThrottle::~NavigationThrottle() {} - -NavigationThrottle::ThrottleCheckResult NavigationThrottle::WillStartRequest() { - return NavigationThrottle::PROCEED; -} - -NavigationThrottle::ThrottleCheckResult -NavigationThrottle::WillRedirectRequest() { - return NavigationThrottle::PROCEED; -} - -} // namespace content diff --git a/content/public/browser/navigation_throttle.h b/content/public/browser/navigation_throttle.h deleted file mode 100644 index ae5883b..0000000 --- a/content/public/browser/navigation_throttle.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_PUBLIC_BROWSER_NAVIGATION_THROTTLE_H_ -#define CONTENT_PUBLIC_BROWSER_NAVIGATION_THROTTLE_H_ - -#include "content/common/content_export.h" - -namespace content { -class NavigationHandle; - -// A NavigationThrottle tracks and allows interaction with a navigation on the -// UI thread. -class CONTENT_EXPORT NavigationThrottle { - public: - // This is returned to the NavigationHandle to allow the navigation to - // proceed, or to cancel it. - enum ThrottleCheckResult { - PROCEED, - CANCEL_AND_IGNORE, - }; - - NavigationThrottle(NavigationHandle* navigation_handle); - virtual ~NavigationThrottle(); - - // Called when a network request is about to be made for this navigation. - virtual ThrottleCheckResult WillStartRequest(); - - // Called when a server redirect is received by the navigation. - virtual ThrottleCheckResult WillRedirectRequest(); - - // The NavigationHandle that is tracking the information related to this - // navigation. - NavigationHandle* navigation_handle() const { return navigation_handle_; } - - private: - NavigationHandle* navigation_handle_; -}; - -} // namespace content - -#endif // CONTENT_PUBLIC_BROWSER_NAVIGATION_THROTTLE_H_ diff --git a/content/test/web_contents_observer_sanity_checker.cc b/content/test/web_contents_observer_sanity_checker.cc index 18d38ae..82bcb60 100644 --- a/content/test/web_contents_observer_sanity_checker.cc +++ b/content/test/web_contents_observer_sanity_checker.cc @@ -129,7 +129,6 @@ void WebContentsObserverSanityChecker::DidStartNavigation( CHECK(navigation_handle->GetNetErrorCode() == net::OK); CHECK(!navigation_handle->HasCommittedDocument()); CHECK(!navigation_handle->HasCommittedErrorPage()); - CHECK_EQ(navigation_handle->GetWebContents(), web_contents()); ongoing_navigations_.insert(navigation_handle); } @@ -142,7 +141,6 @@ void WebContentsObserverSanityChecker::DidRedirectNavigation( CHECK(navigation_handle->GetNetErrorCode() == net::OK); CHECK(!navigation_handle->HasCommittedDocument()); CHECK(!navigation_handle->HasCommittedErrorPage()); - CHECK_EQ(navigation_handle->GetWebContents(), web_contents()); } void WebContentsObserverSanityChecker::ReadyToCommitNavigation( @@ -165,7 +163,6 @@ void WebContentsObserverSanityChecker::DidCommitNavigation( navigation_handle->GetNetErrorCode() == net::OK); CHECK_IMPLIES(navigation_handle->HasCommittedErrorPage(), navigation_handle->GetNetErrorCode() != net::OK); - CHECK_EQ(navigation_handle->GetWebContents(), web_contents()); ongoing_committed_navigations_.insert(navigation_handle); } @@ -181,7 +178,6 @@ void WebContentsObserverSanityChecker::DidFinishNavigation( navigation_handle->GetNetErrorCode() == net::OK); CHECK_IMPLIES(navigation_handle->HasCommittedErrorPage(), navigation_handle->GetNetErrorCode() != net::OK); - CHECK_EQ(navigation_handle->GetWebContents(), web_contents()); if (NavigationIsOngoingAndCommitted(navigation_handle)) ongoing_committed_navigations_.erase(navigation_handle); |