Chromium Code Reviews| Index: chrome/browser/prerender/prerender_resource_throttle.cc |
| diff --git a/chrome/browser/prerender/prerender_resource_throttle.cc b/chrome/browser/prerender/prerender_resource_throttle.cc |
| index 8d8511e22e2fc16a1612f39e862089171ecc2afa..a0cea3cf749c0361d04f42d723e57b4cc33ceff0 100644 |
| --- a/chrome/browser/prerender/prerender_resource_throttle.cc |
| +++ b/chrome/browser/prerender/prerender_resource_throttle.cc |
| @@ -11,6 +11,7 @@ |
| #include "chrome/browser/prerender/prerender_final_status.h" |
| #include "chrome/browser/prerender/prerender_manager.h" |
| #include "chrome/browser/prerender/prerender_util.h" |
| +#include "content/public/browser/appcache_service.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/web_contents.h" |
| #include "net/base/load_flags.h" |
| @@ -91,8 +92,7 @@ PrerenderResourceThrottle::~PrerenderResourceThrottle() {} |
| void PrerenderResourceThrottle::WillStartRequest(bool* defer) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - const content::ResourceRequestInfo* info = |
| - content::ResourceRequestInfo::ForRequest(request_); |
| + const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); |
| *defer = true; |
| BrowserThread::PostTask( |
| BrowserThread::UI, FROM_HERE, |
| @@ -106,8 +106,7 @@ void PrerenderResourceThrottle::WillRedirectRequest( |
| const net::RedirectInfo& redirect_info, |
| bool* defer) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - const content::ResourceRequestInfo* info = |
| - content::ResourceRequestInfo::ForRequest(request_); |
| + const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); |
| *defer = true; |
| std::string header; |
| request_->GetResponseHeaderByName(kFollowOnlyWhenPrerenderShown, &header); |
| @@ -122,11 +121,14 @@ void PrerenderResourceThrottle::WillRedirectRequest( |
| void PrerenderResourceThrottle::WillProcessResponse(bool* defer) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - const content::ResourceRequestInfo* info = |
| - content::ResourceRequestInfo::ForRequest(request_); |
| + |
| + const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); |
| if (!info) |
| return; |
| + bool has_appcache = |
| + content::AppCacheService::URLRequestHasActiveAppCache(request_); |
| + |
| DCHECK_GT(request_->url_chain().size(), 0u); |
| int redirect_count = |
| base::saturated_cast<int>(request_->url_chain().size()) - 1; |
| @@ -134,8 +136,10 @@ void PrerenderResourceThrottle::WillProcessResponse(bool* defer) { |
| BrowserThread::PostTask( |
| BrowserThread::UI, FROM_HERE, |
| base::Bind(&PrerenderResourceThrottle::WillProcessResponseOnUI, |
| + AsWeakPtr(), |
| content::IsResourceTypeFrame(info->GetResourceType()), |
| - IsNoStoreResponse(*request_), redirect_count, |
| + IsNoStoreResponse(*request_), redirect_count, has_appcache, |
| + info->GetWebContentsGetterForRequest(), |
| prerender_throttle_info_)); |
| } |
| @@ -258,9 +262,12 @@ void PrerenderResourceThrottle::WillRedirectRequestOnUI( |
| // static |
| void PrerenderResourceThrottle::WillProcessResponseOnUI( |
|
michaeln
2017/03/27 23:27:45
Since this call on the UI thread is advisory only,
|
| + const base::WeakPtr<PrerenderResourceThrottle>& throttle, |
| bool is_main_resource, |
| bool is_no_store, |
| int redirect_count, |
| + bool has_appcache, |
| + const ResourceRequestInfo::WebContentsGetter& web_contents_getter, |
| scoped_refptr<PrerenderThrottleInfo> prerender_throttle_info) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| DCHECK(prerender_throttle_info); |
| @@ -270,6 +277,23 @@ void PrerenderResourceThrottle::WillProcessResponseOnUI( |
| if (prerender_throttle_info->mode() != PREFETCH_ONLY) |
| return; |
| + // Check for an AppCache. If there is one, the AppCache fetcher (?) may not |
| + // have been properly initialized for a prefetch-only resource, so the request |
| + // is canceled. If there is no appcache, it is appropriate to go to the |
| + // network: even if the main resource lists a manifest, its AppCache has not |
| + // yet been initialized, and a network fetch would have happened in any case. |
| + if (has_appcache) { |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&PrerenderResourceThrottle::Cancel, throttle)); |
| + |
| + PrerenderContents* prerender_contents = |
| + PrerenderContentsFromGetter(web_contents_getter); |
| + if (prerender_contents) |
| + prerender_contents->Destroy(FINAL_STATUS_CANCELLED_FOR_APPCACHE); |
| + return; |
| + } |
| + |
| prerender_throttle_info->manager()->RecordPrefetchResponseReceived( |
| prerender_throttle_info->origin(), is_main_resource, |
| false /* is_redirect */, is_no_store); |