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

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

Issue 297973002: Navigation transitions: Block first response until after transitions have run. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 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/cross_site_request_manager.h" 14 #include "content/browser/cross_site_request_manager.h"
15 #include "content/browser/frame_host/cross_site_transferring_request.h" 15 #include "content/browser/frame_host/cross_site_transferring_request.h"
16 #include "content/browser/frame_host/render_frame_host_impl.h" 16 #include "content/browser/frame_host/render_frame_host_impl.h"
17 #include "content/browser/loader/resource_dispatcher_host_impl.h" 17 #include "content/browser/loader/resource_dispatcher_host_impl.h"
18 #include "content/browser/loader/resource_request_info_impl.h" 18 #include "content/browser/loader/resource_request_info_impl.h"
19 #include "content/browser/transition_request_manager.h"
19 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/content_browser_client.h" 21 #include "content/public/browser/content_browser_client.h"
21 #include "content/public/browser/global_request_id.h" 22 #include "content/public/browser/global_request_id.h"
22 #include "content/public/browser/resource_controller.h" 23 #include "content/public/browser/resource_controller.h"
23 #include "content/public/browser/site_instance.h" 24 #include "content/public/browser/site_instance.h"
24 #include "content/public/common/content_switches.h" 25 #include "content/public/common/content_switches.h"
25 #include "content/public/common/resource_response.h" 26 #include "content/public/common/resource_response.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"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 params.global_request_id, cross_site_transferring_request.Pass(), 78 params.global_request_id, cross_site_transferring_request.Pass(),
78 params.transfer_url_chain, params.referrer, 79 params.transfer_url_chain, params.referrer,
79 params.page_transition, params.should_replace_current_entry); 80 params.page_transition, params.should_replace_current_entry);
80 } else if (leak_requests_for_testing_ && cross_site_transferring_request) { 81 } 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 82 // Some unit tests expect requests to be leaked in this case, so they can
82 // pass them along manually. 83 // pass them along manually.
83 cross_site_transferring_request->ReleaseRequest(); 84 cross_site_transferring_request->ReleaseRequest();
84 } 85 }
85 } 86 }
86 87
88 void OnDeferredAfterResponseStartedHelper(
89 const GlobalRequestID& global_request_id, int render_frame_id) {
nasko 2014/05/28 22:59:00 style: parameters need to be on line of their own.
shatch 2014/05/29 21:41:22 Done.
90
91 RenderFrameHostImpl* rfh =
92 RenderFrameHostImpl::FromID(global_request_id.child_id,
93 render_frame_id);
94 if (rfh) {
nasko 2014/05/28 22:59:00 style: no need for braces here
shatch 2014/05/29 21:41:22 Done.
95 rfh->OnDeferredAfterResponseStarted(global_request_id);
96 }
97 }
98
87 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) { 99 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) {
88 RenderFrameHostImpl* rfh = 100 RenderFrameHostImpl* rfh =
89 RenderFrameHostImpl::FromID(process_id, render_frame_id); 101 RenderFrameHostImpl::FromID(process_id, render_frame_id);
90 if (!rfh) 102 if (!rfh)
91 return false; 103 return false;
92 104
93 // TODO(nasko): This check is very simplistic and is used temporarily only 105 // TODO(nasko): This check is very simplistic and is used temporarily only
94 // for --site-per-process. It should be updated to match the check performed 106 // for --site-per-process. It should be updated to match the check performed
95 // by RenderFrameHostManager::UpdateStateForNavigate. 107 // by RenderFrameHostManager::UpdateStateForNavigate.
96 return !SiteInstance::IsSameWebSite( 108 return !SiteInstance::IsSameWebSite(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // We should not have started the transition before being redirected. 141 // We should not have started the transition before being redirected.
130 DCHECK(!in_cross_site_transition_); 142 DCHECK(!in_cross_site_transition_);
131 return next_handler_->OnRequestRedirected( 143 return next_handler_->OnRequestRedirected(
132 request_id, new_url, response, defer); 144 request_id, new_url, response, defer);
133 } 145 }
134 146
135 bool CrossSiteResourceHandler::OnResponseStarted( 147 bool CrossSiteResourceHandler::OnResponseStarted(
136 int request_id, 148 int request_id,
137 ResourceResponse* response, 149 ResourceResponse* response,
138 bool* defer) { 150 bool* defer) {
151 response_ = response;
152 has_started_response_ = true;
153
154 // Store this handler on the ExtraRequestInfo, so that RDH can call our
155 // ResumeResponse method when we are ready to resume.
156 ResourceRequestInfoImpl* info = GetRequestInfo();
157 info->set_cross_site_handler(this);
158
159 bool is_navigation_transition =
160 TransitionRequestManager::GetInstance()->HasPendingTransitionRequest(
161 info->GetChildID(), info->GetRouteID());
162
163 if (is_navigation_transition)
164 return OnNavigationTransitionResponseStarted(request_id, response, defer);
165 else
166 return OnNormalResponseStarted(request_id, response, defer);
167 }
168
169 bool CrossSiteResourceHandler::OnNormalResponseStarted(
170 int request_id, ResourceResponse* response, bool* defer) {
139 // At this point, we know that the response is safe to send back to the 171 // At this point, we know that the response is safe to send back to the
140 // renderer: it is not a download, and it has passed the SSL and safe 172 // renderer: it is not a download, and it has passed the SSL and safe
141 // browsing checks. 173 // browsing checks.
142 // We should not have already started the transition before now. 174 // We should not have already started the transition before now.
143 DCHECK(!in_cross_site_transition_); 175 DCHECK(!in_cross_site_transition_);
144 has_started_response_ = true;
145 176
146 ResourceRequestInfoImpl* info = GetRequestInfo(); 177 ResourceRequestInfoImpl* info = GetRequestInfo();
147 178
148 // We will need to swap processes if either (1) a redirect that requires a 179 // We will need to swap processes if either (1) a redirect that requires a
149 // transfer occurred before we got here, or (2) a pending cross-site request 180 // transfer occurred before we got here, or (2) a pending cross-site request
150 // was already in progress. Note that a swap may no longer be needed if we 181 // was already in progress. Note that a swap may no longer be needed if we
151 // transferred back into the original process due to a redirect. 182 // transferred back into the original process due to a redirect.
152 bool should_transfer = 183 bool should_transfer =
153 GetContentClient()->browser()->ShouldSwapProcessesForRedirect( 184 GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
154 info->GetContext(), request()->original_url(), request()->url()); 185 info->GetContext(), request()->original_url(), request()->url());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 // pause to let the UI thread run the unload handler of the previous page 224 // pause to let the UI thread run the unload handler of the previous page
194 // and set up a transfer if needed. 225 // and set up a transfer if needed.
195 StartCrossSiteTransition(request_id, response, should_transfer); 226 StartCrossSiteTransition(request_id, response, should_transfer);
196 227
197 // Defer loading until after the onunload event handler has run. 228 // Defer loading until after the onunload event handler has run.
198 *defer = true; 229 *defer = true;
199 OnDidDefer(); 230 OnDidDefer();
200 return true; 231 return true;
201 } 232 }
202 233
234 bool CrossSiteResourceHandler::OnNavigationTransitionResponseStarted(
235 int request_id, ResourceResponse* response, bool* defer) {
236 ResourceRequestInfoImpl* info = GetRequestInfo();
237 DCHECK_EQ(request_id, info->GetRequestID());
238
239 request()->LogBlockedBy("CrossSiteResourceHandler");
240
241 DCHECK_EQ(request_id, info->GetRequestID());
242 GlobalRequestID global_id(info->GetChildID(), info->GetRequestID());
243 int render_frame_id = info->GetRenderFrameID();
244 BrowserThread::PostTask(
245 BrowserThread::UI,
nasko 2014/05/28 22:59:00 style: wrong indent
shatch 2014/05/29 21:41:22 Done.
246 FROM_HERE,
247 base::Bind(
248 &OnDeferredAfterResponseStartedHelper,
249 global_id, render_frame_id));
250
251 *defer = true;
nasko 2014/05/28 22:59:00 Shouldn't there be a call to OnDidDefer()?
shatch 2014/05/29 21:41:22 Done.
252 return true;
253 }
254
255 void CrossSiteResourceHandler::ResumeResponseDeferredAtStart(
256 int request_id) {
257 request()->LogUnblocked();
258
259 bool defer;
260 if (!OnNormalResponseStarted(request_id, response_, &defer)) {
261 controller()->Cancel();
262 } else {
263 controller()->Resume();
264 }
265 }
266
203 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { 267 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) {
204 if (is_transfer) { 268 if (is_transfer) {
205 ResourceRequestInfoImpl* info = GetRequestInfo(); 269 ResourceRequestInfoImpl* info = GetRequestInfo();
206 StartCrossSiteTransition(info->GetRequestID(), response_, is_transfer); 270 StartCrossSiteTransition(info->GetRequestID(), response_, is_transfer);
207 } else { 271 } else {
208 ResumeResponse(); 272 ResumeResponse();
209 } 273 }
210 } 274 }
211 275
212 bool CrossSiteResourceHandler::OnReadCompleted(int request_id, 276 bool CrossSiteResourceHandler::OnReadCompleted(int request_id,
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 controller()->Resume(); 447 controller()->Resume();
384 } 448 }
385 } 449 }
386 450
387 void CrossSiteResourceHandler::OnDidDefer() { 451 void CrossSiteResourceHandler::OnDidDefer() {
388 did_defer_ = true; 452 did_defer_ = true;
389 request()->LogBlockedBy("CrossSiteResourceHandler"); 453 request()->LogBlockedBy("CrossSiteResourceHandler");
390 } 454 }
391 455
392 } // namespace content 456 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698