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

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

Powered by Google App Engine
This is Rietveld 408576698