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

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 2636193003: Fix cross-site subframe navigations that transfer back to original RFH. (Closed)
Patch Set: Fix PlzNavigate Created 3 years, 10 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/render_frame_host_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 const NavigationRequest& request) { 763 const NavigationRequest& request) {
764 CHECK(IsBrowserSideNavigationEnabled()); 764 CHECK(IsBrowserSideNavigationEnabled());
765 765
766 SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance(); 766 SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance();
767 767
768 SiteInstance* candidate_site_instance = 768 SiteInstance* candidate_site_instance =
769 speculative_render_frame_host_ 769 speculative_render_frame_host_
770 ? speculative_render_frame_host_->GetSiteInstance() 770 ? speculative_render_frame_host_->GetSiteInstance()
771 : nullptr; 771 : nullptr;
772 772
773 bool was_server_redirect = request.navigation_handle() &&
774 request.navigation_handle()->WasServerRedirect();
775
773 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation( 776 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation(
774 request.common_params().url, request.source_site_instance(), 777 request.common_params().url, request.source_site_instance(),
775 request.dest_site_instance(), candidate_site_instance, 778 request.dest_site_instance(), candidate_site_instance,
776 request.common_params().transition, 779 request.common_params().transition,
777 request.restore_type() != RestoreType::NONE, request.is_view_source()); 780 request.restore_type() != RestoreType::NONE, request.is_view_source(),
781 was_server_redirect);
778 782
779 // The appropriate RenderFrameHost to commit the navigation. 783 // The appropriate RenderFrameHost to commit the navigation.
780 RenderFrameHostImpl* navigation_rfh = nullptr; 784 RenderFrameHostImpl* navigation_rfh = nullptr;
781 785
782 bool notify_webui_of_rf_creation = false; 786 bool notify_webui_of_rf_creation = false;
783 787
784 // Reuse the current RenderFrameHost if its SiteInstance matches the 788 // Reuse the current RenderFrameHost if its SiteInstance matches the
785 // navigation's. 789 // navigation's.
786 bool no_renderer_swap = current_site_instance == dest_site_instance.get(); 790 bool no_renderer_swap = current_site_instance == dest_site_instance.get();
787 791
788 if (frame_tree_node_->IsMainFrame()) { 792 if (frame_tree_node_->IsMainFrame()) {
789 // Renderer-initiated main frame navigations that may require a 793 // Renderer-initiated main frame navigations that may require a
790 // SiteInstance swap are sent to the browser via the OpenURL IPC and are 794 // SiteInstance swap are sent to the browser via the OpenURL IPC and are
791 // afterwards treated as browser-initiated navigations. NavigationRequests 795 // afterwards treated as browser-initiated navigations. NavigationRequests
792 // marked as renderer-initiated are created by receiving a BeginNavigation 796 // marked as renderer-initiated are created by receiving a BeginNavigation
793 // IPC, and will then proceed in the same renderer. In site-per-process 797 // IPC, and will then proceed in the same renderer. In site-per-process
794 // mode, it is possible for renderer-intiated navigations to be allowed to 798 // mode, it is possible for renderer-intiated navigations to be allowed to
795 // go cross-process. Check it first. 799 // go cross-process. Check it first.
796 bool can_renderer_initiate_transfer = 800 bool can_renderer_initiate_transfer =
797 render_frame_host_->IsRenderFrameLive() && 801 render_frame_host_->IsRenderFrameLive() &&
798 ShouldMakeNetworkRequestForURL(request.common_params().url) && 802 ShouldMakeNetworkRequestForURL(request.common_params().url) &&
799 IsRendererTransferNeededForNavigation(render_frame_host_.get(), 803 IsRendererTransferNeededForNavigation(render_frame_host_.get(),
800 request.common_params().url); 804 request.common_params().url);
801 805
802 no_renderer_swap |= 806 no_renderer_swap |=
803 !request.may_transfer() && !can_renderer_initiate_transfer; 807 !request.may_transfer() && !can_renderer_initiate_transfer;
804 } else { 808 } else {
805 // Subframe navigations will use the current renderer, unless specifically 809 // Subframe navigations will use the current renderer, unless specifically
806 // allowed to swap processes. 810 // allowed to swap processes.
807 no_renderer_swap |= !CanSubframeSwapProcess(request.common_params().url, 811 no_renderer_swap |= !CanSubframeSwapProcess(
808 request.source_site_instance(), 812 request.common_params().url, request.source_site_instance(),
809 request.dest_site_instance()); 813 request.dest_site_instance(), was_server_redirect);
810 } 814 }
811 815
812 if (no_renderer_swap) { 816 if (no_renderer_swap) {
813 // GetFrameHostForNavigation will be called more than once during a 817 // GetFrameHostForNavigation will be called more than once during a
814 // navigation (currently twice, on request and when it's about to commit in 818 // navigation (currently twice, on request and when it's about to commit in
815 // the renderer). In the follow up calls an existing pending WebUI should 819 // the renderer). In the follow up calls an existing pending WebUI should
816 // not be recreated if the URL didn't change. So instead of calling 820 // not be recreated if the URL didn't change. So instead of calling
817 // CleanUpNavigation just discard the speculative RenderFrameHost if one 821 // CleanUpNavigation just discard the speculative RenderFrameHost if one
818 // exists. 822 // exists.
819 if (speculative_render_frame_host_) 823 if (speculative_render_frame_host_)
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 } 1214 }
1211 1215
1212 scoped_refptr<SiteInstance> 1216 scoped_refptr<SiteInstance>
1213 RenderFrameHostManager::GetSiteInstanceForNavigation( 1217 RenderFrameHostManager::GetSiteInstanceForNavigation(
1214 const GURL& dest_url, 1218 const GURL& dest_url,
1215 SiteInstance* source_instance, 1219 SiteInstance* source_instance,
1216 SiteInstance* dest_instance, 1220 SiteInstance* dest_instance,
1217 SiteInstance* candidate_instance, 1221 SiteInstance* candidate_instance,
1218 ui::PageTransition transition, 1222 ui::PageTransition transition,
1219 bool dest_is_restore, 1223 bool dest_is_restore,
1220 bool dest_is_view_source_mode) { 1224 bool dest_is_view_source_mode,
1225 bool was_server_redirect) {
1221 // On renderer-initiated navigations, when the frame initiating the navigation 1226 // On renderer-initiated navigations, when the frame initiating the navigation
1222 // and the frame being navigated differ, |source_instance| is set to the 1227 // and the frame being navigated differ, |source_instance| is set to the
1223 // SiteInstance of the initiating frame. |dest_instance| is present on session 1228 // SiteInstance of the initiating frame. |dest_instance| is present on session
1224 // history navigations. The two cannot be set simultaneously. 1229 // history navigations. The two cannot be set simultaneously.
1225 DCHECK(!source_instance || !dest_instance); 1230 DCHECK(!source_instance || !dest_instance);
1226 1231
1227 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1232 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
1228 1233
1229 // We do not currently swap processes for navigations in webview tag guests. 1234 // We do not currently swap processes for navigations in webview tag guests.
1230 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme)) 1235 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme))
(...skipping 19 matching lines...) Expand all
1250 current_effective_url, 1255 current_effective_url,
1251 current_is_view_source_mode, 1256 current_is_view_source_mode,
1252 dest_instance, 1257 dest_instance,
1253 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url), 1258 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url),
1254 dest_is_view_source_mode); 1259 dest_is_view_source_mode);
1255 SiteInstanceDescriptor new_instance_descriptor = 1260 SiteInstanceDescriptor new_instance_descriptor =
1256 SiteInstanceDescriptor(current_instance); 1261 SiteInstanceDescriptor(current_instance);
1257 if (ShouldTransitionCrossSite() || force_swap) { 1262 if (ShouldTransitionCrossSite() || force_swap) {
1258 new_instance_descriptor = DetermineSiteInstanceForURL( 1263 new_instance_descriptor = DetermineSiteInstanceForURL(
1259 dest_url, source_instance, current_instance, dest_instance, transition, 1264 dest_url, source_instance, current_instance, dest_instance, transition,
1260 dest_is_restore, dest_is_view_source_mode, force_swap); 1265 dest_is_restore, dest_is_view_source_mode, force_swap,
1266 was_server_redirect);
1261 } 1267 }
1262 1268
1263 scoped_refptr<SiteInstance> new_instance = 1269 scoped_refptr<SiteInstance> new_instance =
1264 ConvertToSiteInstance(new_instance_descriptor, candidate_instance); 1270 ConvertToSiteInstance(new_instance_descriptor, candidate_instance);
1265 // If |force_swap| is true, we must use a different SiteInstance than the 1271 // If |force_swap| is true, we must use a different SiteInstance than the
1266 // current one. If we didn't, we would have two RenderFrameHosts in the same 1272 // current one. If we didn't, we would have two RenderFrameHosts in the same
1267 // SiteInstance and the same frame, breaking lookup of RenderFrameHosts by 1273 // SiteInstance and the same frame, breaking lookup of RenderFrameHosts by
1268 // SiteInstance. 1274 // SiteInstance.
1269 if (force_swap) 1275 if (force_swap)
1270 CHECK_NE(new_instance, current_instance); 1276 CHECK_NE(new_instance, current_instance);
1271 1277
1272 // Double-check that the new SiteInstance is associated with the right 1278 // Double-check that the new SiteInstance is associated with the right
1273 // BrowserContext. 1279 // BrowserContext.
1274 DCHECK_EQ(new_instance->GetBrowserContext(), browser_context); 1280 DCHECK_EQ(new_instance->GetBrowserContext(), browser_context);
1275 1281
1276 return new_instance; 1282 return new_instance;
1277 } 1283 }
1278 1284
1279 RenderFrameHostManager::SiteInstanceDescriptor 1285 RenderFrameHostManager::SiteInstanceDescriptor
1280 RenderFrameHostManager::DetermineSiteInstanceForURL( 1286 RenderFrameHostManager::DetermineSiteInstanceForURL(
1281 const GURL& dest_url, 1287 const GURL& dest_url,
1282 SiteInstance* source_instance, 1288 SiteInstance* source_instance,
1283 SiteInstance* current_instance, 1289 SiteInstance* current_instance,
1284 SiteInstance* dest_instance, 1290 SiteInstance* dest_instance,
1285 ui::PageTransition transition, 1291 ui::PageTransition transition,
1286 bool dest_is_restore, 1292 bool dest_is_restore,
1287 bool dest_is_view_source_mode, 1293 bool dest_is_view_source_mode,
1288 bool force_browsing_instance_swap) { 1294 bool force_browsing_instance_swap,
1295 bool was_server_redirect) {
1289 SiteInstanceImpl* current_instance_impl = 1296 SiteInstanceImpl* current_instance_impl =
1290 static_cast<SiteInstanceImpl*>(current_instance); 1297 static_cast<SiteInstanceImpl*>(current_instance);
1291 NavigationControllerImpl& controller = 1298 NavigationControllerImpl& controller =
1292 delegate_->GetControllerForRenderManager(); 1299 delegate_->GetControllerForRenderManager();
1293 BrowserContext* browser_context = controller.GetBrowserContext(); 1300 BrowserContext* browser_context = controller.GetBrowserContext();
1294 1301
1295 // If the entry has an instance already we should use it. 1302 // If the entry has an instance already we should use it.
1296 if (dest_instance) { 1303 if (dest_instance) {
1297 // If we are forcing a swap, this should be in a different BrowsingInstance. 1304 // If we are forcing a swap, this should be in a different BrowsingInstance.
1298 if (force_browsing_instance_swap) { 1305 if (force_browsing_instance_swap) {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 if (current_entry && 1442 if (current_entry &&
1436 current_entry->IsViewSourceMode() != dest_is_view_source_mode && 1443 current_entry->IsViewSourceMode() != dest_is_view_source_mode &&
1437 !IsRendererDebugURL(dest_url)) { 1444 !IsRendererDebugURL(dest_url)) {
1438 return SiteInstanceDescriptor(browser_context, dest_url, 1445 return SiteInstanceDescriptor(browser_context, dest_url,
1439 SiteInstanceRelation::UNRELATED); 1446 SiteInstanceRelation::UNRELATED);
1440 } 1447 }
1441 1448
1442 // Use the source SiteInstance in case of data URLs, about:srcdoc pages and 1449 // Use the source SiteInstance in case of data URLs, about:srcdoc pages and
1443 // about:blank pages because the content is then controlled and/or scriptable 1450 // about:blank pages because the content is then controlled and/or scriptable
1444 // by the source SiteInstance. 1451 // by the source SiteInstance.
1452 //
1453 // One exception to this is when these URLs are
1454 // reached via a server redirect. Normally, redirects to data: or about:
1455 // URLs are disallowed as net::ERR_UNSAFE_REDIRECT, but extensions can still
1456 // redirect arbitary requests to those URLs using webRequest or
1457 // declarativeWebRequest API. For these cases, the content isn't controlled
1458 // by the source SiteInstance, so it need not use it.
1445 GURL about_blank(url::kAboutBlankURL); 1459 GURL about_blank(url::kAboutBlankURL);
1446 GURL about_srcdoc(content::kAboutSrcDocURL); 1460 GURL about_srcdoc(content::kAboutSrcDocURL);
1447 if (source_instance && (dest_url == about_srcdoc || dest_url == about_blank || 1461 bool dest_is_data_or_about = dest_url == about_srcdoc ||
1448 dest_url.scheme() == url::kDataScheme)) { 1462 dest_url == about_blank ||
1463 dest_url.scheme() == url::kDataScheme;
1464 if (source_instance && dest_is_data_or_about && !was_server_redirect)
alexmos 2017/02/14 21:16:07 Note that I fall through instead of returning a ne
Charlie Reis 2017/02/28 00:57:53 Acknowledged.
1449 return SiteInstanceDescriptor(source_instance); 1465 return SiteInstanceDescriptor(source_instance);
1450 }
1451 1466
1452 // Use the current SiteInstance for same site navigations. 1467 // Use the current SiteInstance for same site navigations.
1453 if (IsCurrentlySameSite(render_frame_host_.get(), dest_url)) 1468 if (IsCurrentlySameSite(render_frame_host_.get(), dest_url))
1454 return SiteInstanceDescriptor(render_frame_host_->GetSiteInstance()); 1469 return SiteInstanceDescriptor(render_frame_host_->GetSiteInstance());
1455 1470
1456 if (SiteIsolationPolicy::IsTopDocumentIsolationEnabled()) { 1471 if (SiteIsolationPolicy::IsTopDocumentIsolationEnabled()) {
1457 // TODO(nick): Looking at the main frame and openers is required for TDI 1472 // TODO(nick): Looking at the main frame and openers is required for TDI
1458 // mode, but should be safe to enable unconditionally. 1473 // mode, but should be safe to enable unconditionally.
1459 if (!frame_tree_node_->IsMainFrame()) { 1474 if (!frame_tree_node_->IsMainFrame()) {
1460 RenderFrameHostImpl* main_frame = 1475 RenderFrameHostImpl* main_frame =
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
2298 RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate( 2313 RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
2299 const GURL& dest_url, 2314 const GURL& dest_url,
2300 SiteInstance* source_instance, 2315 SiteInstance* source_instance,
2301 SiteInstance* dest_instance, 2316 SiteInstance* dest_instance,
2302 ui::PageTransition transition, 2317 ui::PageTransition transition,
2303 bool dest_is_restore, 2318 bool dest_is_restore,
2304 bool dest_is_view_source_mode, 2319 bool dest_is_view_source_mode,
2305 const GlobalRequestID& transferred_request_id, 2320 const GlobalRequestID& transferred_request_id,
2306 int bindings, 2321 int bindings,
2307 bool is_reload) { 2322 bool is_reload) {
2308 if (!frame_tree_node_->IsMainFrame() &&
2309 !CanSubframeSwapProcess(dest_url, source_instance, dest_instance)) {
2310 // Note: Do not add code here to determine whether the subframe should swap
2311 // or not. Add it to CanSubframeSwapProcess instead.
2312 return render_frame_host_.get();
2313 }
2314
2315 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 2323 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
2324 bool was_server_redirect = transfer_navigation_handle_ &&
2325 transfer_navigation_handle_->WasServerRedirect();
2316 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( 2326 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
2317 dest_url, source_instance, dest_instance, nullptr, transition, 2327 dest_url, source_instance, dest_instance, nullptr, transition,
2318 dest_is_restore, dest_is_view_source_mode); 2328 dest_is_restore, dest_is_view_source_mode, was_server_redirect);
2319 2329
2320 // Inform the transferring NavigationHandle of a transfer to a different 2330 // Inform the transferring NavigationHandle of a transfer to a different
2321 // SiteInstance. It is important do so now, in order to mark the request as 2331 // SiteInstance. It is important do so now, in order to mark the request as
2322 // transferring on the IO thread before attempting to destroy the pending RFH. 2332 // transferring on the IO thread before attempting to destroy the pending RFH.
2323 // This ensures the network request will not be destroyed along the pending 2333 // This ensures the network request will not be destroyed along the pending
2324 // RFH but will persist until it is picked up by the new RFH. 2334 // RFH but will persist until it is picked up by the new RFH.
2325 if (transfer_navigation_handle_.get() && 2335 if (transfer_navigation_handle_.get() &&
2326 transfer_navigation_handle_->GetGlobalRequestID() == 2336 transfer_navigation_handle_->GetGlobalRequestID() ==
2327 transferred_request_id && 2337 transferred_request_id &&
2328 new_instance.get() != 2338 new_instance.get() !=
2329 transfer_navigation_handle_->GetRenderFrameHost() 2339 transfer_navigation_handle_->GetRenderFrameHost()
2330 ->GetSiteInstance()) { 2340 ->GetSiteInstance()) {
2331 transfer_navigation_handle_->Transfer(); 2341 transfer_navigation_handle_->Transfer();
2332 } 2342 }
2333 2343
2334 // If we are currently navigating cross-process to a pending RFH for a 2344 // If we are currently navigating cross-process to a pending RFH for a
2335 // different SiteInstance, we want to get back to normal and then navigate as 2345 // different SiteInstance, we want to get back to normal and then navigate as
2336 // usual. We will reuse the pending RFH below if it matches the destination 2346 // usual. We will reuse the pending RFH below if it matches the destination
2337 // SiteInstance. 2347 // SiteInstance.
2338 if (pending_render_frame_host_) { 2348 if (pending_render_frame_host_) {
2339 if (pending_render_frame_host_->GetSiteInstance() != new_instance) { 2349 if (pending_render_frame_host_->GetSiteInstance() != new_instance) {
2340 CancelPending(); 2350 CancelPending();
2341 } else { 2351 } else {
2342 // When a pending RFH is reused, it should always be live, since it is 2352 // When a pending RFH is reused, it should always be live, since it is
2343 // cleared whenever a process dies. 2353 // cleared whenever a process dies.
2344 CHECK(pending_render_frame_host_->IsRenderFrameLive()); 2354 CHECK(pending_render_frame_host_->IsRenderFrameLive());
2345 } 2355 }
2346 } 2356 }
2347 2357
2348 if (new_instance.get() != current_instance) { 2358 // Note: Do not add code here to determine whether the subframe should swap
2359 // or not. Add it to CanSubframeSwapProcess instead.
2360 bool allowed_to_swap_process =
2361 frame_tree_node_->IsMainFrame() ||
2362 CanSubframeSwapProcess(dest_url, source_instance, dest_instance,
2363 was_server_redirect);
2364
2365 if (new_instance.get() != current_instance && allowed_to_swap_process) {
2349 TRACE_EVENT_INSTANT2( 2366 TRACE_EVENT_INSTANT2(
2350 "navigation", 2367 "navigation",
2351 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 2368 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
2352 TRACE_EVENT_SCOPE_THREAD, 2369 TRACE_EVENT_SCOPE_THREAD,
2353 "current_instance id", current_instance->GetId(), 2370 "current_instance id", current_instance->GetId(),
2354 "new_instance id", new_instance->GetId()); 2371 "new_instance id", new_instance->GetId());
2355 2372
2356 // New SiteInstance: create a pending RFH to navigate. 2373 // New SiteInstance: create a pending RFH to navigate.
2357 2374
2358 if (!pending_render_frame_host_) 2375 if (!pending_render_frame_host_)
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
2741 msg->set_routing_id(render_frame_host_->GetRoutingID()); 2758 msg->set_routing_id(render_frame_host_->GetRoutingID());
2742 render_frame_host_->Send(msg); 2759 render_frame_host_->Send(msg);
2743 } else { 2760 } else {
2744 delete msg; 2761 delete msg;
2745 } 2762 }
2746 } 2763 }
2747 2764
2748 bool RenderFrameHostManager::CanSubframeSwapProcess( 2765 bool RenderFrameHostManager::CanSubframeSwapProcess(
2749 const GURL& dest_url, 2766 const GURL& dest_url,
2750 SiteInstance* source_instance, 2767 SiteInstance* source_instance,
2751 SiteInstance* dest_instance) { 2768 SiteInstance* dest_instance,
2769 bool was_server_redirect) {
2752 // On renderer-initiated navigations, when the frame initiating the navigation 2770 // On renderer-initiated navigations, when the frame initiating the navigation
2753 // and the frame being navigated differ, |source_instance| is set to the 2771 // and the frame being navigated differ, |source_instance| is set to the
2754 // SiteInstance of the initiating frame. |dest_instance| is present on session 2772 // SiteInstance of the initiating frame. |dest_instance| is present on session
2755 // history navigations. The two cannot be set simultaneously. 2773 // history navigations. The two cannot be set simultaneously.
2756 DCHECK(!source_instance || !dest_instance); 2774 DCHECK(!source_instance || !dest_instance);
2757 2775
2758 // Don't swap for subframes unless we are in an OOPIF-enabled mode. We can 2776 // Don't swap for subframes unless we are in an OOPIF-enabled mode. We can
2759 // get here in tests for subframes (e.g., NavigateFrameToURL). 2777 // get here in tests for subframes (e.g., NavigateFrameToURL).
2760 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) 2778 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
2761 return false; 2779 return false;
2762 2780
2763 // If dest_url is a unique origin like about:blank, then the need for a swap 2781 // If dest_url is a unique origin like about:blank, then the need for a swap
2764 // is determined by the source_instance or dest_instance. 2782 // is determined by the source_instance or dest_instance.
2765 GURL resolved_url = dest_url; 2783 GURL resolved_url = dest_url;
2766 if (url::Origin(resolved_url).unique()) { 2784 if (url::Origin(resolved_url).unique()) {
2767 if (source_instance) { 2785 if (source_instance) {
2768 resolved_url = source_instance->GetSiteURL(); 2786 resolved_url = source_instance->GetSiteURL();
2769 } else if (dest_instance) { 2787 } else if (dest_instance) {
2770 resolved_url = dest_instance->GetSiteURL(); 2788 resolved_url = dest_instance->GetSiteURL();
2771 } else { 2789 } else {
2772 // If there is no SiteInstance this unique origin can be associated with, 2790 // If there is no SiteInstance this unique origin can be associated with,
2773 // then we should avoid a process swap. 2791 // there are two cases:
2774 return false; 2792 // (1) If there was a server redirect, allow a process swap. Normally,
2793 // redirects to data: or about: URLs are disallowed as
2794 // net::ERR_UNSAFE_REDIRECT. However, extensions can still redirect
2795 // arbitary requests to those URLs using the chrome.webRequest or
2796 // chrome.declarativeWebRequest API, which will end up here (for an
2797 // example, see ExtensionWebRequestApiTest.WebRequestDeclarative1). It's
2798 // safest to swap processes for those redirects if we are in an
2799 // appropriate OOPIF-enabled mode.
2800 //
2801 // (2) Otherwise, avoid a process swap. We can get here during session
2802 // restore, and this avoids putting all data: and about:blank subframes
2803 // in OOPIFs. We can also get here in tests with browser-initiated
2804 // subframe navigations (NavigateFrameToURL).
2805 if (!was_server_redirect)
2806 return false;
2775 } 2807 }
2776 } 2808 }
2777 2809
2778 // If we are in an OOPIF mode that only applies to some sites, only swap if 2810 // If we are in an OOPIF mode that only applies to some sites, only swap if
2779 // the policy determines that a transfer would have been needed. We can get 2811 // the policy determines that a transfer would have been needed. We can get
2780 // here for session restore. 2812 // here for session restore.
2781 if (!IsRendererTransferNeededForNavigation(render_frame_host_.get(), 2813 if (!IsRendererTransferNeededForNavigation(render_frame_host_.get(),
2782 resolved_url)) { 2814 resolved_url)) {
2783 DCHECK(!dest_instance || 2815 DCHECK(!dest_instance ||
2784 dest_instance == render_frame_host_->GetSiteInstance()); 2816 dest_instance == render_frame_host_->GetSiteInstance());
2785 return false; 2817 return false;
2786 } 2818 }
2787 2819
2788 return true; 2820 return true;
2789 } 2821 }
2790 2822
2791 } // namespace content 2823 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_manager.h ('k') | content/browser/site_per_process_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698