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

Side by Side Diff: content/browser/frame_host/navigation_controller_impl.cc

Issue 317703004: Simplify AreURLsInPageNavigation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: + fix comment typos 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_controller_impl.h" 5 #include "content/browser/frame_host/navigation_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 for (size_t i = 0; i < entries->size(); ++i) { 97 for (size_t i = 0; i < entries->size(); ++i) {
98 // Use a transition type of reload so that we don't incorrectly increase 98 // Use a transition type of reload so that we don't incorrectly increase
99 // the typed count. 99 // the typed count.
100 (*entries)[i]->SetTransitionType(PAGE_TRANSITION_RELOAD); 100 (*entries)[i]->SetTransitionType(PAGE_TRANSITION_RELOAD);
101 (*entries)[i]->set_restore_type(ControllerRestoreTypeToEntryType(type)); 101 (*entries)[i]->set_restore_type(ControllerRestoreTypeToEntryType(type));
102 // NOTE(darin): This code is only needed for backwards compat. 102 // NOTE(darin): This code is only needed for backwards compat.
103 SetPageStateIfEmpty((*entries)[i].get()); 103 SetPageStateIfEmpty((*entries)[i].get());
104 } 104 }
105 } 105 }
106 106
107 // See NavigationController::IsURLInPageNavigation for how this works and why. 107 // There are two general cases where a navigation is in page:
108 // 1. A fragment navigation, in which the url is kept the same except for the
109 // reference fragment.
110 // 2. A history API navigation (pushState and replaceState). This case is
111 // always in-page, but the urls are not guaranteed to match excluding the
112 // fragment. The relevant spec allows pushState/replaceState to any URL on
113 // the same origin.
114 // However, due to reloads, even identical urls are *not* guaranteed to be
115 // in-page navigations, we have to trust the renderer almost entirely.
116 // The one thing we do know is that cross-origin navigations will *never* be
117 // in-page. Therefore, trust the renderer if the URLs are on the same origin,
118 // and assume the renderer is malicious if a cross-origin navigation claims to
119 // be in-page.
108 bool AreURLsInPageNavigation(const GURL& existing_url, 120 bool AreURLsInPageNavigation(const GURL& existing_url,
109 const GURL& new_url, 121 const GURL& new_url,
110 bool renderer_says_in_page, 122 bool renderer_says_in_page,
111 NavigationType navigation_type) { 123 RenderFrameHost* rfh) {
112 if (existing_url.GetOrigin() == new_url.GetOrigin()) 124 bool is_same_origin = existing_url.is_empty() ||
Nate Chapin 2014/06/06 22:45:23 Declaring a navigation from an empty url same-orig
nasko 2014/06/09 18:49:43 Isn't the initial empty document with "about:blank
Nate Chapin 2014/06/09 18:53:49 It is (most of the time, there's a special case in
nasko 2014/06/09 18:59:24 Ok, though I think we would have to start reportin
Nate Chapin 2014/06/09 19:02:54 Huh, interesting. I would have thought that the in
nasko 2014/06/09 20:41:28 When I discussed this with Charlie, we found that
113 return renderer_says_in_page; 125 existing_url.GetOrigin() == new_url.GetOrigin();
114 126 if (!is_same_origin && renderer_says_in_page)
115 if (!new_url.has_ref()) { 127 rfh->GetProcess()->ReceivedBadMessage();
116 // When going back from the ref URL to the non ref one the navigation type 128 return is_same_origin && renderer_says_in_page;
117 // is IN_PAGE.
118 return navigation_type == NAVIGATION_TYPE_IN_PAGE;
119 }
120
121 url::Replacements<char> replacements;
122 replacements.ClearRef();
123 return existing_url.ReplaceComponents(replacements) ==
124 new_url.ReplaceComponents(replacements);
125 } 129 }
126 130
127 // Determines whether or not we should be carrying over a user agent override 131 // Determines whether or not we should be carrying over a user agent override
128 // between two NavigationEntries. 132 // between two NavigationEntries.
129 bool ShouldKeepOverride(const NavigationEntry* last_entry) { 133 bool ShouldKeepOverride(const NavigationEntry* last_entry) {
130 return last_entry && last_entry->GetIsOverridingUserAgent(); 134 return last_entry && last_entry->GetIsOverridingUserAgent();
131 } 135 }
132 136
133 } // namespace 137 } // namespace
134 138
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 // effect of removing forward browsing history, if such existed. 763 // effect of removing forward browsing history, if such existed.
760 // Or if we are doing a cross-site redirect navigation, 764 // Or if we are doing a cross-site redirect navigation,
761 // we will do a similar thing. 765 // we will do a similar thing.
762 details->did_replace_entry = 766 details->did_replace_entry =
763 pending_entry_ && pending_entry_->should_replace_entry(); 767 pending_entry_ && pending_entry_->should_replace_entry();
764 768
765 // Do navigation-type specific actions. These will make and commit an entry. 769 // Do navigation-type specific actions. These will make and commit an entry.
766 details->type = ClassifyNavigation(rfh, params); 770 details->type = ClassifyNavigation(rfh, params);
767 771
768 // is_in_page must be computed before the entry gets committed. 772 // is_in_page must be computed before the entry gets committed.
769 details->is_in_page = IsURLInPageNavigation( 773 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(),
Nate Chapin 2014/06/06 22:45:23 Unlike other uses of the in-page logic, this calls
nasko 2014/06/09 18:49:43 GetLastCommittedURL on RFH worries me a bit. It co
Nate Chapin 2014/06/09 18:53:49 Fair enough. Is there an alternate way to get the
nasko 2014/06/09 18:59:24 It is already there: https://code.google.com/p/chr
Nate Chapin 2014/06/09 19:02:54 I see the URL being navigated to, the base url, an
nasko 2014/06/09 20:41:28 Duh, I misread what you meant. You are correct. Lo
770 params.url, params.was_within_same_page, details->type); 774 params.url, params.was_within_same_page, rfh);
771 775
772 switch (details->type) { 776 switch (details->type) {
773 case NAVIGATION_TYPE_NEW_PAGE: 777 case NAVIGATION_TYPE_NEW_PAGE:
774 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); 778 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry);
775 break; 779 break;
776 case NAVIGATION_TYPE_EXISTING_PAGE: 780 case NAVIGATION_TYPE_EXISTING_PAGE:
777 RendererDidNavigateToExistingPage(rfh, params); 781 RendererDidNavigateToExistingPage(rfh, params);
778 break; 782 break;
779 case NAVIGATION_TYPE_SAME_PAGE: 783 case NAVIGATION_TYPE_SAME_PAGE:
780 RendererDidNavigateToSamePage(rfh, params); 784 RendererDidNavigateToSamePage(rfh, params);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 // the pending entry and go back to where we were (the "existing entry"). 983 // the pending entry and go back to where we were (the "existing entry").
980 return NAVIGATION_TYPE_SAME_PAGE; 984 return NAVIGATION_TYPE_SAME_PAGE;
981 } 985 }
982 986
983 // Any toplevel navigations with the same base (minus the reference fragment) 987 // Any toplevel navigations with the same base (minus the reference fragment)
984 // are in-page navigations. We weeded out subframe navigations above. Most of 988 // are in-page navigations. We weeded out subframe navigations above. Most of
985 // the time this doesn't matter since WebKit doesn't tell us about subframe 989 // the time this doesn't matter since WebKit doesn't tell us about subframe
986 // navigations that don't actually navigate, but it can happen when there is 990 // navigations that don't actually navigate, but it can happen when there is
987 // an encoding override (it always sends a navigation request). 991 // an encoding override (it always sends a navigation request).
988 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url, 992 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url,
989 params.was_within_same_page, 993 params.was_within_same_page, rfh)) {
990 NAVIGATION_TYPE_UNKNOWN)) {
991 return NAVIGATION_TYPE_IN_PAGE; 994 return NAVIGATION_TYPE_IN_PAGE;
992 } 995 }
993 996
994 // Since we weeded out "new" navigations above, we know this is an existing 997 // Since we weeded out "new" navigations above, we know this is an existing
995 // (back/forward) navigation. 998 // (back/forward) navigation.
996 return NAVIGATION_TYPE_EXISTING_PAGE; 999 return NAVIGATION_TYPE_EXISTING_PAGE;
997 } 1000 }
998 1001
999 void NavigationControllerImpl::RendererDidNavigateToNewPage( 1002 void NavigationControllerImpl::RendererDidNavigateToNewPage(
1000 RenderFrameHost* rfh, 1003 RenderFrameHost* rfh,
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 const NavigationEntries::const_iterator i(std::find( 1249 const NavigationEntries::const_iterator i(std::find(
1247 entries_.begin(), 1250 entries_.begin(),
1248 entries_.end(), 1251 entries_.end(),
1249 entry)); 1252 entry));
1250 return (i == entries_.end()) ? -1 : static_cast<int>(i - entries_.begin()); 1253 return (i == entries_.end()) ? -1 : static_cast<int>(i - entries_.begin());
1251 } 1254 }
1252 1255
1253 bool NavigationControllerImpl::IsURLInPageNavigation( 1256 bool NavigationControllerImpl::IsURLInPageNavigation(
1254 const GURL& url, 1257 const GURL& url,
1255 bool renderer_says_in_page, 1258 bool renderer_says_in_page,
1256 NavigationType navigation_type) const { 1259 RenderFrameHost* rfh) const {
1257 NavigationEntry* last_committed = GetLastCommittedEntry(); 1260 NavigationEntry* last_committed = GetLastCommittedEntry();
1258 return last_committed && AreURLsInPageNavigation( 1261 return last_committed && AreURLsInPageNavigation(
1259 last_committed->GetURL(), url, renderer_says_in_page, navigation_type); 1262 last_committed->GetURL(), url, renderer_says_in_page, rfh);
1260 } 1263 }
1261 1264
1262 void NavigationControllerImpl::CopyStateFrom( 1265 void NavigationControllerImpl::CopyStateFrom(
1263 const NavigationController& temp) { 1266 const NavigationController& temp) {
1264 const NavigationControllerImpl& source = 1267 const NavigationControllerImpl& source =
1265 static_cast<const NavigationControllerImpl&>(temp); 1268 static_cast<const NavigationControllerImpl&>(temp);
1266 // Verify that we look new. 1269 // Verify that we look new.
1267 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); 1270 DCHECK(GetEntryCount() == 0 && !GetPendingEntry());
1268 1271
1269 if (source.GetEntryCount() == 0) 1272 if (source.GetEntryCount() == 0)
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 } 1773 }
1771 } 1774 }
1772 } 1775 }
1773 1776
1774 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 1777 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
1775 const base::Callback<base::Time()>& get_timestamp_callback) { 1778 const base::Callback<base::Time()>& get_timestamp_callback) {
1776 get_timestamp_callback_ = get_timestamp_callback; 1779 get_timestamp_callback_ = get_timestamp_callback;
1777 } 1780 }
1778 1781
1779 } // namespace content 1782 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698