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

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: Rebase. 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 29 matching lines...) Expand all
126 request()->set_first_party_for_cookies(new_url); 136 request()->set_first_party_for_cookies(new_url);
127 137
128 // We should not have started the transition before being redirected. 138 // We should not have started the transition before being redirected.
129 DCHECK(!in_cross_site_transition_); 139 DCHECK(!in_cross_site_transition_);
130 return next_handler_->OnRequestRedirected(new_url, response, defer); 140 return next_handler_->OnRequestRedirected(new_url, response, defer);
131 } 141 }
132 142
133 bool CrossSiteResourceHandler::OnResponseStarted( 143 bool CrossSiteResourceHandler::OnResponseStarted(
134 ResourceResponse* response, 144 ResourceResponse* response,
135 bool* defer) { 145 bool* defer) {
146 response_ = response;
147 has_started_response_ = true;
148
149 // Store this handler on the ExtraRequestInfo, so that RDH can call our
150 // ResumeResponse method when we are ready to resume.
151 ResourceRequestInfoImpl* info = GetRequestInfo();
152 info->set_cross_site_handler(this);
153
154 bool is_navigation_transition =
155 TransitionRequestManager::GetInstance()->HasPendingTransitionRequest(
156 info->GetChildID(), info->GetRenderFrameID());
157
158 if (is_navigation_transition)
159 return OnNavigationTransitionResponseStarted(response, defer);
160 else
161 return OnNormalResponseStarted(response, defer);
162 }
163
164 bool CrossSiteResourceHandler::OnNormalResponseStarted(
165 ResourceResponse* response,
166 bool* defer) {
136 // At this point, we know that the response is safe to send back to the 167 // At this point, we know that the response is safe to send back to the
137 // renderer: it is not a download, and it has passed the SSL and safe 168 // renderer: it is not a download, and it has passed the SSL and safe
138 // browsing checks. 169 // browsing checks.
139 // We should not have already started the transition before now. 170 // We should not have already started the transition before now.
140 DCHECK(!in_cross_site_transition_); 171 DCHECK(!in_cross_site_transition_);
141 has_started_response_ = true;
142 172
143 ResourceRequestInfoImpl* info = GetRequestInfo(); 173 ResourceRequestInfoImpl* info = GetRequestInfo();
144 174
145 // We will need to swap processes if either (1) a redirect that requires a 175 // We will need to swap processes if either (1) a redirect that requires a
146 // transfer occurred before we got here, or (2) a pending cross-site request 176 // transfer occurred before we got here, or (2) a pending cross-site request
147 // was already in progress. Note that a swap may no longer be needed if we 177 // was already in progress. Note that a swap may no longer be needed if we
148 // transferred back into the original process due to a redirect. 178 // transferred back into the original process due to a redirect.
149 bool should_transfer = 179 bool should_transfer =
150 GetContentClient()->browser()->ShouldSwapProcessesForRedirect( 180 GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
151 info->GetContext(), request()->original_url(), request()->url()); 181 info->GetContext(), request()->original_url(), request()->url());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 // pause to let the UI thread run the unload handler of the previous page 220 // pause to let the UI thread run the unload handler of the previous page
191 // and set up a transfer if needed. 221 // and set up a transfer if needed.
192 StartCrossSiteTransition(response, should_transfer); 222 StartCrossSiteTransition(response, should_transfer);
193 223
194 // Defer loading until after the onunload event handler has run. 224 // Defer loading until after the onunload event handler has run.
195 *defer = true; 225 *defer = true;
196 OnDidDefer(); 226 OnDidDefer();
197 return true; 227 return true;
198 } 228 }
199 229
230 bool CrossSiteResourceHandler::OnNavigationTransitionResponseStarted(
231 ResourceResponse* response,
232 bool* defer) {
233 ResourceRequestInfoImpl* info = GetRequestInfo();
234
235 GlobalRequestID global_id(info->GetChildID(), info->GetRequestID());
236 int render_frame_id = info->GetRenderFrameID();
237 BrowserThread::PostTask(
238 BrowserThread::UI,
239 FROM_HERE,
240 base::Bind(
241 &OnDeferredAfterResponseStartedHelper, global_id, render_frame_id));
242
243 *defer = true;
244 OnDidDefer();
245 return true;
246 }
247
248 void CrossSiteResourceHandler::ResumeResponseDeferredAtStart(int request_id) {
249 bool defer = false;
250 if (!OnNormalResponseStarted(response_, &defer)) {
251 controller()->Cancel();
252 } else if (!defer) {
253 ResumeIfDeferred();
254 }
255 }
256
200 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { 257 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) {
201 if (is_transfer) { 258 if (is_transfer) {
202 StartCrossSiteTransition(response_, is_transfer); 259 StartCrossSiteTransition(response_, is_transfer);
203 } else { 260 } else {
204 ResumeResponse(); 261 ResumeResponse();
205 } 262 }
206 } 263 }
207 264
208 bool CrossSiteResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { 265 bool CrossSiteResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
209 CHECK(!in_cross_site_transition_); 266 CHECK(!in_cross_site_transition_);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 controller()->Resume(); 428 controller()->Resume();
372 } 429 }
373 } 430 }
374 431
375 void CrossSiteResourceHandler::OnDidDefer() { 432 void CrossSiteResourceHandler::OnDidDefer() {
376 did_defer_ = true; 433 did_defer_ = true;
377 request()->LogBlockedBy("CrossSiteResourceHandler"); 434 request()->LogBlockedBy("CrossSiteResourceHandler");
378 } 435 }
379 436
380 } // namespace content 437 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/cross_site_resource_handler.h ('k') | content/browser/loader/resource_dispatcher_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698