Update mojo surfaces bindings and mojo/cc/ glue
[chromium-blink-merge.git] / chrome / browser / prerender / prerender_resource_throttle.cc
blob70e1aeefcae471fec122a3e321d7fe71cb7ce56b
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/prerender/prerender_resource_throttle.h"
7 #include "chrome/browser/prerender/prerender_final_status.h"
8 #include "chrome/browser/prerender/prerender_manager.h"
9 #include "chrome/browser/prerender/prerender_util.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/resource_controller.h"
13 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/browser/web_contents.h"
15 #include "net/url_request/url_request.h"
17 using content::ResourceType;
19 namespace prerender {
21 namespace {
22 static const char kFollowOnlyWhenPrerenderShown[] =
23 "follow-only-when-prerender-shown";
25 PrerenderContents* g_prerender_contents_for_testing;
28 void PrerenderResourceThrottle::OverridePrerenderContentsForTesting(
29 PrerenderContents* contents) {
30 g_prerender_contents_for_testing = contents;
33 PrerenderResourceThrottle::PrerenderResourceThrottle(net::URLRequest* request)
34 : request_(request) {
37 void PrerenderResourceThrottle::WillStartRequest(bool* defer) {
38 const content::ResourceRequestInfo* info =
39 content::ResourceRequestInfo::ForRequest(request_);
40 *defer = true;
41 content::BrowserThread::PostTask(
42 content::BrowserThread::UI,
43 FROM_HERE,
44 base::Bind(&PrerenderResourceThrottle::WillStartRequestOnUI,
45 AsWeakPtr(), request_->method(), info->GetResourceType(),
46 info->GetChildID(), info->GetRenderFrameID(),
47 request_->url()));
50 void PrerenderResourceThrottle::WillRedirectRequest(const GURL& new_url,
51 bool* defer) {
52 const content::ResourceRequestInfo* info =
53 content::ResourceRequestInfo::ForRequest(request_);
54 *defer = true;
55 std::string header;
56 request_->GetResponseHeaderByName(kFollowOnlyWhenPrerenderShown, &header);
58 content::BrowserThread::PostTask(
59 content::BrowserThread::UI,
60 FROM_HERE,
61 base::Bind(&PrerenderResourceThrottle::WillRedirectRequestOnUI,
62 AsWeakPtr(), header, info->GetResourceType(), info->IsAsync(),
63 info->GetChildID(), info->GetRenderFrameID(), new_url));
66 const char* PrerenderResourceThrottle::GetNameForLogging() const {
67 return "PrerenderResourceThrottle";
70 void PrerenderResourceThrottle::Resume() {
71 controller()->Resume();
74 void PrerenderResourceThrottle::Cancel() {
75 controller()->Cancel();
78 void PrerenderResourceThrottle::WillStartRequestOnUI(
79 const base::WeakPtr<PrerenderResourceThrottle>& throttle,
80 const std::string& method,
81 ResourceType resource_type,
82 int render_process_id,
83 int render_frame_id,
84 const GURL& url) {
85 bool cancel = false;
86 PrerenderContents* prerender_contents =
87 PrerenderContentsFromRenderFrame(render_process_id, render_frame_id);
88 if (prerender_contents) {
89 // Abort any prerenders that spawn requests that use unsupported HTTP
90 // methods or schemes.
91 if (!PrerenderManager::IsValidHttpMethod(method)) {
92 prerender_contents->Destroy(FINAL_STATUS_INVALID_HTTP_METHOD);
93 cancel = true;
94 } else if (!PrerenderManager::DoesSubresourceURLHaveValidScheme(url)) {
95 prerender_contents->Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME);
96 ReportUnsupportedPrerenderScheme(url);
97 cancel = true;
98 #if defined(OS_ANDROID)
99 } else if (resource_type == content::RESOURCE_TYPE_FAVICON) {
100 // Delay icon fetching until the contents are getting swapped in
101 // to conserve network usage in mobile devices.
102 prerender_contents->AddResourceThrottle(throttle);
103 return;
104 #endif
108 content::BrowserThread::PostTask(
109 content::BrowserThread::IO,
110 FROM_HERE,
111 base::Bind(cancel ? &PrerenderResourceThrottle::Cancel :
112 &PrerenderResourceThrottle::Resume, throttle));
115 void PrerenderResourceThrottle::WillRedirectRequestOnUI(
116 const base::WeakPtr<PrerenderResourceThrottle>& throttle,
117 const std::string& follow_only_when_prerender_shown_header,
118 ResourceType resource_type,
119 bool async,
120 int render_process_id,
121 int render_frame_id,
122 const GURL& new_url) {
123 bool cancel = false;
124 PrerenderContents* prerender_contents =
125 PrerenderContentsFromRenderFrame(render_process_id, render_frame_id);
126 if (prerender_contents) {
127 // Abort any prerenders with requests which redirect to invalid schemes.
128 if (!PrerenderManager::DoesURLHaveValidScheme(new_url)) {
129 prerender_contents->Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME);
130 ReportUnsupportedPrerenderScheme(new_url);
131 cancel = true;
132 } else if (follow_only_when_prerender_shown_header == "1" &&
133 resource_type != content::RESOURCE_TYPE_MAIN_FRAME) {
134 // Only defer redirects with the Follow-Only-When-Prerender-Shown
135 // header. Do not defer redirects on main frame loads.
136 if (!async) {
137 // Cancel on deferred synchronous requests. Those will
138 // indefinitely hang up a renderer process.
139 prerender_contents->Destroy(FINAL_STATUS_BAD_DEFERRED_REDIRECT);
140 cancel = true;
141 } else {
142 // Defer the redirect until the prerender is used or canceled.
143 prerender_contents->AddResourceThrottle(throttle);
144 return;
149 content::BrowserThread::PostTask(
150 content::BrowserThread::IO,
151 FROM_HERE,
152 base::Bind(cancel ? &PrerenderResourceThrottle::Cancel :
153 &PrerenderResourceThrottle::Resume, throttle));
156 PrerenderContents* PrerenderResourceThrottle::PrerenderContentsFromRenderFrame(
157 int render_process_id, int render_frame_id) {
158 if (g_prerender_contents_for_testing)
159 return g_prerender_contents_for_testing;
160 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
161 render_process_id, render_frame_id);
162 content::WebContents* web_contents =
163 content::WebContents::FromRenderFrameHost(rfh);
164 return PrerenderContents::FromWebContents(web_contents);
167 } // namespace prerender