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

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 743803002: Avoid stale navigation requests without excessive page id knowledge in the renderer process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more saving Created 6 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
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 "content/renderer/render_frame_impl.h" 5 #include "content/renderer/render_frame_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 #endif 940 #endif
941 IPC_END_MESSAGE_MAP() 941 IPC_END_MESSAGE_MAP()
942 942
943 return handled; 943 return handled;
944 } 944 }
945 945
946 void RenderFrameImpl::OnNavigate(const FrameMsg_Navigate_Params& params) { 946 void RenderFrameImpl::OnNavigate(const FrameMsg_Navigate_Params& params) {
947 TRACE_EVENT2("navigation", "RenderFrameImpl::OnNavigate", 947 TRACE_EVENT2("navigation", "RenderFrameImpl::OnNavigate",
948 "id", routing_id_, 948 "id", routing_id_,
949 "url", params.common_params.url.possibly_invalid_spec()); 949 "url", params.common_params.url.possibly_invalid_spec());
950
951 // If this is a stale back/forward (due to a recent navigation the browser
Charlie Reis 2014/12/03 23:48:07 Hmm, I wonder why clamy@ disabled the stale back/f
Avi (use Gerrit) 2014/12/04 21:15:16 Please do. Right now this code was built as a refa
Charlie Reis 2014/12/04 23:13:58 I emailed her to find out.
952 // didn't know about), ignore it. Only check if swapped in because navigations
953 // while swapped out are turned into asynchronous navigations.
Charlie Reis 2014/12/03 23:48:07 This comment is a little hard to follow. Asynchro
Avi (use Gerrit) 2014/12/04 21:15:16 That's what I meant, though I'm taking your word f
Charlie Reis 2014/12/04 23:13:58 Acknowledged.
954 bool is_history_navigation = params.commit_params.page_state.IsValid();
955 if (!render_view_->is_swapped_out() && is_history_navigation &&
956 render_view_->history_list_offset_ !=
957 params.current_history_list_offset) {
Charlie Reis 2014/12/03 23:48:07 Yes, I think this will be sufficient to replace th
Avi (use Gerrit) 2014/12/04 21:15:16 I'm trying to get things right the first time. I c
Charlie Reis 2014/12/04 23:13:58 Oh, here's an easy false positive, unless I'm misu
Avi (use Gerrit) 2014/12/05 22:16:39 I'd have to talk to you about that. The pruning is
Charlie Reis 2014/12/05 22:51:15 Yes. I may still be interested in improving the l
958 return;
959 }
960
950 bool is_reload = 961 bool is_reload =
951 RenderViewImpl::IsReload(params.common_params.navigation_type); 962 RenderViewImpl::IsReload(params.common_params.navigation_type);
952 WebURLRequest::CachePolicy cache_policy = 963 WebURLRequest::CachePolicy cache_policy =
953 WebURLRequest::UseProtocolCachePolicy; 964 WebURLRequest::UseProtocolCachePolicy;
954 if (!RenderFrameImpl::PrepareRenderViewForNavigation( 965 if (!RenderFrameImpl::PrepareRenderViewForNavigation(
955 params.common_params.url, params.common_params.navigation_type, 966 params.common_params.url, params.common_params.navigation_type,
956 params.commit_params.page_state, true, params.pending_history_list_offset, 967 params.commit_params.page_state, params.page_id, &is_reload,
957 params.page_id, &is_reload, &cache_policy)) { 968 &cache_policy)) {
958 return; 969 return;
959 } 970 }
960 971
961 int pending_history_list_offset = params.pending_history_list_offset; 972 render_view_->history_list_offset_ = params.current_history_list_offset;
Charlie Reis 2014/12/03 23:48:07 Do we ever still use pending_history_list_offset?
Avi (use Gerrit) 2014/12/04 21:15:16 We do, when history navigations commit. See the !i
962 int current_history_list_offset = params.current_history_list_offset; 973 render_view_->history_list_length_ = params.current_history_list_length;
963 int current_history_list_length = params.current_history_list_length;
964 if (params.should_clear_history_list) { 974 if (params.should_clear_history_list) {
965 CHECK_EQ(pending_history_list_offset, -1); 975 CHECK_EQ(-1, render_view_->history_list_offset_);
966 CHECK_EQ(current_history_list_offset, -1); 976 CHECK_EQ(0, render_view_->history_list_length_);
967 CHECK_EQ(current_history_list_length, 0);
968 }
969 render_view_->history_list_offset_ = current_history_list_offset;
970 render_view_->history_list_length_ = current_history_list_length;
971 if (render_view_->history_list_length_ >= 0) {
972 render_view_->history_page_ids_.resize(
973 render_view_->history_list_length_, -1);
974 }
975 if (pending_history_list_offset >= 0 &&
976 pending_history_list_offset < render_view_->history_list_length_) {
977 render_view_->history_page_ids_[pending_history_list_offset] =
978 params.page_id;
979 } 977 }
980 978
981 GetContentClient()->SetActiveURL(params.common_params.url); 979 GetContentClient()->SetActiveURL(params.common_params.url);
982 980
983 WebFrame* frame = frame_; 981 WebFrame* frame = frame_;
984 if (!params.frame_to_navigate.empty()) { 982 if (!params.frame_to_navigate.empty()) {
985 // TODO(nasko): Move this lookup to the browser process. 983 // TODO(nasko): Move this lookup to the browser process.
986 frame = render_view_->webview()->findFrameByName( 984 frame = render_view_->webview()->findFrameByName(
987 WebString::fromUTF8(params.frame_to_navigate)); 985 WebString::fromUTF8(params.frame_to_navigate));
988 CHECK(frame) << "Invalid frame name passed: " << params.frame_to_navigate; 986 CHECK(frame) << "Invalid frame name passed: " << params.frame_to_navigate;
(...skipping 17 matching lines...) Expand all
1006 bool reload_original_url = 1004 bool reload_original_url =
1007 (params.common_params.navigation_type == 1005 (params.common_params.navigation_type ==
1008 FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL); 1006 FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
1009 bool ignore_cache = (params.common_params.navigation_type == 1007 bool ignore_cache = (params.common_params.navigation_type ==
1010 FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE); 1008 FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE);
1011 1009
1012 if (reload_original_url) 1010 if (reload_original_url)
1013 frame->reloadWithOverrideURL(params.common_params.url, true); 1011 frame->reloadWithOverrideURL(params.common_params.url, true);
1014 else 1012 else
1015 frame->reload(ignore_cache); 1013 frame->reload(ignore_cache);
1016 } else if (params.commit_params.page_state.IsValid()) { 1014 } else if (is_history_navigation) {
1017 // We must know the page ID of the page we are navigating back to. 1015 // We must know the page ID of the page we are navigating back to.
1018 DCHECK_NE(params.page_id, -1); 1016 DCHECK_NE(params.page_id, -1);
1019 scoped_ptr<HistoryEntry> entry = 1017 scoped_ptr<HistoryEntry> entry =
1020 PageStateToHistoryEntry(params.commit_params.page_state); 1018 PageStateToHistoryEntry(params.commit_params.page_state);
1021 if (entry) { 1019 if (entry) {
1022 // Ensure we didn't save the swapped out URL in UpdateState, since the 1020 // Ensure we didn't save the swapped out URL in UpdateState, since the
1023 // browser should never be telling us to navigate to swappedout://. 1021 // browser should never be telling us to navigate to swappedout://.
1024 CHECK(entry->root().urlString() != WebString::fromUTF8(kSwappedOutURL)); 1022 CHECK(entry->root().urlString() != WebString::fromUTF8(kSwappedOutURL));
1025 render_view_->history_controller()->GoToEntry(entry.Pass(), cache_policy); 1023 render_view_->history_controller()->GoToEntry(entry.Pass(), cache_policy);
1026 } 1024 }
(...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after
2341 render_view_->webview()->resetScrollAndScaleState(); 2339 render_view_->webview()->resetScrollAndScaleState();
2342 internal_data->set_must_reset_scroll_and_scale_state(false); 2340 internal_data->set_must_reset_scroll_and_scale_state(false);
2343 } 2341 }
2344 internal_data->set_use_error_page(false); 2342 internal_data->set_use_error_page(false);
2345 2343
2346 bool is_new_navigation = commit_type == blink::WebStandardCommit; 2344 bool is_new_navigation = commit_type == blink::WebStandardCommit;
2347 if (is_new_navigation) { 2345 if (is_new_navigation) {
2348 // We bump our Page ID to correspond with the new session history entry. 2346 // We bump our Page ID to correspond with the new session history entry.
2349 render_view_->page_id_ = render_view_->next_page_id_++; 2347 render_view_->page_id_ = render_view_->next_page_id_++;
2350 2348
2351 // Don't update history_page_ids_ (etc) for kSwappedOutURL, since 2349 // Don't update history list values for kSwappedOutURL, since
2352 // we don't want to forget the entry that was there, and since we will 2350 // we don't want to forget the entry that was there, and since we will
2353 // never come back to kSwappedOutURL. Note that we have to call 2351 // never come back to kSwappedOutURL. Note that we have to call
2354 // UpdateSessionHistory and update page_id_ even in this case, so that 2352 // UpdateSessionHistory and update page_id_ even in this case, so that
2355 // the current entry gets a state update and so that we don't send a 2353 // the current entry gets a state update and so that we don't send a
2356 // state update to the wrong entry when we swap back in. 2354 // state update to the wrong entry when we swap back in.
2357 if (GetLoadingUrl() != GURL(kSwappedOutURL)) { 2355 if (GetLoadingUrl() != GURL(kSwappedOutURL)) {
2358 // Advance our offset in session history, applying the length limit. 2356 // Advance our offset in session history, applying the length limit.
2359 // There is now no forward history. 2357 // There is now no forward history.
2360 render_view_->history_list_offset_++; 2358 render_view_->history_list_offset_++;
2361 if (render_view_->history_list_offset_ >= kMaxSessionHistoryEntries) 2359 if (render_view_->history_list_offset_ >= kMaxSessionHistoryEntries)
2362 render_view_->history_list_offset_ = kMaxSessionHistoryEntries - 1; 2360 render_view_->history_list_offset_ = kMaxSessionHistoryEntries - 1;
2363 render_view_->history_list_length_ = 2361 render_view_->history_list_length_ =
2364 render_view_->history_list_offset_ + 1; 2362 render_view_->history_list_offset_ + 1;
2365 render_view_->history_page_ids_.resize(
2366 render_view_->history_list_length_, -1);
2367 render_view_->history_page_ids_[render_view_->history_list_offset_] =
2368 render_view_->page_id_;
2369 } 2363 }
2370 } else { 2364 } else {
2371 // Inspect the navigation_state on this frame to see if the navigation 2365 // Inspect the navigation_state on this frame to see if the navigation
2372 // corresponds to a session history navigation... Note: |frame| may or 2366 // corresponds to a session history navigation... Note: |frame| may or
2373 // may not be the toplevel frame, but for the case of capturing session 2367 // may not be the toplevel frame, but for the case of capturing session
2374 // history, the first committed frame suffices. We keep track of whether 2368 // history, the first committed frame suffices. We keep track of whether
2375 // we've seen this commit before so that only capture session history once 2369 // we've seen this commit before so that only capture session history once
2376 // per navigation. 2370 // per navigation.
2377 // 2371 //
2378 // Note that we need to check if the page ID changed. In the case of a 2372 // Note that we need to check if the page ID changed. In the case of a
2379 // reload, the page ID doesn't change, and UpdateSessionHistory gets the 2373 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
2380 // previous URL and the current page ID, which would be wrong. 2374 // previous URL and the current page ID, which would be wrong.
2381 if (navigation_state->pending_page_id() != -1 && 2375 if (navigation_state->pending_page_id() != -1 &&
2382 navigation_state->pending_page_id() != render_view_->page_id_ && 2376 navigation_state->pending_page_id() != render_view_->page_id_ &&
2383 !navigation_state->request_committed()) { 2377 !navigation_state->request_committed()) {
2384 // This is a successful session history navigation! 2378 // This is a successful session history navigation!
2385 render_view_->page_id_ = navigation_state->pending_page_id(); 2379 render_view_->page_id_ = navigation_state->pending_page_id();
2386 2380
2387 render_view_->history_list_offset_ = 2381 render_view_->history_list_offset_ =
2388 navigation_state->pending_history_list_offset(); 2382 navigation_state->pending_history_list_offset();
2389
2390 // If the history list is valid, our list of page IDs should be correct.
2391 DCHECK(render_view_->history_list_length_ <= 0 ||
2392 render_view_->history_list_offset_ < 0 ||
2393 render_view_->history_list_offset_ >=
2394 render_view_->history_list_length_ ||
2395 render_view_->history_page_ids_[render_view_->history_list_offset_]
2396 == render_view_->page_id_);
2397 } 2383 }
2398 } 2384 }
2399 2385
2400 bool sent = Send( 2386 bool sent = Send(
2401 new FrameHostMsg_DidAssignPageId(routing_id_, render_view_->page_id_)); 2387 new FrameHostMsg_DidAssignPageId(routing_id_, render_view_->page_id_));
2402 CHECK(sent); // http://crbug.com/407376 2388 CHECK(sent); // http://crbug.com/407376
2403 2389
2404 FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers_, 2390 FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers_,
2405 DidCommitProvisionalLoad(frame, is_new_navigation)); 2391 DidCommitProvisionalLoad(frame, is_new_navigation));
2406 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, 2392 FOR_EACH_OBSERVER(RenderFrameObserver, observers_,
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3677 const GURL& stream_url, 3663 const GURL& stream_url,
3678 const CommonNavigationParams& common_params, 3664 const CommonNavigationParams& common_params,
3679 const CommitNavigationParams& commit_params) { 3665 const CommitNavigationParams& commit_params) {
3680 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( 3666 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
3681 switches::kEnableBrowserSideNavigation)); 3667 switches::kEnableBrowserSideNavigation));
3682 bool is_reload = false; 3668 bool is_reload = false;
3683 WebURLRequest::CachePolicy cache_policy = 3669 WebURLRequest::CachePolicy cache_policy =
3684 WebURLRequest::UseProtocolCachePolicy; 3670 WebURLRequest::UseProtocolCachePolicy;
3685 if (!RenderFrameImpl::PrepareRenderViewForNavigation( 3671 if (!RenderFrameImpl::PrepareRenderViewForNavigation(
3686 common_params.url, common_params.navigation_type, 3672 common_params.url, common_params.navigation_type,
3687 commit_params.page_state, false, -1, -1, &is_reload, &cache_policy)) { 3673 commit_params.page_state, -1, &is_reload, &cache_policy)) {
3688 return; 3674 return;
3689 } 3675 }
3690 3676
3691 GetContentClient()->SetActiveURL(common_params.url); 3677 GetContentClient()->SetActiveURL(common_params.url);
3692 3678
3693 // Create a WebURLRequest that blink can use to get access to the body of the 3679 // Create a WebURLRequest that blink can use to get access to the body of the
3694 // response through a stream in the browser. Blink will then commit the 3680 // response through a stream in the browser. Blink will then commit the
3695 // navigation. 3681 // navigation.
3696 // TODO(clamy): Have the navigation commit directly, without going through 3682 // TODO(clamy): Have the navigation commit directly, without going through
3697 // loading a WebURLRequest. 3683 // loading a WebURLRequest.
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
4099 #else 4085 #else
4100 return scoped_ptr<MediaStreamRendererFactory>( 4086 return scoped_ptr<MediaStreamRendererFactory>(
4101 static_cast<MediaStreamRendererFactory*>(NULL)); 4087 static_cast<MediaStreamRendererFactory*>(NULL));
4102 #endif 4088 #endif
4103 } 4089 }
4104 4090
4105 bool RenderFrameImpl::PrepareRenderViewForNavigation( 4091 bool RenderFrameImpl::PrepareRenderViewForNavigation(
4106 const GURL& url, 4092 const GURL& url,
4107 FrameMsg_Navigate_Type::Value navigate_type, 4093 FrameMsg_Navigate_Type::Value navigate_type,
4108 const PageState& state, 4094 const PageState& state,
4109 bool check_history,
4110 int pending_history_list_offset,
4111 int32 page_id, 4095 int32 page_id,
4112 bool* is_reload, 4096 bool* is_reload,
4113 WebURLRequest::CachePolicy* cache_policy) { 4097 WebURLRequest::CachePolicy* cache_policy) {
4114 MaybeHandleDebugURL(url); 4098 MaybeHandleDebugURL(url);
4115 if (!render_view_->webview()) 4099 if (!render_view_->webview())
4116 return false; 4100 return false;
4117 4101
4118 FOR_EACH_OBSERVER( 4102 FOR_EACH_OBSERVER(
4119 RenderViewObserver, render_view_->observers_, Navigate(url)); 4103 RenderViewObserver, render_view_->observers_, Navigate(url));
4120 4104
4121 // If this is a stale back/forward (due to a recent navigation the browser
4122 // didn't know about), ignore it.
4123 if (check_history && render_view_->IsBackForwardToStaleEntry(
4124 state, pending_history_list_offset, page_id, *is_reload))
4125 return false;
4126
4127 if (!is_swapped_out_ || frame_->parent()) 4105 if (!is_swapped_out_ || frame_->parent())
4128 return true; 4106 return true;
4129 4107
4130 // This is a swapped out main frame, so swap the renderer back in. 4108 // This is a swapped out main frame, so swap the renderer back in.
4131 // We marked the view as hidden when swapping the view out, so be sure to 4109 // We marked the view as hidden when swapping the view out, so be sure to
4132 // reset the visibility state before navigating to the new URL. 4110 // reset the visibility state before navigating to the new URL.
4133 render_view_->webview()->setVisibilityState( 4111 render_view_->webview()->setVisibilityState(
4134 render_view_->visibilityState(), false); 4112 render_view_->visibilityState(), false);
4135 4113
4136 // If this is an attempt to reload while we are swapped out, we should not 4114 // If this is an attempt to reload while we are swapped out, we should not
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4238 4216
4239 #if defined(ENABLE_BROWSER_CDMS) 4217 #if defined(ENABLE_BROWSER_CDMS)
4240 RendererCdmManager* RenderFrameImpl::GetCdmManager() { 4218 RendererCdmManager* RenderFrameImpl::GetCdmManager() {
4241 if (!cdm_manager_) 4219 if (!cdm_manager_)
4242 cdm_manager_ = new RendererCdmManager(this); 4220 cdm_manager_ = new RendererCdmManager(this);
4243 return cdm_manager_; 4221 return cdm_manager_;
4244 } 4222 }
4245 #endif // defined(ENABLE_BROWSER_CDMS) 4223 #endif // defined(ENABLE_BROWSER_CDMS)
4246 4224
4247 } // namespace content 4225 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698