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

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

Issue 1956383003: Forwarding POST body into renderer after a cross-site transfer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: GoBackToCrossSitePostWithRedirect is fixed by this CL. Created 4 years, 6 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/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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698