| 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 <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 3004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3015 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); | 3015 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
| 3016 EXPECT_EQ(entry2, controller.GetLastCommittedEntry()); | 3016 EXPECT_EQ(entry2, controller.GetLastCommittedEntry()); |
| 3017 | 3017 |
| 3018 // The entry should have both the stale FrameNavigationEntry with the old | 3018 // The entry should have both the stale FrameNavigationEntry with the old |
| 3019 // name and the new FrameNavigationEntry for the fallback navigation. | 3019 // name and the new FrameNavigationEntry for the fallback navigation. |
| 3020 ASSERT_EQ(2U, entry2->root_node()->children.size()); | 3020 ASSERT_EQ(2U, entry2->root_node()->children.size()); |
| 3021 EXPECT_EQ(frame_url_b, entry2->root_node()->children[0]->frame_entry->url()); | 3021 EXPECT_EQ(frame_url_b, entry2->root_node()->children[0]->frame_entry->url()); |
| 3022 EXPECT_EQ(data_url, entry2->root_node()->children[1]->frame_entry->url()); | 3022 EXPECT_EQ(data_url, entry2->root_node()->children[1]->frame_entry->url()); |
| 3023 } | 3023 } |
| 3024 | 3024 |
| 3025 // Allows waiting until an URL with a data scheme commits in any frame. |
| 3026 class DataUrlCommitObserver : public WebContentsObserver { |
| 3027 public: |
| 3028 explicit DataUrlCommitObserver(WebContents* web_contents) |
| 3029 : WebContentsObserver(web_contents), |
| 3030 message_loop_runner_(new MessageLoopRunner) {} |
| 3031 |
| 3032 void Wait() { message_loop_runner_->Run(); } |
| 3033 |
| 3034 private: |
| 3035 void DidFinishNavigation(NavigationHandle* navigation_handle) override { |
| 3036 if (navigation_handle->HasCommitted() && |
| 3037 !navigation_handle->IsErrorPage() && |
| 3038 navigation_handle->GetURL().scheme() == "data") |
| 3039 message_loop_runner_->Quit(); |
| 3040 } |
| 3041 |
| 3042 // The MessageLoopRunner used to spin the message loop. |
| 3043 scoped_refptr<MessageLoopRunner> message_loop_runner_; |
| 3044 }; |
| 3045 |
| 3046 // Verify that dynamically generated iframes load properly during a history |
| 3047 // navigation if no history item can be found for them. |
| 3048 // See https://crbug.com/649345. |
| 3049 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 3050 FrameNavigationEntry_DynamicSubframeHistoryFallback) { |
| 3051 // This test only makes sense when subframe FrameNavigationEntries are in use. |
| 3052 if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) |
| 3053 return; |
| 3054 |
| 3055 // 1. Start on a page with a script-generated iframe. The iframe has a |
| 3056 // dynamic name, starts at about:blank, and gets navigated to a dynamic data |
| 3057 // URL as the page is loading. |
| 3058 GURL main_url_a(embedded_test_server()->GetURL( |
| 3059 "a.com", "/navigation_controller/dynamic_iframe.html")); |
| 3060 { |
| 3061 // Wait until the data URL has committed, even if load stop happens after |
| 3062 // about:blank load. |
| 3063 DataUrlCommitObserver data_observer(shell()->web_contents()); |
| 3064 EXPECT_TRUE(NavigateToURL(shell(), main_url_a)); |
| 3065 data_observer.Wait(); |
| 3066 } |
| 3067 const NavigationControllerImpl& controller = |
| 3068 static_cast<const NavigationControllerImpl&>( |
| 3069 shell()->web_contents()->GetController()); |
| 3070 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
| 3071 ->GetFrameTree() |
| 3072 ->root(); |
| 3073 ASSERT_EQ(1U, root->child_count()); |
| 3074 ASSERT_EQ(0U, root->child_at(0)->child_count()); |
| 3075 EXPECT_EQ(main_url_a, root->current_url()); |
| 3076 EXPECT_EQ("data", root->child_at(0)->current_url().scheme()); |
| 3077 |
| 3078 EXPECT_EQ(1, controller.GetEntryCount()); |
| 3079 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
| 3080 NavigationEntryImpl* entry1 = controller.GetLastCommittedEntry(); |
| 3081 |
| 3082 // The entry should have a FrameNavigationEntry for the data subframe. |
| 3083 ASSERT_EQ(1U, entry1->root_node()->children.size()); |
| 3084 EXPECT_EQ("data", |
| 3085 entry1->root_node()->children[0]->frame_entry->url().scheme()); |
| 3086 |
| 3087 // 2. Navigate main frame cross-site, destroying the frames. |
| 3088 GURL main_url_b(embedded_test_server()->GetURL( |
| 3089 "b.com", "/navigation_controller/simple_page_2.html")); |
| 3090 EXPECT_TRUE(NavigateToURL(shell(), main_url_b)); |
| 3091 ASSERT_EQ(0U, root->child_count()); |
| 3092 EXPECT_EQ(main_url_b, root->current_url()); |
| 3093 |
| 3094 EXPECT_EQ(2, controller.GetEntryCount()); |
| 3095 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
| 3096 NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry(); |
| 3097 EXPECT_EQ(0U, entry2->root_node()->children.size()); |
| 3098 |
| 3099 // 3. Go back, recreating the iframe. The subframe will have a new name this |
| 3100 // time, so we won't find a history item for it. We should let the new data |
| 3101 // URL be loaded into it, rather than clobbering it with an about:blank page. |
| 3102 { |
| 3103 // Wait until the data URL has committed, even if load stop happens first. |
| 3104 DataUrlCommitObserver back_load_observer(shell()->web_contents()); |
| 3105 shell()->web_contents()->GetController().GoBack(); |
| 3106 back_load_observer.Wait(); |
| 3107 } |
| 3108 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
| 3109 ASSERT_EQ(1U, root->child_count()); |
| 3110 EXPECT_EQ(main_url_a, root->current_url()); |
| 3111 EXPECT_EQ("data", root->child_at(0)->current_url().scheme()); |
| 3112 |
| 3113 EXPECT_EQ(2, controller.GetEntryCount()); |
| 3114 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
| 3115 EXPECT_EQ(entry1, controller.GetLastCommittedEntry()); |
| 3116 |
| 3117 // The entry should have both the stale FrameNavigationEntry with the old |
| 3118 // name and the new FrameNavigationEntry for the fallback navigation. |
| 3119 ASSERT_EQ(2U, entry1->root_node()->children.size()); |
| 3120 EXPECT_EQ("data", |
| 3121 entry1->root_node()->children[0]->frame_entry->url().scheme()); |
| 3122 EXPECT_EQ("data", |
| 3123 entry1->root_node()->children[1]->frame_entry->url().scheme()); |
| 3124 |
| 3125 // The iframe commit should have been classified AUTO_SUBFRAME and not |
| 3126 // NEW_SUBFRAME, so we should still be able to go forward. |
| 3127 EXPECT_TRUE(shell()->web_contents()->GetController().CanGoForward()); |
| 3128 } |
| 3129 |
| 3025 // Verify that we don't clobber any content injected into the initial blank page | 3130 // Verify that we don't clobber any content injected into the initial blank page |
| 3026 // if we go back to an about:blank subframe. See https://crbug.com/626416. | 3131 // if we go back to an about:blank subframe. See https://crbug.com/626416. |
| 3027 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 3132 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 3028 FrameNavigationEntry_RecreatedBlankSubframe) { | 3133 FrameNavigationEntry_RecreatedBlankSubframe) { |
| 3029 // 1. Start on a page that injects content into an about:blank iframe. | 3134 // 1. Start on a page that injects content into an about:blank iframe. |
| 3030 GURL main_url(embedded_test_server()->GetURL( | 3135 GURL main_url(embedded_test_server()->GetURL( |
| 3031 "/navigation_controller/inject_into_blank_iframe.html")); | 3136 "/navigation_controller/inject_into_blank_iframe.html")); |
| 3032 GURL blank_url(url::kAboutBlankURL); | 3137 GURL blank_url(url::kAboutBlankURL); |
| 3033 EXPECT_TRUE(NavigateToURL(shell(), main_url)); | 3138 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 3034 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( | 3139 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( |
| (...skipping 2955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5990 &headers)); | 6095 &headers)); |
| 5991 | 6096 |
| 5992 // Verify the Origin and Referer headers. | 6097 // Verify the Origin and Referer headers. |
| 5993 EXPECT_THAT(headers, ::testing::HasSubstr("Origin: null")); | 6098 EXPECT_THAT(headers, ::testing::HasSubstr("Origin: null")); |
| 5994 EXPECT_THAT(headers, | 6099 EXPECT_THAT(headers, |
| 5995 ::testing::ContainsRegex( | 6100 ::testing::ContainsRegex( |
| 5996 "Referer: http://a.com:.*/form_that_posts_cross_site.html")); | 6101 "Referer: http://a.com:.*/form_that_posts_cross_site.html")); |
| 5997 } | 6102 } |
| 5998 | 6103 |
| 5999 } // namespace content | 6104 } // namespace content |
| OLD | NEW |