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

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: Attempt to fix compile. Created 5 years, 4 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/browser/web_contents/web_contents_impl.h" 19 #include "content/browser/web_contents/web_contents_impl.h"
20 #include "content/common/site_isolation_policy.h"
20 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/content_browser_client.h" 22 #include "content/public/browser/content_browser_client.h"
22 #include "content/public/browser/global_request_id.h" 23 #include "content/public/browser/global_request_id.h"
23 #include "content/public/browser/resource_controller.h" 24 #include "content/public/browser/resource_controller.h"
24 #include "content/public/browser/site_instance.h" 25 #include "content/public/browser/site_instance.h"
25 #include "content/public/common/content_switches.h" 26 #include "content/public/common/content_switches.h"
26 #include "content/public/common/resource_response.h" 27 #include "content/public/common/resource_response.h"
27 #include "content/public/common/url_constants.h" 28 #include "content/public/common/url_constants.h"
28 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
29 #include "net/url_request/url_request.h" 30 #include "net/url_request/url_request.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 new CrossSiteTransferringRequest(params.global_request_id)); 66 new CrossSiteTransferringRequest(params.global_request_id));
66 67
67 RenderFrameHostImpl* rfh = 68 RenderFrameHostImpl* rfh =
68 RenderFrameHostImpl::FromID(params.global_request_id.child_id, 69 RenderFrameHostImpl::FromID(params.global_request_id.child_id,
69 params.render_frame_id); 70 params.render_frame_id);
70 if (rfh) { 71 if (rfh) {
71 if (rfh->GetParent()) { 72 if (rfh->GetParent()) {
72 // We should only swap processes for subframes in --site-per-process mode. 73 // We should only swap processes for subframes in --site-per-process mode.
73 // CrossSiteResourceHandler is not installed on subframe requests in 74 // CrossSiteResourceHandler is not installed on subframe requests in
74 // default Chrome. 75 // default Chrome.
75 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 76 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
76 switches::kSitePerProcess));
77 } 77 }
78 rfh->OnCrossSiteResponse( 78 rfh->OnCrossSiteResponse(
79 params.global_request_id, cross_site_transferring_request.Pass(), 79 params.global_request_id, cross_site_transferring_request.Pass(),
80 params.transfer_url_chain, params.referrer, 80 params.transfer_url_chain, params.referrer,
81 params.page_transition, params.should_replace_current_entry); 81 params.page_transition, params.should_replace_current_entry);
82 } else if (leak_requests_for_testing_ && cross_site_transferring_request) { 82 } else if (leak_requests_for_testing_ && cross_site_transferring_request) {
83 // Some unit tests expect requests to be leaked in this case, so they can 83 // Some unit tests expect requests to be leaked in this case, so they can
84 // pass them along manually. 84 // pass them along manually.
85 cross_site_transferring_request->ReleaseRequest(); 85 cross_site_transferring_request->ReleaseRequest();
86 } 86 }
87 } 87 }
88 88
89 // Returns whether a transfer is needed by doing a check on the UI thread. 89 // Returns whether a transfer is needed by doing a check on the UI thread.
90 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) { 90 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) {
91 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 91 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
92 switches::kSitePerProcess));
93 RenderFrameHostImpl* rfh = 92 RenderFrameHostImpl* rfh =
94 RenderFrameHostImpl::FromID(process_id, render_frame_id); 93 RenderFrameHostImpl::FromID(process_id, render_frame_id);
95 if (!rfh) 94 if (!rfh)
96 return false; 95 return false;
97 96
98 // A transfer is not needed if the current SiteInstance doesn't yet have a 97 // A transfer is not needed if the current SiteInstance doesn't yet have a
99 // site. This is the case for tests that use NavigateToURL. 98 // site. This is the case for tests that use NavigateToURL.
100 if (!rfh->GetSiteInstance()->HasSite()) 99 if (!rfh->GetSiteInstance()->HasSite())
101 return false; 100 return false;
102 101
103 // For now, GuestViews never transfer on cross-site navigations. 102 // For now, GuestViews never transfer on cross-site navigations.
104 WebContentsImpl* web_contents = 103 WebContentsImpl* web_contents =
105 static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(rfh)); 104 static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(rfh));
106 if (web_contents->GetBrowserPluginGuest()) 105 if (web_contents->GetBrowserPluginGuest())
107 return false; 106 return false;
108 107
109 // TODO(nasko): This check is very simplistic and is used temporarily only 108 // TODO(nasko, nick): These following --site-per-process checks are
110 // for --site-per-process. It should be updated to match the check performed 109 // overly simplistic. Update them to match all the cases
111 // by RenderFrameHostManager::UpdateStateForNavigate. 110 // considered by RenderFrameHostManager::DetermineSiteInstanceForURL.
112 return !SiteInstance::IsSameWebSite( 111 if (SiteInstance::IsSameWebSite(rfh->GetSiteInstance()->GetBrowserContext(),
113 rfh->GetSiteInstance()->GetBrowserContext(), 112 rfh->GetSiteInstance()->GetSiteURL(), url)) {
114 rfh->GetSiteInstance()->GetSiteURL(), url); 113 return false; // The same site, no transition needed.
114 }
115
116 // The sites differ. If either one requires a dedicated process,
117 // then a transfer is needed.
118 return rfh->GetSiteInstance()->RequiresDedicatedProcess() ||
119 SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(url);
115 } 120 }
116 121
117 } // namespace 122 } // namespace
118 123
119 CrossSiteResourceHandler::CrossSiteResourceHandler( 124 CrossSiteResourceHandler::CrossSiteResourceHandler(
120 scoped_ptr<ResourceHandler> next_handler, 125 scoped_ptr<ResourceHandler> next_handler,
121 net::URLRequest* request) 126 net::URLRequest* request)
122 : LayeredResourceHandler(request, next_handler.Pass()), 127 : LayeredResourceHandler(request, next_handler.Pass()),
123 has_started_response_(false), 128 has_started_response_(false),
124 in_cross_site_transition_(false), 129 in_cross_site_transition_(false),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 ResourceResponse* response, 164 ResourceResponse* response,
160 bool* defer) { 165 bool* defer) {
161 // At this point, we know that the response is safe to send back to the 166 // At this point, we know that the response is safe to send back to the
162 // renderer: it is not a download, and it has passed the SSL and safe 167 // renderer: it is not a download, and it has passed the SSL and safe
163 // browsing checks. 168 // browsing checks.
164 // We should not have already started the transition before now. 169 // We should not have already started the transition before now.
165 DCHECK(!in_cross_site_transition_); 170 DCHECK(!in_cross_site_transition_);
166 171
167 ResourceRequestInfoImpl* info = GetRequestInfo(); 172 ResourceRequestInfoImpl* info = GetRequestInfo();
168 173
169 // We only need to pause the response if a transfer to a different process is 174 // The content embedder can decide that a transfer to a different process is
170 // required. Other cross-process navigations can proceed immediately, since 175 // required for this URL. If so, pause the response now. Other cross process
171 // we run the unload handler at commit time. 176 // navigations can proceed immediately, since we run the unload handler at
172 // Note that a process swap may no longer be necessary if we transferred back 177 // commit time. Note that a process swap may no longer be necessary if we
173 // into the original process due to a redirect. 178 // transferred back into the original process due to a redirect.
174 bool should_transfer = 179 bool definitely_transfer =
175 GetContentClient()->browser()->ShouldSwapProcessesForRedirect( 180 GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
176 info->GetContext(), request()->original_url(), request()->url()); 181 info->GetContext(), request()->original_url(), request()->url());
177 182
178 // If this is a download, just pass the response through without doing a 183 // If this is a download, just pass the response through without doing a
179 // cross-site check. The renderer will see it is a download and abort the 184 // cross-site check. The renderer will see it is a download and abort the
180 // request. 185 // request.
181 // 186 //
182 // Similarly, HTTP 204 (No Content) responses leave us showing the previous 187 // Similarly, HTTP 204 (No Content) responses leave us showing the previous
183 // page. We should allow the navigation to finish without running the unload 188 // page. We should allow the navigation to finish without running the unload
184 // handler or swapping in the pending RenderFrameHost. 189 // handler or swapping in the pending RenderFrameHost.
185 // 190 //
186 // In both cases, any pending RenderFrameHost (if one was created for this 191 // In both cases, any pending RenderFrameHost (if one was created for this
187 // navigation) will stick around until the next cross-site navigation, since 192 // navigation) will stick around until the next cross-site navigation, since
188 // we are unable to tell when to destroy it. 193 // we are unable to tell when to destroy it.
189 // See RenderFrameHostManager::RendererAbortedProvisionalLoad. 194 // See RenderFrameHostManager::RendererAbortedProvisionalLoad.
190 // 195 //
191 // TODO(davidben): Unify IsDownload() and is_stream(). Several places need to 196 // TODO(davidben): Unify IsDownload() and is_stream(). Several places need to
192 // check for both and remembering about streams is error-prone. 197 // check for both and remembering about streams is error-prone.
193 if (info->IsDownload() || info->is_stream() || 198 if (info->IsDownload() || info->is_stream() ||
194 (response->head.headers.get() && 199 (response->head.headers.get() &&
195 response->head.headers->response_code() == 204)) { 200 response->head.headers->response_code() == 204)) {
196 return next_handler_->OnResponseStarted(response, defer); 201 return next_handler_->OnResponseStarted(response, defer);
197 } 202 }
198 203
199 // When the --site-per-process flag is passed, we transfer processes for 204 if (definitely_transfer) {
200 // cross-site navigations. This is skipped if a transfer is already required 205 // Now that we know a transfer is needed and we have something to commit, we
201 // or for WebUI processes for now, since pages like the NTP host multiple 206 // pause to let the UI thread set up the transfer.
202 // cross-site WebUI iframes. 207 StartCrossSiteTransition(response);
203 if (!should_transfer && 208
204 base::CommandLine::ForCurrentProcess()->HasSwitch( 209 // Defer loading until after the new renderer process has issued a
205 switches::kSitePerProcess) && 210 // corresponding request.
211 *defer = true;
212 OnDidDefer();
213 return true;
214 }
215
216 // In the site-per-process model, we may also decide (independently from the
217 // content embedder's ShouldSwapProcessesForRedirect decision above) that a
218 // process transfer is needed. For that we need to consult the navigation
219 // policy on the UI thread, so pause the response. Process transfers are
220 // skipped for WebUI processes for now, since e.g. chrome://settings has
221 // multiple "cross-site" chrome:// frames, and that doesn't yet work cross-
222 // process.
223 if (SiteIsolationPolicy::AreCrossProcessFramesPossible() &&
206 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 224 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
207 info->GetChildID())) { 225 info->GetChildID())) {
208 return DeferForNavigationPolicyCheck(info, response, defer); 226 return DeferForNavigationPolicyCheck(info, response, defer);
209 } 227 }
210 228
211 if (!should_transfer) 229 // No deferral needed. Pass the response through.
212 return next_handler_->OnResponseStarted(response, defer); 230 return next_handler_->OnResponseStarted(response, defer);
213
214 // Now that we know a transfer is needed and we have something to commit, we
215 // pause to let the UI thread set up the transfer.
216 StartCrossSiteTransition(response);
217
218 // Defer loading until after the new renderer process has issued a
219 // corresponding request.
220 *defer = true;
221 OnDidDefer();
222 return true;
223 } 231 }
224 232
225 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { 233 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) {
226 if (is_transfer) { 234 if (is_transfer) {
227 StartCrossSiteTransition(response_.get()); 235 StartCrossSiteTransition(response_.get());
228 } else { 236 } else {
229 ResumeResponse(); 237 ResumeResponse();
230 } 238 }
231 } 239 }
232 240
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 controller()->Resume(); 387 controller()->Resume();
380 } 388 }
381 } 389 }
382 390
383 void CrossSiteResourceHandler::OnDidDefer() { 391 void CrossSiteResourceHandler::OnDidDefer() {
384 did_defer_ = true; 392 did_defer_ = true;
385 request()->LogBlockedBy("CrossSiteResourceHandler"); 393 request()->LogBlockedBy("CrossSiteResourceHandler");
386 } 394 }
387 395
388 } // namespace content 396 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698