diff options
11 files changed, 162 insertions, 94 deletions
diff --git a/chrome/browser/prerender/prerender_resource_throttle.cc b/chrome/browser/prerender/prerender_resource_throttle.cc new file mode 100644 index 0000000..df4be12 --- /dev/null +++ b/chrome/browser/prerender/prerender_resource_throttle.cc @@ -0,0 +1,42 @@ +// 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 "chrome/browser/prerender/prerender_resource_throttle.h" + +#include "base/bind.h" +#include "chrome/browser/prerender/prerender_tracker.h" +#include "content/public/browser/resource_throttle_controller.h" +#include "net/url_request/url_request.h" + +namespace prerender { + +PrerenderResourceThrottle::PrerenderResourceThrottle( + PrerenderTracker* prerender_tracker, + const net::URLRequest* request, + int child_id, + int route_id) + : prerender_tracker_(prerender_tracker), + request_(request), + child_id_(child_id), + route_id_(route_id) { +} + +PrerenderResourceThrottle::~PrerenderResourceThrottle() { +} + +void PrerenderResourceThrottle::WillStartRequest(bool* defer) { + *defer = prerender_tracker_->PotentiallyDelayRequestOnIOThread( + request_->url(), child_id_, route_id_, + base::Bind(&PrerenderResourceThrottle::ContinueRequest, AsWeakPtr())); +} + +void PrerenderResourceThrottle::ContinueRequest(bool proceed) { + if (proceed) { + controller()->Resume(); + } else { + controller()->Cancel(); + } +} + +} // namespace prerender diff --git a/chrome/browser/prerender/prerender_resource_throttle.h b/chrome/browser/prerender/prerender_resource_throttle.h new file mode 100644 index 0000000..e6fc3ae --- /dev/null +++ b/chrome/browser/prerender/prerender_resource_throttle.h @@ -0,0 +1,49 @@ +// 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 CHROME_BROWSER_PRERENDER_PRERENDER_RESOURCE_THROTTLE_H_ +#define CHROME_BROWSER_PRERENDER_PRERENDER_RESOURCE_THROTTLE_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/weak_ptr.h" +#include "content/public/browser/resource_throttle.h" + +namespace net { +class URLRequest; +} + +namespace prerender { +class PrerenderTracker; + +class PrerenderResourceThrottle + : public content::ResourceThrottle, + public base::SupportsWeakPtr<PrerenderResourceThrottle> { + public: + PrerenderResourceThrottle(PrerenderTracker* prerender_tracker, + const net::URLRequest* request, + int child_id, + int route_id); + + // content::ResourceThrottle implementation: + virtual void WillStartRequest(bool* defer) OVERRIDE; + + private: + virtual ~PrerenderResourceThrottle(); + + void ContinueRequest(bool proceed); + + PrerenderTracker* prerender_tracker_; + const net::URLRequest* request_; + int child_id_; + int route_id_; + int request_id_; + + DISALLOW_COPY_AND_ASSIGN(PrerenderResourceThrottle); +}; + +} // namespace prerender + +#endif // CHROME_BROWSER_PRERENDER_PRERENDER_RESOURCE_THROTTLE_H_ diff --git a/chrome/browser/prerender/prerender_tracker.cc b/chrome/browser/prerender/prerender_tracker.cc index b82be79..8672762 100644 --- a/chrome/browser/prerender/prerender_tracker.cc +++ b/chrome/browser/prerender/prerender_tracker.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -20,16 +20,6 @@ namespace prerender { namespace { -void CancelDeferredRequestOnIOThread(int child_id, int request_id) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - ResourceDispatcherHost::Get()->CancelRequest(child_id, request_id, false); -} - -void StartDeferredRequestOnIOThread(int child_id, int request_id) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - ResourceDispatcherHost::Get()->StartDeferredRequest(child_id, request_id); -} - bool ShouldCancelRequest( int child_id, int route_id) { @@ -53,17 +43,11 @@ bool ShouldCancelRequest( void HandleDelayedRequestOnUIThread( int child_id, int route_id, - int request_id) { + const PrerenderTracker::CheckURLCallback& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (ShouldCancelRequest(child_id, route_id)) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind(&CancelDeferredRequestOnIOThread, child_id, request_id)); - } else { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind(&StartDeferredRequestOnIOThread, child_id, request_id)); - } + bool should_cancel = ShouldCancelRequest(child_id, route_id); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, base::Bind(callback, !should_cancel)); } void DestroyPrerenderForRenderViewOnUI( @@ -189,7 +173,7 @@ bool PrerenderTracker::PotentiallyDelayRequestOnIOThread( const GURL& gurl, int process_id, int route_id, - int request_id) { + const CheckURLCallback& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (!url_counter_.MatchesURL(gurl)) return false; @@ -197,7 +181,7 @@ bool PrerenderTracker::PotentiallyDelayRequestOnIOThread( BrowserThread::UI, FROM_HERE, base::Bind(&HandleDelayedRequestOnUIThread, process_id, route_id, - request_id)); + callback)); return true; } diff --git a/chrome/browser/prerender/prerender_tracker.h b/chrome/browser/prerender/prerender_tracker.h index 5a3e138..56d5dff 100644 --- a/chrome/browser/prerender/prerender_tracker.h +++ b/chrome/browser/prerender/prerender_tracker.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -47,6 +47,8 @@ class URLCounter : public base::NonThreadSafe { // and can be modified on any thread. class PrerenderTracker { public: + typedef base::Callback<void(bool /* proceed */)> CheckURLCallback; + PrerenderTracker(); ~PrerenderTracker(); @@ -78,12 +80,13 @@ class PrerenderTracker { FinalStatus final_status); // Potentially delay a resource request on the IO thread to prevent a double - // get. + // get. When this method returns true, the callback will be run later to + // indicate if the request should be allowed or canceled. bool PotentiallyDelayRequestOnIOThread( const GURL& gurl, int child_id, int route_id, - int request_id); + const CheckURLCallback& callback); void AddPrerenderURLOnUIThread(const GURL& url); void RemovePrerenderURLsOnUIThread(const std::vector<GURL>& urls); 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 fec7c45..97db0c6 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc @@ -15,6 +15,7 @@ #include "chrome/browser/net/load_timing_observer.h" #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/prerender/prerender_manager_factory.h" +#include "chrome/browser/prerender/prerender_resource_throttle.h" #include "chrome/browser/prerender/prerender_tracker.h" #include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/renderer_host/chrome_url_request_user_data.h" @@ -157,18 +158,20 @@ void ChromeResourceDispatcherHostDelegate::RequestBeginning( throttles->push_back(new OfflineResourceThrottle( child_id, route_id, request, resource_context->GetAppCacheService())); #endif - } -#if defined(ENABLE_SAFE_BROWSING) - // Insert safe browsing at the front of the chain, so it gets to decide - // on policies first. - ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); - if (io_data->safe_browsing_enabled()->GetValue()) { - throttles->push_back(CreateSafeBrowsingResourceThrottle( - request, child_id, route_id, - resource_type != ResourceType::MAIN_FRAME)); + throttles->push_back( + new prerender::PrerenderResourceThrottle(prerender_tracker_, + request, + child_id, + route_id)); } -#endif + + AppendSafeBrowsingResourceThrottle(request, + resource_context, + child_id, + route_id, + resource_type != ResourceType::MAIN_FRAME, + throttles); } void ChromeResourceDispatcherHostDelegate::DownloadStarting( @@ -188,29 +191,18 @@ void ChromeResourceDispatcherHostDelegate::DownloadStarting( // path is only hit for requests initiated through the browser, and not the // web, so no need to add the download throttle. if (is_new_request) { -#if defined(ENABLE_SAFE_BROWSING) - ProfileIOData* io_data = - ProfileIOData::FromResourceContext(resource_context); - if (io_data->safe_browsing_enabled()->GetValue()) { - throttles->push_back(CreateSafeBrowsingResourceThrottle( - request, child_id, route_id, false)); - } -#endif + AppendSafeBrowsingResourceThrottle(request, + resource_context, + child_id, + route_id, + false, + throttles); } else { throttles->push_back(new DownloadResourceThrottle( download_request_limiter_, child_id, route_id, request_id)); } } -bool ChromeResourceDispatcherHostDelegate::ShouldDeferStart( - net::URLRequest* request, - content::ResourceContext* resource_context) { - ResourceDispatcherHostRequestInfo* info = - resource_dispatcher_host_->InfoForRequest(request); - return prerender_tracker_->PotentiallyDelayRequestOnIOThread( - request->url(), info->child_id(), info->route_id(), info->request_id()); -} - bool ChromeResourceDispatcherHostDelegate::AcceptSSLClientCertificateRequest( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) { if (request->load_flags() & net::LOAD_PREFETCH) @@ -278,15 +270,23 @@ void ChromeResourceDispatcherHostDelegate::HandleExternalProtocol( base::Bind(&ExternalProtocolHandler::LaunchUrl, url, child_id, route_id)); } +void ChromeResourceDispatcherHostDelegate::AppendSafeBrowsingResourceThrottle( + const net::URLRequest* request, + content::ResourceContext* resource_context, + int child_id, + int route_id, + bool is_subresource_request, + ScopedVector<content::ResourceThrottle>* throttles) { #if defined(ENABLE_SAFE_BROWSING) -content::ResourceThrottle* - ChromeResourceDispatcherHostDelegate::CreateSafeBrowsingResourceThrottle( - const net::URLRequest* request, int child_id, int route_id, - bool subresource) { - return SafeBrowsingResourceThrottle::Create( - request, child_id, route_id, subresource, safe_browsing_); -} + // Insert safe browsing at the front of the list, so it gets to decide on + // policies first. + ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); + if (io_data->safe_browsing_enabled()->GetValue()) { + throttles->push_back(SafeBrowsingResourceThrottle::Create( + request, child_id, route_id, is_subresource_request, safe_browsing_)); + } #endif +} bool ChromeResourceDispatcherHostDelegate::ShouldForceDownloadResource( const GURL& url, const std::string& mime_type) { diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h index 4934bb9..c5afd9f 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h @@ -57,9 +57,6 @@ class ChromeResourceDispatcherHostDelegate int request_id, bool is_new_request, ScopedVector<content::ResourceThrottle>* throttles) OVERRIDE; - virtual bool ShouldDeferStart( - net::URLRequest* request, - content::ResourceContext* resource_context) OVERRIDE; virtual bool AcceptSSLClientCertificateRequest( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) OVERRIDE; @@ -81,9 +78,13 @@ class ChromeResourceDispatcherHostDelegate content::ResourceResponse* response) OVERRIDE; private: - content::ResourceThrottle* CreateSafeBrowsingResourceThrottle( - const net::URLRequest* request, int child_id, int route_id, - bool subresource); + void AppendSafeBrowsingResourceThrottle( + const net::URLRequest* request, + content::ResourceContext* resource_context, + int child_id, + int route_id, + bool is_subresource_request, + ScopedVector<content::ResourceThrottle>* throttles); ResourceDispatcherHost* resource_dispatcher_host_; scoped_refptr<DownloadRequestLimiter> download_request_limiter_; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 89326e5..61d3c59 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2000,6 +2000,8 @@ 'browser/prerender/prerender_origin.h', 'browser/prerender/prerender_render_view_host_observer.cc', 'browser/prerender/prerender_render_view_host_observer.h', + 'browser/prerender/prerender_resource_throttle.cc', + 'browser/prerender/prerender_resource_throttle.h', 'browser/prerender/prerender_tab_helper.cc', 'browser/prerender/prerender_tab_helper.h', 'browser/prerender/prerender_tracker.cc', diff --git a/content/browser/renderer_host/resource_dispatcher_host.cc b/content/browser/renderer_host/resource_dispatcher_host.cc index 578c9c8..5b73ae8 100644 --- a/content/browser/renderer_host/resource_dispatcher_host.cc +++ b/content/browser/renderer_host/resource_dispatcher_host.cc @@ -676,8 +676,11 @@ void ResourceDispatcherHost::BeginRequest( (deferred_request != NULL); ScopedVector<ResourceThrottle> throttles; - delegate_->RequestBeginning(request, resource_context, - request_data.resource_type, child_id, route_id, + delegate_->RequestBeginning(request, + resource_context, + request_data.resource_type, + child_id, + route_id, is_continuation_of_transferred_request, &throttles); if (!throttles.empty()) { @@ -1683,13 +1686,6 @@ void ResourceDispatcherHost::BeginRequestInternal(net::URLRequest* request) { return; } - // TODO(cbentzel): Should we isolate this to resource handlers instead of - // adding an interface to the observer? - if (!defer_start && delegate_ && filter_) { - defer_start = delegate_->ShouldDeferStart(request, - filter_->resource_context()); - } - if (!defer_start) InsertIntoResourceQueue(request, *info); } diff --git a/content/browser/renderer_host/resource_dispatcher_host_unittest.cc b/content/browser/renderer_host/resource_dispatcher_host_unittest.cc index 5075014..3bf44bd 100644 --- a/content/browser/renderer_host/resource_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/resource_dispatcher_host_unittest.cc @@ -24,6 +24,7 @@ #include "content/common/view_messages.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" +#include "content/public/browser/resource_throttle.h" #include "content/public/common/resource_response.h" #include "net/base/net_errors.h" #include "net/base/upload_data.h" @@ -284,6 +285,13 @@ class TestUserData : public base::SupportsUserData::Data { bool* was_deleted_; }; +class DefersStartResourceThrottle : public content::ResourceThrottle { + public: + virtual void WillStartRequest(bool* defer) { + *defer = true; + } +}; + class TestResourceDispatcherHostDelegate : public content::ResourceDispatcherHostDelegate { public: @@ -311,12 +319,9 @@ class TestResourceDispatcherHostDelegate ScopedVector<content::ResourceThrottle>* throttles) OVERRIDE { const void* key = user_data_.get(); request->SetUserData(key, user_data_.release()); - } - virtual bool ShouldDeferStart( - net::URLRequest* request, - content::ResourceContext* resource_context) OVERRIDE { - return defer_start_; + if (defer_start_) + throttles->push_back(new DefersStartResourceThrottle()); } private: diff --git a/content/public/browser/resource_dispatcher_host_delegate.cc b/content/public/browser/resource_dispatcher_host_delegate.cc index ae15e67..3dc1c7e 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.cc +++ b/content/public/browser/resource_dispatcher_host_delegate.cc @@ -37,12 +37,6 @@ void ResourceDispatcherHostDelegate::DownloadStarting( ScopedVector<ResourceThrottle>* throttles) { } -bool ResourceDispatcherHostDelegate::ShouldDeferStart( - net::URLRequest* request, - ResourceContext* resource_context) { - return false; -} - bool ResourceDispatcherHostDelegate::AcceptSSLClientCertificateRequest( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) { diff --git a/content/public/browser/resource_dispatcher_host_delegate.h b/content/public/browser/resource_dispatcher_host_delegate.h index e2fe99e..4c2fef0 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.h +++ b/content/public/browser/resource_dispatcher_host_delegate.h @@ -75,14 +75,6 @@ class CONTENT_EXPORT ResourceDispatcherHostDelegate { bool is_new_request, ScopedVector<ResourceThrottle>* throttles); - // Called to determine whether a request's start should be deferred. This - // is only called if the ResourceHandler associated with the request does - // not ask for a deferral. A return value of true will defer the start of - // the request, false will continue the request. - virtual bool ShouldDeferStart( - net::URLRequest* request, - ResourceContext* resource_context); - // Called when an SSL Client Certificate is requested. If false is returned, // the request is canceled. Otherwise, the certificate is chosen. virtual bool AcceptSSLClientCertificateRequest( |