| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <stdint.h> | 7 #include <stdint.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 6030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6041 // Test that navigations classified as SAME_PAGE properly update all the | 6041 // Test that navigations classified as SAME_PAGE properly update all the |
| 6042 // members of FrameNavigationEntry. If not, it is possible to get a mismatch | 6042 // members of FrameNavigationEntry. If not, it is possible to get a mismatch |
| 6043 // between the origin and URL of a document as seen in | 6043 // between the origin and URL of a document as seen in |
| 6044 // https://crbug.com/630103. | 6044 // https://crbug.com/630103. |
| 6045 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 6045 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 6046 EnsureSamePageNavigationUpdatesFrameNavigationEntry) { | 6046 EnsureSamePageNavigationUpdatesFrameNavigationEntry) { |
| 6047 WebContentsImpl* web_contents = | 6047 WebContentsImpl* web_contents = |
| 6048 static_cast<WebContentsImpl*>(shell()->web_contents()); | 6048 static_cast<WebContentsImpl*>(shell()->web_contents()); |
| 6049 FrameTreeNode* root = web_contents->GetFrameTree()->root(); | 6049 FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
| 6050 | 6050 |
| 6051 // Navigate to a simple page and then perform an in-page navigation. | 6051 // Navigate to a simple page and then perform a fragment change navigation. |
| 6052 GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); | 6052 GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); |
| 6053 EXPECT_TRUE(NavigateToURL(shell(), start_url)); | 6053 EXPECT_TRUE(NavigateToURL(shell(), start_url)); |
| 6054 | 6054 |
| 6055 GURL same_page_url( | 6055 GURL fragment_change_url( |
| 6056 embedded_test_server()->GetURL("a.com", "/title1.html#foo")); | 6056 embedded_test_server()->GetURL("a.com", "/title1.html#foo")); |
| 6057 EXPECT_TRUE(NavigateToURL(shell(), same_page_url)); | 6057 EXPECT_TRUE(NavigateToURL(shell(), fragment_change_url)); |
| 6058 EXPECT_EQ(2, web_contents->GetController().GetEntryCount()); | 6058 EXPECT_EQ(2, web_contents->GetController().GetEntryCount()); |
| 6059 | 6059 |
| 6060 // Replace the URL of the current NavigationEntry with one that will cause | 6060 // Replace the URL of the current NavigationEntry with one that will cause |
| 6061 // a server redirect when loaded. | 6061 // a server redirect when loaded. |
| 6062 { | 6062 { |
| 6063 GURL redirect_dest_url( | 6063 GURL redirect_dest_url( |
| 6064 embedded_test_server()->GetURL("sub.a.com", "/simple_page.html")); | 6064 embedded_test_server()->GetURL("sub.a.com", "/simple_page.html")); |
| 6065 TestNavigationObserver observer(web_contents); | 6065 TestNavigationObserver observer(web_contents); |
| 6066 std::string script = "history.replaceState({}, '', '/server-redirect?" + | 6066 std::string script = "history.replaceState({}, '', '/server-redirect?" + |
| 6067 redirect_dest_url.spec() + "')"; | 6067 redirect_dest_url.spec() + "')"; |
| 6068 EXPECT_TRUE(ExecuteScript(root, script)); | 6068 EXPECT_TRUE(ExecuteScript(root, script)); |
| 6069 observer.Wait(); | 6069 observer.Wait(); |
| 6070 } | 6070 } |
| 6071 | 6071 |
| 6072 // Simulate the user hitting Enter in the omnibox without changing the URL. | 6072 // Simulate the user hitting Enter in the omnibox without changing the URL. |
| 6073 { | 6073 { |
| 6074 TestNavigationObserver observer(web_contents); | 6074 TestNavigationObserver observer(web_contents); |
| 6075 web_contents->GetController().LoadURL(web_contents->GetLastCommittedURL(), | 6075 web_contents->GetController().LoadURL(web_contents->GetLastCommittedURL(), |
| 6076 Referrer(), ui::PAGE_TRANSITION_LINK, | 6076 Referrer(), ui::PAGE_TRANSITION_LINK, |
| 6077 std::string()); | 6077 std::string()); |
| 6078 observer.Wait(); | 6078 observer.Wait(); |
| 6079 } | 6079 } |
| 6080 | 6080 |
| 6081 // Prior to fixing the issue, the above omnibox navigation (which is | 6081 // Prior to fixing the issue, the above omnibox navigation (which is |
| 6082 // classified as SAME_PAGE) was leaving the FrameNavigationEntry with the | 6082 // classified as SAME_PAGE) was leaving the FrameNavigationEntry with the |
| 6083 // same document sequence number as the previous entry but updates the URL. | 6083 // same document sequence number as the previous entry but updates the URL. |
| 6084 // Doing a back session history navigation now will cause the browser to | 6084 // Doing a back session history navigation now will cause the browser to |
| 6085 // consider it as in-page because of this matching document sequence number | 6085 // consider it as same document because of this matching document sequence |
| 6086 // and lead to a mismatch of origin and URL in the renderer process. | 6086 // number and lead to a mismatch of origin and URL in the renderer process. |
| 6087 { | 6087 { |
| 6088 TestNavigationObserver observer(web_contents); | 6088 TestNavigationObserver observer(web_contents); |
| 6089 web_contents->GetController().GoBack(); | 6089 web_contents->GetController().GoBack(); |
| 6090 observer.Wait(); | 6090 observer.Wait(); |
| 6091 } | 6091 } |
| 6092 | 6092 |
| 6093 // Verify the expected origin through JavaScript. It also has the additional | 6093 // Verify the expected origin through JavaScript. It also has the additional |
| 6094 // verification of the process also being still alive. | 6094 // verification of the process also being still alive. |
| 6095 std::string origin; | 6095 std::string origin; |
| 6096 EXPECT_TRUE(ExecuteScriptAndExtractString( | 6096 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6144 return true; | 6144 return true; |
| 6145 } | 6145 } |
| 6146 | 6146 |
| 6147 GURL url_; | 6147 GURL url_; |
| 6148 WebContentsImpl* web_contents_; | 6148 WebContentsImpl* web_contents_; |
| 6149 | 6149 |
| 6150 DISALLOW_COPY_AND_ASSIGN(GoBackAndCommitFilter); | 6150 DISALLOW_COPY_AND_ASSIGN(GoBackAndCommitFilter); |
| 6151 }; | 6151 }; |
| 6152 | 6152 |
| 6153 // Test which simulates a race condition between a cross-origin, same-process | 6153 // Test which simulates a race condition between a cross-origin, same-process |
| 6154 // navigation and a same page session history navigation. When such a race | 6154 // navigation and a same document session history navigation. When such a race |
| 6155 // occurs, the renderer will commit the cross-origin navigation, updating its | 6155 // occurs, the renderer will commit the cross-origin navigation, updating its |
| 6156 // version of the current document sequence number, and will send an IPC to the | 6156 // version of the current document sequence number, and will send an IPC to the |
| 6157 // browser process. The session history navigation comes after the commit for | 6157 // browser process. The session history navigation comes after the commit for |
| 6158 // the cross-origin navigation and updates the URL, but not the origin of the | 6158 // the cross-origin navigation and updates the URL, but not the origin of the |
| 6159 // document. This results in mismatch between the two and causes the renderer | 6159 // document. This results in mismatch between the two and causes the renderer |
| 6160 // process to be killed. See https://crbug.com/630103. | 6160 // process to be killed. See https://crbug.com/630103. |
| 6161 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 6161 IN_PROC_BROWSER_TEST_F( |
| 6162 RaceCrossOriginNavigationAndSamePageHistoryNavigation) { | 6162 NavigationControllerBrowserTest, |
| 6163 RaceCrossOriginNavigationAndSameDocumentHistoryNavigation) { |
| 6163 WebContentsImpl* web_contents = | 6164 WebContentsImpl* web_contents = |
| 6164 static_cast<WebContentsImpl*>(shell()->web_contents()); | 6165 static_cast<WebContentsImpl*>(shell()->web_contents()); |
| 6165 FrameTreeNode* root = web_contents->GetFrameTree()->root(); | 6166 FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
| 6166 | 6167 |
| 6167 // Navigate to a simple page and then perform an in-page navigation. | 6168 // Navigate to a simple page and then perform a same document navigation. |
| 6168 GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); | 6169 GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); |
| 6169 EXPECT_TRUE(NavigateToURL(shell(), start_url)); | 6170 EXPECT_TRUE(NavigateToURL(shell(), start_url)); |
| 6170 | 6171 |
| 6171 GURL same_page_url( | 6172 GURL same_document_url( |
| 6172 embedded_test_server()->GetURL("a.com", "/title1.html#foo")); | 6173 embedded_test_server()->GetURL("a.com", "/title1.html#foo")); |
| 6173 EXPECT_TRUE(NavigateToURL(shell(), same_page_url)); | 6174 EXPECT_TRUE(NavigateToURL(shell(), same_document_url)); |
| 6174 EXPECT_EQ(2, web_contents->GetController().GetEntryCount()); | 6175 EXPECT_EQ(2, web_contents->GetController().GetEntryCount()); |
| 6175 | 6176 |
| 6176 // Create a GoBackAndCommitFilter, which will delay the commit IPC for a | 6177 // Create a GoBackAndCommitFilter, which will delay the commit IPC for a |
| 6177 // cross-origin, same process navigation and will perform a GoBack. | 6178 // cross-origin, same process navigation and will perform a GoBack. |
| 6178 GURL cross_origin_url( | 6179 GURL cross_origin_url( |
| 6179 embedded_test_server()->GetURL("suborigin.a.com", "/title2.html")); | 6180 embedded_test_server()->GetURL("suborigin.a.com", "/title2.html")); |
| 6180 scoped_refptr<GoBackAndCommitFilter> filter = | 6181 scoped_refptr<GoBackAndCommitFilter> filter = |
| 6181 new GoBackAndCommitFilter(cross_origin_url, web_contents); | 6182 new GoBackAndCommitFilter(cross_origin_url, web_contents); |
| 6182 web_contents->GetMainFrame()->GetProcess()->AddFilter(filter.get()); | 6183 web_contents->GetMainFrame()->GetProcess()->AddFilter(filter.get()); |
| 6183 | 6184 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 6207 web_contents->GetController().GoBack(); | 6208 web_contents->GetController().GoBack(); |
| 6208 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); | 6209 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
| 6209 EXPECT_EQ(1, web_contents->GetController().GetLastCommittedEntryIndex()); | 6210 EXPECT_EQ(1, web_contents->GetController().GetLastCommittedEntryIndex()); |
| 6210 EXPECT_EQ(3, web_contents->GetController().GetEntryCount()); | 6211 EXPECT_EQ(3, web_contents->GetController().GetEntryCount()); |
| 6211 | 6212 |
| 6212 // Verify the expected origin through JavaScript. It also has the additional | 6213 // Verify the expected origin through JavaScript. It also has the additional |
| 6213 // verification of the process also being still alive. | 6214 // verification of the process also being still alive. |
| 6214 EXPECT_TRUE(ExecuteScriptAndExtractString( | 6215 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 6215 web_contents, "domAutomationController.send(document.origin)", | 6216 web_contents, "domAutomationController.send(document.origin)", |
| 6216 &origin)); | 6217 &origin)); |
| 6217 EXPECT_EQ(same_page_url.GetOrigin().spec(), origin + "/"); | 6218 EXPECT_EQ(same_document_url.GetOrigin().spec(), origin + "/"); |
| 6218 } else { | 6219 } else { |
| 6219 // Wait for the back navigation to commit as well. | 6220 // Wait for the back navigation to commit as well. |
| 6220 history_commit_observer.Wait(); | 6221 history_commit_observer.Wait(); |
| 6221 EXPECT_EQ(start_url, web_contents->GetLastCommittedURL()); | 6222 EXPECT_EQ(start_url, web_contents->GetLastCommittedURL()); |
| 6222 EXPECT_EQ(0, web_contents->GetController().GetLastCommittedEntryIndex()); | 6223 EXPECT_EQ(0, web_contents->GetController().GetLastCommittedEntryIndex()); |
| 6223 EXPECT_EQ(3, web_contents->GetController().GetEntryCount()); | 6224 EXPECT_EQ(3, web_contents->GetController().GetEntryCount()); |
| 6224 | 6225 |
| 6225 // Verify the expected origin through JavaScript. It also has the additional | 6226 // Verify the expected origin through JavaScript. It also has the additional |
| 6226 // verification of the process also being still alive. | 6227 // verification of the process also being still alive. |
| 6227 std::string origin; | 6228 std::string origin; |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6669 was_same_page_ = handle->IsSameDocument(); | 6670 was_same_page_ = handle->IsSameDocument(); |
| 6670 was_renderer_initiated_ = handle->IsRendererInitiated(); | 6671 was_renderer_initiated_ = handle->IsRendererInitiated(); |
| 6671 } | 6672 } |
| 6672 | 6673 |
| 6673 const GURL url_; | 6674 const GURL url_; |
| 6674 bool has_committed_; | 6675 bool has_committed_; |
| 6675 bool was_same_page_; | 6676 bool was_same_page_; |
| 6676 bool was_renderer_initiated_; | 6677 bool was_renderer_initiated_; |
| 6677 }; | 6678 }; |
| 6678 | 6679 |
| 6679 // Test that a same-page navigation does not lead to the deletion of the | 6680 // Test that a same document navigation does not lead to the deletion of the |
| 6680 // NavigationHandle for an ongoing different page navigation. | 6681 // NavigationHandle for an ongoing different document navigation. |
| 6681 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 6682 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 6682 SamePageNavigationDoesntDeleteNavigationHandle) { | 6683 SameDocumentNavigationDoesntDeleteNavigationHandle) { |
| 6683 const GURL kURL1 = embedded_test_server()->GetURL("/title1.html"); | 6684 const GURL kURL1 = embedded_test_server()->GetURL("/title1.html"); |
| 6684 const GURL kPushStateURL = | 6685 const GURL kPushStateURL = |
| 6685 embedded_test_server()->GetURL("/title1.html#fragment"); | 6686 embedded_test_server()->GetURL("/title1.html#fragment"); |
| 6686 const GURL kURL2 = embedded_test_server()->GetURL("/title2.html"); | 6687 const GURL kURL2 = embedded_test_server()->GetURL("/title2.html"); |
| 6687 | 6688 |
| 6688 // Navigate to the initial page. | 6689 // Navigate to the initial page. |
| 6689 EXPECT_TRUE(NavigateToURL(shell(), kURL1)); | 6690 EXPECT_TRUE(NavigateToURL(shell(), kURL1)); |
| 6690 RenderFrameHostImpl* main_frame = | 6691 RenderFrameHostImpl* main_frame = |
| 6691 static_cast<WebContentsImpl*>(shell()->web_contents())->GetMainFrame(); | 6692 static_cast<WebContentsImpl*>(shell()->web_contents())->GetMainFrame(); |
| 6692 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | 6693 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6742 shell()->web_contents()->GetController().GetLastCommittedEntry(); | 6743 shell()->web_contents()->GetController().GetLastCommittedEntry(); |
| 6743 ASSERT_TRUE(last_committed); | 6744 ASSERT_TRUE(last_committed); |
| 6744 EXPECT_EQ(kURL2, last_committed->GetURL()); | 6745 EXPECT_EQ(kURL2, last_committed->GetURL()); |
| 6745 | 6746 |
| 6746 EXPECT_TRUE(navigation_observer.has_committed()); | 6747 EXPECT_TRUE(navigation_observer.has_committed()); |
| 6747 EXPECT_FALSE(navigation_observer.was_same_page()); | 6748 EXPECT_FALSE(navigation_observer.was_same_page()); |
| 6748 EXPECT_FALSE(navigation_observer.was_renderer_initiated()); | 6749 EXPECT_FALSE(navigation_observer.was_renderer_initiated()); |
| 6749 | 6750 |
| 6750 } | 6751 } |
| 6751 | 6752 |
| 6752 // Tests that a same-page browser-initiated navigation is properly reported by | 6753 // Tests that a same document browser-initiated navigation is properly reported |
| 6753 // the NavigationHandle. | 6754 // by the NavigationHandle. |
| 6754 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 6755 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 6755 SamePageBrowserInitiated) { | 6756 SameDocumentBrowserInitiated) { |
| 6756 const GURL kURL = embedded_test_server()->GetURL("/title1.html"); | 6757 const GURL kURL = embedded_test_server()->GetURL("/title1.html"); |
| 6757 const GURL kFragmentURL = | 6758 const GURL kFragmentURL = |
| 6758 embedded_test_server()->GetURL("/title1.html#fragment"); | 6759 embedded_test_server()->GetURL("/title1.html#fragment"); |
| 6759 | 6760 |
| 6760 // Navigate to the initial page. | 6761 // Navigate to the initial page. |
| 6761 EXPECT_TRUE(NavigateToURL(shell(), kURL)); | 6762 EXPECT_TRUE(NavigateToURL(shell(), kURL)); |
| 6762 | 6763 |
| 6763 // Do a browser-initiated fragment navigation. | 6764 // Do a browser-initiated fragment navigation. |
| 6764 NavigationHandleCommitObserver handle_observer(shell()->web_contents(), | 6765 NavigationHandleCommitObserver handle_observer(shell()->web_contents(), |
| 6765 kFragmentURL); | 6766 kFragmentURL); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 6790 | 6791 |
| 6791 // Do a 204 navigation. | 6792 // Do a 204 navigation. |
| 6792 EXPECT_FALSE(NavigateToURL(shell(), kURL204)); | 6793 EXPECT_FALSE(NavigateToURL(shell(), kURL204)); |
| 6793 | 6794 |
| 6794 entry = controller.GetLastCommittedEntry(); | 6795 entry = controller.GetLastCommittedEntry(); |
| 6795 EXPECT_EQ(kURL, entry->GetURL()); | 6796 EXPECT_EQ(kURL, entry->GetURL()); |
| 6796 EXPECT_EQ(1, controller.GetEntryCount()); | 6797 EXPECT_EQ(1, controller.GetEntryCount()); |
| 6797 } | 6798 } |
| 6798 | 6799 |
| 6799 } // namespace content | 6800 } // namespace content |
| OLD | NEW |