| OLD | NEW |
| 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/navigator_impl.h" | 5 #include "content/browser/frame_host/navigator_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 error_description, was_ignored_by_handler); | 250 error_description, was_ignored_by_handler); |
| 251 } | 251 } |
| 252 } | 252 } |
| 253 | 253 |
| 254 bool NavigatorImpl::NavigateToEntry( | 254 bool NavigatorImpl::NavigateToEntry( |
| 255 FrameTreeNode* frame_tree_node, | 255 FrameTreeNode* frame_tree_node, |
| 256 const FrameNavigationEntry& frame_entry, | 256 const FrameNavigationEntry& frame_entry, |
| 257 const NavigationEntryImpl& entry, | 257 const NavigationEntryImpl& entry, |
| 258 NavigationController::ReloadType reload_type, | 258 NavigationController::ReloadType reload_type, |
| 259 bool is_same_document_history_load, | 259 bool is_same_document_history_load, |
| 260 bool is_pending_entry) { | 260 bool is_pending_entry, |
| 261 const scoped_refptr<ResourceRequestBody>& post_body) { |
| 261 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); | 262 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); |
| 262 | 263 |
| 263 GURL dest_url = frame_entry.url(); | 264 GURL dest_url = frame_entry.url(); |
| 264 Referrer dest_referrer = frame_entry.referrer(); | 265 Referrer dest_referrer = frame_entry.referrer(); |
| 265 if (reload_type == | 266 if (reload_type == |
| 266 NavigationController::ReloadType::RELOAD_ORIGINAL_REQUEST_URL && | 267 NavigationController::ReloadType::RELOAD_ORIGINAL_REQUEST_URL && |
| 267 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { | 268 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { |
| 268 // We may have been redirected when navigating to the current URL. | 269 // We may have been redirected when navigating to the current URL. |
| 269 // Use the URL the user originally intended to visit, if it's valid and if a | 270 // Use the URL the user originally intended to visit, if it's valid and if a |
| 270 // POST wasn't involved; the latter case avoids issues with sending data to | 271 // POST wasn't involved; the latter case avoids issues with sending data to |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 bool is_transfer_to_same = | 368 bool is_transfer_to_same = |
| 368 is_transfer && | 369 is_transfer && |
| 369 entry.transferred_global_request_id().child_id == | 370 entry.transferred_global_request_id().child_id == |
| 370 dest_render_frame_host->GetProcess()->GetID(); | 371 dest_render_frame_host->GetProcess()->GetID(); |
| 371 if (!is_transfer_to_same) { | 372 if (!is_transfer_to_same) { |
| 372 navigation_data_.reset(new NavigationMetricsData( | 373 navigation_data_.reset(new NavigationMetricsData( |
| 373 navigation_start, dest_url, entry.restore_type())); | 374 navigation_start, dest_url, entry.restore_type())); |
| 374 // Create the navigation parameters. | 375 // Create the navigation parameters. |
| 375 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( | 376 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( |
| 376 controller_->GetBrowserContext(), entry, reload_type); | 377 controller_->GetBrowserContext(), entry, reload_type); |
| 378 bool force_post_method = static_cast<bool>(post_body); |
| 377 dest_render_frame_host->Navigate( | 379 dest_render_frame_host->Navigate( |
| 378 entry.ConstructCommonNavigationParams(frame_entry, dest_url, | 380 entry.ConstructCommonNavigationParams( |
| 379 dest_referrer, navigation_type, | 381 frame_entry, force_post_method, dest_url, |
| 380 lofi_state, navigation_start), | 382 dest_referrer, navigation_type, lofi_state, navigation_start), |
| 381 entry.ConstructStartNavigationParams(), | 383 entry.ConstructStartNavigationParams(post_body), |
| 382 entry.ConstructRequestNavigationParams( | 384 entry.ConstructRequestNavigationParams( |
| 383 frame_entry, is_same_document_history_load, | 385 frame_entry, is_same_document_history_load, |
| 384 frame_tree_node->has_committed_real_load(), | 386 frame_tree_node->has_committed_real_load(), |
| 385 controller_->GetPendingEntryIndex() == -1, | 387 controller_->GetPendingEntryIndex() == -1, |
| 386 controller_->GetIndexOfEntry(&entry), | 388 controller_->GetIndexOfEntry(&entry), |
| 387 controller_->GetLastCommittedEntryIndex(), | 389 controller_->GetLastCommittedEntryIndex(), |
| 388 controller_->GetEntryCount())); | 390 controller_->GetEntryCount())); |
| 389 } else { | 391 } else { |
| 390 // No need to navigate again. Just resume the deferred request. | 392 // No need to navigate again. Just resume the deferred request. |
| 391 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( | 393 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 417 return true; | 419 return true; |
| 418 } | 420 } |
| 419 | 421 |
| 420 bool NavigatorImpl::NavigateToPendingEntry( | 422 bool NavigatorImpl::NavigateToPendingEntry( |
| 421 FrameTreeNode* frame_tree_node, | 423 FrameTreeNode* frame_tree_node, |
| 422 const FrameNavigationEntry& frame_entry, | 424 const FrameNavigationEntry& frame_entry, |
| 423 NavigationController::ReloadType reload_type, | 425 NavigationController::ReloadType reload_type, |
| 424 bool is_same_document_history_load) { | 426 bool is_same_document_history_load) { |
| 425 return NavigateToEntry(frame_tree_node, frame_entry, | 427 return NavigateToEntry(frame_tree_node, frame_entry, |
| 426 *controller_->GetPendingEntry(), reload_type, | 428 *controller_->GetPendingEntry(), reload_type, |
| 427 is_same_document_history_load, true); | 429 is_same_document_history_load, true, nullptr); |
| 428 } | 430 } |
| 429 | 431 |
| 430 bool NavigatorImpl::NavigateNewChildFrame( | 432 bool NavigatorImpl::NavigateNewChildFrame( |
| 431 RenderFrameHostImpl* render_frame_host, | 433 RenderFrameHostImpl* render_frame_host, |
| 432 const std::string& unique_name) { | 434 const std::string& unique_name) { |
| 433 NavigationEntryImpl* entry = | 435 NavigationEntryImpl* entry = |
| 434 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); | 436 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); |
| 435 if (!entry) | 437 if (!entry) |
| 436 return false; | 438 return false; |
| 437 | 439 |
| 438 // TODO(creis): Remove unique_name from the IPC, now that we can rely on the | 440 // TODO(creis): Remove unique_name from the IPC, now that we can rely on the |
| 439 // replication state. | 441 // replication state. |
| 440 DCHECK_EQ(render_frame_host->frame_tree_node()->unique_name(), unique_name); | 442 DCHECK_EQ(render_frame_host->frame_tree_node()->unique_name(), unique_name); |
| 441 FrameNavigationEntry* frame_entry = | 443 FrameNavigationEntry* frame_entry = |
| 442 entry->GetFrameEntry(render_frame_host->frame_tree_node()); | 444 entry->GetFrameEntry(render_frame_host->frame_tree_node()); |
| 443 if (!frame_entry) | 445 if (!frame_entry) |
| 444 return false; | 446 return false; |
| 445 | 447 |
| 446 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, | 448 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, |
| 447 *entry, NavigationControllerImpl::NO_RELOAD, false, | 449 *entry, NavigationControllerImpl::NO_RELOAD, false, |
| 448 false); | 450 false, nullptr); |
| 449 } | 451 } |
| 450 | 452 |
| 451 void NavigatorImpl::DidNavigate( | 453 void NavigatorImpl::DidNavigate( |
| 452 RenderFrameHostImpl* render_frame_host, | 454 RenderFrameHostImpl* render_frame_host, |
| 453 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 455 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 454 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); | 456 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); |
| 455 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); | 457 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); |
| 456 | 458 |
| 457 bool has_embedded_credentials = | 459 bool has_embedded_credentials = |
| 458 params.url.has_username() || params.url.has_password(); | 460 params.url.has_username() || params.url.has_password(); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 } | 702 } |
| 701 | 703 |
| 702 void NavigatorImpl::RequestTransferURL( | 704 void NavigatorImpl::RequestTransferURL( |
| 703 RenderFrameHostImpl* render_frame_host, | 705 RenderFrameHostImpl* render_frame_host, |
| 704 const GURL& url, | 706 const GURL& url, |
| 705 SiteInstance* source_site_instance, | 707 SiteInstance* source_site_instance, |
| 706 const std::vector<GURL>& redirect_chain, | 708 const std::vector<GURL>& redirect_chain, |
| 707 const Referrer& referrer, | 709 const Referrer& referrer, |
| 708 ui::PageTransition page_transition, | 710 ui::PageTransition page_transition, |
| 709 const GlobalRequestID& transferred_global_request_id, | 711 const GlobalRequestID& transferred_global_request_id, |
| 710 bool should_replace_current_entry) { | 712 bool should_replace_current_entry, |
| 713 const std::string& method, |
| 714 const scoped_refptr<ResourceRequestBody>& post_body) { |
| 711 // This call only makes sense for subframes if OOPIFs are possible. | 715 // This call only makes sense for subframes if OOPIFs are possible. |
| 712 DCHECK(!render_frame_host->GetParent() || | 716 DCHECK(!render_frame_host->GetParent() || |
| 713 SiteIsolationPolicy::AreCrossProcessFramesPossible()); | 717 SiteIsolationPolicy::AreCrossProcessFramesPossible()); |
| 714 | 718 |
| 715 // Allow the delegate to cancel the transfer. | 719 // Allow the delegate to cancel the transfer. |
| 716 if (!delegate_->ShouldTransferNavigation()) | 720 if (!delegate_->ShouldTransferNavigation()) |
| 717 return; | 721 return; |
| 718 | 722 |
| 719 GURL dest_url(url); | 723 GURL dest_url(url); |
| 720 Referrer referrer_to_use(referrer); | 724 Referrer referrer_to_use(referrer); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 } else { | 768 } else { |
| 765 // If there's no last committed entry, create an entry for about:blank | 769 // If there's no last committed entry, create an entry for about:blank |
| 766 // with a subframe entry for our destination. | 770 // with a subframe entry for our destination. |
| 767 // TODO(creis): Ensure this case can't exist in https://crbug.com/524208. | 771 // TODO(creis): Ensure this case can't exist in https://crbug.com/524208. |
| 768 entry = NavigationEntryImpl::FromNavigationEntry( | 772 entry = NavigationEntryImpl::FromNavigationEntry( |
| 769 controller_->CreateNavigationEntry( | 773 controller_->CreateNavigationEntry( |
| 770 GURL(url::kAboutBlankURL), referrer_to_use, page_transition, | 774 GURL(url::kAboutBlankURL), referrer_to_use, page_transition, |
| 771 is_renderer_initiated, std::string(), | 775 is_renderer_initiated, std::string(), |
| 772 controller_->GetBrowserContext())); | 776 controller_->GetBrowserContext())); |
| 773 } | 777 } |
| 774 // TODO(creis): Handle POST submissions. See https://crbug.com/582211 and | |
| 775 // https://crbug.com/101395. | |
| 776 entry->AddOrUpdateFrameEntry( | 778 entry->AddOrUpdateFrameEntry( |
| 777 node, -1, -1, nullptr, | 779 node, -1, -1, nullptr, |
| 778 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, | 780 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, |
| 779 referrer_to_use, PageState(), "GET", -1); | 781 referrer_to_use, PageState(), method, -1); |
| 780 } else { | 782 } else { |
| 781 // Main frame case. | 783 // Main frame case. |
| 782 entry = NavigationEntryImpl::FromNavigationEntry( | 784 entry = NavigationEntryImpl::FromNavigationEntry( |
| 783 controller_->CreateNavigationEntry( | 785 controller_->CreateNavigationEntry( |
| 784 dest_url, referrer_to_use, page_transition, is_renderer_initiated, | 786 dest_url, referrer_to_use, page_transition, is_renderer_initiated, |
| 785 std::string(), controller_->GetBrowserContext())); | 787 std::string(), controller_->GetBrowserContext())); |
| 786 entry->root_node()->frame_entry->set_source_site_instance( | 788 entry->root_node()->frame_entry->set_source_site_instance( |
| 787 static_cast<SiteInstanceImpl*>(source_site_instance)); | 789 static_cast<SiteInstanceImpl*>(source_site_instance)); |
| 788 } | 790 } |
| 789 | 791 |
| 790 entry->SetRedirectChain(redirect_chain); | 792 entry->SetRedirectChain(redirect_chain); |
| 791 // Don't allow an entry replacement if there is no entry to replace. | 793 // Don't allow an entry replacement if there is no entry to replace. |
| 792 // http://crbug.com/457149 | 794 // http://crbug.com/457149 |
| 793 if (should_replace_current_entry && controller_->GetEntryCount() > 0) | 795 if (should_replace_current_entry && controller_->GetEntryCount() > 0) |
| 794 entry->set_should_replace_entry(true); | 796 entry->set_should_replace_entry(true); |
| 795 if (controller_->GetLastCommittedEntry() && | 797 if (controller_->GetLastCommittedEntry() && |
| 796 controller_->GetLastCommittedEntry()->GetIsOverridingUserAgent()) { | 798 controller_->GetLastCommittedEntry()->GetIsOverridingUserAgent()) { |
| 797 entry->SetIsOverridingUserAgent(true); | 799 entry->SetIsOverridingUserAgent(true); |
| 798 } | 800 } |
| 799 entry->set_transferred_global_request_id(transferred_global_request_id); | 801 entry->set_transferred_global_request_id(transferred_global_request_id); |
| 800 // TODO(creis): Set user gesture and intent received timestamp on Android. | 802 // TODO(creis): Set user gesture and intent received timestamp on Android. |
| 801 | 803 |
| 802 // We may not have successfully added the FrameNavigationEntry to |entry| | 804 // We may not have successfully added the FrameNavigationEntry to |entry| |
| 803 // above (per https://crbug.com/608402), in which case we create it from | 805 // above (per https://crbug.com/608402), in which case we create it from |
| 804 // scratch. This works because we do not depend on |frame_entry| being inside | 806 // scratch. This works because we do not depend on |frame_entry| being inside |
| 805 // |entry| during NavigateToEntry. This will go away when we shortcut this | 807 // |entry| during NavigateToEntry. This will go away when we shortcut this |
| 806 // further in https://crbug.com/536906. | 808 // further in https://crbug.com/536906. |
| 807 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); | 809 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); |
| 808 if (!frame_entry) { | 810 if (!frame_entry) { |
| 809 // TODO(creis): Handle POST submissions here, as above. | |
| 810 frame_entry = new FrameNavigationEntry( | 811 frame_entry = new FrameNavigationEntry( |
| 811 node->unique_name(), -1, -1, nullptr, | 812 node->unique_name(), -1, -1, nullptr, |
| 812 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, | 813 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, |
| 813 referrer_to_use, "GET", -1); | 814 referrer_to_use, method, -1); |
| 814 } | 815 } |
| 815 NavigateToEntry(node, *frame_entry, *entry.get(), | 816 NavigateToEntry(node, *frame_entry, *entry.get(), |
| 816 NavigationController::NO_RELOAD, false, false); | 817 NavigationController::NO_RELOAD, false, false, post_body); |
| 817 } | 818 } |
| 818 | 819 |
| 819 // PlzNavigate | 820 // PlzNavigate |
| 820 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, | 821 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, |
| 821 bool proceed) { | 822 bool proceed) { |
| 822 CHECK(IsBrowserSideNavigationEnabled()); | 823 CHECK(IsBrowserSideNavigationEnabled()); |
| 823 DCHECK(frame_tree_node); | 824 DCHECK(frame_tree_node); |
| 824 | 825 |
| 825 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); | 826 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
| 826 | 827 |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 if (pending_entry != controller_->GetVisibleEntry() || | 1148 if (pending_entry != controller_->GetVisibleEntry() || |
| 1148 !should_preserve_entry) { | 1149 !should_preserve_entry) { |
| 1149 controller_->DiscardPendingEntry(true); | 1150 controller_->DiscardPendingEntry(true); |
| 1150 | 1151 |
| 1151 // Also force the UI to refresh. | 1152 // Also force the UI to refresh. |
| 1152 controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); | 1153 controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); |
| 1153 } | 1154 } |
| 1154 } | 1155 } |
| 1155 | 1156 |
| 1156 } // namespace content | 1157 } // namespace content |
| OLD | NEW |