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

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: Extracted a shared NavigationEntryImpl::ConstructResourceRequestBody. Created 4 years, 7 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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
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);
377 dest_render_frame_host->Navigate( 378 dest_render_frame_host->Navigate(
378 entry.ConstructCommonNavigationParams(dest_url, dest_referrer, 379 entry.ConstructCommonNavigationParams(frame_entry.method(), dest_url,
clamy 2016/05/19 16:08:00 In the current code, the method is always GET for
Łukasz Anforowicz 2016/05/19 18:06:59 Oh, I see - this is the concern that you're addres
379 navigation_type, lofi_state, 380 dest_referrer, navigation_type,
380 navigation_start), 381 lofi_state, navigation_start),
381 entry.ConstructStartNavigationParams(), 382 entry.ConstructStartNavigationParams(post_body),
382 entry.ConstructRequestNavigationParams( 383 entry.ConstructRequestNavigationParams(
383 frame_entry, is_same_document_history_load, 384 frame_entry, is_same_document_history_load,
384 frame_tree_node->has_committed_real_load(), 385 frame_tree_node->has_committed_real_load(),
385 controller_->GetPendingEntryIndex() == -1, 386 controller_->GetPendingEntryIndex() == -1,
386 controller_->GetIndexOfEntry(&entry), 387 controller_->GetIndexOfEntry(&entry),
387 controller_->GetLastCommittedEntryIndex(), 388 controller_->GetLastCommittedEntryIndex(),
388 controller_->GetEntryCount())); 389 controller_->GetEntryCount()));
389 } else { 390 } else {
390 // No need to navigate again. Just resume the deferred request. 391 // No need to navigate again. Just resume the deferred request.
391 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( 392 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation(
(...skipping 25 matching lines...) Expand all
417 return true; 418 return true;
418 } 419 }
419 420
420 bool NavigatorImpl::NavigateToPendingEntry( 421 bool NavigatorImpl::NavigateToPendingEntry(
421 FrameTreeNode* frame_tree_node, 422 FrameTreeNode* frame_tree_node,
422 const FrameNavigationEntry& frame_entry, 423 const FrameNavigationEntry& frame_entry,
423 NavigationController::ReloadType reload_type, 424 NavigationController::ReloadType reload_type,
424 bool is_same_document_history_load) { 425 bool is_same_document_history_load) {
425 return NavigateToEntry(frame_tree_node, frame_entry, 426 return NavigateToEntry(frame_tree_node, frame_entry,
426 *controller_->GetPendingEntry(), reload_type, 427 *controller_->GetPendingEntry(), reload_type,
427 is_same_document_history_load, true); 428 is_same_document_history_load, true, nullptr);
428 } 429 }
429 430
430 bool NavigatorImpl::NavigateNewChildFrame( 431 bool NavigatorImpl::NavigateNewChildFrame(
431 RenderFrameHostImpl* render_frame_host, 432 RenderFrameHostImpl* render_frame_host,
432 const std::string& unique_name) { 433 const std::string& unique_name) {
433 NavigationEntryImpl* entry = 434 NavigationEntryImpl* entry =
434 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); 435 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id());
435 if (!entry) 436 if (!entry)
436 return false; 437 return false;
437 438
438 // TODO(creis): Remove unique_name from the IPC, now that we can rely on the 439 // TODO(creis): Remove unique_name from the IPC, now that we can rely on the
439 // replication state. 440 // replication state.
440 DCHECK_EQ(render_frame_host->frame_tree_node()->unique_name(), unique_name); 441 DCHECK_EQ(render_frame_host->frame_tree_node()->unique_name(), unique_name);
441 FrameNavigationEntry* frame_entry = 442 FrameNavigationEntry* frame_entry =
442 entry->GetFrameEntry(render_frame_host->frame_tree_node()); 443 entry->GetFrameEntry(render_frame_host->frame_tree_node());
443 if (!frame_entry) 444 if (!frame_entry)
444 return false; 445 return false;
445 446
446 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, 447 return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry,
447 *entry, NavigationControllerImpl::NO_RELOAD, false, 448 *entry, NavigationControllerImpl::NO_RELOAD, false,
448 false); 449 false, nullptr);
449 } 450 }
450 451
451 void NavigatorImpl::DidNavigate( 452 void NavigatorImpl::DidNavigate(
452 RenderFrameHostImpl* render_frame_host, 453 RenderFrameHostImpl* render_frame_host,
453 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { 454 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
454 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); 455 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree();
455 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); 456 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible();
456 457
457 bool has_embedded_credentials = 458 bool has_embedded_credentials =
458 params.url.has_username() || params.url.has_password(); 459 params.url.has_username() || params.url.has_password();
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 } 701 }
701 702
702 void NavigatorImpl::RequestTransferURL( 703 void NavigatorImpl::RequestTransferURL(
703 RenderFrameHostImpl* render_frame_host, 704 RenderFrameHostImpl* render_frame_host,
704 const GURL& url, 705 const GURL& url,
705 SiteInstance* source_site_instance, 706 SiteInstance* source_site_instance,
706 const std::vector<GURL>& redirect_chain, 707 const std::vector<GURL>& redirect_chain,
707 const Referrer& referrer, 708 const Referrer& referrer,
708 ui::PageTransition page_transition, 709 ui::PageTransition page_transition,
709 const GlobalRequestID& transferred_global_request_id, 710 const GlobalRequestID& transferred_global_request_id,
710 bool should_replace_current_entry) { 711 bool should_replace_current_entry,
712 const NavigationHandleImpl* transfer_navigation_handle) {
711 // This call only makes sense for subframes if OOPIFs are possible. 713 // This call only makes sense for subframes if OOPIFs are possible.
712 DCHECK(!render_frame_host->GetParent() || 714 DCHECK(!render_frame_host->GetParent() ||
713 SiteIsolationPolicy::AreCrossProcessFramesPossible()); 715 SiteIsolationPolicy::AreCrossProcessFramesPossible());
714 716
717 // Figure out the HTTP method.
718 // TODO(lukasza): Guarantee that |transfer_navigation_handle| is not null (it
719 // is null, when we are called from RenderFrameProxyHost::OnOpenURL).
clamy 2016/05/19 16:08:00 I think it would be better to pass the post data a
Łukasz Anforowicz 2016/05/19 18:06:59 Done. And thanks a lot for the suggestion - it re
720 std::string method =
721 transfer_navigation_handle ? transfer_navigation_handle->method() : "GET";
722
715 // Allow the delegate to cancel the transfer. 723 // Allow the delegate to cancel the transfer.
716 if (!delegate_->ShouldTransferNavigation()) 724 if (!delegate_->ShouldTransferNavigation())
717 return; 725 return;
718 726
719 GURL dest_url(url); 727 GURL dest_url(url);
720 Referrer referrer_to_use(referrer); 728 Referrer referrer_to_use(referrer);
721 FrameTreeNode* node = render_frame_host->frame_tree_node(); 729 FrameTreeNode* node = render_frame_host->frame_tree_node();
722 SiteInstance* current_site_instance = render_frame_host->GetSiteInstance(); 730 SiteInstance* current_site_instance = render_frame_host->GetSiteInstance();
723 if (!GetContentClient()->browser()->ShouldAllowOpenURL(current_site_instance, 731 if (!GetContentClient()->browser()->ShouldAllowOpenURL(current_site_instance,
724 url)) { 732 url)) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 } else { 772 } else {
765 // If there's no last committed entry, create an entry for about:blank 773 // If there's no last committed entry, create an entry for about:blank
766 // with a subframe entry for our destination. 774 // with a subframe entry for our destination.
767 // TODO(creis): Ensure this case can't exist in https://crbug.com/524208. 775 // TODO(creis): Ensure this case can't exist in https://crbug.com/524208.
768 entry = NavigationEntryImpl::FromNavigationEntry( 776 entry = NavigationEntryImpl::FromNavigationEntry(
769 controller_->CreateNavigationEntry( 777 controller_->CreateNavigationEntry(
770 GURL(url::kAboutBlankURL), referrer_to_use, page_transition, 778 GURL(url::kAboutBlankURL), referrer_to_use, page_transition,
771 is_renderer_initiated, std::string(), 779 is_renderer_initiated, std::string(),
772 controller_->GetBrowserContext())); 780 controller_->GetBrowserContext()));
773 } 781 }
774 // TODO(creis): Handle POST submissions. See https://crbug.com/582211 and 782 // TODO(lukasza): https://crbug.com/568703: Keep pre-transfer PageState.
775 // https://crbug.com/101395.
776 entry->AddOrUpdateFrameEntry( 783 entry->AddOrUpdateFrameEntry(
777 node, -1, -1, nullptr, 784 node, -1, -1, nullptr,
778 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, 785 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url,
779 referrer_to_use, PageState(), "GET", -1); 786 referrer_to_use, PageState(), method, -1);
780 } else { 787 } else {
781 // Main frame case. 788 // Main frame case.
782 entry = NavigationEntryImpl::FromNavigationEntry( 789 entry = NavigationEntryImpl::FromNavigationEntry(
783 controller_->CreateNavigationEntry( 790 controller_->CreateNavigationEntry(
784 dest_url, referrer_to_use, page_transition, is_renderer_initiated, 791 dest_url, referrer_to_use, page_transition, is_renderer_initiated,
785 std::string(), controller_->GetBrowserContext())); 792 std::string(), controller_->GetBrowserContext()));
786 entry->root_node()->frame_entry->set_source_site_instance( 793 entry->root_node()->frame_entry->set_source_site_instance(
787 static_cast<SiteInstanceImpl*>(source_site_instance)); 794 static_cast<SiteInstanceImpl*>(source_site_instance));
788 } 795 }
789 796
790 entry->SetRedirectChain(redirect_chain); 797 entry->SetRedirectChain(redirect_chain);
791 // Don't allow an entry replacement if there is no entry to replace. 798 // Don't allow an entry replacement if there is no entry to replace.
792 // http://crbug.com/457149 799 // http://crbug.com/457149
793 if (should_replace_current_entry && controller_->GetEntryCount() > 0) 800 if (should_replace_current_entry && controller_->GetEntryCount() > 0)
794 entry->set_should_replace_entry(true); 801 entry->set_should_replace_entry(true);
795 if (controller_->GetLastCommittedEntry() && 802 if (controller_->GetLastCommittedEntry() &&
796 controller_->GetLastCommittedEntry()->GetIsOverridingUserAgent()) { 803 controller_->GetLastCommittedEntry()->GetIsOverridingUserAgent()) {
797 entry->SetIsOverridingUserAgent(true); 804 entry->SetIsOverridingUserAgent(true);
798 } 805 }
799 entry->set_transferred_global_request_id(transferred_global_request_id); 806 entry->set_transferred_global_request_id(transferred_global_request_id);
800 // TODO(creis): Set user gesture and intent received timestamp on Android. 807 // TODO(creis): Set user gesture and intent received timestamp on Android.
801 808
802 // We may not have successfully added the FrameNavigationEntry to |entry| 809 // We may not have successfully added the FrameNavigationEntry to |entry|
803 // above (per https://crbug.com/608402), in which case we create it from 810 // 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 811 // 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 812 // |entry| during NavigateToEntry. This will go away when we shortcut this
806 // further in https://crbug.com/536906. 813 // further in https://crbug.com/536906.
807 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node)); 814 scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node));
808 if (!frame_entry) { 815 if (!frame_entry) {
809 // TODO(creis): Handle POST submissions here, as above.
810 frame_entry = new FrameNavigationEntry( 816 frame_entry = new FrameNavigationEntry(
811 node->unique_name(), -1, -1, nullptr, 817 node->unique_name(), -1, -1, nullptr,
812 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url, 818 static_cast<SiteInstanceImpl*>(source_site_instance), dest_url,
813 referrer_to_use, "GET", -1); 819 referrer_to_use, method, -1);
814 } 820 }
821
822 // TODO(lukasza): Guarantee that |transfer_navigation_handle| is not null (it
823 // is null, when we are called from RenderFrameProxyHost::OnOpenURL).
824 scoped_refptr<ResourceRequestBody> post_body;
825 if (transfer_navigation_handle)
826 post_body = transfer_navigation_handle->resource_request_body();
827
815 NavigateToEntry(node, *frame_entry, *entry.get(), 828 NavigateToEntry(node, *frame_entry, *entry.get(),
816 NavigationController::NO_RELOAD, false, false); 829 NavigationController::NO_RELOAD, false, false, post_body);
817 } 830 }
818 831
819 // PlzNavigate 832 // PlzNavigate
820 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, 833 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node,
821 bool proceed) { 834 bool proceed) {
822 CHECK(IsBrowserSideNavigationEnabled()); 835 CHECK(IsBrowserSideNavigationEnabled());
823 DCHECK(frame_tree_node); 836 DCHECK(frame_tree_node);
824 837
825 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); 838 NavigationRequest* navigation_request = frame_tree_node->navigation_request();
826 839
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 if (pending_entry != controller_->GetVisibleEntry() || 1160 if (pending_entry != controller_->GetVisibleEntry() ||
1148 !should_preserve_entry) { 1161 !should_preserve_entry) {
1149 controller_->DiscardPendingEntry(true); 1162 controller_->DiscardPendingEntry(true);
1150 1163
1151 // Also force the UI to refresh. 1164 // Also force the UI to refresh.
1152 controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); 1165 controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
1153 } 1166 }
1154 } 1167 }
1155 1168
1156 } // namespace content 1169 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698