Chromium Code Reviews| 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..43dad2d9b6faff44873ceebc365a63af19c09a60 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), |
| + speculative_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,18 @@ NavigationHandleImpl::NavigationHandleImpl( |
| } |
| NavigationHandleImpl::~NavigationHandleImpl() { |
| + // Inform the RenderProcessHost to no longer expect a navigation. |
| + if (speculative_render_process_host_id_ != |
| + ChildProcessHost::kInvalidUniqueID) { |
| + RenderProcessHost* process = |
| + RenderProcessHost::FromID(speculative_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 +609,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 +700,9 @@ void NavigationHandleImpl::ReadyToCommitNavigation( |
| render_frame_host_ = render_frame_host; |
| state_ = READY_TO_COMMIT; |
| + if (IsBrowserSideNavigationEnabled()) |
| + SetSpeculativeProcess(render_frame_host->GetProcess()); |
| + |
| if (!IsRendererDebugURL(url_) && !IsSameDocument()) |
| GetDelegate()->ReadyToCommitNavigation(this); |
| } |
| @@ -726,6 +748,38 @@ void NavigationHandleImpl::DidCommitNavigation( |
| } |
| } |
| +void NavigationHandleImpl::SetSpeculativeProcess( |
| + RenderProcessHost* speculative_host) { |
|
Charlie Reis
2017/05/18 00:58:34
nit: speculative_process
clamy
2017/05/22 16:59:52
Done.
|
| + if (speculative_host && |
| + speculative_host->GetID() == speculative_render_process_host_id_) { |
| + // This |speculative_host| 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(speculative_render_process_host_id_); |
| + if (old_process) { |
| + RenderProcessHostImpl::RemoveExpectedNavigationToSite( |
| + frame_tree_node_->navigator()->GetController()->GetBrowserContext(), |
| + old_process, site_url_); |
| + } |
| + |
| + if (speculative_host == nullptr) { |
| + speculative_render_process_host_id_ = ChildProcessHost::kInvalidUniqueID; |
| + return; |
| + } |
| + |
| + // Keep track of the speculative RenderProcessHost and tell it to expect a |
| + // navigation to |site_url_|. |
| + speculative_render_process_host_id_ = speculative_host->GetID(); |
| + RenderProcessHostImpl::AddExpectedNavigationToSite( |
| + frame_tree_node_->navigator()->GetController()->GetBrowserContext(), |
| + speculative_host, site_url_); |
| +} |
| + |
| void NavigationHandleImpl::Transfer() { |
| DCHECK(!IsBrowserSideNavigationEnabled()); |
| // This is an actual transfer. Inform the NavigationResourceThrottle. This |
| @@ -1053,4 +1107,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. |
| + SetSpeculativeProcess(nullptr); |
| + site_url_ = new_site_url; |
| +} |
| + |
| } // namespace content |