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

Side by Side Diff: content/browser/frame_host/navigation_handle_impl.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/frame_host/navigation_handle_impl.h" 5 #include "content/browser/frame_host/navigation_handle_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "content/browser/browsing_data/clear_site_data_throttle.h" 10 #include "content/browser/browsing_data/clear_site_data_throttle.h"
11 #include "content/browser/child_process_security_policy_impl.h"
11 #include "content/browser/devtools/render_frame_devtools_agent_host.h" 12 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
12 #include "content/browser/frame_host/frame_tree_node.h" 13 #include "content/browser/frame_host/frame_tree_node.h"
13 #include "content/browser/frame_host/navigator.h" 14 #include "content/browser/frame_host/navigator.h"
14 #include "content/browser/frame_host/navigator_delegate.h" 15 #include "content/browser/frame_host/navigator_delegate.h"
15 #include "content/browser/service_worker/service_worker_context_wrapper.h" 16 #include "content/browser/service_worker/service_worker_context_wrapper.h"
16 #include "content/common/frame_messages.h" 17 #include "content/common/frame_messages.h"
17 #include "content/common/resource_request_body_impl.h" 18 #include "content/common/resource_request_body_impl.h"
19 #include "content/common/site_isolation_policy.h"
18 #include "content/public/browser/content_browser_client.h" 20 #include "content/public/browser/content_browser_client.h"
19 #include "content/public/common/browser_side_navigation_policy.h" 21 #include "content/public/common/browser_side_navigation_policy.h"
20 #include "content/public/common/content_client.h" 22 #include "content/public/common/content_client.h"
21 #include "net/url_request/redirect_info.h" 23 #include "net/url_request/redirect_info.h"
22 #include "url/gurl.h" 24 #include "url/gurl.h"
23 #include "url/url_constants.h" 25 #include "url/url_constants.h"
24 26
25 namespace content { 27 namespace content {
26 28
27 namespace { 29 namespace {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 has_user_gesture_(false), 63 has_user_gesture_(false),
62 transition_(ui::PAGE_TRANSITION_LINK), 64 transition_(ui::PAGE_TRANSITION_LINK),
63 is_external_protocol_(false), 65 is_external_protocol_(false),
64 net_error_code_(net::OK), 66 net_error_code_(net::OK),
65 render_frame_host_(nullptr), 67 render_frame_host_(nullptr),
66 is_renderer_initiated_(is_renderer_initiated), 68 is_renderer_initiated_(is_renderer_initiated),
67 is_same_page_(false), 69 is_same_page_(false),
68 is_synchronous_(is_synchronous), 70 is_synchronous_(is_synchronous),
69 is_srcdoc_(is_srcdoc), 71 is_srcdoc_(is_srcdoc),
70 was_redirected_(false), 72 was_redirected_(false),
73 original_url_(url),
71 state_(INITIAL), 74 state_(INITIAL),
72 is_transferring_(false), 75 is_transferring_(false),
73 frame_tree_node_(frame_tree_node), 76 frame_tree_node_(frame_tree_node),
74 next_index_(0), 77 next_index_(0),
75 navigation_start_(navigation_start), 78 navigation_start_(navigation_start),
76 pending_nav_entry_id_(pending_nav_entry_id), 79 pending_nav_entry_id_(pending_nav_entry_id),
77 request_context_type_(REQUEST_CONTEXT_TYPE_UNSPECIFIED) { 80 request_context_type_(REQUEST_CONTEXT_TYPE_UNSPECIFIED),
81 should_replace_current_entry_(false),
82 is_download_(false),
83 is_stream_(false),
84 weak_factory_(this) {
78 DCHECK(!navigation_start.is_null()); 85 DCHECK(!navigation_start.is_null());
79 GetDelegate()->DidStartNavigation(this); 86 GetDelegate()->DidStartNavigation(this);
87 redirect_chain_.push_back(url);
80 88
81 if (IsInMainFrame()) { 89 if (IsInMainFrame()) {
82 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( 90 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
83 "navigation", "Navigation StartToCommit", this, 91 "navigation", "Navigation StartToCommit", this,
84 navigation_start.ToInternalValue(), "Initial URL", url_.spec()); 92 navigation_start.ToInternalValue(), "Initial URL", url_.spec());
85 } 93 }
86 } 94 }
87 95
88 NavigationHandleImpl::~NavigationHandleImpl() { 96 NavigationHandleImpl::~NavigationHandleImpl() {
89 GetDelegate()->DidFinishNavigation(this); 97 GetDelegate()->DidFinishNavigation(this);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 235
228 NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER; 236 NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
229 if (state_ == DEFERRING_START) { 237 if (state_ == DEFERRING_START) {
230 result = CheckWillStartRequest(); 238 result = CheckWillStartRequest();
231 } else if (state_ == DEFERRING_REDIRECT) { 239 } else if (state_ == DEFERRING_REDIRECT) {
232 result = CheckWillRedirectRequest(); 240 result = CheckWillRedirectRequest();
233 } else { 241 } else {
234 result = CheckWillProcessResponse(); 242 result = CheckWillProcessResponse();
235 243
236 // If the navigation is about to proceed after processing the response, then 244 // If the navigation is about to proceed after processing the response, then
237 // it's ready to commit. 245 // it's ready to commit. Determine the final RenderFrameHost handling it.
238 if (result == NavigationThrottle::PROCEED) 246 // Note: if GetFinalRenderFrameHost() returns false, this means that this
239 ReadyToCommitNavigation(render_frame_host_); 247 // NavigationHandle was deleted, so return immediately.
248 if (result == NavigationThrottle::PROCEED && !GetFinalRenderFrameHost())
249 return;
240 } 250 }
241 251
242 if (result != NavigationThrottle::DEFER) 252 if (result != NavigationThrottle::DEFER)
243 RunCompleteCallback(result); 253 RunCompleteCallback(result);
244 } 254 }
245 255
246 void NavigationHandleImpl::CancelDeferredNavigation( 256 void NavigationHandleImpl::CancelDeferredNavigation(
247 NavigationThrottle::ThrottleCheckResult result) { 257 NavigationThrottle::ThrottleCheckResult result) {
248 DCHECK(state_ == DEFERRING_START || state_ == DEFERRING_REDIRECT); 258 DCHECK(state_ == DEFERRING_START || state_ == DEFERRING_REDIRECT);
249 DCHECK(result == NavigationThrottle::CANCEL_AND_IGNORE || 259 DCHECK(result == NavigationThrottle::CANCEL_AND_IGNORE ||
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 complete_callback_.Reset(); 312 complete_callback_.Reset();
303 return result; 313 return result;
304 } 314 }
305 315
306 NavigationThrottle::ThrottleCheckResult 316 NavigationThrottle::ThrottleCheckResult
307 NavigationHandleImpl::CallWillProcessResponseForTesting( 317 NavigationHandleImpl::CallWillProcessResponseForTesting(
308 content::RenderFrameHost* render_frame_host) { 318 content::RenderFrameHost* render_frame_host) {
309 NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER; 319 NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
310 WillProcessResponse(static_cast<RenderFrameHostImpl*>(render_frame_host), 320 WillProcessResponse(static_cast<RenderFrameHostImpl*>(render_frame_host),
311 scoped_refptr<net::HttpResponseHeaders>(), SSLStatus(), 321 scoped_refptr<net::HttpResponseHeaders>(), SSLStatus(),
322 GlobalRequestID(), false, false, false, base::Closure(),
312 base::Bind(&UpdateThrottleCheckResult, &result)); 323 base::Bind(&UpdateThrottleCheckResult, &result));
313 324
314 // Reset the callback to ensure it will not be called later. 325 // Reset the callback to ensure it will not be called later.
315 complete_callback_.Reset(); 326 complete_callback_.Reset();
316 return result; 327 return result;
317 } 328 }
318 329
319 NavigationData* NavigationHandleImpl::GetNavigationData() { 330 NavigationData* NavigationHandleImpl::GetNavigationData() {
320 return navigation_data_.get(); 331 return navigation_data_.get();
321 } 332 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 scoped_refptr<net::HttpResponseHeaders> response_headers, 376 scoped_refptr<net::HttpResponseHeaders> response_headers,
366 const ThrottleChecksFinishedCallback& callback) { 377 const ThrottleChecksFinishedCallback& callback) {
367 // Update the navigation parameters. 378 // Update the navigation parameters.
368 url_ = new_url; 379 url_ = new_url;
369 method_ = new_method; 380 method_ = new_method;
370 sanitized_referrer_.url = new_referrer_url; 381 sanitized_referrer_.url = new_referrer_url;
371 sanitized_referrer_ = Referrer::SanitizeForRequest(url_, sanitized_referrer_); 382 sanitized_referrer_ = Referrer::SanitizeForRequest(url_, sanitized_referrer_);
372 is_external_protocol_ = new_is_external_protocol; 383 is_external_protocol_ = new_is_external_protocol;
373 response_headers_ = response_headers; 384 response_headers_ = response_headers;
374 was_redirected_ = true; 385 was_redirected_ = true;
386 redirect_chain_.push_back(new_url);
375 if (new_method != "POST") 387 if (new_method != "POST")
376 resource_request_body_ = nullptr; 388 resource_request_body_ = nullptr;
377 389
378 state_ = WILL_REDIRECT_REQUEST; 390 state_ = WILL_REDIRECT_REQUEST;
379 complete_callback_ = callback; 391 complete_callback_ = callback;
380 392
381 // Notify each throttle of the request. 393 // Notify each throttle of the request.
382 NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest(); 394 NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest();
383 395
384 // If the navigation is not deferred, run the callback. 396 // If the navigation is not deferred, run the callback.
385 if (result != NavigationThrottle::DEFER) 397 if (result != NavigationThrottle::DEFER)
386 RunCompleteCallback(result); 398 RunCompleteCallback(result);
387 } 399 }
388 400
389 void NavigationHandleImpl::WillProcessResponse( 401 void NavigationHandleImpl::WillProcessResponse(
390 RenderFrameHostImpl* render_frame_host, 402 RenderFrameHostImpl* render_frame_host,
391 scoped_refptr<net::HttpResponseHeaders> response_headers, 403 scoped_refptr<net::HttpResponseHeaders> response_headers,
392 const SSLStatus& ssl_status, 404 const SSLStatus& ssl_status,
405 const GlobalRequestID& request_id,
406 bool should_replace_current_entry,
407 bool is_download,
408 bool is_stream,
409 const base::Closure& transfer_callback,
393 const ThrottleChecksFinishedCallback& callback) { 410 const ThrottleChecksFinishedCallback& callback) {
394 DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host); 411 DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
395 render_frame_host_ = render_frame_host; 412 render_frame_host_ = render_frame_host;
396 response_headers_ = response_headers; 413 response_headers_ = response_headers;
414 request_id_ = request_id;
415 should_replace_current_entry_ = should_replace_current_entry;
416 is_download_ = is_download;
417 is_stream_ = is_stream;
397 state_ = WILL_PROCESS_RESPONSE; 418 state_ = WILL_PROCESS_RESPONSE;
398 ssl_status_ = ssl_status; 419 ssl_status_ = ssl_status;
399 complete_callback_ = callback; 420 complete_callback_ = callback;
421 transfer_callback_ = transfer_callback;
400 422
401 // Notify each throttle of the response. 423 // Notify each throttle of the response.
402 NavigationThrottle::ThrottleCheckResult result = CheckWillProcessResponse(); 424 NavigationThrottle::ThrottleCheckResult result = CheckWillProcessResponse();
403 425
404 // If the navigation is about to proceed, then it's ready to commit. 426 // If the navigation is about to proceed, check for the final RenderFrameHost
405 if (result == NavigationThrottle::PROCEED) 427 // for the navigation.
406 ReadyToCommitNavigation(render_frame_host); 428 // Note: if GetFinalRenderFrameHost() returns false, this means that this
429 // NavigationHandle was deleted, so return immediately.
430 if (result == NavigationThrottle::PROCEED && !GetFinalRenderFrameHost())
431 return;
407 432
408 // If the navigation is not deferred, run the callback. 433 // If the navigation is not deferred, run the callback.
409 if (result != NavigationThrottle::DEFER) 434 if (result != NavigationThrottle::DEFER)
410 RunCompleteCallback(result); 435 RunCompleteCallback(result);
411 } 436 }
412 437
413 void NavigationHandleImpl::ReadyToCommitNavigation( 438 void NavigationHandleImpl::ReadyToCommitNavigation(
414 RenderFrameHostImpl* render_frame_host) { 439 RenderFrameHostImpl* render_frame_host) {
415 DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host); 440 DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
416 render_frame_host_ = render_frame_host; 441 render_frame_host_ = render_frame_host;
417 state_ = READY_TO_COMMIT; 442 state_ = READY_TO_COMMIT;
418 443
419 // Only notify the WebContentsObservers when PlzNavigate is enabled, as 444 GetDelegate()->ReadyToCommitNavigation(this);
420 // |render_frame_host_| may be wrong in the case of transfer navigations.
421 if (IsBrowserSideNavigationEnabled())
422 GetDelegate()->ReadyToCommitNavigation(this);
423 } 445 }
424 446
425 void NavigationHandleImpl::DidCommitNavigation( 447 void NavigationHandleImpl::DidCommitNavigation(
426 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, 448 const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
427 bool same_page, 449 bool same_page,
428 RenderFrameHostImpl* render_frame_host) { 450 RenderFrameHostImpl* render_frame_host) {
429 DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host); 451 DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
430 DCHECK_EQ(frame_tree_node_, render_frame_host->frame_tree_node()); 452 DCHECK_EQ(frame_tree_node_, render_frame_host->frame_tree_node());
431 CHECK_EQ(url_, params.url); 453 CHECK_EQ(url_, params.url);
432 454
433 method_ = params.method; 455 method_ = params.method;
434 has_user_gesture_ = (params.gesture == NavigationGestureUser); 456 has_user_gesture_ = (params.gesture == NavigationGestureUser);
435 transition_ = params.transition; 457 transition_ = params.transition;
436 render_frame_host_ = render_frame_host; 458 render_frame_host_ = render_frame_host;
437 is_same_page_ = same_page; 459 is_same_page_ = same_page;
438 460
439 state_ = net_error_code_ == net::OK ? DID_COMMIT : DID_COMMIT_ERROR_PAGE; 461 state_ = net_error_code_ == net::OK ? DID_COMMIT : DID_COMMIT_ERROR_PAGE;
440 } 462 }
441 463
442 void NavigationHandleImpl::UpdateSSLCertId(int new_cert_id) { 464 void NavigationHandleImpl::UpdateSSLCertId(int new_cert_id) {
443 DCHECK(ssl_status_.cert_id) << "Must have set an SSL certificate already."; 465 DCHECK(ssl_status_.cert_id) << "Must have set an SSL certificate already.";
444 ssl_status_.cert_id = new_cert_id; 466 ssl_status_.cert_id = new_cert_id;
445 } 467 }
446 468
469 void NavigationHandleImpl::TransferredToRenderFrameHost(
470 RenderFrameHostImpl* render_frame_host) {
471 DCHECK(!IsBrowserSideNavigationEnabled());
472 if (render_frame_host != render_frame_host_) {
473 // This is an actual transfer. Inform the NavigationResourceThrottle.
474 BrowserThread::PostTask(
475 BrowserThread::IO, FROM_HERE, transfer_callback_);
476 transfer_callback_.Reset();
477 }
478 render_frame_host_ = render_frame_host;
479 }
480
447 NavigationThrottle::ThrottleCheckResult 481 NavigationThrottle::ThrottleCheckResult
448 NavigationHandleImpl::CheckWillStartRequest() { 482 NavigationHandleImpl::CheckWillStartRequest() {
449 DCHECK(state_ == WILL_SEND_REQUEST || state_ == DEFERRING_START); 483 DCHECK(state_ == WILL_SEND_REQUEST || state_ == DEFERRING_START);
450 DCHECK(state_ != WILL_SEND_REQUEST || next_index_ == 0); 484 DCHECK(state_ != WILL_SEND_REQUEST || next_index_ == 0);
451 DCHECK(state_ != DEFERRING_START || next_index_ != 0); 485 DCHECK(state_ != DEFERRING_START || next_index_ != 0);
452 for (size_t i = next_index_; i < throttles_.size(); ++i) { 486 for (size_t i = next_index_; i < throttles_.size(); ++i) {
453 NavigationThrottle::ThrottleCheckResult result = 487 NavigationThrottle::ThrottleCheckResult result =
454 throttles_[i]->WillStartRequest(); 488 throttles_[i]->WillStartRequest();
455 switch (result) { 489 switch (result) {
456 case NavigationThrottle::PROCEED: 490 case NavigationThrottle::PROCEED:
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 567
534 case NavigationThrottle::BLOCK_REQUEST: 568 case NavigationThrottle::BLOCK_REQUEST:
535 NOTREACHED(); 569 NOTREACHED();
536 } 570 }
537 } 571 }
538 next_index_ = 0; 572 next_index_ = 0;
539 state_ = WILL_PROCESS_RESPONSE; 573 state_ = WILL_PROCESS_RESPONSE;
540 return NavigationThrottle::PROCEED; 574 return NavigationThrottle::PROCEED;
541 } 575 }
542 576
577 bool NavigationHandleImpl::GetFinalRenderFrameHost() {
578 DCHECK_EQ(WILL_PROCESS_RESPONSE, state_);
579
580 // Check if the navigation should transfer. This may result in the
581 // destruction of this NavigationHandle, and the cancellation of the request.
582 if (!CheckForTransfer())
583 return false;
584
585 // Inform observers that the navigation is now ready to commit, unless a
586 // transfer of the navigation failed.
587 ReadyToCommitNavigation(render_frame_host_);
588 return true;
589 }
590
591 bool NavigationHandleImpl::CheckForTransfer() {
nasko 2016/09/08 23:45:39 Should we DCHECK that render_frame_host_ is valid?
clamy 2016/09/09 15:06:41 Done.
592 // PlzNavigate: the final RenderFrameHost handling this navigation has been
593 // decided before calling WillProcessResponse.
594 if (IsBrowserSideNavigationEnabled())
595 return true;
596
597 // Subframes shouldn't swap processes unless out-of-process iframes are
598 // possible.
599 if (!IsInMainFrame() && !SiteIsolationPolicy::AreCrossProcessFramesPossible())
600 return true;
601
602 // If this is a download, do not do a cross-site check. The renderer will
603 // see it is a download and abort the request.
604 //
605 // Similarly, HTTP 204 (No Content) responses leave the renderer showing the
606 // previous page. The navigation should be allowed to finish without running
607 // the unload handler or swapping in the pending RenderFrameHost.
608 if (is_download_ || is_stream_ ||
609 (response_headers_.get() && response_headers_->response_code() == 204)) {
610 return true;
611 }
612
613 // The content embedder can decide that a transfer to a different process is
614 // required for this URL.
615 bool should_transfer =
616 GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
617 frame_tree_node_->navigator()->GetController()->GetBrowserContext(),
618 original_url_, url_);
619
620 RenderFrameHostManager* manager =
621 render_frame_host_->frame_tree_node()->render_manager();
622
623 // In the site-per-process model, the RenderFrameHostManager may also decide
624 // (independently from the content embedder's ShouldSwapProcessesForRedirect
625 // above) that a process transfer is needed. Process transfers are skipped for
626 // WebUI processes for now, since e.g. chrome://settings has multiple
627 // "cross-site" chrome:// frames, and that doesn't yet work cross- process.
628 if (SiteIsolationPolicy::AreCrossProcessFramesPossible() &&
629 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
630 render_frame_host_->GetProcess()->GetID())) {
631 should_transfer |= manager->IsRendererTransferNeededForNavigation(
632 render_frame_host_, GetURL());
nasko 2016/09/08 23:45:39 Why call GetURL()? Should just use url_ to be cons
clamy 2016/09/09 15:06:41 Done.
633 }
634
635 // Complete the transfer if needed.
nasko 2016/09/08 23:45:39 This comment is confusing to me. The following cod
clamy 2016/09/09 15:06:41 Done.
636 if (should_transfer) {
637 // This may destroy the NavigationHandle if the transfer fails.
638 base::WeakPtr<NavigationHandleImpl> weak_self = weak_factory_.GetWeakPtr();
639 manager->OnCrossSiteResponse(render_frame_host_, request_id_,
640 redirect_chain_, sanitized_referrer_,
641 transition_, should_replace_current_entry_);
642 if (!weak_self)
643 return false;
644 }
645
646 return true;
647 }
648
543 void NavigationHandleImpl::RunCompleteCallback( 649 void NavigationHandleImpl::RunCompleteCallback(
544 NavigationThrottle::ThrottleCheckResult result) { 650 NavigationThrottle::ThrottleCheckResult result) {
545 DCHECK(result != NavigationThrottle::DEFER); 651 DCHECK(result != NavigationThrottle::DEFER);
546 652
547 ThrottleChecksFinishedCallback callback = complete_callback_; 653 ThrottleChecksFinishedCallback callback = complete_callback_;
548 complete_callback_.Reset(); 654 complete_callback_.Reset();
549 655
550 if (!callback.is_null()) 656 if (!callback.is_null())
551 callback.Run(result); 657 callback.Run(result);
552 658
(...skipping 19 matching lines...) Expand all
572 throttles_to_register.push_back(std::move(clear_site_data_throttle)); 678 throttles_to_register.push_back(std::move(clear_site_data_throttle));
573 679
574 if (throttles_to_register.size() > 0) { 680 if (throttles_to_register.size() > 0) {
575 throttles_.insert(throttles_.begin(), throttles_to_register.begin(), 681 throttles_.insert(throttles_.begin(), throttles_to_register.begin(),
576 throttles_to_register.end()); 682 throttles_to_register.end());
577 throttles_to_register.weak_clear(); 683 throttles_to_register.weak_clear();
578 } 684 }
579 } 685 }
580 686
581 } // namespace content 687 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698