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

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

Issue 6901128: Cancel prerenders that spawn post requests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Missed the call to erase. Created 9 years, 7 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_manager.h" 5 #include "chrome/browser/prerender/prerender_manager.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/field_trial.h" 8 #include "base/metrics/field_trial.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 30 matching lines...) Expand all
41 // Time window for which we will record windowed PLT's from the last 41 // Time window for which we will record windowed PLT's from the last
42 // observed link rel=prefetch tag. 42 // observed link rel=prefetch tag.
43 const int kWindowDurationSeconds = 30; 43 const int kWindowDurationSeconds = 30;
44 44
45 // Time interval at which periodic cleanups are performed. 45 // Time interval at which periodic cleanups are performed.
46 const int kPeriodicCleanupIntervalMs = 1000; 46 const int kPeriodicCleanupIntervalMs = 1000;
47 47
48 // Time interval before a new prerender is allowed. 48 // Time interval before a new prerender is allowed.
49 const int kMinTimeBetweenPrerendersMs = 500; 49 const int kMinTimeBetweenPrerendersMs = 500;
50 50
51 // Valid HTTP methods for prerendering.
52 const char* kValidHttpMethods[] = {
cbentzel 2011/04/30 01:03:34 I've usually seen as const char* const
dominich 2011/05/02 16:45:55 Done.
53 "OPTIONS", "GET", "HEAD", "TRACE", "CONNECT",
cbentzel 2011/04/30 01:03:34 I'd do one of these per-line, and not include the
dominich 2011/05/02 16:45:55 Done.
54 // "PUT", "POST", "DELETE"
55 };
56
51 } // namespace 57 } // namespace
52 58
53 // static 59 // static
54 int PrerenderManager::prerenders_per_session_count_ = 0; 60 int PrerenderManager::prerenders_per_session_count_ = 0;
55 61
56 // static 62 // static
57 PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ = 63 PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ =
58 PRERENDER_MODE_ENABLED; 64 PRERENDER_MODE_ENABLED;
59 65
60 // static 66 // static
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 GURL new_url(string16(decoded_url.data(), decoded_url.length())); 108 GURL new_url(string16(decoded_url.data(), decoded_url.length()));
103 if (!new_url.is_empty() && new_url.is_valid()) { 109 if (!new_url.is_empty() && new_url.is_valid()) {
104 *alias_url = new_url; 110 *alias_url = new_url;
105 return true; 111 return true;
106 } 112 }
107 return false; 113 return false;
108 } 114 }
109 return false; 115 return false;
110 } 116 }
111 117
118 // static
119 bool PrerenderManager::IsValidHttpMethod(const std::string& method) {
120 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) {
121 if (method == kValidHttpMethods[i])
cbentzel 2011/04/30 01:03:34 I'm not sure if these are canonicalized to upper c
dominich 2011/05/02 16:45:55 Tested and they are. Added comment to confirm.
122 return true;
123 }
124
125 return false;
126 }
127
112 struct PrerenderManager::PrerenderContentsData { 128 struct PrerenderManager::PrerenderContentsData {
113 PrerenderContents* contents_; 129 PrerenderContents* contents_;
114 base::Time start_time_; 130 base::Time start_time_;
115 PrerenderContentsData(PrerenderContents* contents, base::Time start_time) 131 PrerenderContentsData(PrerenderContents* contents, base::Time start_time)
116 : contents_(contents), 132 : contents_(contents),
117 start_time_(start_time) { 133 start_time_(start_time) {
118 } 134 }
119 }; 135 };
120 136
121 struct PrerenderManager::PendingContentsData { 137 struct PrerenderManager::PendingContentsData {
(...skipping 18 matching lines...) Expand all
140 prerender_manager->RecordPrefetchTagObserved(); 156 prerender_manager->RecordPrefetchTagObserved();
141 // TODO(cbentzel): Should the decision to make pending be done on the 157 // TODO(cbentzel): Should the decision to make pending be done on the
142 // UI thread rather than the IO thread? The page may have 158 // UI thread rather than the IO thread? The page may have
143 // become activated at this point. 159 // become activated at this point.
144 if (make_pending) 160 if (make_pending)
145 prerender_manager->AddPendingPreload(child_route_id_pair, url, referrer); 161 prerender_manager->AddPendingPreload(child_route_id_pair, url, referrer);
146 else 162 else
147 prerender_manager->AddPreload(child_route_id_pair, url, referrer); 163 prerender_manager->AddPreload(child_route_id_pair, url, referrer);
148 } 164 }
149 165
166 void DestroyPreloadForChildRouteIdPairOnUIThread(
167 const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr,
168 const std::pair<int, int>& child_route_id_pair,
169 FinalStatus final_status) {
170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
171 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get();
172 if (!prerender_manager)
173 return;
174 prerender_manager->DestroyPreloadForChildRouteIdPair(child_route_id_pair,
175 final_status);
176 }
177
150 PrerenderManager::PrerenderManager(Profile* profile) 178 PrerenderManager::PrerenderManager(Profile* profile)
151 : rate_limit_enabled_(true), 179 : rate_limit_enabled_(true),
152 enabled_(true), 180 enabled_(true),
153 profile_(profile), 181 profile_(profile),
154 max_prerender_age_(base::TimeDelta::FromSeconds( 182 max_prerender_age_(base::TimeDelta::FromSeconds(
155 kDefaultMaxPrerenderAgeSeconds)), 183 kDefaultMaxPrerenderAgeSeconds)),
156 max_prerender_memory_mb_(kDefaultMaxPrerenderMemoryMB), 184 max_prerender_memory_mb_(kDefaultMaxPrerenderMemoryMB),
157 max_elements_(kDefaultMaxPrerenderElements), 185 max_elements_(kDefaultMaxPrerenderElements),
158 prerender_contents_factory_(PrerenderContents::CreateFactory()), 186 prerender_contents_factory_(PrerenderContents::CreateFactory()),
159 last_prerender_start_time_(GetCurrentTimeTicks() - 187 last_prerender_start_time_(GetCurrentTimeTicks() -
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 StartSchedulingPeriodicCleanups(); 286 StartSchedulingPeriodicCleanups();
259 return true; 287 return true;
260 } 288 }
261 289
262 void PrerenderManager::AddPendingPreload( 290 void PrerenderManager::AddPendingPreload(
263 const std::pair<int, int>& child_route_id_pair, 291 const std::pair<int, int>& child_route_id_pair,
264 const GURL& url, 292 const GURL& url,
265 const GURL& referrer) { 293 const GURL& referrer) {
266 DCHECK(CalledOnValidThread()); 294 DCHECK(CalledOnValidThread());
267 // Check if this is coming from a valid prerender RenderViewHost. 295 // Check if this is coming from a valid prerender RenderViewHost.
268 bool is_valid_prerender = false; 296 bool is_valid_prerender =
269 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); 297 (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) !=
270 it != prerender_list_.end(); ++it) { 298 prerender_list_.end());
271 PrerenderContents* prerender_contents = it->contents_;
272
273 int child_id;
274 int route_id;
275 bool has_child_id = prerender_contents->GetChildId(&child_id);
276 bool has_route_id = has_child_id &&
277 prerender_contents->GetRouteId(&route_id);
278
279 if (has_child_id && has_route_id &&
280 child_id == child_route_id_pair.first &&
281 route_id == child_route_id_pair.second) {
282 is_valid_prerender = true;
283 break;
284 }
285 }
286 299
287 // If not, we could check to see if the RenderViewHost specified by the 300 // If not, we could check to see if the RenderViewHost specified by the
288 // child_route_id_pair exists and if so just start prerendering, as this 301 // child_route_id_pair exists and if so just start prerendering, as this
289 // suggests that the link was clicked, though this might prerender something 302 // suggests that the link was clicked, though this might prerender something
290 // that the user has already navigated away from. For now, we'll be 303 // that the user has already navigated away from. For now, we'll be
291 // conservative and skip the prerender which will mean some prerender requests 304 // conservative and skip the prerender which will mean some prerender requests
292 // from prerendered pages will be missed if the user navigates quickly. 305 // from prerendered pages will be missed if the user navigates quickly.
293 if (!is_valid_prerender) { 306 if (!is_valid_prerender) {
294 RecordFinalStatus(FINAL_STATUS_PENDING_SKIPPED); 307 RecordFinalStatus(FINAL_STATUS_PENDING_SKIPPED);
295 return; 308 return;
296 } 309 }
297 310
298 PendingPrerenderList::iterator it = 311 PendingPrerenderList::iterator it =
299 pending_prerender_list_.find(child_route_id_pair); 312 pending_prerender_list_.find(child_route_id_pair);
300 if (it == pending_prerender_list_.end()) { 313 if (it == pending_prerender_list_.end()) {
301 PendingPrerenderList::value_type el = std::make_pair(child_route_id_pair, 314 PendingPrerenderList::value_type el = std::make_pair(child_route_id_pair,
302 std::vector<PendingContentsData>()); 315 std::vector<PendingContentsData>());
303 it = pending_prerender_list_.insert(el).first; 316 it = pending_prerender_list_.insert(el).first;
304 } 317 }
305 318
306 it->second.push_back(PendingContentsData(url, referrer)); 319 it->second.push_back(PendingContentsData(url, referrer));
307 } 320 }
308 321
322 std::list<PrerenderManager::PrerenderContentsData>::iterator
323 PrerenderManager::FindPrerenderContentsForChildRouteIdPair(
324 const std::pair<int, int>& child_route_id_pair) {
325 std::list<PrerenderContentsData>::iterator it = prerender_list_.begin();
326 for (; it != prerender_list_.end(); ++it) {
327 PrerenderContents* prerender_contents = it->contents_;
328
329 int child_id;
330 int route_id;
331 bool has_child_id = prerender_contents->GetChildId(&child_id);
332 bool has_route_id = has_child_id &&
333 prerender_contents->GetRouteId(&route_id);
334
335 if (has_child_id && has_route_id &&
336 child_id == child_route_id_pair.first &&
337 route_id == child_route_id_pair.second) {
338 break;
339 }
340 }
341 return it;
342 }
343
344 void PrerenderManager::DestroyPreloadForChildRouteIdPair(
345 const std::pair<int, int>& child_route_id_pair,
346 FinalStatus final_status) {
347 DCHECK(CalledOnValidThread());
348 std::list<PrerenderContentsData>::iterator it =
349 FindPrerenderContentsForChildRouteIdPair(child_route_id_pair);
350 if (it != prerender_list_.end()) {
351 PrerenderContents* prerender_contents = it->contents_;
352 prerender_contents->set_final_status(final_status);
353 RemovePendingPreload(prerender_contents);
354
355 delete prerender_contents;
356 prerender_list_.erase(it);
357 }
358 }
359
309 void PrerenderManager::DeleteOldEntries() { 360 void PrerenderManager::DeleteOldEntries() {
310 DCHECK(CalledOnValidThread()); 361 DCHECK(CalledOnValidThread());
311 while (!prerender_list_.empty()) { 362 while (!prerender_list_.empty()) {
312 PrerenderContentsData data = prerender_list_.front(); 363 PrerenderContentsData data = prerender_list_.front();
313 if (IsPrerenderElementFresh(data.start_time_)) 364 if (IsPrerenderElementFresh(data.start_time_))
314 return; 365 return;
315 prerender_list_.pop_front(); 366 prerender_list_.pop_front();
316 data.contents_->set_final_status(FINAL_STATUS_TIMED_OUT); 367 data.contents_->set_final_status(FINAL_STATUS_TIMED_OUT);
317 delete data.contents_; 368 delete data.contents_;
318 } 369 }
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 return prerendered_tab_contents_set_.count(tab_contents) > 0; 729 return prerendered_tab_contents_set_.count(tab_contents) > 0;
679 } 730 }
680 731
681 bool PrerenderManager::WouldTabContentsBePrerendered( 732 bool PrerenderManager::WouldTabContentsBePrerendered(
682 TabContents* tab_contents) const { 733 TabContents* tab_contents) const {
683 DCHECK(CalledOnValidThread()); 734 DCHECK(CalledOnValidThread());
684 return would_be_prerendered_tab_contents_set_.count(tab_contents) > 0; 735 return would_be_prerendered_tab_contents_set_.count(tab_contents) > 0;
685 } 736 }
686 737
687 } // namespace prerender 738 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698