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

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

Issue 1384113002: CrossSiteResourceHandler: cancel request if the RFH is gone (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@no_isolate_apps
Patch Set: Add EXPECT_TRUE's Created 5 years, 2 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"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 // Determines whether a navigation to |dest_url| may be completed using an
90 bool CheckNavigationPolicyOnUI(GURL real_url, 90 // existing RenderFrameHost, or whether transferring to a new RenderFrameHost
91 int process_id, 91 // backed by a different render process is required. This is a security policy
92 int render_frame_id) { 92 // check determined by the current site isolation mode, and must be done
93 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible()); 93 // before the resource at |dest_url| is delivered to |rfh|.
94 RenderFrameHostImpl* rfh = 94 //
95 RenderFrameHostImpl::FromID(process_id, render_frame_id); 95 // When this function returns true for a subframe, an out-of-process iframe
96 if (!rfh) 96 // must be created.
97 return false; 97 //
98 98 // TODO(nick): Move this function to RFHM.
99 bool IsRendererTransferNeededForNavigation(RenderFrameHostImpl* rfh,
100 const GURL& dest_url) {
99 // A transfer is not needed if the current SiteInstance doesn't yet have a 101 // A transfer is not needed if the current SiteInstance doesn't yet have a
100 // site. This is the case for tests that use NavigateToURL. 102 // site. This is the case for tests that use NavigateToURL.
101 if (!rfh->GetSiteInstance()->HasSite()) 103 if (!rfh->GetSiteInstance()->HasSite())
102 return false; 104 return false;
103 105
104 // For now, GuestViews never transfer on cross-site navigations. 106 // For now, GuestViews never transfer on cross-site navigations.
105 WebContentsImpl* web_contents = 107 WebContentsImpl* web_contents =
106 static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(rfh)); 108 static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(rfh));
107 if (web_contents->GetBrowserPluginGuest()) 109 if (web_contents->GetBrowserPluginGuest())
108 return false; 110 return false;
109 111
110 GURL effective_url = SiteInstanceImpl::GetEffectiveURL( 112 GURL effective_url = SiteInstanceImpl::GetEffectiveURL(
111 rfh->GetSiteInstance()->GetBrowserContext(), real_url); 113 rfh->GetSiteInstance()->GetBrowserContext(), dest_url);
112 114
113 // TODO(nasko, nick): These following --site-per-process checks are 115 // TODO(nasko, nick): These following --site-per-process checks are
114 // overly simplistic. Update them to match all the cases 116 // overly simplistic. Update them to match all the cases
115 // considered by RenderFrameHostManager::DetermineSiteInstanceForURL. 117 // considered by RenderFrameHostManager::DetermineSiteInstanceForURL.
116 if (SiteInstance::IsSameWebSite(rfh->GetSiteInstance()->GetBrowserContext(), 118 if (SiteInstance::IsSameWebSite(rfh->GetSiteInstance()->GetBrowserContext(),
117 rfh->GetSiteInstance()->GetSiteURL(), 119 rfh->GetSiteInstance()->GetSiteURL(),
118 real_url)) { 120 dest_url)) {
119 return false; // The same site, no transition needed. 121 return false; // The same site, no transition needed.
120 } 122 }
121 123
122 // The sites differ. If either one requires a dedicated process, 124 // The sites differ. If either one requires a dedicated process,
123 // then a transfer is needed. 125 // then a transfer is needed.
124 return rfh->GetSiteInstance()->RequiresDedicatedProcess() || 126 return rfh->GetSiteInstance()->RequiresDedicatedProcess() ||
125 SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(effective_url); 127 SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(effective_url);
126 } 128 }
127 129
130 // Returns whether a transfer is needed by doing a check on the UI thread.
131 CrossSiteResourceHandler::NavigationDecision
132 CheckNavigationPolicyOnUI(GURL real_url, int process_id, int render_frame_id) {
133 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
134 RenderFrameHostImpl* rfh =
135 RenderFrameHostImpl::FromID(process_id, render_frame_id);
136
137 // Without a valid RFH against which to check, we must cancel the request,
138 // to prevent the resource at |url| from being delivered to a potentially
139 // unsuitable renderer process.
140 if (!rfh)
141 return CrossSiteResourceHandler::NavigationDecision::CANCEL_REQUEST;
142
143 if (IsRendererTransferNeededForNavigation(rfh, real_url))
144 return CrossSiteResourceHandler::NavigationDecision::TRANSFER_REQUIRED;
145 else
146 return CrossSiteResourceHandler::NavigationDecision::USE_EXISTING_RENDERER;
147 }
148
128 } // namespace 149 } // namespace
129 150
130 CrossSiteResourceHandler::CrossSiteResourceHandler( 151 CrossSiteResourceHandler::CrossSiteResourceHandler(
131 scoped_ptr<ResourceHandler> next_handler, 152 scoped_ptr<ResourceHandler> next_handler,
132 net::URLRequest* request) 153 net::URLRequest* request)
133 : LayeredResourceHandler(request, next_handler.Pass()), 154 : LayeredResourceHandler(request, next_handler.Pass()),
134 has_started_response_(false), 155 has_started_response_(false),
135 in_cross_site_transition_(false), 156 in_cross_site_transition_(false),
136 completed_during_transition_(false), 157 completed_during_transition_(false),
137 did_defer_(false), 158 did_defer_(false),
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 if (SiteIsolationPolicy::AreCrossProcessFramesPossible() && 250 if (SiteIsolationPolicy::AreCrossProcessFramesPossible() &&
230 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 251 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
231 info->GetChildID())) { 252 info->GetChildID())) {
232 return DeferForNavigationPolicyCheck(info, response, defer); 253 return DeferForNavigationPolicyCheck(info, response, defer);
233 } 254 }
234 255
235 // No deferral needed. Pass the response through. 256 // No deferral needed. Pass the response through.
236 return next_handler_->OnResponseStarted(response, defer); 257 return next_handler_->OnResponseStarted(response, defer);
237 } 258 }
238 259
239 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { 260 void CrossSiteResourceHandler::ResumeOrTransfer(NavigationDecision decision) {
240 if (is_transfer) { 261 switch (decision) {
241 StartCrossSiteTransition(response_.get()); 262 case NavigationDecision::CANCEL_REQUEST:
242 } else { 263 // TODO(nick): What kind of cleanup do we need here?
243 ResumeResponse(); 264 controller()->Cancel();
265 break;
266 case NavigationDecision::USE_EXISTING_RENDERER:
267 ResumeResponse();
268 break;
269 case NavigationDecision::TRANSFER_REQUIRED:
270 StartCrossSiteTransition(response_.get());
271 break;
244 } 272 }
245 } 273 }
246 274
247 bool CrossSiteResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { 275 bool CrossSiteResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
248 CHECK(!in_cross_site_transition_); 276 CHECK(!in_cross_site_transition_);
249 return next_handler_->OnReadCompleted(bytes_read, defer); 277 return next_handler_->OnReadCompleted(bytes_read, defer);
250 } 278 }
251 279
252 void CrossSiteResourceHandler::OnResponseCompleted( 280 void CrossSiteResourceHandler::OnResponseCompleted(
253 const net::URLRequestStatus& status, 281 const net::URLRequestStatus& status,
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 controller()->Resume(); 421 controller()->Resume();
394 } 422 }
395 } 423 }
396 424
397 void CrossSiteResourceHandler::OnDidDefer() { 425 void CrossSiteResourceHandler::OnDidDefer() {
398 did_defer_ = true; 426 did_defer_ = true;
399 request()->LogBlockedBy("CrossSiteResourceHandler"); 427 request()->LogBlockedBy("CrossSiteResourceHandler");
400 } 428 }
401 429
402 } // namespace content 430 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698