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/content_subresource_filt
er_throttle_manager.h" |
| 6 |
| 7 #include <memory> |
| 8 #include <utility> |
| 9 |
| 10 #include "base/logging.h" |
| 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/run_loop.h" |
| 13 #include "base/strings/stringprintf.h" |
| 14 #include "base/test/test_simple_task_runner.h" |
| 15 #include "components/subresource_filter/content/browser/async_document_subresour
ce_filter.h" |
| 16 #include "components/subresource_filter/core/common/activation_level.h" |
| 17 #include "components/subresource_filter/core/common/activation_state.h" |
| 18 #include "components/subresource_filter/core/common/proto/rules.pb.h" |
| 19 #include "components/subresource_filter/core/common/test_ruleset_creator.h" |
| 20 #include "components/subresource_filter/core/common/test_ruleset_utils.h" |
| 21 #include "content/public/browser/navigation_handle.h" |
| 22 #include "content/public/browser/navigation_throttle.h" |
| 23 #include "content/public/browser/web_contents.h" |
| 24 #include "content/public/test/mock_render_process_host.h" |
| 25 #include "content/public/test/navigation_simulator.h" |
| 26 #include "content/public/test/test_renderer_host.h" |
| 27 #include "net/base/net_errors.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" |
| 29 #include "url/url_constants.h" |
| 30 |
| 31 namespace subresource_filter { |
| 32 |
| 33 const char kTestURLWithActivation[] = "https://www.page-with-activation.com/"; |
| 34 const char kTestURLWithActivation2[] = |
| 35 "https://www.page-with-activation-2.com/"; |
| 36 const char kTestURLWithDryRun[] = "https://www.page-with-dryrun.com/"; |
| 37 |
| 38 // Enum determining when the mock page state throttle notifies the throttle |
| 39 // manager of page level activation state. |
| 40 enum PageActivationNotificationTiming { |
| 41 WILL_START_REQUEST, |
| 42 WILL_PROCESS_RESPONSE, |
| 43 }; |
| 44 |
| 45 // Simple throttle that sends page-level activation to the manager for a |
| 46 // specific set of URLs. |
| 47 class MockPageStateActivationThrottle : public content::NavigationThrottle { |
| 48 public: |
| 49 MockPageStateActivationThrottle( |
| 50 content::NavigationHandle* navigation_handle, |
| 51 PageActivationNotificationTiming activation_throttle_state, |
| 52 ContentSubresourceFilterThrottleManager* throttle_manager) |
| 53 : content::NavigationThrottle(navigation_handle), |
| 54 activation_throttle_state_(activation_throttle_state), |
| 55 throttle_manager_(throttle_manager) { |
| 56 // Add some default activations. |
| 57 mock_page_activations_[GURL(kTestURLWithActivation)] = |
| 58 ActivationState(ActivationLevel::ENABLED); |
| 59 mock_page_activations_[GURL(kTestURLWithActivation2)] = |
| 60 ActivationState(ActivationLevel::ENABLED); |
| 61 mock_page_activations_[GURL(kTestURLWithDryRun)] = |
| 62 ActivationState(ActivationLevel::DRYRUN); |
| 63 } |
| 64 ~MockPageStateActivationThrottle() override {} |
| 65 |
| 66 // content::NavigationThrottle: |
| 67 content::NavigationThrottle::ThrottleCheckResult WillStartRequest() override { |
| 68 return MaybeNotifyActivation(WILL_START_REQUEST); |
| 69 } |
| 70 |
| 71 content::NavigationThrottle::ThrottleCheckResult WillProcessResponse() |
| 72 override { |
| 73 return MaybeNotifyActivation(WILL_PROCESS_RESPONSE); |
| 74 } |
| 75 |
| 76 private: |
| 77 content::NavigationThrottle::ThrottleCheckResult MaybeNotifyActivation( |
| 78 PageActivationNotificationTiming throttle_state) { |
| 79 if (throttle_state == activation_throttle_state_) { |
| 80 auto it = mock_page_activations_.find(navigation_handle()->GetURL()); |
| 81 if (it != mock_page_activations_.end()) { |
| 82 throttle_manager_->NotifyPageActivationComputed(navigation_handle(), |
| 83 it->second); |
| 84 } |
| 85 } |
| 86 return content::NavigationThrottle::PROCEED; |
| 87 } |
| 88 |
| 89 std::map<GURL, ActivationState> mock_page_activations_; |
| 90 PageActivationNotificationTiming activation_throttle_state_; |
| 91 ContentSubresourceFilterThrottleManager* throttle_manager_; |
| 92 |
| 93 DISALLOW_COPY_AND_ASSIGN(MockPageStateActivationThrottle); |
| 94 }; |
| 95 |
| 96 class ContentSubresourceFilterThrottleManagerTest |
| 97 : public content::RenderViewHostTestHarness, |
| 98 public content::WebContentsObserver, |
| 99 public ContentSubresourceFilterThrottleManager::Delegate, |
| 100 public ::testing::WithParamInterface<PageActivationNotificationTiming> { |
| 101 public: |
| 102 ContentSubresourceFilterThrottleManagerTest() |
| 103 : ContentSubresourceFilterThrottleManager::Delegate() {} |
| 104 ~ContentSubresourceFilterThrottleManagerTest() override {} |
| 105 |
| 106 // content::RenderViewHostTestHarness: |
| 107 void SetUp() override { |
| 108 content::RenderViewHostTestHarness::SetUp(); |
| 109 |
| 110 NavigateAndCommit(GURL("https://example.first")); |
| 111 |
| 112 Observe(RenderViewHostTestHarness::web_contents()); |
| 113 |
| 114 // Initialize the ruleset dealer. |
| 115 std::vector<proto::UrlRule> rules; |
| 116 rules.push_back(testing::CreateWhitelistRuleForDocument( |
| 117 "whitelist.com", proto::ACTIVATION_TYPE_DOCUMENT, |
| 118 {"page-with-activation.com"})); |
| 119 rules.push_back(testing::CreateSuffixRule("disallowed.html")); |
| 120 ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules( |
| 121 rules, &test_ruleset_pair_)); |
| 122 |
| 123 // Make the blocking task runner run on the current task runner for the |
| 124 // tests, to ensure that the NavigationSimulator properly runs all necessary |
| 125 // tasks while waiting for throttle checks to finish. |
| 126 dealer_handle_ = base::MakeUnique<VerifiedRulesetDealer::Handle>( |
| 127 base::MessageLoop::current()->task_runner()); |
| 128 dealer_handle_->SetRulesetFile( |
| 129 testing::TestRuleset::Open(test_ruleset_pair_.indexed)); |
| 130 |
| 131 throttle_manager_ = |
| 132 base::MakeUnique<ContentSubresourceFilterThrottleManager>( |
| 133 this, dealer_handle_.get(), |
| 134 RenderViewHostTestHarness::web_contents()); |
| 135 } |
| 136 |
| 137 void TearDown() override { |
| 138 throttle_manager_.reset(); |
| 139 dealer_handle_.reset(); |
| 140 base::RunLoop().RunUntilIdle(); |
| 141 content::RenderViewHostTestHarness::TearDown(); |
| 142 } |
| 143 |
| 144 // Helper methods: |
| 145 |
| 146 void CreateTestNavigation(const GURL& url, |
| 147 content::RenderFrameHost* render_frame_host) { |
| 148 DCHECK(!navigation_simulator_); |
| 149 DCHECK(render_frame_host); |
| 150 navigation_simulator_ = |
| 151 content::NavigationSimulator::CreateRendererInitiated( |
| 152 url, render_frame_host); |
| 153 } |
| 154 |
| 155 void CreateSubframeWithTestNavigation(const GURL& url, |
| 156 content::RenderFrameHost* parent) { |
| 157 content::RenderFrameHost* subframe = |
| 158 content::RenderFrameHostTester::For(parent)->AppendChild( |
| 159 base::StringPrintf("subframe-%s", url.spec().c_str())); |
| 160 CreateTestNavigation(url, subframe); |
| 161 } |
| 162 |
| 163 void SimulateStartAndExpectResult( |
| 164 content::NavigationThrottle::ThrottleCheckResult expect_result) { |
| 165 navigation_simulator_->Start(); |
| 166 content::NavigationThrottle::ThrottleCheckResult result = |
| 167 navigation_simulator_->GetLastThrottleCheckResult(); |
| 168 EXPECT_EQ(expect_result, result); |
| 169 if (result != content::NavigationThrottle::PROCEED) |
| 170 navigation_simulator_.reset(); |
| 171 } |
| 172 |
| 173 void SimulateRedirectAndExpectResult( |
| 174 const GURL& new_url, |
| 175 content::NavigationThrottle::ThrottleCheckResult expect_result) { |
| 176 navigation_simulator_->Redirect(new_url); |
| 177 content::NavigationThrottle::ThrottleCheckResult result = |
| 178 navigation_simulator_->GetLastThrottleCheckResult(); |
| 179 EXPECT_EQ(expect_result, result); |
| 180 if (result != content::NavigationThrottle::PROCEED) |
| 181 navigation_simulator_.reset(); |
| 182 } |
| 183 |
| 184 // Returns the RenderFrameHost that the navigation commit in. |
| 185 content::RenderFrameHost* SimulateCommitAndExpectResult( |
| 186 content::NavigationThrottle::ThrottleCheckResult expect_result) { |
| 187 navigation_simulator_->Commit(); |
| 188 content::NavigationThrottle::ThrottleCheckResult result = |
| 189 navigation_simulator_->GetLastThrottleCheckResult(); |
| 190 EXPECT_EQ(expect_result, result); |
| 191 |
| 192 auto scoped_simulator = std::move(navigation_simulator_); |
| 193 if (result == content::NavigationThrottle::PROCEED) |
| 194 return scoped_simulator->GetFinalRenderFrameHost(); |
| 195 return nullptr; |
| 196 } |
| 197 |
| 198 void SimulateSamePageCommit() { |
| 199 navigation_simulator_->CommitSameDocument(); |
| 200 navigation_simulator_.reset(); |
| 201 } |
| 202 |
| 203 void SimulateFailedNavigation(net::Error error) { |
| 204 navigation_simulator_->Fail(error); |
| 205 if (error != net::ERR_ABORTED) { |
| 206 navigation_simulator_->CommitErrorPage(); |
| 207 } |
| 208 navigation_simulator_.reset(); |
| 209 } |
| 210 |
| 211 void NavigateAndCommitMainFrame(const GURL& url) { |
| 212 CreateTestNavigation(url, main_rfh()); |
| 213 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 214 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 215 } |
| 216 |
| 217 void SuppressActivationForUrl(const GURL& url) { |
| 218 urls_to_suppress_activation_.insert(url); |
| 219 } |
| 220 |
| 221 bool ManagerHasRulesetHandle() { |
| 222 return throttle_manager_->ruleset_handle_for_testing(); |
| 223 } |
| 224 |
| 225 int disallowed_notification_count() { return disallowed_notification_count_; } |
| 226 |
| 227 int attempted_frame_activations() { return attempted_frame_activations_; } |
| 228 |
| 229 protected: |
| 230 // content::WebContentsObserver |
| 231 void DidStartNavigation( |
| 232 content::NavigationHandle* navigation_handle) override { |
| 233 if (navigation_handle->IsSameDocument()) |
| 234 return; |
| 235 |
| 236 // Inject the proper throttles at this time. |
| 237 std::vector<std::unique_ptr<content::NavigationThrottle>> throttles; |
| 238 PageActivationNotificationTiming state = |
| 239 ::testing::UnitTest::GetInstance()->current_test_info()->value_param() |
| 240 ? GetParam() |
| 241 : WILL_PROCESS_RESPONSE; |
| 242 throttles.push_back(base::MakeUnique<MockPageStateActivationThrottle>( |
| 243 navigation_handle, state, throttle_manager_.get())); |
| 244 throttle_manager_->MaybeAppendNavigationThrottles(navigation_handle, |
| 245 &throttles); |
| 246 for (auto& it : throttles) { |
| 247 navigation_handle->RegisterThrottleForTesting(std::move(it)); |
| 248 } |
| 249 } |
| 250 |
| 251 // ContentSubresourceFilterThrottleManager::Delegate: |
| 252 void OnFirstSubresourceLoadDisallowed() override { |
| 253 ++disallowed_notification_count_; |
| 254 } |
| 255 |
| 256 bool ShouldSuppressActivation( |
| 257 content::NavigationHandle* navigation_handle) override { |
| 258 ++attempted_frame_activations_; |
| 259 return urls_to_suppress_activation_.find(navigation_handle->GetURL()) != |
| 260 urls_to_suppress_activation_.end(); |
| 261 } |
| 262 |
| 263 private: |
| 264 testing::TestRulesetCreator test_ruleset_creator_; |
| 265 testing::TestRulesetPair test_ruleset_pair_; |
| 266 |
| 267 std::set<GURL> urls_to_suppress_activation_; |
| 268 |
| 269 std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_; |
| 270 |
| 271 std::unique_ptr<ContentSubresourceFilterThrottleManager> throttle_manager_; |
| 272 |
| 273 std::unique_ptr<content::NavigationSimulator> navigation_simulator_; |
| 274 |
| 275 // Incremented on every OnFirstSubresourceLoadDisallowed call. |
| 276 int disallowed_notification_count_ = 0; |
| 277 |
| 278 // Incremented every time the manager queries the harness for activation |
| 279 // suppression. |
| 280 int attempted_frame_activations_ = 0; |
| 281 |
| 282 DISALLOW_COPY_AND_ASSIGN(ContentSubresourceFilterThrottleManagerTest); |
| 283 }; |
| 284 |
| 285 INSTANTIATE_TEST_CASE_P(PageActivationNotificationTiming, |
| 286 ContentSubresourceFilterThrottleManagerTest, |
| 287 ::testing::Values(WILL_START_REQUEST, |
| 288 WILL_PROCESS_RESPONSE)); |
| 289 |
| 290 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 291 ActivateMainFrameAndFilterSubframeNavigation) { |
| 292 // Commit a navigation that triggers page level activation. |
| 293 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 294 |
| 295 // A disallowed subframe navigation should be successfully filtered. |
| 296 CreateSubframeWithTestNavigation( |
| 297 GURL("https://www.example.com/disallowed.html"), main_rfh()); |
| 298 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 299 |
| 300 EXPECT_EQ(1, disallowed_notification_count()); |
| 301 EXPECT_EQ(1, attempted_frame_activations()); |
| 302 } |
| 303 |
| 304 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 305 ActivateMainFrameAndDoNotFilterDryRun) { |
| 306 // Commit a navigation that triggers page level activation. |
| 307 NavigateAndCommitMainFrame(GURL(kTestURLWithDryRun)); |
| 308 |
| 309 // A disallowed subframe navigation should not be filtered in dry-run mode. |
| 310 CreateSubframeWithTestNavigation( |
| 311 GURL("https://www.example.com/disallowed.html"), main_rfh()); |
| 312 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 313 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 314 |
| 315 EXPECT_EQ(0, disallowed_notification_count()); |
| 316 EXPECT_EQ(2, attempted_frame_activations()); |
| 317 } |
| 318 |
| 319 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 320 ActivateMainFrameAndFilterSubframeNavigationOnRedirect) { |
| 321 // Commit a navigation that triggers page level activation. |
| 322 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 323 |
| 324 // A disallowed subframe navigation via redirect should be successfully |
| 325 // filtered. |
| 326 CreateSubframeWithTestNavigation( |
| 327 GURL("https://www.example.com/before-redirect.html"), main_rfh()); |
| 328 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 329 SimulateRedirectAndExpectResult( |
| 330 GURL("https://www.example.com/disallowed.html"), |
| 331 content::NavigationThrottle::CANCEL); |
| 332 |
| 333 EXPECT_EQ(1, disallowed_notification_count()); |
| 334 EXPECT_EQ(1, attempted_frame_activations()); |
| 335 } |
| 336 |
| 337 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 338 ActivateMainFrameAndDoNotFilterSubframeNavigation) { |
| 339 // Commit a navigation that triggers page level activation. |
| 340 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 341 |
| 342 // An allowed subframe navigation should complete successfully. |
| 343 CreateSubframeWithTestNavigation( |
| 344 GURL("https://www.example.com/allowed1.html"), main_rfh()); |
| 345 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 346 SimulateRedirectAndExpectResult(GURL("https://www.example.com/allowed2.html"), |
| 347 content::NavigationThrottle::PROCEED); |
| 348 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 349 |
| 350 EXPECT_EQ(0, disallowed_notification_count()); |
| 351 EXPECT_EQ(2, attempted_frame_activations()); |
| 352 } |
| 353 |
| 354 // This should fail if the throttle manager notifies the delegate twice of a |
| 355 // disallowed load for the same page load. |
| 356 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 357 ActivateMainFrameAndFilterTwoSubframeNavigations) { |
| 358 // Commit a navigation that triggers page level activation. |
| 359 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 360 |
| 361 // A disallowed subframe navigation should be successfully filtered. |
| 362 CreateSubframeWithTestNavigation( |
| 363 GURL("https://www.example.com/1/disallowed.html"), main_rfh()); |
| 364 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 365 |
| 366 EXPECT_EQ(1, disallowed_notification_count()); |
| 367 |
| 368 CreateSubframeWithTestNavigation( |
| 369 GURL("https://www.example.com/2/disallowed.html"), main_rfh()); |
| 370 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 371 |
| 372 EXPECT_EQ(1, disallowed_notification_count()); |
| 373 EXPECT_EQ(1, attempted_frame_activations()); |
| 374 } |
| 375 |
| 376 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 377 ActivateTwoMainFramesAndFilterTwoSubframeNavigations) { |
| 378 // Commit a navigation that triggers page level activation. |
| 379 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 380 |
| 381 // A disallowed subframe navigation should be successfully filtered. |
| 382 CreateSubframeWithTestNavigation( |
| 383 GURL("https://www.example.com/1/disallowed.html"), main_rfh()); |
| 384 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 385 |
| 386 EXPECT_EQ(1, disallowed_notification_count()); |
| 387 |
| 388 // Commit another navigation that triggers page level activation. |
| 389 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation2)); |
| 390 |
| 391 CreateSubframeWithTestNavigation( |
| 392 GURL("https://www.example.com/2/disallowed.html"), main_rfh()); |
| 393 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 394 |
| 395 EXPECT_EQ(2, disallowed_notification_count()); |
| 396 EXPECT_EQ(2, attempted_frame_activations()); |
| 397 } |
| 398 |
| 399 // Test that the disallow load notification will not be repeated for the first |
| 400 // disallowed load that follows a same-document navigation. |
| 401 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 402 ActivateMainFrameDoNotNotifyAfterSameDocumentNav) { |
| 403 // Commit a navigation that triggers page level activation. |
| 404 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 405 |
| 406 // A disallowed subframe navigation should be successfully filtered. |
| 407 CreateSubframeWithTestNavigation( |
| 408 GURL("https://www.example.com/1/disallowed.html"), main_rfh()); |
| 409 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 410 |
| 411 EXPECT_EQ(1, disallowed_notification_count()); |
| 412 |
| 413 // Commit another navigation that triggers page level activation. |
| 414 GURL url2 = GURL(base::StringPrintf("%s#ref", kTestURLWithActivation)); |
| 415 CreateTestNavigation(url2, main_rfh()); |
| 416 SimulateSamePageCommit(); |
| 417 |
| 418 CreateSubframeWithTestNavigation( |
| 419 GURL("https://www.example.com/2/disallowed.html"), main_rfh()); |
| 420 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 421 |
| 422 EXPECT_EQ(1, disallowed_notification_count()); |
| 423 EXPECT_EQ(1, attempted_frame_activations()); |
| 424 } |
| 425 |
| 426 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 427 DoNotFilterForInactiveFrame) { |
| 428 NavigateAndCommitMainFrame(GURL("https://do-not-activate.html")); |
| 429 |
| 430 // A subframe navigation should complete successfully. |
| 431 CreateSubframeWithTestNavigation(GURL("https://www.example.com/allowed.html"), |
| 432 main_rfh()); |
| 433 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 434 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 435 |
| 436 EXPECT_EQ(0, disallowed_notification_count()); |
| 437 EXPECT_EQ(0, attempted_frame_activations()); |
| 438 } |
| 439 |
| 440 TEST_P(ContentSubresourceFilterThrottleManagerTest, SuppressActivation) { |
| 441 SuppressActivationForUrl(GURL(kTestURLWithActivation)); |
| 442 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 443 |
| 444 // A subframe navigation should complete successfully. |
| 445 CreateSubframeWithTestNavigation(GURL("https://www.example.com/allowed.html"), |
| 446 main_rfh()); |
| 447 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 448 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 449 |
| 450 EXPECT_EQ(0, disallowed_notification_count()); |
| 451 EXPECT_EQ(1, attempted_frame_activations()); |
| 452 } |
| 453 |
| 454 // Once there are no activated frames, the manager drops its ruleset handle. If |
| 455 // another frame is activated, make sure the handle is regenerated. |
| 456 TEST_P(ContentSubresourceFilterThrottleManagerTest, RulesetHandleRegeneration) { |
| 457 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 458 |
| 459 CreateSubframeWithTestNavigation( |
| 460 GURL("https://www.example.com/disallowed.html"), main_rfh()); |
| 461 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 462 |
| 463 EXPECT_EQ(1, disallowed_notification_count()); |
| 464 |
| 465 // Simulate a renderer crash which should delete the frame. |
| 466 EXPECT_TRUE(ManagerHasRulesetHandle()); |
| 467 process()->SimulateCrash(); |
| 468 EXPECT_FALSE(ManagerHasRulesetHandle()); |
| 469 |
| 470 NavigateAndCommit(GURL("https://example.reset")); |
| 471 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 472 |
| 473 CreateSubframeWithTestNavigation( |
| 474 GURL("https://www.example.com/disallowed.html"), main_rfh()); |
| 475 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 476 |
| 477 EXPECT_EQ(2, disallowed_notification_count()); |
| 478 EXPECT_EQ(2, attempted_frame_activations()); |
| 479 } |
| 480 |
| 481 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 482 SameSiteNavigation_RulesetGoesAway) { |
| 483 GURL same_site_inactive_url = |
| 484 GURL(base::StringPrintf("%ssuppressed.html", kTestURLWithActivation)); |
| 485 SuppressActivationForUrl(same_site_inactive_url); |
| 486 |
| 487 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 488 EXPECT_TRUE(ManagerHasRulesetHandle()); |
| 489 |
| 490 NavigateAndCommitMainFrame(same_site_inactive_url); |
| 491 EXPECT_FALSE(ManagerHasRulesetHandle()); |
| 492 |
| 493 // A subframe navigation should complete successfully. |
| 494 CreateSubframeWithTestNavigation( |
| 495 GURL("https://www.example.com/disallowed.html"), main_rfh()); |
| 496 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 497 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 498 |
| 499 EXPECT_EQ(0, disallowed_notification_count()); |
| 500 EXPECT_EQ(1, attempted_frame_activations()); |
| 501 } |
| 502 |
| 503 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 504 SameSiteFailedNavigation_MaintainActivation) { |
| 505 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 506 EXPECT_TRUE(ManagerHasRulesetHandle()); |
| 507 |
| 508 GURL same_site_inactive_url = |
| 509 GURL(base::StringPrintf("%ssuppressed.html", kTestURLWithActivation)); |
| 510 SuppressActivationForUrl(same_site_inactive_url); |
| 511 |
| 512 CreateTestNavigation(same_site_inactive_url, main_rfh()); |
| 513 SimulateFailedNavigation(net::ERR_ABORTED); |
| 514 EXPECT_TRUE(ManagerHasRulesetHandle()); |
| 515 |
| 516 // A subframe navigation fail. |
| 517 CreateSubframeWithTestNavigation( |
| 518 GURL("https://www.example.com/disallowed.html"), main_rfh()); |
| 519 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 520 |
| 521 EXPECT_EQ(1, disallowed_notification_count()); |
| 522 EXPECT_EQ(1, attempted_frame_activations()); |
| 523 } |
| 524 |
| 525 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 526 FailedNavigationToErrorPage_NoActivation) { |
| 527 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 528 EXPECT_TRUE(ManagerHasRulesetHandle()); |
| 529 |
| 530 GURL same_site_inactive_url = |
| 531 GURL(base::StringPrintf("%ssuppressed.html", kTestURLWithActivation)); |
| 532 SuppressActivationForUrl(same_site_inactive_url); |
| 533 |
| 534 CreateTestNavigation(same_site_inactive_url, main_rfh()); |
| 535 SimulateFailedNavigation(net::ERR_FAILED); |
| 536 EXPECT_FALSE(ManagerHasRulesetHandle()); |
| 537 |
| 538 // A subframe navigation fail. |
| 539 CreateSubframeWithTestNavigation( |
| 540 GURL("https://www.example.com/disallowed.html"), main_rfh()); |
| 541 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 542 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 543 |
| 544 EXPECT_EQ(0, disallowed_notification_count()); |
| 545 EXPECT_EQ(1, attempted_frame_activations()); |
| 546 } |
| 547 |
| 548 // Ensure activation propagates into great-grandchild frames, including cross |
| 549 // process ones. |
| 550 TEST_P(ContentSubresourceFilterThrottleManagerTest, ActivationPropagation) { |
| 551 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 552 |
| 553 // Navigate a subframe to a URL that is not itself disallowed. Subresource |
| 554 // filtering for this subframe document should still be activated. |
| 555 CreateSubframeWithTestNavigation(GURL("https://www.a.com/allowed.html"), |
| 556 main_rfh()); |
| 557 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 558 content::RenderFrameHost* subframe1 = |
| 559 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 560 |
| 561 // Navigate a sub-subframe to a URL that is not itself disallowed. Subresource |
| 562 // filtering for this subframe document should still be activated. |
| 563 CreateSubframeWithTestNavigation(GURL("https://www.b.com/allowed.html"), |
| 564 subframe1); |
| 565 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 566 content::RenderFrameHost* subframe2 = |
| 567 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 568 |
| 569 // A final, nested subframe navigation is filtered. |
| 570 CreateSubframeWithTestNavigation(GURL("https://www.c.com/disallowed.html"), |
| 571 subframe2); |
| 572 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 573 |
| 574 EXPECT_EQ(1, disallowed_notification_count()); |
| 575 EXPECT_EQ(3, attempted_frame_activations()); |
| 576 } |
| 577 |
| 578 // Ensure activation propagates through whitelisted documents. |
| 579 TEST_P(ContentSubresourceFilterThrottleManagerTest, ActivationPropagation2) { |
| 580 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 581 |
| 582 // Navigate a subframe that is not filtered, but should still activate. |
| 583 CreateSubframeWithTestNavigation(GURL("https://whitelist.com"), main_rfh()); |
| 584 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 585 content::RenderFrameHost* subframe1 = |
| 586 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 587 |
| 588 // Navigate a sub-subframe that is not filtered due to the whitelist. |
| 589 CreateSubframeWithTestNavigation( |
| 590 GURL("https://www.example.com/disallowed.html"), subframe1); |
| 591 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 592 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 593 |
| 594 EXPECT_EQ(3, attempted_frame_activations()); |
| 595 EXPECT_EQ(0, disallowed_notification_count()); |
| 596 |
| 597 // An identical series of events that don't match whitelist rules cause |
| 598 // filtering. |
| 599 CreateSubframeWithTestNavigation(GURL("https://average-joe.com"), main_rfh()); |
| 600 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 601 content::RenderFrameHost* subframe3 = |
| 602 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 603 |
| 604 // Navigate a sub-subframe that is not filtered due to the whitelist. |
| 605 CreateSubframeWithTestNavigation( |
| 606 GURL("https://www.example.com/disallowed.html"), subframe3); |
| 607 SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); |
| 608 |
| 609 EXPECT_EQ(4, attempted_frame_activations()); |
| 610 EXPECT_EQ(1, disallowed_notification_count()); |
| 611 } |
| 612 |
| 613 // Same-site navigations within a single RFH do not persist activation. |
| 614 TEST_P(ContentSubresourceFilterThrottleManagerTest, |
| 615 SameSiteNavigationStopsActivation) { |
| 616 NavigateAndCommitMainFrame(GURL(kTestURLWithActivation)); |
| 617 EXPECT_EQ(1, attempted_frame_activations()); |
| 618 |
| 619 // Mock a same-site navigation, in the same RFH, this URL does not trigger |
| 620 // page level activation. |
| 621 NavigateAndCommitMainFrame( |
| 622 GURL(base::StringPrintf("%s/some_path/", kTestURLWithActivation))); |
| 623 EXPECT_EQ(1, attempted_frame_activations()); |
| 624 |
| 625 CreateSubframeWithTestNavigation( |
| 626 GURL("https://www.example.com/disallowed.html"), main_rfh()); |
| 627 SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); |
| 628 SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); |
| 629 |
| 630 EXPECT_EQ(0, disallowed_notification_count()); |
| 631 EXPECT_EQ(1, attempted_frame_activations()); |
| 632 } |
| 633 |
| 634 // TODO(csharrison): Make sure the following conditions are exercised in tests: |
| 635 // |
| 636 // - Verify IPCs are sent on activation. |
| 637 // |
| 638 // - Synchronous navigations to about:blank. These hit issues with the |
| 639 // NavigationSimulator currently. |
| 640 |
| 641 } // namespace subresource_filter |
OLD | NEW |