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

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

Issue 248963007: Perform navigation policy check on UI thread for --site-per-process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Some minor cleanup. Created 6 years, 8 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 | Annotate | Revision Log
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"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 params.global_request_id, cross_site_transferring_request.Pass(), 77 params.global_request_id, cross_site_transferring_request.Pass(),
78 params.transfer_url_chain, params.referrer, 78 params.transfer_url_chain, params.referrer,
79 params.page_transition, params.should_replace_current_entry); 79 params.page_transition, params.should_replace_current_entry);
80 } else if (leak_requests_for_testing_ && cross_site_transferring_request) { 80 } else if (leak_requests_for_testing_ && cross_site_transferring_request) {
81 // Some unit tests expect requests to be leaked in this case, so they can 81 // Some unit tests expect requests to be leaked in this case, so they can
82 // pass them along manually. 82 // pass them along manually.
83 cross_site_transferring_request->ReleaseRequest(); 83 cross_site_transferring_request->ReleaseRequest();
84 } 84 }
85 } 85 }
86 86
87 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) {
88 RenderFrameHostImpl* rfh =
89 RenderFrameHostImpl::FromID(process_id, render_frame_id);
Charlie Reis 2014/04/24 20:37:50 We should check for null here, in case the tab was
nasko 2014/04/24 22:31:12 Do'h, I had a check here.
90
91 // TODO(nasko): This check is very simplistic and is used temporarily only
92 // for --site-per-process. It should be updated to match the check performed
93 // by RenderFrameHostManager::UpdateRendererStateForNavigate.
94 bool transfer = !SiteInstance::IsSameWebSite(
Charlie Reis 2014/04/24 20:37:50 Why not just return from here?
nasko 2014/04/24 22:31:12 Done.
95 rfh->GetSiteInstance()->GetBrowserContext(),
96 rfh->GetSiteInstance()->GetSiteURL(), url);
97
98 return transfer;
99 }
100
87 } // namespace 101 } // namespace
88 102
89 CrossSiteResourceHandler::CrossSiteResourceHandler( 103 CrossSiteResourceHandler::CrossSiteResourceHandler(
90 scoped_ptr<ResourceHandler> next_handler, 104 scoped_ptr<ResourceHandler> next_handler,
91 net::URLRequest* request) 105 net::URLRequest* request)
92 : LayeredResourceHandler(request, next_handler.Pass()), 106 : LayeredResourceHandler(request, next_handler.Pass()),
93 has_started_response_(false), 107 has_started_response_(false),
94 in_cross_site_transition_(false), 108 in_cross_site_transition_(false),
95 completed_during_transition_(false), 109 completed_during_transition_(false),
96 did_defer_(false) { 110 did_defer_(false),
111 weak_ptr_factory_(this) {
97 } 112 }
98 113
99 CrossSiteResourceHandler::~CrossSiteResourceHandler() { 114 CrossSiteResourceHandler::~CrossSiteResourceHandler() {
100 // Cleanup back-pointer stored on the request info. 115 // Cleanup back-pointer stored on the request info.
101 GetRequestInfo()->set_cross_site_handler(NULL); 116 GetRequestInfo()->set_cross_site_handler(NULL);
102 } 117 }
103 118
104 bool CrossSiteResourceHandler::OnRequestRedirected( 119 bool CrossSiteResourceHandler::OnRequestRedirected(
105 int request_id, 120 int request_id,
106 const GURL& new_url, 121 const GURL& new_url,
(...skipping 20 matching lines...) Expand all
127 142
128 // We will need to swap processes if either (1) a redirect that requires a 143 // We will need to swap processes if either (1) a redirect that requires a
129 // transfer occurred before we got here, or (2) a pending cross-site request 144 // transfer occurred before we got here, or (2) a pending cross-site request
130 // was already in progress. Note that a swap may no longer be needed if we 145 // was already in progress. Note that a swap may no longer be needed if we
131 // transferred back into the original process due to a redirect. 146 // transferred back into the original process due to a redirect.
132 bool should_transfer = 147 bool should_transfer =
133 GetContentClient()->browser()->ShouldSwapProcessesForRedirect( 148 GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
134 info->GetContext(), request()->original_url(), request()->url()); 149 info->GetContext(), request()->original_url(), request()->url());
135 150
136 // When the --site-per-process flag is passed, we transfer processes for 151 // When the --site-per-process flag is passed, we transfer processes for
137 // cross-site subframe navigations. 152 // cross-site navigations. This is skipped if a transfer is already required
138 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { 153 // or for WebUI processes for now, since pages like the NTP host cross-site
154 // WebUI iframes but don't have referrers.
Charlie Reis 2014/04/24 20:37:50 We can drop the "but don't have referrers" part no
nasko 2014/04/24 22:31:12 Done.
155 if (!should_transfer &&
156 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) &&
157 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
158 info->GetChildID())) {
139 GURL referrer(request()->referrer()); 159 GURL referrer(request()->referrer());
Charlie Reis 2014/04/24 20:37:50 referrer looks unused now.
nasko 2014/04/24 22:31:12 Done.
140 // We skip this for WebUI processes for now, since pages like the NTP host 160 // Store the response_ object internally, since it is needed when the flow
Charlie Reis 2014/04/24 20:37:50 Can we move this whole block out to a helper funct
nasko 2014/04/24 22:31:12 Done.
141 // cross-site WebUI iframes but don't have referrers. 161 // comes back to the IO thread.
142 bool is_webui_process = ChildProcessSecurityPolicyImpl::GetInstance()-> 162 response_ = response;
Charlie Reis 2014/04/24 20:37:50 Hmm, this is subtle. It means this value is set i
nasko 2014/04/24 22:31:12 Done.
143 HasWebUIBindings(info->GetChildID());
144 163
145 // TODO(creis): This shouldn't rely on the referrer to determine the parent 164 // Always send the navigation to the UI thread to make a policy decision. It
Charlie Reis 2014/04/24 20:37:50 nit: send the navigation to the -> defer to the
nasko 2014/04/24 22:31:12 Done.
146 // frame's URL. This also doesn't work for hosted apps, due to passing NULL 165 // will send the result back to the IO thread to either resume or transfer
147 // to IsSameWebSite. It should be possible to always send the navigation to 166 // it to a new renderer.
148 // the UI thread to make a policy decision, which could let us eliminate the 167 BrowserThread::PostTaskAndReplyWithResult(
Charlie Reis 2014/04/24 20:37:50 This function and the use of WeakPtr here is still
nasko 2014/04/24 22:31:12 I'll add dcheng@ to review.
149 // renderer-side check in RenderViewImpl::decidePolicyForNavigation as well. 168 BrowserThread::UI,
150 if (info->GetResourceType() == ResourceType::SUB_FRAME && 169 FROM_HERE,
151 !is_webui_process && 170 base::Bind(&CheckNavigationPolicyOnUI,
152 !SiteInstance::IsSameWebSite(NULL, request()->url(), referrer)) { 171 request()->url(),
153 should_transfer = true; 172 info->GetChildID(),
154 } 173 info->GetRenderFrameID()),
174 base::Bind(&CrossSiteResourceHandler::ResumeOrTransfer,
175 weak_ptr_factory_.GetWeakPtr()));
Charlie Reis 2014/04/24 20:37:50 I'm sad that we need to add a weak pointer factory
nasko 2014/04/24 22:31:12 I could do away without the factory, but then we r
176 // Defer loading until it is known whether the navigation will transfer
177 // to a new process or continue in the existing one.
178 *defer = true;
179 OnDidDefer();
180 return true;
155 } 181 }
156 182
157 bool swap_needed = should_transfer || 183 bool swap_needed = should_transfer ||
158 CrossSiteRequestManager::GetInstance()-> 184 CrossSiteRequestManager::GetInstance()->
159 HasPendingCrossSiteRequest(info->GetChildID(), info->GetRouteID()); 185 HasPendingCrossSiteRequest(info->GetChildID(), info->GetRouteID());
160 186
161 // If this is a download, just pass the response through without doing a 187 // If this is a download, just pass the response through without doing a
162 // cross-site check. The renderer will see it is a download and abort the 188 // cross-site check. The renderer will see it is a download and abort the
163 // request. 189 // request.
164 // 190 //
(...skipping 18 matching lines...) Expand all
183 // pause to let the UI thread run the unload handler of the previous page 209 // pause to let the UI thread run the unload handler of the previous page
184 // and set up a transfer if needed. 210 // and set up a transfer if needed.
185 StartCrossSiteTransition(request_id, response, should_transfer); 211 StartCrossSiteTransition(request_id, response, should_transfer);
186 212
187 // Defer loading until after the onunload event handler has run. 213 // Defer loading until after the onunload event handler has run.
188 *defer = true; 214 *defer = true;
189 OnDidDefer(); 215 OnDidDefer();
190 return true; 216 return true;
191 } 217 }
192 218
219 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) {
220 if (is_transfer) {
221 ResourceRequestInfoImpl* info = GetRequestInfo();
222 StartCrossSiteTransition(info->GetRequestID(), response_, is_transfer);
223 } else {
224 ResumeResponse();
225 }
226 }
227
193 bool CrossSiteResourceHandler::OnReadCompleted(int request_id, 228 bool CrossSiteResourceHandler::OnReadCompleted(int request_id,
194 int bytes_read, 229 int bytes_read,
195 bool* defer) { 230 bool* defer) {
196 CHECK(!in_cross_site_transition_); 231 CHECK(!in_cross_site_transition_);
197 return next_handler_->OnReadCompleted(request_id, bytes_read, defer); 232 return next_handler_->OnReadCompleted(request_id, bytes_read, defer);
198 } 233 }
199 234
200 void CrossSiteResourceHandler::OnResponseCompleted( 235 void CrossSiteResourceHandler::OnResponseCompleted(
201 int request_id, 236 int request_id,
202 const net::URLRequestStatus& status, 237 const net::URLRequestStatus& status,
(...skipping 28 matching lines...) Expand all
231 // Defer to tell RDH not to notify the world or clean up the pending request. 266 // Defer to tell RDH not to notify the world or clean up the pending request.
232 // We will do so in ResumeResponse. 267 // We will do so in ResumeResponse.
233 *defer = true; 268 *defer = true;
234 OnDidDefer(); 269 OnDidDefer();
235 } 270 }
236 271
237 // We can now send the response to the new renderer, which will cause 272 // We can now send the response to the new renderer, which will cause
238 // WebContentsImpl to swap in the new renderer and destroy the old one. 273 // WebContentsImpl to swap in the new renderer and destroy the old one.
239 void CrossSiteResourceHandler::ResumeResponse() { 274 void CrossSiteResourceHandler::ResumeResponse() {
240 DCHECK(request()); 275 DCHECK(request());
241 DCHECK(in_cross_site_transition_);
242 in_cross_site_transition_ = false; 276 in_cross_site_transition_ = false;
243 ResourceRequestInfoImpl* info = GetRequestInfo(); 277 ResourceRequestInfoImpl* info = GetRequestInfo();
244 278
245 if (has_started_response_) { 279 if (has_started_response_) {
246 // Send OnResponseStarted to the new renderer. 280 // Send OnResponseStarted to the new renderer.
247 DCHECK(response_); 281 DCHECK(response_);
248 bool defer = false; 282 bool defer = false;
249 if (!next_handler_->OnResponseStarted(info->GetRequestID(), response_.get(), 283 if (!next_handler_->OnResponseStarted(info->GetRequestID(), response_.get(),
250 &defer)) { 284 &defer)) {
251 controller()->Cancel(); 285 controller()->Cancel();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 controller()->Resume(); 367 controller()->Resume();
334 } 368 }
335 } 369 }
336 370
337 void CrossSiteResourceHandler::OnDidDefer() { 371 void CrossSiteResourceHandler::OnDidDefer() {
338 did_defer_ = true; 372 did_defer_ = true;
339 request()->LogBlockedBy("CrossSiteResourceHandler"); 373 request()->LogBlockedBy("CrossSiteResourceHandler");
340 } 374 }
341 375
342 } // namespace content 376 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698