OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |