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

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

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

Powered by Google App Engine
This is Rietveld 408576698