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

Side by Side Diff: content/browser/frame_host/render_frame_host_impl.cc

Issue 2475693002: Do not reset NavigationHandle when navigating same-page (Closed)
Patch Set: Created 4 years, 1 month 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/browser/frame_host/render_frame_host_impl.h" 5 #include "content/browser/frame_host/render_frame_host_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 process->FilterURL(true, &validated_params.searchable_form_url); 1172 process->FilterURL(true, &validated_params.searchable_form_url);
1173 1173
1174 // Without this check, the renderer can trick the browser into using 1174 // Without this check, the renderer can trick the browser into using
1175 // filenames it can't access in a future session restore. 1175 // filenames it can't access in a future session restore.
1176 if (!CanAccessFilesOfPageState(validated_params.page_state)) { 1176 if (!CanAccessFilesOfPageState(validated_params.page_state)) {
1177 bad_message::ReceivedBadMessage( 1177 bad_message::ReceivedBadMessage(
1178 GetProcess(), bad_message::RFH_CAN_ACCESS_FILES_OF_PAGE_STATE); 1178 GetProcess(), bad_message::RFH_CAN_ACCESS_FILES_OF_PAGE_STATE);
1179 return; 1179 return;
1180 } 1180 }
1181 1181
1182 // If the URL or |was_within_same_page| does not match what the 1182 // PlzNavigate
1183 // NavigationHandle expects, treat the commit as a new navigation. This can 1183 if (!navigation_handle_ && IsBrowserSideNavigationEnabled()) {
1184 // happen if an ongoing slow same-process navigation is interwoven with a 1184 // PlzNavigate: the browser has not been notified about the start of the
1185 // synchronous renderer-initiated navigation. 1185 // load in this renderer yet. Do it now.
Charlie Reis 2016/11/03 22:02:22 nit: Add something like: (e.g., for same-page navi
clamy 2016/11/04 14:18:21 Done.
1186 // TODO(csharrison): Data navigations loaded with LoadDataWithBaseURL get 1186 if (!is_loading()) {
1187 // reset here, because the NavigationHandle tracks the URL but the 1187 bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
1188 // validated_params.url tracks the data. The trick of saving the old entry ids 1188 is_loading_ = true;
1189 // for these navigations should go away when this is properly handled. See 1189 frame_tree_node()->DidStartLoading(true, was_loading);
1190 // crbug.com/588317.
1191 int entry_id_for_data_nav = 0;
1192 bool is_renderer_initiated = true;
1193 if (navigation_handle_ &&
1194 ((navigation_handle_->GetURL() != validated_params.url) ||
1195 navigation_handle_->IsSamePage() !=
1196 validated_params.was_within_same_page)) {
1197 // Make sure that the pending entry was really loaded via
1198 // LoadDataWithBaseURL and that it matches this handle.
1199 NavigationEntryImpl* pending_entry =
1200 NavigationEntryImpl::FromNavigationEntry(
1201 frame_tree_node()->navigator()->GetController()->GetPendingEntry());
1202 bool pending_entry_matches_handle =
1203 pending_entry &&
1204 pending_entry->GetUniqueID() ==
1205 navigation_handle_->pending_nav_entry_id();
1206 // TODO(csharrison): The pending entry's base url should equal
1207 // |validated_params.base_url|. This is not the case for loads with invalid
1208 // base urls.
Charlie Reis 2016/11/03 22:02:22 Is there a reason not to preserve this TODO?
clamy 2016/11/04 14:18:21 Nope, it got lost in code reordering. I brought it
1209 if (navigation_handle_->GetURL() == validated_params.base_url &&
1210 pending_entry_matches_handle &&
1211 !pending_entry->GetBaseURLForDataURL().is_empty()) {
1212 entry_id_for_data_nav = navigation_handle_->pending_nav_entry_id();
1213 is_renderer_initiated = pending_entry->is_renderer_initiated();
1214 } 1190 }
1215 navigation_handle_.reset(); 1191 pending_commit_ = false;
1216 } 1192 }
1217 1193
1218 // Synchronous renderer-initiated navigations will send a 1194 // Find the appropriate NavigationHandle for this navigation.
1219 // DidCommitProvisionalLoad IPC without a prior DidStartProvisionalLoad 1195 std::unique_ptr<NavigationHandleImpl> navigation_handle =
1220 // message. Or in addition, the if block above can reset the NavigationHandle 1196 FindNavigationHandleForCommit(validated_params);
1221 // in cases it doesn't match the expected commit. 1197 DCHECK(navigation_handle);
1222 if (!navigation_handle_) {
1223 // There is no pending NavigationEntry in these cases, so pass 0 as the
1224 // nav_id. If the previous handle was a prematurely aborted navigation
1225 // loaded via LoadDataWithBaseURL, propogate the entry id.
1226 navigation_handle_ = NavigationHandleImpl::Create(
1227 validated_params.url, frame_tree_node_, is_renderer_initiated,
1228 validated_params.was_within_same_page, validated_params.is_srcdoc,
1229 base::TimeTicks::Now(), entry_id_for_data_nav,
1230 false); // started_from_context_menu
1231 // PlzNavigate
1232 if (IsBrowserSideNavigationEnabled()) {
1233 // PlzNavigate: synchronous loads happen in the renderer, and the browser
1234 // has not been notified about the start of the load yet. Do it now.
1235 if (!is_loading()) {
1236 bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
1237 is_loading_ = true;
1238 frame_tree_node()->DidStartLoading(true, was_loading);
1239 }
1240 pending_commit_ = false;
1241 }
1242 }
1243 1198
1244 accessibility_reset_count_ = 0; 1199 accessibility_reset_count_ = 0;
1245 frame_tree_node()->navigator()->DidNavigate(this, validated_params); 1200 frame_tree_node()->navigator()->DidNavigate(this, validated_params,
1201 std::move(navigation_handle));
1246 1202
1247 // Since we didn't early return, it's safe to keep the commit state. 1203 // Since we didn't early return, it's safe to keep the commit state.
1248 commit_state_resetter.disable(); 1204 commit_state_resetter.disable();
1249 1205
1250 // For a top-level frame, there are potential security concerns associated 1206 // For a top-level frame, there are potential security concerns associated
1251 // with displaying graphics from a previously loaded page after the URL in 1207 // with displaying graphics from a previously loaded page after the URL in
1252 // the omnibar has been changed. It is unappealing to clear the page 1208 // the omnibar has been changed. It is unappealing to clear the page
1253 // immediately, but if the renderer is taking a long time to issue any 1209 // immediately, but if the renderer is taking a long time to issue any
1254 // compositor output (possibly because of script deliberately creating this 1210 // compositor output (possibly because of script deliberately creating this
1255 // situation) then we clear it after a while anyway. 1211 // situation) then we clear it after a while anyway.
(...skipping 1926 matching lines...) Expand 10 before | Expand all | Expand 10 after
3182 // handler after it's destroyed so it can't run after the RFHI is destroyed. 3138 // handler after it's destroyed so it can't run after the RFHI is destroyed.
3183 web_bluetooth_service_->SetClientConnectionErrorHandler(base::Bind( 3139 web_bluetooth_service_->SetClientConnectionErrorHandler(base::Bind(
3184 &RenderFrameHostImpl::DeleteWebBluetoothService, base::Unretained(this))); 3140 &RenderFrameHostImpl::DeleteWebBluetoothService, base::Unretained(this)));
3185 return web_bluetooth_service_.get(); 3141 return web_bluetooth_service_.get();
3186 } 3142 }
3187 3143
3188 void RenderFrameHostImpl::DeleteWebBluetoothService() { 3144 void RenderFrameHostImpl::DeleteWebBluetoothService() {
3189 web_bluetooth_service_.reset(); 3145 web_bluetooth_service_.reset();
3190 } 3146 }
3191 3147
3148 std::unique_ptr<NavigationHandleImpl>
3149 RenderFrameHostImpl::FindNavigationHandleForCommit(
3150 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
3151 // If this is a same-page navigation, there isn't an existing NavigationHandle
3152 // to use for the navigation. Create one, but don't reset any NavigationHandle
3153 // tracking an ongoing navigation, since this may lead to the cancellation of
3154 // the navigation.
3155 if (params.was_within_same_page) {
3156 // There is no pending NavigationEntry in these cases, so pass 0 as the
3157 // nav_id.
Charlie Reis 2016/11/03 22:02:22 nit: pending_nav_entry_id
clamy 2016/11/04 14:18:21 Done.
3158 return NavigationHandleImpl::Create(
3159 params.url, frame_tree_node_, true, // is_renderer_initiated
Charlie Reis 2016/11/03 22:02:22 Hmm, is_renderer_initiated isn't necessarily true
clamy 2016/11/04 14:18:21 That's a good point, though in this case we don't
Charlie Reis 2016/11/04 17:30:53 Good point. I think missing the canceled-pending-
3160 params.was_within_same_page, params.is_srcdoc, base::TimeTicks::Now(),
3161 0, false); // started_from_context_menu
3162 }
3163
3164 // Determine if the current NavigationHandle can be used.
3165 if (navigation_handle_ && navigation_handle_->GetURL() == params.url) {
3166 DCHECK(!navigation_handle_->IsSamePage());
3167 return std::move(navigation_handle_);
3168 }
3169
3170 // If the URL does not match what the NavigationHandle expects, treat the
3171 // commit as a new navigation. This can happen when loading a Data
3172 // navigation with LoadDataWithBaseURL.
3173 //
3174 // TODO(csharrison): Data navigations loaded with LoadDataWithBaseURL get
3175 // reset here, because the NavigationHandle tracks the URL but the params.url
3176 // tracks the data. The trick of saving the old entry ids for these
3177 // navigations should go away when this is properly handled.
3178 // See crbug.com/588317.
3179 int entry_id_for_data_nav = 0;
3180 bool is_renderer_initiated = true;
3181
3182 // Make sure that the pending entry was really loaded via LoadDataWithBaseURL
3183 // and that it matches this handle. TODO(csharrison): The pending entry's
3184 // base url should equal |params.base_url|. This is not the case for loads
3185 // with invalid base urls.
3186 if (navigation_handle_) {
3187 NavigationEntryImpl* pending_entry =
3188 NavigationEntryImpl::FromNavigationEntry(
3189 frame_tree_node()->navigator()->GetController()->GetPendingEntry());
3190 bool pending_entry_matches_handle =
3191 pending_entry &&
3192 pending_entry->GetUniqueID() ==
3193 navigation_handle_->pending_nav_entry_id();
3194 if (navigation_handle_->GetURL() == params.base_url &&
3195 pending_entry_matches_handle &&
3196 !pending_entry->GetBaseURLForDataURL().is_empty()) {
3197 entry_id_for_data_nav = navigation_handle_->pending_nav_entry_id();
3198 is_renderer_initiated = pending_entry->is_renderer_initiated();
3199 }
3200
3201 // Reset any existing NavigationHandle.
3202 navigation_handle_.reset();
3203 }
3204
3205 // There is no pending NavigationEntry in these cases, so pass 0 as the
3206 // nav_id. If the previous handle was a prematurely aborted navigation loaded
Charlie Reis 2016/11/03 22:02:22 nit: pending_nav_entry_id
clamy 2016/11/04 14:18:21 Done.
3207 // via LoadDataWithBaseURL, propagate the entry id.
3208 return NavigationHandleImpl::Create(
3209 params.url, frame_tree_node_, is_renderer_initiated,
3210 params.was_within_same_page, params.is_srcdoc, base::TimeTicks::Now(),
3211 entry_id_for_data_nav, false); // started_from_context_menu
3212 }
3213
3192 } // namespace content 3214 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698