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

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

Issue 2321543002: Merge CrossSiteResourceHandler and NavigationResourceThrottle (Closed)
Patch Set: Fixed test compilation error Created 4 years, 3 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/navigation_resource_throttle.h" 5 #include "content/browser/loader/navigation_resource_throttle.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
14 #include "content/browser/frame_host/navigation_handle_impl.h" 14 #include "content/browser/frame_host/navigation_handle_impl.h"
15 #include "content/browser/frame_host/render_frame_host_impl.h" 15 #include "content/browser/frame_host/render_frame_host_impl.h"
16 #include "content/browser/loader/resource_dispatcher_host_impl.h"
16 #include "content/browser/loader/resource_loader.h" 17 #include "content/browser/loader/resource_loader.h"
17 #include "content/browser/loader/resource_request_info_impl.h" 18 #include "content/browser/loader/resource_request_info_impl.h"
18 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/navigation_data.h" 20 #include "content/public/browser/navigation_data.h"
20 #include "content/public/browser/resource_context.h" 21 #include "content/public/browser/resource_context.h"
21 #include "content/public/browser/resource_controller.h" 22 #include "content/public/browser/resource_controller.h"
22 #include "content/public/browser/resource_dispatcher_host_delegate.h" 23 #include "content/public/browser/resource_dispatcher_host_delegate.h"
23 #include "content/public/browser/resource_request_info.h" 24 #include "content/public/browser/resource_request_info.h"
24 #include "content/public/common/referrer.h" 25 #include "content/public/common/referrer.h"
25 #include "content/public/common/ssl_status.h" 26 #include "content/public/common/ssl_status.h"
26 #include "net/url_request/redirect_info.h" 27 #include "net/url_request/redirect_info.h"
27 #include "net/url_request/url_request.h" 28 #include "net/url_request/url_request.h"
28 #include "net/url_request/url_request_context.h" 29 #include "net/url_request/url_request_context.h"
29 #include "net/url_request/url_request_job_factory.h" 30 #include "net/url_request/url_request_job_factory.h"
30 #include "ui/base/page_transition_types.h" 31 #include "ui/base/page_transition_types.h"
31 32
32 namespace content { 33 namespace content {
33 34
34 namespace { 35 namespace {
36
37 // Used in unit tests to make UI checks succeed even if there is no
38 // NavigationHandle and to transfer all navigations.
39 bool g_ui_checks_always_succeed = false;
40 bool g_force_transfer = false;
41
35 typedef base::Callback<void(NavigationThrottle::ThrottleCheckResult)> 42 typedef base::Callback<void(NavigationThrottle::ThrottleCheckResult)>
36 UIChecksPerformedCallback; 43 UIChecksPerformedCallback;
37 44
38 void SendCheckResultToIOThread(UIChecksPerformedCallback callback, 45 void SendCheckResultToIOThread(UIChecksPerformedCallback callback,
39 NavigationThrottle::ThrottleCheckResult result) { 46 NavigationThrottle::ThrottleCheckResult result) {
40 DCHECK_CURRENTLY_ON(BrowserThread::UI); 47 DCHECK_CURRENTLY_ON(BrowserThread::UI);
41 DCHECK_NE(result, NavigationThrottle::DEFER); 48 DCHECK_NE(result, NavigationThrottle::DEFER);
42 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 49 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
43 base::Bind(callback, result)); 50 base::Bind(callback, result));
44 } 51 }
45 52
46 void CheckWillStartRequestOnUIThread( 53 void CheckWillStartRequestOnUIThread(
47 UIChecksPerformedCallback callback, 54 UIChecksPerformedCallback callback,
48 int render_process_id, 55 int render_process_id,
49 int render_frame_host_id, 56 int render_frame_host_id,
50 const std::string& method, 57 const std::string& method,
51 const scoped_refptr<content::ResourceRequestBodyImpl>& 58 const scoped_refptr<content::ResourceRequestBodyImpl>&
52 resource_request_body, 59 resource_request_body,
53 const Referrer& sanitized_referrer, 60 const Referrer& sanitized_referrer,
54 bool has_user_gesture, 61 bool has_user_gesture,
55 ui::PageTransition transition, 62 ui::PageTransition transition,
56 bool is_external_protocol, 63 bool is_external_protocol,
57 RequestContextType request_context_type) { 64 RequestContextType request_context_type) {
58 DCHECK_CURRENTLY_ON(BrowserThread::UI); 65 DCHECK_CURRENTLY_ON(BrowserThread::UI);
59 RenderFrameHostImpl* render_frame_host = 66 RenderFrameHostImpl* render_frame_host =
60 RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id); 67 RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
68 if (g_ui_checks_always_succeed) {
69 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED);
70 return;
71 }
72
61 if (!render_frame_host) { 73 if (!render_frame_host) {
62 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED); 74 SendCheckResultToIOThread(callback, NavigationThrottle::CANCEL);
63 return; 75 return;
64 } 76 }
65 77
66 NavigationHandleImpl* navigation_handle = 78 NavigationHandleImpl* navigation_handle =
67 render_frame_host->navigation_handle(); 79 render_frame_host->navigation_handle();
68 if (!navigation_handle) { 80 if (!navigation_handle) {
69 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED); 81 SendCheckResultToIOThread(callback, NavigationThrottle::CANCEL);
70 return; 82 return;
71 } 83 }
72 84
73 navigation_handle->WillStartRequest( 85 navigation_handle->WillStartRequest(
74 method, resource_request_body, sanitized_referrer, has_user_gesture, 86 method, resource_request_body, sanitized_referrer, has_user_gesture,
75 transition, is_external_protocol, request_context_type, 87 transition, is_external_protocol, request_context_type,
76 base::Bind(&SendCheckResultToIOThread, callback)); 88 base::Bind(&SendCheckResultToIOThread, callback));
77 } 89 }
78 90
79 void CheckWillRedirectRequestOnUIThread( 91 void CheckWillRedirectRequestOnUIThread(
80 UIChecksPerformedCallback callback, 92 UIChecksPerformedCallback callback,
81 int render_process_id, 93 int render_process_id,
82 int render_frame_host_id, 94 int render_frame_host_id,
83 const GURL& new_url, 95 const GURL& new_url,
84 const std::string& new_method, 96 const std::string& new_method,
85 const GURL& new_referrer_url, 97 const GURL& new_referrer_url,
86 bool new_is_external_protocol, 98 bool new_is_external_protocol,
87 scoped_refptr<net::HttpResponseHeaders> headers) { 99 scoped_refptr<net::HttpResponseHeaders> headers) {
88 DCHECK_CURRENTLY_ON(BrowserThread::UI); 100 DCHECK_CURRENTLY_ON(BrowserThread::UI);
89 RenderFrameHostImpl* render_frame_host = 101 RenderFrameHostImpl* render_frame_host =
90 RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id); 102 RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
103 if (g_ui_checks_always_succeed) {
104 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED);
105 return;
106 }
107
91 if (!render_frame_host) { 108 if (!render_frame_host) {
92 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED); 109 SendCheckResultToIOThread(callback, NavigationThrottle::CANCEL);
93 return; 110 return;
94 } 111 }
95 112
96 NavigationHandleImpl* navigation_handle = 113 NavigationHandleImpl* navigation_handle =
97 render_frame_host->navigation_handle(); 114 render_frame_host->navigation_handle();
98 if (!navigation_handle) { 115 if (!navigation_handle) {
99 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED); 116 SendCheckResultToIOThread(callback, NavigationThrottle::CANCEL);
100 return; 117 return;
101 } 118 }
102 119
103 GURL new_validated_url(new_url); 120 GURL new_validated_url(new_url);
104 RenderProcessHost::FromID(render_process_id) 121 RenderProcessHost::FromID(render_process_id)
105 ->FilterURL(false, &new_validated_url); 122 ->FilterURL(false, &new_validated_url);
106 navigation_handle->WillRedirectRequest( 123 navigation_handle->WillRedirectRequest(
107 new_validated_url, new_method, new_referrer_url, new_is_external_protocol, 124 new_validated_url, new_method, new_referrer_url, new_is_external_protocol,
108 headers, base::Bind(&SendCheckResultToIOThread, callback)); 125 headers, base::Bind(&SendCheckResultToIOThread, callback));
109 } 126 }
110 127
111 void WillProcessResponseOnUIThread( 128 void WillProcessResponseOnUIThread(
112 UIChecksPerformedCallback callback, 129 UIChecksPerformedCallback callback,
113 int render_process_id, 130 int render_process_id,
114 int render_frame_host_id, 131 int render_frame_host_id,
115 scoped_refptr<net::HttpResponseHeaders> headers, 132 scoped_refptr<net::HttpResponseHeaders> headers,
116 const SSLStatus& ssl_status, 133 const SSLStatus& ssl_status,
134 const GlobalRequestID& request_id,
135 bool should_replace_current_entry,
136 bool is_download,
137 bool is_stream,
138 const base::Closure& transfer_callback,
117 std::unique_ptr<NavigationData> navigation_data) { 139 std::unique_ptr<NavigationData> navigation_data) {
118 DCHECK_CURRENTLY_ON(BrowserThread::UI); 140 DCHECK_CURRENTLY_ON(BrowserThread::UI);
119 RenderFrameHostImpl* render_frame_host = 141 RenderFrameHostImpl* render_frame_host =
120 RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id); 142 RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
143 if (g_force_transfer) {
144 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, transfer_callback);
145 }
146
147 if (g_ui_checks_always_succeed) {
148 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED);
149 return;
150 }
151
121 if (!render_frame_host) { 152 if (!render_frame_host) {
122 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED); 153 SendCheckResultToIOThread(callback, NavigationThrottle::CANCEL);
123 return; 154 return;
124 } 155 }
125 156
126 NavigationHandleImpl* navigation_handle = 157 NavigationHandleImpl* navigation_handle =
127 render_frame_host->navigation_handle(); 158 render_frame_host->navigation_handle();
128 if (!navigation_handle) { 159 if (!navigation_handle) {
129 SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED); 160 SendCheckResultToIOThread(callback, NavigationThrottle::CANCEL);
130 return; 161 return;
131 } 162 }
132 163
133 if (navigation_data) 164 if (navigation_data)
134 navigation_handle->set_navigation_data(std::move(navigation_data)); 165 navigation_handle->set_navigation_data(std::move(navigation_data));
135 166
136 navigation_handle->WillProcessResponse( 167 navigation_handle->WillProcessResponse(
137 render_frame_host, headers, ssl_status, 168 render_frame_host, headers, ssl_status, request_id,
169 should_replace_current_entry, is_download, is_stream, transfer_callback,
138 base::Bind(&SendCheckResultToIOThread, callback)); 170 base::Bind(&SendCheckResultToIOThread, callback));
139 } 171 }
140 172
141 } // namespace 173 } // namespace
142 174
143 NavigationResourceThrottle::NavigationResourceThrottle( 175 NavigationResourceThrottle::NavigationResourceThrottle(
144 net::URLRequest* request, 176 net::URLRequest* request,
145 ResourceDispatcherHostDelegate* resource_dispatcher_host_delegate, 177 ResourceDispatcherHostDelegate* resource_dispatcher_host_delegate,
146 CertStore* cert_store, 178 CertStore* cert_store,
147 RequestContextType request_context_type) 179 RequestContextType request_context_type)
148 : request_(request), 180 : request_(request),
149 resource_dispatcher_host_delegate_(resource_dispatcher_host_delegate), 181 resource_dispatcher_host_delegate_(resource_dispatcher_host_delegate),
150 cert_store_(cert_store), 182 cert_store_(cert_store),
151 request_context_type_(request_context_type), 183 request_context_type_(request_context_type),
184 in_cross_site_transition_(false),
185 on_transfer_done_result_(NavigationThrottle::CANCEL),
152 weak_ptr_factory_(this) {} 186 weak_ptr_factory_(this) {}
153 187
154 NavigationResourceThrottle::~NavigationResourceThrottle() {} 188 NavigationResourceThrottle::~NavigationResourceThrottle() {}
155 189
156 void NavigationResourceThrottle::WillStartRequest(bool* defer) { 190 void NavigationResourceThrottle::WillStartRequest(bool* defer) {
157 DCHECK_CURRENTLY_ON(BrowserThread::IO); 191 DCHECK_CURRENTLY_ON(BrowserThread::IO);
158 const ResourceRequestInfoImpl* info = 192 const ResourceRequestInfoImpl* info =
159 ResourceRequestInfoImpl::ForRequest(request_); 193 ResourceRequestInfoImpl::ForRequest(request_);
160 if (!info) 194 if (!info)
161 return; 195 return;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 BrowserThread::UI, FROM_HERE, 254 BrowserThread::UI, FROM_HERE,
221 base::Bind(&CheckWillRedirectRequestOnUIThread, callback, 255 base::Bind(&CheckWillRedirectRequestOnUIThread, callback,
222 render_process_id, render_frame_id, redirect_info.new_url, 256 render_process_id, render_frame_id, redirect_info.new_url,
223 redirect_info.new_method, GURL(redirect_info.new_referrer), 257 redirect_info.new_method, GURL(redirect_info.new_referrer),
224 new_is_external_protocol, response_headers)); 258 new_is_external_protocol, response_headers));
225 *defer = true; 259 *defer = true;
226 } 260 }
227 261
228 void NavigationResourceThrottle::WillProcessResponse(bool* defer) { 262 void NavigationResourceThrottle::WillProcessResponse(bool* defer) {
229 DCHECK_CURRENTLY_ON(BrowserThread::IO); 263 DCHECK_CURRENTLY_ON(BrowserThread::IO);
230 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); 264 const ResourceRequestInfoImpl* info =
265 ResourceRequestInfoImpl::ForRequest(request_);
231 if (!info) 266 if (!info)
232 return; 267 return;
233 268
234 int render_process_id, render_frame_id; 269 int render_process_id, render_frame_id;
235 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) 270 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id))
236 return; 271 return;
237 272
238 // Send a copy of the response headers to the NavigationHandle on the UI 273 // Send a copy of the response headers to the NavigationHandle on the UI
239 // thread. 274 // thread.
240 scoped_refptr<net::HttpResponseHeaders> response_headers; 275 scoped_refptr<net::HttpResponseHeaders> response_headers;
241 if (request_->response_headers()) { 276 if (request_->response_headers()) {
242 response_headers = new net::HttpResponseHeaders( 277 response_headers = new net::HttpResponseHeaders(
243 request_->response_headers()->raw_headers()); 278 request_->response_headers()->raw_headers());
244 } 279 }
245 280
246 std::unique_ptr<NavigationData> cloned_data; 281 std::unique_ptr<NavigationData> cloned_data;
247 if (resource_dispatcher_host_delegate_) { 282 if (resource_dispatcher_host_delegate_) {
248 // Ask the embedder for a NavigationData instance. 283 // Ask the embedder for a NavigationData instance.
249 NavigationData* navigation_data = 284 NavigationData* navigation_data =
250 resource_dispatcher_host_delegate_->GetNavigationData(request_); 285 resource_dispatcher_host_delegate_->GetNavigationData(request_);
251 286
252 // Clone the embedder's NavigationData before moving it to the UI thread. 287 // Clone the embedder's NavigationData before moving it to the UI thread.
253 if (navigation_data) 288 if (navigation_data)
254 cloned_data = navigation_data->Clone(); 289 cloned_data = navigation_data->Clone();
255 } 290 }
256 291
257 UIChecksPerformedCallback callback = 292 UIChecksPerformedCallback callback =
258 base::Bind(&NavigationResourceThrottle::OnUIChecksPerformed, 293 base::Bind(&NavigationResourceThrottle::OnUIChecksPerformed,
259 weak_ptr_factory_.GetWeakPtr()); 294 weak_ptr_factory_.GetWeakPtr());
295 base::Closure transfer_callback =
296 base::Bind(&NavigationResourceThrottle::InitiateTransfer,
297 weak_ptr_factory_.GetWeakPtr());
260 298
261 SSLStatus ssl_status; 299 SSLStatus ssl_status;
262 if (request_->ssl_info().cert.get()) { 300 if (request_->ssl_info().cert.get()) {
263 ResourceLoader::GetSSLStatusForRequest( 301 ResourceLoader::GetSSLStatusForRequest(
264 request_->url(), request_->ssl_info(), info->GetChildID(), 302 request_->url(), request_->ssl_info(), info->GetChildID(),
265 cert_store_, &ssl_status); 303 cert_store_, &ssl_status);
266 } 304 }
267 305
268 BrowserThread::PostTask( 306 BrowserThread::PostTask(
269 BrowserThread::UI, FROM_HERE, 307 BrowserThread::UI, FROM_HERE,
270 base::Bind(&WillProcessResponseOnUIThread, callback, render_process_id, 308 base::Bind(&WillProcessResponseOnUIThread, callback, render_process_id,
271 render_frame_id, response_headers, ssl_status, 309 render_frame_id, response_headers, ssl_status,
310 info->GetGlobalRequestID(),
311 info->should_replace_current_entry(), info->IsDownload(),
312 info->is_stream(), transfer_callback,
272 base::Passed(&cloned_data))); 313 base::Passed(&cloned_data)));
273 *defer = true; 314 *defer = true;
274 } 315 }
275 316
276 const char* NavigationResourceThrottle::GetNameForLogging() const { 317 const char* NavigationResourceThrottle::GetNameForLogging() const {
277 return "NavigationResourceThrottle"; 318 return "NavigationResourceThrottle";
278 } 319 }
279 320
321 void NavigationResourceThrottle::SetUIChecksAlwaysSuccedForTesting(
322 bool ui_checks_always_succeed) {
323 g_ui_checks_always_succeed = ui_checks_always_succeed;
324 }
325
326 void NavigationResourceThrottle::SetForceTransferForTesting(
327 bool force_transfer) {
328 g_force_transfer = force_transfer;
329 }
330
280 void NavigationResourceThrottle::OnUIChecksPerformed( 331 void NavigationResourceThrottle::OnUIChecksPerformed(
281 NavigationThrottle::ThrottleCheckResult result) { 332 NavigationThrottle::ThrottleCheckResult result) {
282 DCHECK_CURRENTLY_ON(BrowserThread::IO); 333 DCHECK_CURRENTLY_ON(BrowserThread::IO);
334 if (in_cross_site_transition_) {
335 on_transfer_done_result_ = result;
336 return;
337 }
338
283 if (result == NavigationThrottle::CANCEL_AND_IGNORE) { 339 if (result == NavigationThrottle::CANCEL_AND_IGNORE) {
284 controller()->CancelAndIgnore(); 340 controller()->CancelAndIgnore();
285 } else if (result == NavigationThrottle::CANCEL) { 341 } else if (result == NavigationThrottle::CANCEL) {
286 controller()->Cancel(); 342 controller()->Cancel();
287 } else if (result == NavigationThrottle::BLOCK_REQUEST) { 343 } else if (result == NavigationThrottle::BLOCK_REQUEST) {
288 controller()->CancelWithError(net::ERR_BLOCKED_BY_CLIENT); 344 controller()->CancelWithError(net::ERR_BLOCKED_BY_CLIENT);
289 } else { 345 } else {
290 controller()->Resume(); 346 controller()->Resume();
291 } 347 }
292 } 348 }
293 349
350 void NavigationResourceThrottle::InitiateTransfer() {
nasko 2016/09/08 23:45:39 Can we put a DCHECK_CURRENTLY_ON to make it easier
clamy 2016/09/09 15:06:41 Done.
351 in_cross_site_transition_ = true;
352 ResourceRequestInfoImpl* info =
353 ResourceRequestInfoImpl::ForRequest(request_);
354 ResourceDispatcherHostImpl::Get()->MarkAsTransferredNavigation(
355 info->GetGlobalRequestID(),
356 base::Bind(&NavigationResourceThrottle::OnTransferDone,
357 weak_ptr_factory_.GetWeakPtr()));
358 }
359
360 void NavigationResourceThrottle::OnTransferDone() {
nasko 2016/09/08 23:45:39 Same here, add DCHECK_CURRENTLY_ON.
clamy 2016/09/09 15:06:41 Done.
361 DCHECK(in_cross_site_transition_);
362 in_cross_site_transition_ = false;
363 OnUIChecksPerformed(on_transfer_done_result_);
364 }
365
294 } // namespace content 366 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698