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

Side by Side Diff: content/browser/loader/cross_site_resource_handler.cc

Issue 1208143002: Move existing kSitePerProcess checks to a policy-oracle object (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@swapped_out_cmdline_checks
Patch Set: rparen Created 5 years, 5 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/loader/cross_site_resource_handler.h" 5 #include "content/browser/loader/cross_site_resource_handler.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "content/browser/appcache/appcache_interceptor.h" 12 #include "content/browser/appcache/appcache_interceptor.h"
13 #include "content/browser/child_process_security_policy_impl.h" 13 #include "content/browser/child_process_security_policy_impl.h"
14 #include "content/browser/frame_host/cross_site_transferring_request.h" 14 #include "content/browser/frame_host/cross_site_transferring_request.h"
15 #include "content/browser/frame_host/render_frame_host_impl.h" 15 #include "content/browser/frame_host/render_frame_host_impl.h"
16 #include "content/browser/loader/resource_dispatcher_host_impl.h" 16 #include "content/browser/loader/resource_dispatcher_host_impl.h"
17 #include "content/browser/loader/resource_request_info_impl.h" 17 #include "content/browser/loader/resource_request_info_impl.h"
18 #include "content/browser/site_instance_impl.h" 18 #include "content/browser/site_instance_impl.h"
19 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/content_browser_client.h" 20 #include "content/public/browser/content_browser_client.h"
21 #include "content/public/browser/global_request_id.h" 21 #include "content/public/browser/global_request_id.h"
22 #include "content/public/browser/resource_controller.h" 22 #include "content/public/browser/resource_controller.h"
23 #include "content/public/browser/site_instance.h" 23 #include "content/public/browser/site_instance.h"
24 #include "content/public/common/content_switches.h" 24 #include "content/public/common/content_switches.h"
25 #include "content/public/common/resource_response.h" 25 #include "content/public/common/resource_response.h"
26 #include "content/public/common/site_isolation_policy.h"
26 #include "content/public/common/url_constants.h" 27 #include "content/public/common/url_constants.h"
27 #include "net/http/http_response_headers.h" 28 #include "net/http/http_response_headers.h"
28 #include "net/url_request/url_request.h" 29 #include "net/url_request/url_request.h"
29 30
30 namespace content { 31 namespace content {
31 32
32 namespace { 33 namespace {
33 34
34 bool leak_requests_for_testing_ = false; 35 bool leak_requests_for_testing_ = false;
35 36
(...skipping 28 matching lines...) Expand all
64 new CrossSiteTransferringRequest(params.global_request_id)); 65 new CrossSiteTransferringRequest(params.global_request_id));
65 66
66 RenderFrameHostImpl* rfh = 67 RenderFrameHostImpl* rfh =
67 RenderFrameHostImpl::FromID(params.global_request_id.child_id, 68 RenderFrameHostImpl::FromID(params.global_request_id.child_id,
68 params.render_frame_id); 69 params.render_frame_id);
69 if (rfh) { 70 if (rfh) {
70 if (rfh->GetParent()) { 71 if (rfh->GetParent()) {
71 // We should only swap processes for subframes in --site-per-process mode. 72 // We should only swap processes for subframes in --site-per-process mode.
72 // CrossSiteResourceHandler is not installed on subframe requests in 73 // CrossSiteResourceHandler is not installed on subframe requests in
73 // default Chrome. 74 // default Chrome.
74 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 75 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
75 switches::kSitePerProcess));
76 } 76 }
77 rfh->OnCrossSiteResponse( 77 rfh->OnCrossSiteResponse(
78 params.global_request_id, cross_site_transferring_request.Pass(), 78 params.global_request_id, cross_site_transferring_request.Pass(),
79 params.transfer_url_chain, params.referrer, 79 params.transfer_url_chain, params.referrer,
80 params.page_transition, params.should_replace_current_entry); 80 params.page_transition, params.should_replace_current_entry);
81 } else if (leak_requests_for_testing_ && cross_site_transferring_request) { 81 } else if (leak_requests_for_testing_ && cross_site_transferring_request) {
82 // Some unit tests expect requests to be leaked in this case, so they can 82 // Some unit tests expect requests to be leaked in this case, so they can
83 // pass them along manually. 83 // pass them along manually.
84 cross_site_transferring_request->ReleaseRequest(); 84 cross_site_transferring_request->ReleaseRequest();
85 } 85 }
86 } 86 }
87 87
88 // Returns whether a transfer is needed by doing a check on the UI thread. 88 // Returns whether a transfer is needed by doing a check on the UI thread.
89 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) { 89 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) {
90 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 90 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
91 switches::kSitePerProcess));
92 RenderFrameHostImpl* rfh = 91 RenderFrameHostImpl* rfh =
93 RenderFrameHostImpl::FromID(process_id, render_frame_id); 92 RenderFrameHostImpl::FromID(process_id, render_frame_id);
94 if (!rfh) 93 if (!rfh)
95 return false; 94 return false;
96 95
97 // A transfer is not needed if the current SiteInstance doesn't yet have a 96 // A transfer is not needed if the current SiteInstance doesn't yet have a
98 // site. This is the case for tests that use NavigateToURL. 97 // site. This is the case for tests that use NavigateToURL.
99 if (!rfh->GetSiteInstance()->HasSite()) 98 if (!rfh->GetSiteInstance()->HasSite())
100 return false; 99 return false;
101 100
102 // TODO(nasko): This check is very simplistic and is used temporarily only 101 // TODO(nasko, nick): These following --site-per-process checks are
103 // for --site-per-process. It should be updated to match the check performed 102 // overly simplistic. Update them to match all the cases
104 // by RenderFrameHostManager::UpdateStateForNavigate. 103 // considered by RenderFrameHostManager::UpdateStateForNavigate.
nasko 2015/07/08 12:52:23 We should update this comment to point to RenderFr
ncarter (slow) 2015/07/10 23:29:18 Done.
105 return !SiteInstance::IsSameWebSite( 104 if (SiteInstance::IsSameWebSite(rfh->GetSiteInstance()->GetBrowserContext(),
106 rfh->GetSiteInstance()->GetBrowserContext(), 105 rfh->GetSiteInstance()->GetSiteURL(), url)) {
107 rfh->GetSiteInstance()->GetSiteURL(), url); 106 return false; // The same site, no transition needed.
107 }
108
109 // The sites differ. If either one requires a dedicated process,
110 // then a transfer is needed.
111 return rfh->GetSiteInstance()->RequiresDedicatedProcess() ||
112 SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(url);
108 } 113 }
109 114
110 } // namespace 115 } // namespace
111 116
112 CrossSiteResourceHandler::CrossSiteResourceHandler( 117 CrossSiteResourceHandler::CrossSiteResourceHandler(
113 scoped_ptr<ResourceHandler> next_handler, 118 scoped_ptr<ResourceHandler> next_handler,
114 net::URLRequest* request) 119 net::URLRequest* request)
115 : LayeredResourceHandler(request, next_handler.Pass()), 120 : LayeredResourceHandler(request, next_handler.Pass()),
116 has_started_response_(false), 121 has_started_response_(false),
117 in_cross_site_transition_(false), 122 in_cross_site_transition_(false),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 // renderer: it is not a download, and it has passed the SSL and safe 160 // renderer: it is not a download, and it has passed the SSL and safe
156 // browsing checks. 161 // browsing checks.
157 // We should not have already started the transition before now. 162 // We should not have already started the transition before now.
158 DCHECK(!in_cross_site_transition_); 163 DCHECK(!in_cross_site_transition_);
159 164
160 ResourceRequestInfoImpl* info = GetRequestInfo(); 165 ResourceRequestInfoImpl* info = GetRequestInfo();
161 166
162 // We only need to pause the response if a transfer to a different process is 167 // We only need to pause the response if a transfer to a different process is
163 // required. Other cross-process navigations can proceed immediately, since 168 // required. Other cross-process navigations can proceed immediately, since
164 // we run the unload handler at commit time. 169 // we run the unload handler at commit time.
170 // TODO(nick): What does "other cross-process navigations" mean in the
nasko 2015/07/08 12:52:23 There are two types of cross-process navigations:
ncarter (slow) 2015/07/10 23:29:18 Done.
171 // above language. Is that a typo?
165 // Note that a process swap may no longer be necessary if we transferred back 172 // Note that a process swap may no longer be necessary if we transferred back
166 // into the original process due to a redirect. 173 // into the original process due to a redirect.
167 bool should_transfer = 174 bool embedder_requests_transfer =
nasko 2015/07/08 12:52:23 What is "embedder" in this context?
ncarter (slow) 2015/07/10 23:29:18 I meant the content embedder (GetContentClient()).
168 GetContentClient()->browser()->ShouldSwapProcessesForRedirect( 175 GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
169 info->GetContext(), request()->original_url(), request()->url()); 176 info->GetContext(), request()->original_url(), request()->url());
170 177
171 // If this is a download, just pass the response through without doing a 178 // If this is a download, just pass the response through without doing a
172 // cross-site check. The renderer will see it is a download and abort the 179 // cross-site check. The renderer will see it is a download and abort the
173 // request. 180 // request.
174 // 181 //
175 // Similarly, HTTP 204 (No Content) responses leave us showing the previous 182 // Similarly, HTTP 204 (No Content) responses leave us showing the previous
176 // page. We should allow the navigation to finish without running the unload 183 // page. We should allow the navigation to finish without running the unload
177 // handler or swapping in the pending RenderFrameHost. 184 // handler or swapping in the pending RenderFrameHost.
178 // 185 //
179 // In both cases, any pending RenderFrameHost (if one was created for this 186 // In both cases, any pending RenderFrameHost (if one was created for this
180 // navigation) will stick around until the next cross-site navigation, since 187 // navigation) will stick around until the next cross-site navigation, since
181 // we are unable to tell when to destroy it. 188 // we are unable to tell when to destroy it.
182 // See RenderFrameHostManager::RendererAbortedProvisionalLoad. 189 // See RenderFrameHostManager::RendererAbortedProvisionalLoad.
183 // 190 //
184 // TODO(davidben): Unify IsDownload() and is_stream(). Several places need to 191 // TODO(davidben): Unify IsDownload() and is_stream(). Several places need to
185 // check for both and remembering about streams is error-prone. 192 // check for both and remembering about streams is error-prone.
186 if (info->IsDownload() || info->is_stream() || 193 if (info->IsDownload() || info->is_stream() ||
187 (response->head.headers.get() && 194 (response->head.headers.get() &&
188 response->head.headers->response_code() == 204)) { 195 response->head.headers->response_code() == 204)) {
189 return next_handler_->OnResponseStarted(response, defer); 196 return next_handler_->OnResponseStarted(response, defer);
190 } 197 }
191 198
192 // When the --site-per-process flag is passed, we transfer processes for 199 if (embedder_requests_transfer) {
193 // cross-site navigations. This is skipped if a transfer is already required 200 // Now that we know a transfer is needed and we have something to commit, we
194 // or for WebUI processes for now, since pages like the NTP host multiple 201 // pause to let the UI thread set up the transfer.
195 // cross-site WebUI iframes. 202 StartCrossSiteTransition(response);
196 if (!should_transfer && 203
197 base::CommandLine::ForCurrentProcess()->HasSwitch( 204 // Defer loading until after the new renderer process has issued a
198 switches::kSitePerProcess) && 205 // corresponding request.
206 *defer = true;
207 OnDidDefer();
208 return true;
209 }
210
211 // Under the --site-per-process flag, we'll need to consult the policy to
212 // determine whether to transfer processes. Process transfers are skipped for
213 // WebUI processes for now, since pages like the NTP host multiple cross-site
214 // WebUI iframes.
215 if (SiteIsolationPolicy::AreCrossProcessFramesPossible() &&
199 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 216 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
200 info->GetChildID())) { 217 info->GetChildID())) {
201 return DeferForNavigationPolicyCheck(info, response, defer); 218 return DeferForNavigationPolicyCheck(info, response, defer);
202 } 219 }
203 220
204 if (!should_transfer) 221 // No process transfer needed. Pass the response through.
205 return next_handler_->OnResponseStarted(response, defer); 222 return next_handler_->OnResponseStarted(response, defer);
206
207 // Now that we know a transfer is needed and we have something to commit, we
208 // pause to let the UI thread set up the transfer.
209 StartCrossSiteTransition(response);
210
211 // Defer loading until after the new renderer process has issued a
212 // corresponding request.
213 *defer = true;
214 OnDidDefer();
215 return true;
216 } 223 }
217 224
218 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { 225 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) {
219 if (is_transfer) { 226 if (is_transfer) {
220 StartCrossSiteTransition(response_.get()); 227 StartCrossSiteTransition(response_.get());
221 } else { 228 } else {
222 ResumeResponse(); 229 ResumeResponse();
223 } 230 }
224 } 231 }
225 232
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 controller()->Resume(); 379 controller()->Resume();
373 } 380 }
374 } 381 }
375 382
376 void CrossSiteResourceHandler::OnDidDefer() { 383 void CrossSiteResourceHandler::OnDidDefer() {
377 did_defer_ = true; 384 did_defer_ = true;
378 request()->LogBlockedBy("CrossSiteResourceHandler"); 385 request()->LogBlockedBy("CrossSiteResourceHandler");
379 } 386 }
380 387
381 } // namespace content 388 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698