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

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

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

Powered by Google App Engine
This is Rietveld 408576698