Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <iterator> | 7 #include <iterator> |
| 8 | 8 |
| 9 #include "base/debug/dump_without_crashing.h" | 9 #include "base/debug/dump_without_crashing.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 NavigationThrottle::ThrottleCheckResult result) { | 47 NavigationThrottle::ThrottleCheckResult result) { |
| 48 *to_update = result; | 48 *to_update = result; |
| 49 } | 49 } |
| 50 | 50 |
| 51 void NotifyAbandonedTransferNavigation(const GlobalRequestID& id) { | 51 void NotifyAbandonedTransferNavigation(const GlobalRequestID& id) { |
| 52 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 52 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 53 if (ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get()) | 53 if (ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get()) |
| 54 rdh->CancelRequest(id.child_id, id.request_id); | 54 rdh->CancelRequest(id.child_id, id.request_id); |
| 55 } | 55 } |
| 56 | 56 |
| 57 // This is a helper method used in IsSelfReferentialURL. It checks if two | |
| 58 // URLs are identical when the URL fragments are removed. | |
| 59 bool EqualIgnoringFragmentIdentifier(const GURL& a, const GURL& b) { | |
|
nasko
2017/02/07 19:51:20
This is actually being implemented in GURL itself
davidsac (gone - try alexmos)
2017/02/10 18:44:26
Acknowledged.
| |
| 60 // Compute the length of each URL without its ref. Note that the reference | |
| 61 // begin (if it exists) points to the character *after* the '#', so we need | |
| 62 // to subtract one. | |
| 63 int aLength = a.spec().length(); | |
| 64 if (a.parsed_for_possibly_invalid_spec().ref.len >= 0) | |
| 65 aLength = a.parsed_for_possibly_invalid_spec().ref.begin - 1; | |
| 66 | |
| 67 int bLength = b.spec().length(); | |
| 68 if (b.parsed_for_possibly_invalid_spec().ref.len >= 0) | |
| 69 bLength = b.parsed_for_possibly_invalid_spec().ref.begin - 1; | |
| 70 | |
| 71 if (aLength != bLength) | |
| 72 return false; | |
| 73 | |
| 74 const std::string& aString = a.spec(); | |
| 75 const std::string& bString = b.spec(); | |
| 76 // FIXME: Abstraction this into a function in WTFString.h. | |
| 77 for (int i = 0; i < aLength; ++i) { | |
| 78 if (aString[i] != bString[i]) | |
| 79 return false; | |
| 80 } | |
| 81 return true; | |
| 82 } | |
| 83 | |
| 57 } // namespace | 84 } // namespace |
| 58 | 85 |
| 59 // static | 86 // static |
| 60 std::unique_ptr<NavigationHandleImpl> NavigationHandleImpl::Create( | 87 std::unique_ptr<NavigationHandleImpl> NavigationHandleImpl::Create( |
| 61 const GURL& url, | 88 const GURL& url, |
| 62 const std::vector<GURL>& redirect_chain, | 89 const std::vector<GURL>& redirect_chain, |
| 63 FrameTreeNode* frame_tree_node, | 90 FrameTreeNode* frame_tree_node, |
| 64 bool is_renderer_initiated, | 91 bool is_renderer_initiated, |
| 65 bool is_same_page, | 92 bool is_same_page, |
| 66 const base::TimeTicks& navigation_start, | 93 const base::TimeTicks& navigation_start, |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 Referrer(redirect_chain_[0], sanitized_referrer.policy); | 527 Referrer(redirect_chain_[0], sanitized_referrer.policy); |
| 501 } else { | 528 } else { |
| 502 sanitized_referrer_ = sanitized_referrer; | 529 sanitized_referrer_ = sanitized_referrer; |
| 503 } | 530 } |
| 504 is_external_protocol_ = is_external_protocol; | 531 is_external_protocol_ = is_external_protocol; |
| 505 request_context_type_ = request_context_type; | 532 request_context_type_ = request_context_type; |
| 506 mixed_content_context_type_ = mixed_content_context_type; | 533 mixed_content_context_type_ = mixed_content_context_type; |
| 507 state_ = WILL_SEND_REQUEST; | 534 state_ = WILL_SEND_REQUEST; |
| 508 complete_callback_ = callback; | 535 complete_callback_ = callback; |
| 509 | 536 |
| 537 if (IsSelfReferentialURL()) { | |
| 538 state_ = CANCELING; | |
| 539 RunCompleteCallback(NavigationThrottle::CANCEL); | |
| 540 return; | |
| 541 } | |
| 542 | |
| 510 RegisterNavigationThrottles(); | 543 RegisterNavigationThrottles(); |
| 511 | 544 |
| 512 if (IsBrowserSideNavigationEnabled()) | 545 if (IsBrowserSideNavigationEnabled()) |
| 513 navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this); | 546 navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this); |
| 514 | 547 |
| 515 // Notify each throttle of the request. | 548 // Notify each throttle of the request. |
| 516 NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest(); | 549 NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest(); |
| 517 | 550 |
| 518 // If the navigation is not deferred, run the callback. | 551 // If the navigation is not deferred, run the callback. |
| 519 if (result != NavigationThrottle::DEFER) | 552 if (result != NavigationThrottle::DEFER) |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 542 response_headers_ = response_headers; | 575 response_headers_ = response_headers; |
| 543 connection_info_ = connection_info; | 576 connection_info_ = connection_info; |
| 544 was_redirected_ = true; | 577 was_redirected_ = true; |
| 545 redirect_chain_.push_back(new_url); | 578 redirect_chain_.push_back(new_url); |
| 546 if (new_method != "POST") | 579 if (new_method != "POST") |
| 547 resource_request_body_ = nullptr; | 580 resource_request_body_ = nullptr; |
| 548 | 581 |
| 549 state_ = WILL_REDIRECT_REQUEST; | 582 state_ = WILL_REDIRECT_REQUEST; |
| 550 complete_callback_ = callback; | 583 complete_callback_ = callback; |
| 551 | 584 |
| 585 if (IsSelfReferentialURL()) { | |
| 586 state_ = CANCELING; | |
| 587 RunCompleteCallback(NavigationThrottle::CANCEL); | |
| 588 return; | |
| 589 } | |
| 590 | |
| 552 // Notify each throttle of the request. | 591 // Notify each throttle of the request. |
| 553 NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest(); | 592 NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest(); |
| 554 | 593 |
| 555 // If the navigation is not deferred, run the callback. | 594 // If the navigation is not deferred, run the callback. |
| 556 if (result != NavigationThrottle::DEFER) | 595 if (result != NavigationThrottle::DEFER) |
| 557 RunCompleteCallback(result); | 596 RunCompleteCallback(result); |
| 558 } | 597 } |
| 559 | 598 |
| 560 void NavigationHandleImpl::WillProcessResponse( | 599 void NavigationHandleImpl::WillProcessResponse( |
| 561 RenderFrameHostImpl* render_frame_host, | 600 RenderFrameHostImpl* render_frame_host, |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 878 std::unique_ptr<content::NavigationThrottle> ancestor_throttle = | 917 std::unique_ptr<content::NavigationThrottle> ancestor_throttle = |
| 879 content::AncestorThrottle::MaybeCreateThrottleFor(this); | 918 content::AncestorThrottle::MaybeCreateThrottleFor(this); |
| 880 if (ancestor_throttle) | 919 if (ancestor_throttle) |
| 881 throttles_.push_back(std::move(ancestor_throttle)); | 920 throttles_.push_back(std::move(ancestor_throttle)); |
| 882 | 921 |
| 883 throttles_.insert(throttles_.begin(), | 922 throttles_.insert(throttles_.begin(), |
| 884 std::make_move_iterator(throttles_to_register.begin()), | 923 std::make_move_iterator(throttles_to_register.begin()), |
| 885 std::make_move_iterator(throttles_to_register.end())); | 924 std::make_move_iterator(throttles_to_register.end())); |
| 886 } | 925 } |
| 887 | 926 |
| 927 bool NavigationHandleImpl::IsSelfReferentialURL() { | |
| 928 // about: URLs should be exempted since they are reserved for other purposes | |
| 929 // and cannot be the source of infinite recursion. See | |
| 930 // https://crbug.com/341858 . | |
| 931 if (url_.SchemeIs("about")) | |
| 932 return false; | |
| 933 | |
| 934 // Browser-triggered navigations should be exempted. | |
| 935 if (!is_renderer_initiated_) | |
| 936 return false; | |
| 937 | |
| 938 // We allow one level of self-reference because some sites depend on that, | |
| 939 // but we don't allow more than one. | |
| 940 bool found_self_reference = false; | |
| 941 for (const FrameTreeNode* node = frame_tree_node_->parent(); node; | |
| 942 node = node->parent()) { | |
| 943 if (EqualIgnoringFragmentIdentifier(node->current_url(), url_)) { | |
| 944 if (found_self_reference) | |
| 945 return true; | |
| 946 found_self_reference = true; | |
| 947 } | |
| 948 } | |
| 949 return false; | |
| 950 } | |
| 951 | |
| 888 } // namespace content | 952 } // namespace content |
| OLD | NEW |