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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 error_description, was_ignored_by_handler); | 262 error_description, was_ignored_by_handler); |
263 } | 263 } |
264 } | 264 } |
265 | 265 |
266 bool NavigatorImpl::NavigateToEntry( | 266 bool NavigatorImpl::NavigateToEntry( |
267 FrameTreeNode* frame_tree_node, | 267 FrameTreeNode* frame_tree_node, |
268 const FrameNavigationEntry& frame_entry, | 268 const FrameNavigationEntry& frame_entry, |
269 const NavigationEntryImpl& entry, | 269 const NavigationEntryImpl& entry, |
270 NavigationController::ReloadType reload_type, | 270 NavigationController::ReloadType reload_type, |
271 bool is_same_document_history_load, | 271 bool is_same_document_history_load, |
272 bool is_pending_entry) { | 272 bool is_pending_entry, |
| 273 const scoped_refptr<ResourceRequestBody>& post_body) { |
273 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); | 274 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); |
274 | 275 |
275 GURL dest_url = frame_entry.url(); | 276 GURL dest_url = frame_entry.url(); |
276 Referrer dest_referrer = frame_entry.referrer(); | 277 Referrer dest_referrer = frame_entry.referrer(); |
277 if (reload_type == | 278 if (reload_type == |
278 NavigationController::ReloadType::RELOAD_ORIGINAL_REQUEST_URL && | 279 NavigationController::ReloadType::RELOAD_ORIGINAL_REQUEST_URL && |
279 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { | 280 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { |
280 // We may have been redirected when navigating to the current URL. | 281 // We may have been redirected when navigating to the current URL. |
281 // Use the URL the user originally intended to visit, if it's valid and if a | 282 // Use the URL the user originally intended to visit, if it's valid and if a |
282 // POST wasn't involved; the latter case avoids issues with sending data to | 283 // POST wasn't involved; the latter case avoids issues with sending data to |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 is_transfer && | 382 is_transfer && |
382 entry.transferred_global_request_id().child_id == | 383 entry.transferred_global_request_id().child_id == |
383 dest_render_frame_host->GetProcess()->GetID(); | 384 dest_render_frame_host->GetProcess()->GetID(); |
384 if (!is_transfer_to_same) { | 385 if (!is_transfer_to_same) { |
385 navigation_data_.reset(new NavigationMetricsData( | 386 navigation_data_.reset(new NavigationMetricsData( |
386 navigation_start, dest_url, entry.restore_type())); | 387 navigation_start, dest_url, entry.restore_type())); |
387 // Create the navigation parameters. | 388 // Create the navigation parameters. |
388 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( | 389 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( |
389 controller_->GetBrowserContext(), entry, reload_type); | 390 controller_->GetBrowserContext(), entry, reload_type); |
390 dest_render_frame_host->Navigate( | 391 dest_render_frame_host->Navigate( |
391 entry.ConstructCommonNavigationParams(frame_entry, nullptr, dest_url, | 392 entry.ConstructCommonNavigationParams( |
392 dest_referrer, navigation_type, | 393 frame_entry, post_body, dest_url, dest_referrer, navigation_type, |
393 lofi_state, navigation_start), | 394 lofi_state, navigation_start), |
394 entry.ConstructStartNavigationParams(), | 395 entry.ConstructStartNavigationParams(), |
395 entry.ConstructRequestNavigationParams( | 396 entry.ConstructRequestNavigationParams( |
396 frame_entry, is_same_document_history_load, | 397 frame_entry, is_same_document_history_load, |
397 frame_tree_node->has_committed_real_load(), | 398 frame_tree_node->has_committed_real_load(), |
398 controller_->GetPendingEntryIndex() == -1, | 399 controller_->GetPendingEntryIndex() == -1, |
399 controller_->GetIndexOfEntry(&entry), | 400 controller_->GetIndexOfEntry(&entry), |
400 controller_->GetLastCommittedEntryIndex(), | 401 controller_->GetLastCommittedEntryIndex(), |
401 controller_->GetEntryCount())); | 402 controller_->GetEntryCount())); |
402 } else { | 403 } else { |
403 // No need to navigate again. Just resume the deferred request. | 404 // No need to navigate again. Just resume the deferred request. |
(...skipping 26 matching lines...) Expand all Loading... |
430 return true; | 431 return true; |
431 } | 432 } |
432 | 433 |
433 bool NavigatorImpl::NavigateToPendingEntry( | 434 bool NavigatorImpl::NavigateToPendingEntry( |
434 FrameTreeNode* frame_tree_node, | 435 FrameTreeNode* frame_tree_node, |
435 const FrameNavigationEntry& frame_entry, | 436 const FrameNavigationEntry& frame_entry, |
436 NavigationController::ReloadType reload_type, | 437 NavigationController::ReloadType reload_type, |
437 bool is_same_document_history_load) { | 438 bool is_same_document_history_load) { |
438 return NavigateToEntry(frame_tree_node, frame_entry, | 439 return NavigateToEntry(frame_tree_node, frame_entry, |
439 *controller_->GetPendingEntry(), reload_type, | 440 *controller_->GetPendingEntry(), reload_type, |
440 is_same_document_history_load, true); | 441 is_same_document_history_load, true, nullptr); |
441 } | 442 } |
442 | 443 |
443 bool NavigatorImpl::NavigateNewChildFrame( | 444 bool NavigatorImpl::NavigateNewChildFrame( |
444 RenderFrameHostImpl* render_frame_host, | 445 RenderFrameHostImpl* render_frame_host, |
445 const std::string& unique_name) { | 446 const std::string& unique_name) { |
446 NavigationEntryImpl* entry = | 447 NavigationEntryImpl* entry = |
447 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); | 448 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); |
448 if (!entry) | 449 if (!entry) |
449 return false; | 450 return false; |
450 | 451 |
451 // TODO(creis): Remove unique_name from the IPC, now that we can rely on the | 452 // TODO(creis): Remove unique_name from the IPC, now that we can rely on the |
452 // replication state. | 453 // replication state. |
453 DCHECK_EQ(render_frame_host->frame_tree_node()->unique_name(), unique_name); | 454 DCHECK_EQ(render_frame_host->frame_tree_node()->unique_name(), unique_name); |
454 FrameNavigationEntry* frame_entry = | 455 FrameNavigationEntry* frame_entry = |
455 entry->GetFrameEntry(render_frame_host->frame_tree_node()); | 456 entry->GetFrameEntry(render_frame_host->frame_tree_node()); |
456 if (!frame_entry) | 457 if (!frame_entry) |
457 return false; | 458 return false; |
458 | 459 |
459 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, | 460 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, |
460 *entry, NavigationControllerImpl::NO_RELOAD, false, | 461 *entry, NavigationControllerImpl::NO_RELOAD, false, |
461 false); | 462 false, nullptr); |
462 } | 463 } |
463 | 464 |
464 void NavigatorImpl::DidNavigate( | 465 void NavigatorImpl::DidNavigate( |
465 RenderFrameHostImpl* render_frame_host, | 466 RenderFrameHostImpl* render_frame_host, |
466 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 467 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
467 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); | 468 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); |
468 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); | 469 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); |
469 | 470 |
470 bool has_embedded_credentials = | 471 bool has_embedded_credentials = |
471 params.url.has_username() || params.url.has_password(); | 472 params.url.has_username() || params.url.has_password(); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 } | 719 } |
719 | 720 |
720 void NavigatorImpl::RequestTransferURL( | 721 void NavigatorImpl::RequestTransferURL( |
721 RenderFrameHostImpl* render_frame_host, | 722 RenderFrameHostImpl* render_frame_host, |
722 const GURL& url, | 723 const GURL& url, |
723 SiteInstance* source_site_instance, | 724 SiteInstance* source_site_instance, |
724 const std::vector<GURL>& redirect_chain, | 725 const std::vector<GURL>& redirect_chain, |
725 const Referrer& referrer, | 726 const Referrer& referrer, |
726 ui::PageTransition page_transition, | 727 ui::PageTransition page_transition, |
727 const GlobalRequestID& transferred_global_request_id, | 728 const GlobalRequestID& transferred_global_request_id, |
728 bool should_replace_current_entry) { | 729 bool should_replace_current_entry, |
| 730 const std::string& method, |
| 731 const scoped_refptr<ResourceRequestBody>& post_body) { |
| 732 // |method != "POST"| should imply absence of |post_body|. |
| 733 DCHECK(method == "POST" || !post_body); |
| 734 |
729 // This call only makes sense for subframes if OOPIFs are possible. | 735 // This call only makes sense for subframes if OOPIFs are possible. |
730 DCHECK(!render_frame_host->GetParent() || | 736 DCHECK(!render_frame_host->GetParent() || |
731 SiteIsolationPolicy::AreCrossProcessFramesPossible()); | 737 SiteIsolationPolicy::AreCrossProcessFramesPossible()); |
732 | 738 |
733 // Allow the delegate to cancel the transfer. | 739 // Allow the delegate to cancel the transfer. |
734 if (!delegate_->ShouldTransferNavigation()) | 740 if (!delegate_->ShouldTransferNavigation()) |
735 return; | 741 return; |
736 | 742 |
737 GURL dest_url(url); | 743 GURL dest_url(url); |
738 Referrer referrer_to_use(referrer); | 744 Referrer referrer_to_use(referrer); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 } else { | 788 } else { |
783 // If there's no last committed entry, create an entry for about:blank | 789 // If there's no last committed entry, create an entry for about:blank |
784 // with a subframe entry for our destination. | 790 // with a subframe entry for our destination. |
785 // TODO(creis): Ensure this case can't exist in https://crbug.com/524208. | 791 // TODO(creis): Ensure this case can't exist in https://crbug.com/524208. |
786 entry = NavigationEntryImpl::FromNavigationEntry( | 792 entry = NavigationEntryImpl::FromNavigationEntry( |
787 controller_->CreateNavigationEntry( | 793 controller_->CreateNavigationEntry( |
788 GURL(url::kAboutBlankURL), referrer_to_use, page_transition, | 794 GURL(url::kAboutBlankURL), referrer_to_use, page_transition, |
789 is_renderer_initiated, std::string(), | 795 is_renderer_initiated, std::string(), |
790 controller_->GetBrowserContext())); | 796 controller_->GetBrowserContext())); |
791 } | 797 } |
792 // TODO(creis): Handle POST submissions. See https://crbug.com/582211 and | |
793 // https://crbug.com/101395. | |
794 entry->AddOrUpdateFrameEntry( | 798 entry->AddOrUpdateFrameEntry( |
795 node, -1, -1, nullptr, | 799 node, -1, -1, nullptr, |
796 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, | 800 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, |
797 referrer_to_use, PageState(), "GET", -1); | 801 referrer_to_use, PageState(), method, -1); |
798 } else { | 802 } else { |
799 // Main frame case. | 803 // Main frame case. |
800 entry = NavigationEntryImpl::FromNavigationEntry( | 804 entry = NavigationEntryImpl::FromNavigationEntry( |
801 controller_->CreateNavigationEntry( | 805 controller_->CreateNavigationEntry( |
802 dest_url, referrer_to_use, page_transition, is_renderer_initiated, | 806 dest_url, referrer_to_use, page_transition, is_renderer_initiated, |
803 std::string(), controller_->GetBrowserContext())); | 807 std::string(), controller_->GetBrowserContext())); |
804 entry->root_node()->frame_entry->set_source_site_instance( | 808 entry->root_node()->frame_entry->set_source_site_instance( |
805 static_cast<SiteInstanceImpl*>(source_site_instance)); | 809 static_cast<SiteInstanceImpl*>(source_site_instance)); |
806 } | 810 } |
807 | 811 |
808 entry->SetRedirectChain(redirect_chain); | 812 entry->SetRedirectChain(redirect_chain); |
809 // Don't allow an entry replacement if there is no entry to replace. | 813 // Don't allow an entry replacement if there is no entry to replace. |
810 // http://crbug.com/457149 | 814 // http://crbug.com/457149 |
811 if (should_replace_current_entry && controller_->GetEntryCount() > 0) | 815 if (should_replace_current_entry && controller_->GetEntryCount() > 0) |
812 entry->set_should_replace_entry(true); | 816 entry->set_should_replace_entry(true); |
813 if (controller_->GetLastCommittedEntry() && | 817 if (controller_->GetLastCommittedEntry() && |
814 controller_->GetLastCommittedEntry()->GetIsOverridingUserAgent()) { | 818 controller_->GetLastCommittedEntry()->GetIsOverridingUserAgent()) { |
815 entry->SetIsOverridingUserAgent(true); | 819 entry->SetIsOverridingUserAgent(true); |
816 } | 820 } |
817 entry->set_transferred_global_request_id(transferred_global_request_id); | 821 entry->set_transferred_global_request_id(transferred_global_request_id); |
818 // TODO(creis): Set user gesture and intent received timestamp on Android. | 822 // TODO(creis): Set user gesture and intent received timestamp on Android. |
819 | 823 |
820 // We may not have successfully added the FrameNavigationEntry to |entry| | 824 // We may not have successfully added the FrameNavigationEntry to |entry| |
821 // above (per https://crbug.com/608402), in which case we create it from | 825 // above (per https://crbug.com/608402), in which case we create it from |
822 // scratch. This works because we do not depend on |frame_entry| being inside | 826 // scratch. This works because we do not depend on |frame_entry| being inside |
823 // |entry| during NavigateToEntry. This will go away when we shortcut this | 827 // |entry| during NavigateToEntry. This will go away when we shortcut this |
824 // further in https://crbug.com/536906. | 828 // further in https://crbug.com/536906. |
825 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); | 829 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); |
826 if (!frame_entry) { | 830 if (!frame_entry) { |
827 // TODO(creis): Handle POST submissions here, as above. | |
828 frame_entry = new FrameNavigationEntry( | 831 frame_entry = new FrameNavigationEntry( |
829 node->unique_name(), -1, -1, nullptr, | 832 node->unique_name(), -1, -1, nullptr, |
830 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, | 833 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, |
831 referrer_to_use, "GET", -1); | 834 referrer_to_use, method, -1); |
832 } | 835 } |
833 NavigateToEntry(node, *frame_entry, *entry.get(), | 836 NavigateToEntry(node, *frame_entry, *entry.get(), |
834 NavigationController::NO_RELOAD, false, false); | 837 NavigationController::NO_RELOAD, false, false, post_body); |
835 } | 838 } |
836 | 839 |
837 // PlzNavigate | 840 // PlzNavigate |
838 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, | 841 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, |
839 bool proceed) { | 842 bool proceed) { |
840 CHECK(IsBrowserSideNavigationEnabled()); | 843 CHECK(IsBrowserSideNavigationEnabled()); |
841 DCHECK(frame_tree_node); | 844 DCHECK(frame_tree_node); |
842 | 845 |
843 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); | 846 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
844 | 847 |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 if (pending_entry != controller_->GetVisibleEntry() || | 1168 if (pending_entry != controller_->GetVisibleEntry() || |
1166 !should_preserve_entry) { | 1169 !should_preserve_entry) { |
1167 controller_->DiscardPendingEntry(true); | 1170 controller_->DiscardPendingEntry(true); |
1168 | 1171 |
1169 // Also force the UI to refresh. | 1172 // Also force the UI to refresh. |
1170 controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); | 1173 controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); |
1171 } | 1174 } |
1172 } | 1175 } |
1173 | 1176 |
1174 } // namespace content | 1177 } // namespace content |
OLD | NEW |