Index: content/browser/frame_host/navigation_handle_impl.cc |
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc |
index c4524a8a7c3e821dcff3c9d33ec625071afdc5bc..9fd4e4c7664f60eb1f3952d9420796ffb25aa3c5 100644 |
--- a/content/browser/frame_host/navigation_handle_impl.cc |
+++ b/content/browser/frame_host/navigation_handle_impl.cc |
@@ -25,6 +25,7 @@ |
#include "content/browser/loader/resource_dispatcher_host_impl.h" |
#include "content/browser/service_worker/service_worker_context_wrapper.h" |
#include "content/browser/service_worker/service_worker_navigation_handle.h" |
+#include "content/common/child_process_host_impl.h" |
#include "content/common/frame_messages.h" |
#include "content/common/resource_request_body_impl.h" |
#include "content/common/site_isolation_policy.h" |
@@ -119,12 +120,17 @@ NavigationHandleImpl::NavigationHandleImpl( |
navigation_type_(NAVIGATION_TYPE_UNKNOWN), |
should_check_main_world_csp_(should_check_main_world_csp), |
is_form_submission_(is_form_submission), |
+ expected_render_process_host_id_(ChildProcessHost::kInvalidUniqueID), |
weak_factory_(this) { |
TRACE_EVENT_ASYNC_BEGIN2("navigation", "NavigationHandle", this, |
"frame_tree_node", |
frame_tree_node_->frame_tree_node_id(), "url", |
url_.possibly_invalid_spec()); |
DCHECK(!navigation_start.is_null()); |
+ |
+ site_url_ = SiteInstance::GetSiteForURL( |
+ frame_tree_node_->navigator()->GetController()->GetBrowserContext(), |
+ url_); |
if (redirect_chain_.empty()) |
redirect_chain_.push_back(url); |
@@ -166,6 +172,17 @@ NavigationHandleImpl::NavigationHandleImpl( |
} |
NavigationHandleImpl::~NavigationHandleImpl() { |
+ // Inform the RenderProcessHost to no longer expect a navigation. |
+ if (expected_render_process_host_id_ != ChildProcessHost::kInvalidUniqueID) { |
+ RenderProcessHost* process = |
+ RenderProcessHost::FromID(expected_render_process_host_id_); |
+ if (process) { |
+ RenderProcessHostImpl::RemoveExpectedNavigationToSite( |
+ frame_tree_node_->navigator()->GetController()->GetBrowserContext(), |
+ process, site_url_); |
+ } |
+ } |
+ |
// Transfer requests that have not matched up with another navigation request |
// from the renderer need to be cleaned up. These are marked as protected in |
// the RDHI, so they do not get cancelled when frames are destroyed. |
@@ -591,6 +608,7 @@ void NavigationHandleImpl::WillRedirectRequest( |
// Update the navigation parameters. |
url_ = new_url; |
method_ = new_method; |
+ UpdateSiteURL(); |
if (!(transition_ & ui::PAGE_TRANSITION_CLIENT_REDIRECT)) { |
sanitized_referrer_.url = new_referrer_url; |
@@ -681,6 +699,9 @@ void NavigationHandleImpl::ReadyToCommitNavigation( |
render_frame_host_ = render_frame_host; |
state_ = READY_TO_COMMIT; |
+ if (IsBrowserSideNavigationEnabled()) |
+ SetExpectedProcess(render_frame_host->GetProcess()); |
+ |
if (!IsRendererDebugURL(url_) && !IsSameDocument()) |
GetDelegate()->ReadyToCommitNavigation(this); |
} |
@@ -726,6 +747,38 @@ void NavigationHandleImpl::DidCommitNavigation( |
} |
} |
+void NavigationHandleImpl::SetExpectedProcess( |
+ RenderProcessHost* expected_process) { |
+ if (expected_process && |
+ expected_process->GetID() == expected_render_process_host_id_) { |
+ // This |expected_process| has already been informed of the navigation, |
+ // no need to update it again. |
+ return; |
+ } |
+ |
+ // If a RenderProcessHost was expecting this navigation to commit, have it |
+ // stop tracking this site. |
+ RenderProcessHost* old_process = |
+ RenderProcessHost::FromID(expected_render_process_host_id_); |
+ if (old_process) { |
+ RenderProcessHostImpl::RemoveExpectedNavigationToSite( |
+ frame_tree_node_->navigator()->GetController()->GetBrowserContext(), |
+ old_process, site_url_); |
+ } |
+ |
+ if (expected_process == nullptr) { |
+ expected_render_process_host_id_ = ChildProcessHost::kInvalidUniqueID; |
+ return; |
+ } |
+ |
+ // Keep track of the speculative RenderProcessHost and tell it to expect a |
+ // navigation to |site_url_|. |
+ expected_render_process_host_id_ = expected_process->GetID(); |
+ RenderProcessHostImpl::AddExpectedNavigationToSite( |
+ frame_tree_node_->navigator()->GetController()->GetBrowserContext(), |
+ expected_process, site_url_); |
+} |
+ |
void NavigationHandleImpl::Transfer() { |
DCHECK(!IsBrowserSideNavigationEnabled()); |
// This is an actual transfer. Inform the NavigationResourceThrottle. This |
@@ -1053,4 +1106,17 @@ bool NavigationHandleImpl::IsSelfReferentialURL() { |
return false; |
} |
+void NavigationHandleImpl::UpdateSiteURL() { |
+ GURL new_site_url = SiteInstance::GetSiteForURL( |
+ frame_tree_node_->navigator()->GetController()->GetBrowserContext(), |
+ url_); |
+ if (new_site_url == site_url_) |
+ return; |
+ |
+ // When redirecting cross-site, stop telling the speculative |
+ // RenderProcessHost to expect a navigation commit. |
+ SetExpectedProcess(nullptr); |
+ site_url_ = new_site_url; |
+} |
+ |
} // namespace content |