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

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: Changes from review. Created 6 years, 6 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,
90 int render_frame_id) {
91 RenderFrameHostImpl* rfh =
92 RenderFrameHostImpl::FromID(global_request_id.child_id, render_frame_id);
93 if (rfh)
94 rfh->OnDeferredAfterResponseStarted(global_request_id);
95 }
96
87 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) { 97 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) {
88 RenderFrameHostImpl* rfh = 98 RenderFrameHostImpl* rfh =
89 RenderFrameHostImpl::FromID(process_id, render_frame_id); 99 RenderFrameHostImpl::FromID(process_id, render_frame_id);
90 if (!rfh) 100 if (!rfh)
91 return false; 101 return false;
92 102
93 // TODO(nasko): This check is very simplistic and is used temporarily only 103 // 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 104 // for --site-per-process. It should be updated to match the check performed
95 // by RenderFrameHostManager::UpdateStateForNavigate. 105 // by RenderFrameHostManager::UpdateStateForNavigate.
96 return !SiteInstance::IsSameWebSite( 106 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. 139 // We should not have started the transition before being redirected.
130 DCHECK(!in_cross_site_transition_); 140 DCHECK(!in_cross_site_transition_);
131 return next_handler_->OnRequestRedirected( 141 return next_handler_->OnRequestRedirected(
132 request_id, new_url, response, defer); 142 request_id, new_url, response, defer);
133 } 143 }
134 144
135 bool CrossSiteResourceHandler::OnResponseStarted( 145 bool CrossSiteResourceHandler::OnResponseStarted(
136 int request_id, 146 int request_id,
137 ResourceResponse* response, 147 ResourceResponse* response,
138 bool* defer) { 148 bool* defer) {
149 response_ = response;
150 has_started_response_ = true;
151
152 // Store this handler on the ExtraRequestInfo, so that RDH can call our
153 // ResumeResponse method when we are ready to resume.
154 ResourceRequestInfoImpl* info = GetRequestInfo();
155 info->set_cross_site_handler(this);
156
157 bool is_navigation_transition =
158 TransitionRequestManager::GetInstance()->HasPendingTransitionRequest(
159 info->GetChildID(), info->GetRenderFrameID());
160
161 if (is_navigation_transition)
162 return OnNavigationTransitionResponseStarted(request_id, response, defer);
163 else
164 return OnNormalResponseStarted(request_id, response, defer);
165 }
166
167 bool CrossSiteResourceHandler::OnNormalResponseStarted(
168 int request_id,
169 ResourceResponse* response,
170 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,
236 ResourceResponse* response,
237 bool* defer) {
238 ResourceRequestInfoImpl* info = GetRequestInfo();
239 DCHECK_EQ(request_id, info->GetRequestID());
240
241 GlobalRequestID global_id(info->GetChildID(), info->GetRequestID());
242 int render_frame_id = info->GetRenderFrameID();
243 BrowserThread::PostTask(
244 BrowserThread::UI,
245 FROM_HERE,
246 base::Bind(
247 &OnDeferredAfterResponseStartedHelper, global_id, render_frame_id));
248
249 *defer = true;
250 OnDidDefer();
251 return true;
252 }
253
254 void CrossSiteResourceHandler::ResumeResponseDeferredAtStart(int request_id) {
255 bool defer;
256 if (!OnNormalResponseStarted(request_id, response_, &defer)) {
257 controller()->Cancel();
258 } else if (!defer) {
259 ResumeIfDeferred();
260 }
261 }
262
203 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { 263 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) {
204 if (is_transfer) { 264 if (is_transfer) {
205 ResourceRequestInfoImpl* info = GetRequestInfo(); 265 ResourceRequestInfoImpl* info = GetRequestInfo();
206 StartCrossSiteTransition(info->GetRequestID(), response_, is_transfer); 266 StartCrossSiteTransition(info->GetRequestID(), response_, is_transfer);
207 } else { 267 } else {
208 ResumeResponse(); 268 ResumeResponse();
209 } 269 }
210 } 270 }
211 271
212 bool CrossSiteResourceHandler::OnReadCompleted(int request_id, 272 bool CrossSiteResourceHandler::OnReadCompleted(int request_id,
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 controller()->Resume(); 443 controller()->Resume();
384 } 444 }
385 } 445 }
386 446
387 void CrossSiteResourceHandler::OnDidDefer() { 447 void CrossSiteResourceHandler::OnDidDefer() {
388 did_defer_ = true; 448 did_defer_ = true;
389 request()->LogBlockedBy("CrossSiteResourceHandler"); 449 request()->LogBlockedBy("CrossSiteResourceHandler");
390 } 450 }
391 451
392 } // namespace content 452 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698