Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: chrome/browser/prerender/prerender_resource_throttle.cc

Issue 2576443002: [PlzNavigate] Use WebContentsGetter in PrerenderResourceThrottle (Closed)
Patch Set: Fix subresource check Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/prerender/prerender_resource_throttle.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/prerender/prerender_resource_throttle.h" 5 #include "chrome/browser/prerender/prerender_resource_throttle.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "base/numerics/safe_conversions.h" 9 #include "base/numerics/safe_conversions.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
11 #include "chrome/browser/prerender/prerender_final_status.h" 11 #include "chrome/browser/prerender/prerender_final_status.h"
12 #include "chrome/browser/prerender/prerender_manager.h" 12 #include "chrome/browser/prerender/prerender_manager.h"
13 #include "chrome/browser/prerender/prerender_util.h" 13 #include "chrome/browser/prerender/prerender_util.h"
14 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/resource_request_info.h"
17 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
18 #include "net/http/http_response_headers.h" 16 #include "net/http/http_response_headers.h"
19 #include "net/url_request/redirect_info.h" 17 #include "net/url_request/redirect_info.h"
20 #include "net/url_request/url_request.h" 18 #include "net/url_request/url_request.h"
21 19
22 using content::BrowserThread; 20 using content::BrowserThread;
21 using content::ResourceRequestInfo;
23 using content::ResourceType; 22 using content::ResourceType;
24 23
25 namespace prerender { 24 namespace prerender {
26 25
27 namespace { 26 namespace {
28 static const char kFollowOnlyWhenPrerenderShown[] = 27 static const char kFollowOnlyWhenPrerenderShown[] =
29 "follow-only-when-prerender-shown"; 28 "follow-only-when-prerender-shown";
30 29
31 PrerenderContents* g_prerender_contents_for_testing; 30 PrerenderContents* g_prerender_contents_for_testing;
32 31
33 // Returns true if the response has a "no-store" cache control header. 32 // Returns true if the response has a "no-store" cache control header.
34 bool IsNoStoreResponse(const net::URLRequest& request) { 33 bool IsNoStoreResponse(const net::URLRequest& request) {
35 const net::HttpResponseInfo& response_info = request.response_info(); 34 const net::HttpResponseInfo& response_info = request.response_info();
36 return response_info.headers.get() && 35 return response_info.headers.get() &&
37 response_info.headers->HasHeaderValue("cache-control", "no-store"); 36 response_info.headers->HasHeaderValue("cache-control", "no-store");
38 } 37 }
39 38
40 } // namespace 39 } // namespace
41 40
42 // Used to pass information between different UI thread tasks of the same 41 // Used to pass information between different UI thread tasks of the same
43 // throttle. This is reference counted as the throttler may be destroyed before 42 // throttle. This is reference counted as the throttler may be destroyed before
44 // the UI thread task has a chance to run. 43 // the UI thread task has a chance to run.
45 // 44 //
46 // This class is created on the IO thread, and destroyed on the UI thread. Its 45 // This class is created on the IO thread, and destroyed on the UI thread. Its
47 // members should only be accessed on the UI thread. 46 // members should only be accessed on the UI thread.
48 class PrerenderThrottleInfo 47 class PrerenderThrottleInfo
49 : public base::RefCountedThreadSafe<PrerenderThrottleInfo, 48 : public base::RefCountedThreadSafe<PrerenderThrottleInfo,
50 BrowserThread::DeleteOnUIThread> { 49 BrowserThread::DeleteOnUIThread> {
51 public: 50 public:
52 PrerenderThrottleInfo() : manager_(nullptr) {} 51 PrerenderThrottleInfo()
52 : mode_(NO_PRERENDER), origin_(ORIGIN_NONE), manager_(nullptr) {}
53 53
54 void Set(PrerenderMode mode, Origin origin, PrerenderManager* manager) { 54 void Set(PrerenderMode mode, Origin origin, PrerenderManager* manager) {
55 DCHECK_CURRENTLY_ON(BrowserThread::UI); 55 DCHECK_CURRENTLY_ON(BrowserThread::UI);
56 mode_ = mode; 56 mode_ = mode;
57 origin_ = origin; 57 origin_ = origin;
58 manager_ = manager->AsWeakPtr(); 58 manager_ = manager->AsWeakPtr();
59 } 59 }
60 60
61 PrerenderMode mode() const { return mode_; } 61 PrerenderMode mode() const { return mode_; }
62 Origin origin() const { return origin_; } 62 Origin origin() const { return origin_; }
(...skipping 24 matching lines...) Expand all
87 87
88 PrerenderResourceThrottle::~PrerenderResourceThrottle() {} 88 PrerenderResourceThrottle::~PrerenderResourceThrottle() {}
89 89
90 void PrerenderResourceThrottle::WillStartRequest(bool* defer) { 90 void PrerenderResourceThrottle::WillStartRequest(bool* defer) {
91 const content::ResourceRequestInfo* info = 91 const content::ResourceRequestInfo* info =
92 content::ResourceRequestInfo::ForRequest(request_); 92 content::ResourceRequestInfo::ForRequest(request_);
93 *defer = true; 93 *defer = true;
94 BrowserThread::PostTask( 94 BrowserThread::PostTask(
95 BrowserThread::UI, FROM_HERE, 95 BrowserThread::UI, FROM_HERE,
96 base::Bind(&PrerenderResourceThrottle::WillStartRequestOnUI, AsWeakPtr(), 96 base::Bind(&PrerenderResourceThrottle::WillStartRequestOnUI, AsWeakPtr(),
97 request_->method(), info->GetResourceType(), 97 request_->method(), info->GetResourceType(), request_->url(),
98 info->GetChildID(), info->GetRenderFrameID(), request_->url(), 98 info->GetWebContentsGetterForRequest(),
99 prerender_throttle_info_)); 99 prerender_throttle_info_));
100 } 100 }
101 101
102 void PrerenderResourceThrottle::WillRedirectRequest( 102 void PrerenderResourceThrottle::WillRedirectRequest(
103 const net::RedirectInfo& redirect_info, 103 const net::RedirectInfo& redirect_info,
104 bool* defer) { 104 bool* defer) {
105 const content::ResourceRequestInfo* info = 105 const content::ResourceRequestInfo* info =
106 content::ResourceRequestInfo::ForRequest(request_); 106 content::ResourceRequestInfo::ForRequest(request_);
107 *defer = true; 107 *defer = true;
108 std::string header; 108 std::string header;
109 request_->GetResponseHeaderByName(kFollowOnlyWhenPrerenderShown, &header); 109 request_->GetResponseHeaderByName(kFollowOnlyWhenPrerenderShown, &header);
110 110
111 BrowserThread::PostTask( 111 BrowserThread::PostTask(
112 BrowserThread::UI, FROM_HERE, 112 BrowserThread::UI, FROM_HERE,
113 base::Bind(&PrerenderResourceThrottle::WillRedirectRequestOnUI, 113 base::Bind(&PrerenderResourceThrottle::WillRedirectRequestOnUI,
114 AsWeakPtr(), header, info->GetResourceType(), info->IsAsync(), 114 AsWeakPtr(), header, info->GetResourceType(), info->IsAsync(),
115 IsNoStoreResponse(*request_), info->GetChildID(), 115 IsNoStoreResponse(*request_), redirect_info.new_url,
116 info->GetRenderFrameID(), redirect_info.new_url)); 116 info->GetWebContentsGetterForRequest()));
117 } 117 }
118 118
119 void PrerenderResourceThrottle::WillProcessResponse(bool* defer) { 119 void PrerenderResourceThrottle::WillProcessResponse(bool* defer) {
120 const content::ResourceRequestInfo* info = 120 const content::ResourceRequestInfo* info =
121 content::ResourceRequestInfo::ForRequest(request_); 121 content::ResourceRequestInfo::ForRequest(request_);
122 if (!info) 122 if (!info)
123 return; 123 return;
124 124
125 DCHECK_GT(request_->url_chain().size(), 0u); 125 DCHECK_GT(request_->url_chain().size(), 0u);
126 int redirect_count = 126 int redirect_count =
127 base::saturated_cast<int>(request_->url_chain().size()) - 1; 127 base::saturated_cast<int>(request_->url_chain().size()) - 1;
128 128
129 BrowserThread::PostTask( 129 BrowserThread::PostTask(
130 BrowserThread::UI, FROM_HERE, 130 BrowserThread::UI, FROM_HERE,
131 base::Bind(&PrerenderResourceThrottle::WillProcessResponseOnUI, 131 base::Bind(&PrerenderResourceThrottle::WillProcessResponseOnUI,
132 content::IsResourceTypeFrame(info->GetResourceType()), 132 content::IsResourceTypeFrame(info->GetResourceType()),
133 IsNoStoreResponse(*request_), redirect_count, 133 IsNoStoreResponse(*request_), redirect_count,
134 info->GetChildID(), info->GetRenderFrameID(),
135 prerender_throttle_info_)); 134 prerender_throttle_info_));
136 } 135 }
137 136
138 const char* PrerenderResourceThrottle::GetNameForLogging() const { 137 const char* PrerenderResourceThrottle::GetNameForLogging() const {
139 return "PrerenderResourceThrottle"; 138 return "PrerenderResourceThrottle";
140 } 139 }
141 140
142 void PrerenderResourceThrottle::ResumeHandler() { 141 void PrerenderResourceThrottle::ResumeHandler() {
143 Resume(); 142 Resume();
144 } 143 }
145 144
146 // static 145 // static
147 void PrerenderResourceThrottle::WillStartRequestOnUI( 146 void PrerenderResourceThrottle::WillStartRequestOnUI(
148 const base::WeakPtr<PrerenderResourceThrottle>& throttle, 147 const base::WeakPtr<PrerenderResourceThrottle>& throttle,
149 const std::string& method, 148 const std::string& method,
150 ResourceType resource_type, 149 ResourceType resource_type,
151 int render_process_id,
152 int render_frame_id,
153 const GURL& url, 150 const GURL& url,
151 const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
154 scoped_refptr<PrerenderThrottleInfo> prerender_throttle_info) { 152 scoped_refptr<PrerenderThrottleInfo> prerender_throttle_info) {
155 bool cancel = false; 153 bool cancel = false;
156 PrerenderContents* prerender_contents = 154 PrerenderContents* prerender_contents =
157 PrerenderContentsFromRenderFrame(render_process_id, render_frame_id); 155 PrerenderContentsFromGetter(web_contents_getter);
158 if (prerender_contents) { 156 if (prerender_contents) {
159 DCHECK(prerender_throttle_info); 157 DCHECK(prerender_throttle_info);
160 prerender_throttle_info->Set(prerender_contents->prerender_mode(), 158 prerender_throttle_info->Set(prerender_contents->prerender_mode(),
161 prerender_contents->origin(), 159 prerender_contents->origin(),
162 prerender_contents->prerender_manager()); 160 prerender_contents->prerender_manager());
163 161
164 // Abort any prerenders that spawn requests that use unsupported HTTP 162 // Abort any prerenders that spawn requests that use unsupported HTTP
165 // methods or schemes. 163 // methods or schemes.
166 if (!prerender_contents->IsValidHttpMethod(method)) { 164 if (!prerender_contents->IsValidHttpMethod(method)) {
167 // If this is a full prerender, cancel the prerender in response to 165 // If this is a full prerender, cancel the prerender in response to
168 // invalid requests. For prefetches, cancel invalid requests but keep the 166 // invalid requests. For prefetches, cancel invalid requests but keep the
169 // prefetch going, unless it's the main frame that's invalid. 167 // prefetch going, unless it's the main frame that's invalid.
170 if (prerender_contents->prerender_mode() == FULL_PRERENDER || 168 if (prerender_contents->prerender_mode() == FULL_PRERENDER ||
171 resource_type == content::RESOURCE_TYPE_MAIN_FRAME) { 169 resource_type == content::RESOURCE_TYPE_MAIN_FRAME) {
172 prerender_contents->Destroy(FINAL_STATUS_INVALID_HTTP_METHOD); 170 prerender_contents->Destroy(FINAL_STATUS_INVALID_HTTP_METHOD);
173 } 171 }
174 cancel = true; 172 cancel = true;
175 } else if (!PrerenderManager::DoesSubresourceURLHaveValidScheme(url)) { 173 } else if (!PrerenderManager::DoesSubresourceURLHaveValidScheme(url) &&
174 resource_type != content::RESOURCE_TYPE_MAIN_FRAME) {
droger 2016/12/15 09:46:21 This is the one line fix for the failing tests. T
pasko 2016/12/15 15:25:45 Thanks. That's very informative! Can we put a comm
droger 2016/12/15 16:25:01 Done. Note also that DoesSubresourceURLHaveValidS
176 prerender_contents->Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME); 175 prerender_contents->Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME);
177 ReportUnsupportedPrerenderScheme(url); 176 ReportUnsupportedPrerenderScheme(url);
178 cancel = true; 177 cancel = true;
179 #if defined(OS_ANDROID) 178 #if defined(OS_ANDROID)
180 } else if (resource_type == content::RESOURCE_TYPE_FAVICON) { 179 } else if (resource_type == content::RESOURCE_TYPE_FAVICON) {
181 // Delay icon fetching until the contents are getting swapped in 180 // Delay icon fetching until the contents are getting swapped in
182 // to conserve network usage in mobile devices. 181 // to conserve network usage in mobile devices.
183 prerender_contents->AddResourceThrottle(throttle); 182 prerender_contents->AddResourceThrottle(throttle);
184 return; 183 return;
185 #endif 184 #endif
186 } 185 }
187 } 186 }
188 187
189 BrowserThread::PostTask( 188 BrowserThread::PostTask(
190 BrowserThread::IO, FROM_HERE, 189 BrowserThread::IO, FROM_HERE,
191 base::Bind(cancel ? &PrerenderResourceThrottle::Cancel 190 base::Bind(cancel ? &PrerenderResourceThrottle::Cancel
192 : &PrerenderResourceThrottle::ResumeHandler, 191 : &PrerenderResourceThrottle::ResumeHandler,
193 throttle)); 192 throttle));
194 } 193 }
195 194
196 // static 195 // static
197 void PrerenderResourceThrottle::WillRedirectRequestOnUI( 196 void PrerenderResourceThrottle::WillRedirectRequestOnUI(
198 const base::WeakPtr<PrerenderResourceThrottle>& throttle, 197 const base::WeakPtr<PrerenderResourceThrottle>& throttle,
199 const std::string& follow_only_when_prerender_shown_header, 198 const std::string& follow_only_when_prerender_shown_header,
200 ResourceType resource_type, 199 ResourceType resource_type,
201 bool async, 200 bool async,
202 bool is_no_store, 201 bool is_no_store,
203 int render_process_id, 202 const GURL& new_url,
204 int render_frame_id, 203 const ResourceRequestInfo::WebContentsGetter& web_contents_getter) {
205 const GURL& new_url) {
206 bool cancel = false; 204 bool cancel = false;
207 PrerenderContents* prerender_contents = 205 PrerenderContents* prerender_contents =
208 PrerenderContentsFromRenderFrame(render_process_id, render_frame_id); 206 PrerenderContentsFromGetter(web_contents_getter);
209 if (prerender_contents) { 207 if (prerender_contents) {
210 prerender_contents->prerender_manager()->RecordPrefetchResponseReceived( 208 prerender_contents->prerender_manager()->RecordPrefetchResponseReceived(
211 prerender_contents->origin(), 209 prerender_contents->origin(),
212 content::IsResourceTypeFrame(resource_type), true /* is_redirect */, 210 content::IsResourceTypeFrame(resource_type), true /* is_redirect */,
213 is_no_store); 211 is_no_store);
214 // Abort any prerenders with requests which redirect to invalid schemes. 212 // Abort any prerenders with requests which redirect to invalid schemes.
215 if (!PrerenderManager::DoesURLHaveValidScheme(new_url)) { 213 if (!PrerenderManager::DoesURLHaveValidScheme(new_url)) {
216 prerender_contents->Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME); 214 prerender_contents->Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME);
217 ReportUnsupportedPrerenderScheme(new_url); 215 ReportUnsupportedPrerenderScheme(new_url);
218 cancel = true; 216 cancel = true;
(...skipping 19 matching lines...) Expand all
238 base::Bind(cancel ? &PrerenderResourceThrottle::Cancel 236 base::Bind(cancel ? &PrerenderResourceThrottle::Cancel
239 : &PrerenderResourceThrottle::ResumeHandler, 237 : &PrerenderResourceThrottle::ResumeHandler,
240 throttle)); 238 throttle));
241 } 239 }
242 240
243 // static 241 // static
244 void PrerenderResourceThrottle::WillProcessResponseOnUI( 242 void PrerenderResourceThrottle::WillProcessResponseOnUI(
245 bool is_main_resource, 243 bool is_main_resource,
246 bool is_no_store, 244 bool is_no_store,
247 int redirect_count, 245 int redirect_count,
248 int render_process_id,
249 int render_frame_id,
250 scoped_refptr<PrerenderThrottleInfo> prerender_throttle_info) { 246 scoped_refptr<PrerenderThrottleInfo> prerender_throttle_info) {
251 DCHECK(prerender_throttle_info); 247 DCHECK(prerender_throttle_info);
252 if (!prerender_throttle_info->manager()) 248 if (!prerender_throttle_info->manager())
253 return; 249 return;
254 250
255 if (prerender_throttle_info->mode() != PREFETCH_ONLY) 251 if (prerender_throttle_info->mode() != PREFETCH_ONLY)
256 return; 252 return;
257 253
258 prerender_throttle_info->manager()->RecordPrefetchResponseReceived( 254 prerender_throttle_info->manager()->RecordPrefetchResponseReceived(
259 prerender_throttle_info->origin(), is_main_resource, 255 prerender_throttle_info->origin(), is_main_resource,
260 false /* is_redirect */, is_no_store); 256 false /* is_redirect */, is_no_store);
261 prerender_throttle_info->manager()->RecordPrefetchRedirectCount( 257 prerender_throttle_info->manager()->RecordPrefetchRedirectCount(
262 prerender_throttle_info->origin(), is_main_resource, redirect_count); 258 prerender_throttle_info->origin(), is_main_resource, redirect_count);
263 } 259 }
264 260
265 // static 261 // static
266 PrerenderContents* PrerenderResourceThrottle::PrerenderContentsFromRenderFrame( 262 PrerenderContents* PrerenderResourceThrottle::PrerenderContentsFromGetter(
267 int render_process_id, int render_frame_id) { 263 const ResourceRequestInfo::WebContentsGetter& web_contents_getter) {
268 if (g_prerender_contents_for_testing) 264 if (g_prerender_contents_for_testing)
269 return g_prerender_contents_for_testing; 265 return g_prerender_contents_for_testing;
270 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID( 266 return PrerenderContents::FromWebContents(web_contents_getter.Run());
271 render_process_id, render_frame_id);
272 content::WebContents* web_contents =
273 content::WebContents::FromRenderFrameHost(rfh);
274 return PrerenderContents::FromWebContents(web_contents);
275 } 267 }
276 268
277 } // namespace prerender 269 } // namespace prerender
OLDNEW
« no previous file with comments | « chrome/browser/prerender/prerender_resource_throttle.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698