Index: content/browser/loader/cross_site_resource_handler.cc |
diff --git a/content/browser/loader/cross_site_resource_handler.cc b/content/browser/loader/cross_site_resource_handler.cc |
index 7ffb659744a03ca22070a0c390e2fb18d7b86367..b05ac5d8e4f13255d7839e98d88f8312a9af8dd1 100644 |
--- a/content/browser/loader/cross_site_resource_handler.cc |
+++ b/content/browser/loader/cross_site_resource_handler.cc |
@@ -86,16 +86,18 @@ void OnCrossSiteResponseHelper(const CrossSiteResponseParams& params) { |
} |
} |
-// Returns whether a transfer is needed by doing a check on the UI thread. |
-bool CheckNavigationPolicyOnUI(GURL real_url, |
- int process_id, |
- int render_frame_id) { |
- CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible()); |
- RenderFrameHostImpl* rfh = |
- RenderFrameHostImpl::FromID(process_id, render_frame_id); |
- if (!rfh) |
- return false; |
- |
+// Determines whether a navigation to |dest_url| may be completed using an |
+// existing RenderFrameHost, or whether transferring to a new RenderFrameHost |
+// backed by a different render process is required. This is a security policy |
+// check determined by the current site isolation mode, and must be done |
+// before the resource at |dest_url| is delivered to |rfh|. |
+// |
+// When this function returns true for a subframe, an out-of-process iframe |
+// must be created. |
+// |
+// TODO(nick): Move this function to RFHM. |
+bool IsRendererTransferNeededForNavigation(RenderFrameHostImpl* rfh, |
+ const GURL& dest_url) { |
// A transfer is not needed if the current SiteInstance doesn't yet have a |
// site. This is the case for tests that use NavigateToURL. |
if (!rfh->GetSiteInstance()->HasSite()) |
@@ -108,14 +110,14 @@ bool CheckNavigationPolicyOnUI(GURL real_url, |
return false; |
GURL effective_url = SiteInstanceImpl::GetEffectiveURL( |
- rfh->GetSiteInstance()->GetBrowserContext(), real_url); |
+ rfh->GetSiteInstance()->GetBrowserContext(), dest_url); |
// TODO(nasko, nick): These following --site-per-process checks are |
// overly simplistic. Update them to match all the cases |
// considered by RenderFrameHostManager::DetermineSiteInstanceForURL. |
if (SiteInstance::IsSameWebSite(rfh->GetSiteInstance()->GetBrowserContext(), |
rfh->GetSiteInstance()->GetSiteURL(), |
- real_url)) { |
+ dest_url)) { |
return false; // The same site, no transition needed. |
} |
@@ -125,6 +127,25 @@ bool CheckNavigationPolicyOnUI(GURL real_url, |
SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(effective_url); |
} |
+// Returns whether a transfer is needed by doing a check on the UI thread. |
+CrossSiteResourceHandler::NavigationDecision |
+CheckNavigationPolicyOnUI(GURL real_url, int process_id, int render_frame_id) { |
+ CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible()); |
+ RenderFrameHostImpl* rfh = |
+ RenderFrameHostImpl::FromID(process_id, render_frame_id); |
+ |
+ // Without a valid RFH against which to check, we must cancel the request, |
+ // to prevent the resource at |url| from being delivered to a potentially |
+ // unsuitable renderer process. |
+ if (!rfh) |
+ return CrossSiteResourceHandler::NavigationDecision::CANCEL_REQUEST; |
+ |
+ if (IsRendererTransferNeededForNavigation(rfh, real_url)) |
+ return CrossSiteResourceHandler::NavigationDecision::TRANSFER_REQUIRED; |
+ else |
+ return CrossSiteResourceHandler::NavigationDecision::USE_EXISTING_RENDERER; |
+} |
+ |
} // namespace |
CrossSiteResourceHandler::CrossSiteResourceHandler( |
@@ -236,11 +257,18 @@ bool CrossSiteResourceHandler::OnNormalResponseStarted( |
return next_handler_->OnResponseStarted(response, defer); |
} |
-void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { |
- if (is_transfer) { |
- StartCrossSiteTransition(response_.get()); |
- } else { |
- ResumeResponse(); |
+void CrossSiteResourceHandler::ResumeOrTransfer(NavigationDecision decision) { |
+ switch (decision) { |
+ case NavigationDecision::CANCEL_REQUEST: |
+ // TODO(nick): What kind of cleanup do we need here? |
+ controller()->Cancel(); |
+ break; |
+ case NavigationDecision::USE_EXISTING_RENDERER: |
+ ResumeResponse(); |
+ break; |
+ case NavigationDecision::TRANSFER_REQUIRED: |
+ StartCrossSiteTransition(response_.get()); |
+ break; |
} |
} |