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

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

Issue 2321543002: Merge CrossSiteResourceHandler and NavigationResourceThrottle (Closed)
Patch Set: Addressed nits Created 4 years, 2 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
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_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/debug/crash_logging.h" 13 #include "base/debug/crash_logging.h"
14 #include "base/debug/dump_without_crashing.h" 14 #include "base/debug/dump_without_crashing.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/trace_event/trace_event.h" 18 #include "base/trace_event/trace_event.h"
19 #include "content/browser/child_process_security_policy_impl.h" 19 #include "content/browser/child_process_security_policy_impl.h"
20 #include "content/browser/devtools/render_frame_devtools_agent_host.h" 20 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
21 #include "content/browser/frame_host/cross_site_transferring_request.h"
22 #include "content/browser/frame_host/debug_urls.h" 21 #include "content/browser/frame_host/debug_urls.h"
23 #include "content/browser/frame_host/frame_navigation_entry.h" 22 #include "content/browser/frame_host/frame_navigation_entry.h"
24 #include "content/browser/frame_host/interstitial_page_impl.h" 23 #include "content/browser/frame_host/interstitial_page_impl.h"
25 #include "content/browser/frame_host/navigation_controller_impl.h" 24 #include "content/browser/frame_host/navigation_controller_impl.h"
26 #include "content/browser/frame_host/navigation_entry_impl.h" 25 #include "content/browser/frame_host/navigation_entry_impl.h"
27 #include "content/browser/frame_host/navigation_handle_impl.h" 26 #include "content/browser/frame_host/navigation_handle_impl.h"
28 #include "content/browser/frame_host/navigation_request.h" 27 #include "content/browser/frame_host/navigation_request.h"
29 #include "content/browser/frame_host/navigator.h" 28 #include "content/browser/frame_host/navigator.h"
30 #include "content/browser/frame_host/render_frame_host_factory.h" 29 #include "content/browser/frame_host/render_frame_host_factory.h"
31 #include "content/browser/frame_host/render_frame_host_impl.h" 30 #include "content/browser/frame_host/render_frame_host_impl.h"
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 // RenderFrameHostManager are completely initialized. This should be 272 // RenderFrameHostManager are completely initialized. This should be
274 // removed once the process manager moves away from NotificationService. 273 // removed once the process manager moves away from NotificationService.
275 // See https://crbug.com/462682. 274 // See https://crbug.com/462682.
276 delegate_->NotifyMainFrameSwappedFromRenderManager( 275 delegate_->NotifyMainFrameSwappedFromRenderManager(
277 nullptr, render_frame_host_->render_view_host()); 276 nullptr, render_frame_host_->render_view_host());
278 } 277 }
279 } 278 }
280 279
281 // If entry includes the request ID of a request that is being transferred, 280 // If entry includes the request ID of a request that is being transferred,
282 // the destination render frame will take ownership, so release ownership of 281 // the destination render frame will take ownership, so release ownership of
283 // the request. 282 // the transferring NavigationHandle.
284 if (cross_site_transferring_request_.get() && 283 if (transfer_navigation_handle_.get() &&
285 cross_site_transferring_request_->request_id() == 284 transfer_navigation_handle_->request_id() ==
286 entry.transferred_global_request_id()) { 285 entry.transferred_global_request_id()) {
287 cross_site_transferring_request_->ReleaseRequest();
288
289 DCHECK(transfer_navigation_handle_);
290
291 // Update the pending NavigationEntry ID on the transferring handle.
292 // TODO(creis): Make this line unnecessary by avoiding having a pending
293 // entry for transfer navigations. See https://crbug.com/495161.
294 transfer_navigation_handle_->update_entry_id_for_transfer(
295 entry.GetUniqueID());
296
297 // The navigating RenderFrameHost should take ownership of the 286 // The navigating RenderFrameHost should take ownership of the
298 // NavigationHandle that came from the transferring RenderFrameHost. 287 // NavigationHandle that came from the transferring RenderFrameHost.
299 dest_render_frame_host->SetNavigationHandle( 288 dest_render_frame_host->SetNavigationHandle(
300 std::move(transfer_navigation_handle_)); 289 std::move(transfer_navigation_handle_));
290
291 dest_render_frame_host->navigation_handle()->set_render_frame_host(
292 dest_render_frame_host);
301 } 293 }
302 DCHECK(!transfer_navigation_handle_);
303 294
304 return dest_render_frame_host; 295 return dest_render_frame_host;
305 } 296 }
306 297
307 void RenderFrameHostManager::Stop() { 298 void RenderFrameHostManager::Stop() {
308 render_frame_host_->Stop(); 299 render_frame_host_->Stop();
309 300
310 // If a cross-process navigation is happening, the pending RenderFrameHost 301 // If a cross-process navigation is happening, the pending RenderFrameHost
311 // should stop. This will lead to a DidFailProvisionalLoad, which will 302 // should stop. This will lead to a DidFailProvisionalLoad, which will
312 // properly destroy it. 303 // properly destroy it.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 405
415 // This is not a cross-process navigation; the tab is being closed. 406 // This is not a cross-process navigation; the tab is being closed.
416 render_frame_host_->render_view_host()->ClosePage(); 407 render_frame_host_->render_view_host()->ClosePage();
417 } 408 }
418 } 409 }
419 } 410 }
420 411
421 void RenderFrameHostManager::OnCrossSiteResponse( 412 void RenderFrameHostManager::OnCrossSiteResponse(
422 RenderFrameHostImpl* transferring_render_frame_host, 413 RenderFrameHostImpl* transferring_render_frame_host,
423 const GlobalRequestID& global_request_id, 414 const GlobalRequestID& global_request_id,
424 std::unique_ptr<CrossSiteTransferringRequest>
425 cross_site_transferring_request,
426 const std::vector<GURL>& transfer_url_chain, 415 const std::vector<GURL>& transfer_url_chain,
427 const Referrer& referrer, 416 const Referrer& referrer,
428 ui::PageTransition page_transition, 417 ui::PageTransition page_transition,
429 bool should_replace_current_entry) { 418 bool should_replace_current_entry) {
430 // We should only get here for transfer navigations. Most cross-process
431 // navigations can just continue and wait to run the unload handler (by
432 // swapping out) when the new navigation commits.
433 CHECK(cross_site_transferring_request);
434
435 // A transfer should only have come from our pending or current RFH. If it 419 // A transfer should only have come from our pending or current RFH. If it
436 // started as a cross-process navigation via OpenURL, this is the pending 420 // started as a cross-process navigation via OpenURL, this is the pending
437 // one. If it wasn't cross-process until the transfer, this is the current 421 // one. If it wasn't cross-process until the transfer, this is the current
438 // one. 422 // one.
439 // 423 //
440 // Note that having a pending RFH does not imply that it was the one that 424 // Note that having a pending RFH does not imply that it was the one that
441 // made the request. Suppose that during a pending cross-site navigation, 425 // made the request. Suppose that during a pending cross-site navigation,
442 // the frame performs a different same-site navigation which redirects 426 // the frame performs a different same-site navigation which redirects
443 // cross-site. In this case, there will be a pending RFH, but this request 427 // cross-site. In this case, there will be a pending RFH, but this request
444 // is made by the current RFH. Later, this will create a new pending RFH and 428 // is made by the current RFH. Later, this will create a new pending RFH and
445 // clean up the old one. 429 // clean up the old one.
446 // 430 //
447 // TODO(creis): We need to handle the case that the pending RFH has changed 431 // TODO(creis): We need to handle the case that the pending RFH has changed
448 // in the mean time, while this was being posted from the IO thread. We 432 // in the mean time, while this was being posted from the IO thread. We
449 // should probably cancel the request in that case. 433 // should probably cancel the request in that case.
450 DCHECK(transferring_render_frame_host == pending_render_frame_host_.get() || 434 DCHECK(transferring_render_frame_host == pending_render_frame_host_.get() ||
451 transferring_render_frame_host == render_frame_host_.get()); 435 transferring_render_frame_host == render_frame_host_.get());
452 436
453 // Check if the FrameTreeNode is loading. This will be used later to notify 437 // Check if the FrameTreeNode is loading. This will be used later to notify
454 // the FrameTreeNode that the load stop if the transfer fails. 438 // the FrameTreeNode that the load stop if the transfer fails.
455 bool frame_tree_node_was_loading = frame_tree_node_->IsLoading(); 439 bool frame_tree_node_was_loading = frame_tree_node_->IsLoading();
456 440
457 // Store the NavigationHandle to give it to the appropriate RenderFrameHost 441 // Store the NavigationHandle to give it to the appropriate RenderFrameHost
458 // after it started navigating. 442 // after it started navigating.
459 transfer_navigation_handle_ = 443 transfer_navigation_handle_ =
460 transferring_render_frame_host->PassNavigationHandleOwnership(); 444 transferring_render_frame_host->PassNavigationHandleOwnership();
461 445 CHECK(transfer_navigation_handle_);
462 // If something caused the cancellation of this navigation on the UI thread
463 // (possibly for security reasons) the navigation should not be allowed to
464 // proceed.
465 if (!transfer_navigation_handle_)
466 return;
467
468 // Store the transferring request so that we can release it if the transfer
469 // navigation matches.
470 cross_site_transferring_request_ = std::move(cross_site_transferring_request);
471 446
472 // Set the transferring RenderFrameHost as not loading, so that it does not 447 // Set the transferring RenderFrameHost as not loading, so that it does not
473 // emit a DidStopLoading notification if it is destroyed when creating the 448 // emit a DidStopLoading notification if it is destroyed when creating the
474 // new navigating RenderFrameHost. 449 // new navigating RenderFrameHost.
475 transferring_render_frame_host->set_is_loading(false); 450 transferring_render_frame_host->set_is_loading(false);
476 451
477 // Treat the last URL in the chain as the destination and the remainder as 452 // Treat the last URL in the chain as the destination and the remainder as
478 // the redirect chain. 453 // the redirect chain.
479 CHECK(transfer_url_chain.size()); 454 CHECK(transfer_url_chain.size());
480 GURL transfer_url = transfer_url_chain.back(); 455 GURL transfer_url = transfer_url_chain.back();
481 std::vector<GURL> rest_of_chain = transfer_url_chain; 456 std::vector<GURL> rest_of_chain = transfer_url_chain;
482 rest_of_chain.pop_back(); 457 rest_of_chain.pop_back();
483 458
484 transferring_render_frame_host->frame_tree_node() 459 transferring_render_frame_host->frame_tree_node()
485 ->navigator() 460 ->navigator()
486 ->RequestTransferURL( 461 ->RequestTransferURL(
487 transferring_render_frame_host, transfer_url, nullptr, rest_of_chain, 462 transferring_render_frame_host, transfer_url, nullptr, rest_of_chain,
488 referrer, page_transition, global_request_id, 463 referrer, page_transition, global_request_id,
489 should_replace_current_entry, 464 should_replace_current_entry,
490 transfer_navigation_handle_->IsPost() ? "POST" : "GET", 465 transfer_navigation_handle_->IsPost() ? "POST" : "GET",
491 transfer_navigation_handle_->resource_request_body()); 466 transfer_navigation_handle_->resource_request_body());
492 467
493 // The transferring request was only needed during the RequestTransferURL
494 // call, so it is safe to clear at this point.
495 cross_site_transferring_request_.reset();
496
497 // If the navigation continued, the NavigationHandle should have been 468 // If the navigation continued, the NavigationHandle should have been
498 // transfered to a RenderFrameHost. In the other cases, it should be cleared. 469 // transfered to a RenderFrameHost. In the other cases, it should be cleared.
470 // If the NavigationHandle wasn't claimed, this will lead to the cancelation
471 // of the request in the network stack.
499 transfer_navigation_handle_.reset(); 472 transfer_navigation_handle_.reset();
500 473
501 // If the navigation in the new renderer did not start, inform the 474 // If the navigation in the new renderer did not start, inform the
502 // FrameTreeNode that it stopped loading. 475 // FrameTreeNode that it stopped loading.
503 if (!frame_tree_node_->IsLoading() && frame_tree_node_was_loading) 476 if (!frame_tree_node_->IsLoading() && frame_tree_node_was_loading)
504 frame_tree_node_->DidStopLoading(); 477 frame_tree_node_->DidStopLoading();
505 } 478 }
506 479
507 void RenderFrameHostManager::DidNavigateFrame( 480 void RenderFrameHostManager::DidNavigateFrame(
508 RenderFrameHostImpl* render_frame_host, 481 RenderFrameHostImpl* render_frame_host,
(...skipping 1727 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 // Note: Do not add code here to determine whether the subframe should swap 2209 // Note: Do not add code here to determine whether the subframe should swap
2237 // or not. Add it to CanSubframeSwapProcess instead. 2210 // or not. Add it to CanSubframeSwapProcess instead.
2238 return render_frame_host_.get(); 2211 return render_frame_host_.get();
2239 } 2212 }
2240 2213
2241 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 2214 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
2242 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( 2215 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
2243 dest_url, source_instance, dest_instance, nullptr, transition, 2216 dest_url, source_instance, dest_instance, nullptr, transition,
2244 dest_is_restore, dest_is_view_source_mode); 2217 dest_is_restore, dest_is_view_source_mode);
2245 2218
2219 // Inform the transferring NavigationHandle of a transfer to a different
2220 // SiteInstance. It is important do so now, in order to mark the request as
2221 // transferring on the IO thread before attempting to destroy the pending RFH.
2222 // This ensures the network request will not be destroyed along the pending
2223 // RFH but will persist until it is picked up by the new RFH.
2224 if (transfer_navigation_handle_.get() &&
2225 transfer_navigation_handle_->request_id() == transferred_request_id &&
2226 new_instance.get() !=
2227 transfer_navigation_handle_->GetRenderFrameHost()
2228 ->GetSiteInstance()) {
2229 transfer_navigation_handle_->Transfer();
2230 }
2231
2246 // If we are currently navigating cross-process to a pending RFH for a 2232 // If we are currently navigating cross-process to a pending RFH for a
2247 // different SiteInstance, we want to get back to normal and then navigate as 2233 // different SiteInstance, we want to get back to normal and then navigate as
2248 // usual. We will reuse the pending RFH below if it matches the destination 2234 // usual. We will reuse the pending RFH below if it matches the destination
2249 // SiteInstance. 2235 // SiteInstance.
2250 if (pending_render_frame_host_) { 2236 if (pending_render_frame_host_) {
2251 if (pending_render_frame_host_->GetSiteInstance() != new_instance) { 2237 if (pending_render_frame_host_->GetSiteInstance() != new_instance) {
2252 CancelPending(); 2238 CancelPending();
2253 } else { 2239 } else {
2254 // When a pending RFH is reused, it should always be live, since it is 2240 // When a pending RFH is reused, it should always be live, since it is
2255 // cleared whenever a process dies. 2241 // cleared whenever a process dies.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 // RFH isn't live.) 2281 // RFH isn't live.)
2296 CommitPending(); 2282 CommitPending();
2297 return render_frame_host_.get(); 2283 return render_frame_host_.get();
2298 } 2284 }
2299 // Otherwise, it's safe to treat this as a pending cross-process transition. 2285 // Otherwise, it's safe to treat this as a pending cross-process transition.
2300 2286
2301 bool is_transfer = transferred_request_id != GlobalRequestID(); 2287 bool is_transfer = transferred_request_id != GlobalRequestID();
2302 if (is_transfer) { 2288 if (is_transfer) {
2303 // We don't need to stop the old renderer or run beforeunload/unload 2289 // We don't need to stop the old renderer or run beforeunload/unload
2304 // handlers, because those have already been done. 2290 // handlers, because those have already been done.
2305 DCHECK(cross_site_transferring_request_->request_id() == 2291 DCHECK(transfer_navigation_handle_ &&
2306 transferred_request_id); 2292 transfer_navigation_handle_->request_id() ==
2293 transferred_request_id);
2307 } else if (!pending_render_frame_host_->are_navigations_suspended()) { 2294 } else if (!pending_render_frame_host_->are_navigations_suspended()) {
2308 // If the pending RFH hasn't already been suspended from a previous 2295 // If the pending RFH hasn't already been suspended from a previous
2309 // attempt to navigate it, then we need to wait for the beforeunload 2296 // attempt to navigate it, then we need to wait for the beforeunload
2310 // handler to run. Suspend navigations in the pending RFH until we hear 2297 // handler to run. Suspend navigations in the pending RFH until we hear
2311 // back from the old RFH's beforeunload handler (via OnBeforeUnloadACK or 2298 // back from the old RFH's beforeunload handler (via OnBeforeUnloadACK or
2312 // a timeout). If the handler returns false, we'll have to cancel the 2299 // a timeout). If the handler returns false, we'll have to cancel the
2313 // request. 2300 // request.
2314 // 2301 //
2315 // Also make sure the old RenderFrame stops, in case a load is in 2302 // Also make sure the old RenderFrame stops, in case a load is in
2316 // progress. (We don't want to do this for transfers, since it will 2303 // progress. (We don't want to do this for transfers, since it will
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
2681 resolved_url)) { 2668 resolved_url)) {
2682 DCHECK(!dest_instance || 2669 DCHECK(!dest_instance ||
2683 dest_instance == render_frame_host_->GetSiteInstance()); 2670 dest_instance == render_frame_host_->GetSiteInstance());
2684 return false; 2671 return false;
2685 } 2672 }
2686 2673
2687 return true; 2674 return true;
2688 } 2675 }
2689 2676
2690 } // namespace content 2677 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698