OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "components/subresource_filter/content/browser/subframe_navigation_filt
ering_throttle.h" |
| 6 |
| 7 #include <memory> |
| 8 |
| 9 #include "base/callback_forward.h" |
| 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/run_loop.h" |
| 12 #include "base/strings/stringprintf.h" |
| 13 #include "base/test/test_simple_task_runner.h" |
| 14 #include "components/subresource_filter/content/browser/async_document_subresour
ce_filter.h" |
| 15 #include "components/subresource_filter/core/common/activation_level.h" |
| 16 #include "components/subresource_filter/core/common/activation_state.h" |
| 17 #include "components/subresource_filter/core/common/proto/rules.pb.h" |
| 18 #include "components/subresource_filter/core/common/test_ruleset_creator.h" |
| 19 #include "components/subresource_filter/core/common/test_ruleset_utils.h" |
| 20 #include "content/public/browser/navigation_handle.h" |
| 21 #include "content/public/common/referrer.h" |
| 22 #include "content/public/test/test_renderer_host.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" |
| 24 |
| 25 namespace subresource_filter { |
| 26 |
| 27 namespace { |
| 28 |
| 29 static void UpdateThrottleCheckResult( |
| 30 content::NavigationThrottle::ThrottleCheckResult* to_update, |
| 31 content::NavigationThrottle::ThrottleCheckResult result) { |
| 32 *to_update = result; |
| 33 } |
| 34 |
| 35 } // namespace |
| 36 |
| 37 class SubframeNavigationFilteringThrottleTest |
| 38 : public content::RenderViewHostTestHarness { |
| 39 public: |
| 40 SubframeNavigationFilteringThrottleTest() |
| 41 : blocking_task_runner_(new base::TestSimpleTaskRunner) {} |
| 42 ~SubframeNavigationFilteringThrottleTest() override {} |
| 43 |
| 44 void SetUp() override { |
| 45 content::RenderViewHostTestHarness::SetUp(); |
| 46 NavigateAndCommit(GURL("https://example.test")); |
| 47 } |
| 48 |
| 49 void TearDown() override { |
| 50 test_handle_.reset(); |
| 51 dealer_handle_.reset(); |
| 52 ruleset_handle_.reset(); |
| 53 async_filter_.reset(); |
| 54 RunUntilIdle(); |
| 55 content::RenderViewHostTestHarness::TearDown(); |
| 56 } |
| 57 |
| 58 void InitializeDocumentSubresourceFilter(const GURL& document_url) { |
| 59 ASSERT_NO_FATAL_FAILURE( |
| 60 test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( |
| 61 "disallowed.html", &test_ruleset_pair_)); |
| 62 dealer_handle_ = |
| 63 base::MakeUnique<VerifiedRulesetDealer::Handle>(blocking_task_runner_); |
| 64 dealer_handle_->SetRulesetFile( |
| 65 testing::TestRuleset::Open(test_ruleset_pair_.indexed)); |
| 66 ruleset_handle_ = |
| 67 base::MakeUnique<VerifiedRuleset::Handle>(dealer_handle_.get()); |
| 68 // Unretained is safe because the test blocks waiting until the task is |
| 69 // run. |
| 70 async_filter_ = base::MakeUnique<AsyncDocumentSubresourceFilter>( |
| 71 ruleset_handle_.get(), |
| 72 AsyncDocumentSubresourceFilter::InitializationParams( |
| 73 document_url, ActivationLevel::ENABLED, |
| 74 false /* measure_performance */), |
| 75 base::Bind(&SubframeNavigationFilteringThrottleTest::ExpectActivation, |
| 76 base::Unretained(this), |
| 77 ActivationState(ActivationLevel::ENABLED)), |
| 78 base::OnceClosure()); |
| 79 RunUntilIdle(); |
| 80 } |
| 81 |
| 82 void ExpectActivation(ActivationState expected, ActivationState state) { |
| 83 EXPECT_EQ(expected.activation_level, state.activation_level); |
| 84 } |
| 85 |
| 86 void RunUntilIdle() { |
| 87 blocking_task_runner_->RunUntilIdle(); |
| 88 base::RunLoop().RunUntilIdle(); |
| 89 } |
| 90 |
| 91 void CreateTestSubframeNavigation(const GURL& first_url, |
| 92 content::RenderFrameHost* parent) { |
| 93 navigating_subframe_ = |
| 94 content::RenderFrameHostTester::For(parent)->AppendChild( |
| 95 base::StringPrintf("subframe-%s", first_url.spec().c_str())); |
| 96 test_handle_ = content::NavigationHandle::CreateNavigationHandleForTesting( |
| 97 first_url, navigating_subframe_); |
| 98 test_handle_->RegisterThrottleForTesting( |
| 99 base::MakeUnique<SubframeNavigationFilteringThrottle>( |
| 100 test_handle_.get(), async_filter_.get())); |
| 101 } |
| 102 |
| 103 // Calls WillStartRequest and runs the run loop until the throttle has |
| 104 // finished checking. |
| 105 void SimulateWillStartAndExpectAsyncResult( |
| 106 content::NavigationThrottle::ThrottleCheckResult expected_result) { |
| 107 auto async_result = content::NavigationThrottle::DEFER; |
| 108 auto sync_result = test_handle_->CallWillStartRequestForTesting( |
| 109 false /* is_post */, content::Referrer(), true /* has_user_gesture */, |
| 110 ui::PageTransition::PAGE_TRANSITION_LINK, |
| 111 false /* is_external_protocol */, |
| 112 base::Bind(&UpdateThrottleCheckResult, &async_result)); |
| 113 EXPECT_EQ(content::NavigationThrottle::DEFER, sync_result); |
| 114 RunUntilIdle(); |
| 115 EXPECT_EQ(expected_result, async_result); |
| 116 } |
| 117 |
| 118 // Calls WillRedirectRequest and runs the run loop until the throttle has |
| 119 // finished checking. |
| 120 void SimulateWillRedirectAndExpectAsyncResult( |
| 121 const GURL& new_url, |
| 122 content::NavigationThrottle::ThrottleCheckResult expected_result) { |
| 123 auto async_result = content::NavigationThrottle::DEFER; |
| 124 auto sync_result = test_handle_->CallWillRedirectRequestForTesting( |
| 125 new_url, false /* new_method_is_post */, GURL(), |
| 126 false /* new_is_external_protocol */, |
| 127 base::Bind(&UpdateThrottleCheckResult, &async_result)); |
| 128 EXPECT_EQ(content::NavigationThrottle::DEFER, sync_result); |
| 129 RunUntilIdle(); |
| 130 EXPECT_EQ(expected_result, async_result); |
| 131 } |
| 132 |
| 133 void SimulateWillProcessResponseAndExpectResult( |
| 134 content::NavigationThrottle::ThrottleCheckResult expected_result) { |
| 135 EXPECT_EQ(expected_result, |
| 136 test_handle_->CallWillProcessResponseForTesting( |
| 137 navigating_subframe_, "", |
| 138 content::NavigationHandle::ThrottleChecksFinishedCallback())); |
| 139 } |
| 140 |
| 141 private: |
| 142 scoped_refptr<base::TestSimpleTaskRunner> blocking_task_runner_; |
| 143 |
| 144 testing::TestRulesetCreator test_ruleset_creator_; |
| 145 testing::TestRulesetPair test_ruleset_pair_; |
| 146 |
| 147 std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_; |
| 148 std::unique_ptr<VerifiedRuleset::Handle> ruleset_handle_; |
| 149 |
| 150 std::unique_ptr<AsyncDocumentSubresourceFilter> async_filter_; |
| 151 |
| 152 std::unique_ptr<content::NavigationHandle> test_handle_; |
| 153 |
| 154 content::RenderFrameHost* navigating_subframe_ = nullptr; |
| 155 |
| 156 DISALLOW_COPY_AND_ASSIGN(SubframeNavigationFilteringThrottleTest); |
| 157 }; |
| 158 |
| 159 TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnStart) { |
| 160 InitializeDocumentSubresourceFilter(GURL("https://example.test")); |
| 161 CreateTestSubframeNavigation(GURL("https://example.test/disallowed.html"), |
| 162 main_rfh()); |
| 163 SimulateWillStartAndExpectAsyncResult(content::NavigationThrottle::CANCEL); |
| 164 } |
| 165 |
| 166 TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnRedirect) { |
| 167 InitializeDocumentSubresourceFilter(GURL("https://example.test")); |
| 168 CreateTestSubframeNavigation(GURL("https://example.test/allowed.html"), |
| 169 main_rfh()); |
| 170 |
| 171 SimulateWillStartAndExpectAsyncResult(content::NavigationThrottle::PROCEED); |
| 172 SimulateWillRedirectAndExpectAsyncResult( |
| 173 GURL("https://example.test/disallowed.html"), |
| 174 content::NavigationThrottle::CANCEL); |
| 175 } |
| 176 |
| 177 TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnSecondRedirect) { |
| 178 InitializeDocumentSubresourceFilter(GURL("https://example.test")); |
| 179 CreateTestSubframeNavigation(GURL("https://example.test/allowed.html"), |
| 180 main_rfh()); |
| 181 |
| 182 SimulateWillStartAndExpectAsyncResult(content::NavigationThrottle::PROCEED); |
| 183 SimulateWillRedirectAndExpectAsyncResult( |
| 184 GURL("https://example.test/allowed2.html"), |
| 185 content::NavigationThrottle::PROCEED); |
| 186 SimulateWillRedirectAndExpectAsyncResult( |
| 187 GURL("https://example.test/disallowed.html"), |
| 188 content::NavigationThrottle::CANCEL); |
| 189 } |
| 190 |
| 191 TEST_F(SubframeNavigationFilteringThrottleTest, NeverFilterNonMatchingRule) { |
| 192 InitializeDocumentSubresourceFilter(GURL("https://example.test")); |
| 193 CreateTestSubframeNavigation(GURL("https://example.test/allowed.html"), |
| 194 main_rfh()); |
| 195 |
| 196 SimulateWillStartAndExpectAsyncResult(content::NavigationThrottle::PROCEED); |
| 197 SimulateWillRedirectAndExpectAsyncResult( |
| 198 GURL("https://example.test/allowed2.html"), |
| 199 content::NavigationThrottle::PROCEED); |
| 200 SimulateWillProcessResponseAndExpectResult( |
| 201 content::NavigationThrottle::PROCEED); |
| 202 } |
| 203 |
| 204 TEST_F(SubframeNavigationFilteringThrottleTest, FilterSubsubframe) { |
| 205 // Fake an activation of the subframe. |
| 206 content::RenderFrameHost* parent_subframe = |
| 207 content::RenderFrameHostTester::For(main_rfh()) |
| 208 ->AppendChild("parent-sub"); |
| 209 GURL test_url = GURL("https://example.test"); |
| 210 content::RenderFrameHostTester::For(parent_subframe) |
| 211 ->SimulateNavigationStart(test_url); |
| 212 InitializeDocumentSubresourceFilter(GURL("https://example.test")); |
| 213 content::RenderFrameHostTester::For(parent_subframe) |
| 214 ->SimulateNavigationCommit(test_url); |
| 215 |
| 216 CreateTestSubframeNavigation(GURL("https://example.test/disallowed.html"), |
| 217 parent_subframe); |
| 218 SimulateWillStartAndExpectAsyncResult(content::NavigationThrottle::CANCEL); |
| 219 } |
| 220 |
| 221 } // namespace subresource_filter |
OLD | NEW |