| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 net::NetworkDelegate* delegate) { | 66 net::NetworkDelegate* delegate) { |
| 67 const char kPlainTextHeaders[] = | 67 const char kPlainTextHeaders[] = |
| 68 "HTTP/1.1 200 OK\n" | 68 "HTTP/1.1 200 OK\n" |
| 69 "Content-Type: text/plain\n" | 69 "Content-Type: text/plain\n" |
| 70 "Access-Control-Allow-Origin: *\n" | 70 "Access-Control-Allow-Origin: *\n" |
| 71 "\n"; | 71 "\n"; |
| 72 return new net::URLRequestTestJob(request, delegate, kPlainTextHeaders, "", | 72 return new net::URLRequestTestJob(request, delegate, kPlainTextHeaders, "", |
| 73 true); | 73 true); |
| 74 } | 74 } |
| 75 | 75 |
| 76 net::URLRequestJob* CreateRedirectRequestJob(std::string location, | |
| 77 net::URLRequest* request, | |
| 78 net::NetworkDelegate* delegate) { | |
| 79 char kPlainTextHeaders[] = | |
| 80 "HTTP/1.1 302 \n" | |
| 81 "Location: %s\n" | |
| 82 "Access-Control-Allow-Origin: *\n" | |
| 83 "\n"; | |
| 84 return new net::URLRequestTestJob( | |
| 85 request, delegate, | |
| 86 base::StringPrintf(kPlainTextHeaders, location.c_str()), "", true); | |
| 87 } | |
| 88 | |
| 89 // Override the test server to redirect requests matching some path. This is | 76 // Override the test server to redirect requests matching some path. This is |
| 90 // used because the predictor only learns simple redirects with a path of "/" | 77 // used because the predictor only learns simple redirects with a path of "/" |
| 91 std::unique_ptr<net::test_server::HttpResponse> RedirectForPathHandler( | 78 std::unique_ptr<net::test_server::HttpResponse> RedirectForPathHandler( |
| 92 const std::string& path, | 79 const std::string& path, |
| 93 const GURL& redirect_url, | 80 const GURL& redirect_url, |
| 94 const net::test_server::HttpRequest& request) { | 81 const net::test_server::HttpRequest& request) { |
| 95 if (request.GetURL().path() != path) | 82 if (request.GetURL().path() != path) |
| 96 return nullptr; | 83 return nullptr; |
| 97 std::unique_ptr<net::test_server::BasicHttpResponse> response( | 84 std::unique_ptr<net::test_server::BasicHttpResponse> response( |
| 98 new net::test_server::BasicHttpResponse); | 85 new net::test_server::BasicHttpResponse); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 class CrossSitePredictorObserver | 291 class CrossSitePredictorObserver |
| 305 : public chrome_browser_net::PredictorObserver { | 292 : public chrome_browser_net::PredictorObserver { |
| 306 public: | 293 public: |
| 307 CrossSitePredictorObserver(const GURL& source_host, | 294 CrossSitePredictorObserver(const GURL& source_host, |
| 308 const GURL& cross_site_host) | 295 const GURL& cross_site_host) |
| 309 : source_host_(source_host), | 296 : source_host_(source_host), |
| 310 cross_site_host_(cross_site_host), | 297 cross_site_host_(cross_site_host), |
| 311 cross_site_learned_(0), | 298 cross_site_learned_(0), |
| 312 cross_site_preconnected_(0), | 299 cross_site_preconnected_(0), |
| 313 same_site_preconnected_(0), | 300 same_site_preconnected_(0), |
| 314 dns_run_loop_(nullptr), | 301 dns_run_loop_(nullptr) {} |
| 315 strict_(true) {} | |
| 316 | 302 |
| 317 void OnPreconnectUrl( | 303 void OnPreconnectUrl( |
| 318 const GURL& original_url, | 304 const GURL& original_url, |
| 319 const GURL& first_party_for_cookies, | 305 const GURL& first_party_for_cookies, |
| 320 chrome_browser_net::UrlInfo::ResolutionMotivation motivation, | 306 chrome_browser_net::UrlInfo::ResolutionMotivation motivation, |
| 321 int count) override { | 307 int count) override { |
| 322 base::AutoLock lock(lock_); | 308 base::AutoLock lock(lock_); |
| 323 if (original_url == cross_site_host_) { | 309 if (original_url == cross_site_host_) { |
| 324 cross_site_preconnected_ = std::max(cross_site_preconnected_, count); | 310 cross_site_preconnected_ = std::max(cross_site_preconnected_, count); |
| 325 } else if (original_url == source_host_) { | 311 } else if (original_url == source_host_) { |
| 326 same_site_preconnected_ = std::max(same_site_preconnected_, count); | 312 same_site_preconnected_ = std::max(same_site_preconnected_, count); |
| 327 } else if (strict_) { | 313 } else { |
| 328 ADD_FAILURE() << "Preconnected " << original_url | 314 ADD_FAILURE() << "Preconnected " << original_url |
| 329 << " when should only be preconnecting the source host: " | 315 << " when should only be preconnecting the source host: " |
| 330 << source_host_ | 316 << source_host_ |
| 331 << " or the cross site host: " << cross_site_host_; | 317 << " or the cross site host: " << cross_site_host_; |
| 332 } | 318 } |
| 333 } | 319 } |
| 334 | 320 |
| 335 void OnLearnFromNavigation(const GURL& referring_url, | 321 void OnLearnFromNavigation(const GURL& referring_url, |
| 336 const GURL& target_url) override { | 322 const GURL& target_url) override { |
| 337 base::AutoLock lock(lock_); | 323 base::AutoLock lock(lock_); |
| 338 // There are three possibilities: | 324 // There are three possibilities: |
| 339 // source => target | 325 // source => target |
| 340 // source => source | 326 // source => source |
| 341 // target => target | 327 // target => target |
| 342 if (referring_url == source_host_ && target_url == cross_site_host_) { | 328 if (referring_url == source_host_ && target_url == cross_site_host_) { |
| 343 cross_site_learned_++; | 329 cross_site_learned_++; |
| 344 } else if (referring_url == source_host_ && target_url == source_host_) { | 330 } else if (referring_url == source_host_ && target_url == source_host_) { |
| 345 // Same site learned. Branch retained for clarity. | 331 // Same site learned. Branch retained for clarity. |
| 346 } else if (strict_ && | 332 } else if (!(referring_url == cross_site_host_ && |
| 347 !(referring_url == cross_site_host_ && | |
| 348 target_url == cross_site_host_)) { | 333 target_url == cross_site_host_)) { |
| 349 ADD_FAILURE() << "Learned " << referring_url << " => " << target_url | 334 ADD_FAILURE() << "Learned " << referring_url << " => " << target_url |
| 350 << " when should only be learning the source host: " | 335 << " when should only be learning the source host: " |
| 351 << source_host_ | 336 << source_host_ |
| 352 << " or the cross site host: " << cross_site_host_; | 337 << " or the cross site host: " << cross_site_host_; |
| 353 } | 338 } |
| 354 } | 339 } |
| 355 | 340 |
| 356 void OnDnsLookupFinished(const GURL& url, bool found) override { | 341 void OnDnsLookupFinished(const GURL& url, bool found) override { |
| 357 base::AutoLock lock(lock_); | 342 base::AutoLock lock(lock_); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 EXPECT_TRUE(HasHostBeenLookedUpLocked(url)) << "Expected to have looked up " | 420 EXPECT_TRUE(HasHostBeenLookedUpLocked(url)) << "Expected to have looked up " |
| 436 << url.spec(); | 421 << url.spec(); |
| 437 return base::ContainsKey(successful_dns_lookups_, url); | 422 return base::ContainsKey(successful_dns_lookups_, url); |
| 438 } | 423 } |
| 439 | 424 |
| 440 void set_task_runner( | 425 void set_task_runner( |
| 441 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | 426 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| 442 task_runner_.swap(task_runner); | 427 task_runner_.swap(task_runner); |
| 443 } | 428 } |
| 444 | 429 |
| 445 // Optionally allows the object to observe preconnects / learning from other | |
| 446 // hosts. | |
| 447 void SetStrict(bool strict) { | |
| 448 base::AutoLock lock(lock_); | |
| 449 strict_ = strict; | |
| 450 } | |
| 451 | |
| 452 private: | 430 private: |
| 453 const GURL source_host_; | 431 const GURL source_host_; |
| 454 const GURL cross_site_host_; | 432 const GURL cross_site_host_; |
| 455 | 433 |
| 456 GURL waiting_on_dns_; | 434 GURL waiting_on_dns_; |
| 457 | 435 |
| 458 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 436 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 459 | 437 |
| 460 // Protects all following members. They are read and updated from different | 438 // Protects all following members. They are read and updated from different |
| 461 // threads. | 439 // threads. |
| 462 base::Lock lock_; | 440 base::Lock lock_; |
| 463 | 441 |
| 464 int cross_site_learned_; | 442 int cross_site_learned_; |
| 465 int cross_site_preconnected_; | 443 int cross_site_preconnected_; |
| 466 int same_site_preconnected_; | 444 int same_site_preconnected_; |
| 467 | 445 |
| 468 std::set<GURL> successful_dns_lookups_; | 446 std::set<GURL> successful_dns_lookups_; |
| 469 std::set<GURL> unsuccessful_dns_lookups_; | 447 std::set<GURL> unsuccessful_dns_lookups_; |
| 470 base::RunLoop* dns_run_loop_; | 448 base::RunLoop* dns_run_loop_; |
| 471 | 449 |
| 472 // This member can be set to optionally allow url learning other than from | |
| 473 // source => source, source => target, or target => target. It will also allow | |
| 474 // preconnects to other hosts. | |
| 475 bool strict_; | |
| 476 | |
| 477 DISALLOW_COPY_AND_ASSIGN(CrossSitePredictorObserver); | 450 DISALLOW_COPY_AND_ASSIGN(CrossSitePredictorObserver); |
| 478 }; | 451 }; |
| 479 | 452 |
| 480 } // namespace | 453 } // namespace |
| 481 | 454 |
| 482 namespace chrome_browser_net { | 455 namespace chrome_browser_net { |
| 483 | 456 |
| 484 class PredictorBrowserTest : public InProcessBrowserTest { | 457 class PredictorBrowserTest : public InProcessBrowserTest { |
| 485 public: | 458 public: |
| 486 PredictorBrowserTest() | 459 PredictorBrowserTest() |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 base::Bind(&RedirectForPathHandler, "/", | 505 base::Bind(&RedirectForPathHandler, "/", |
| 533 cross_site_test_server()->GetURL("/title1.html"))); | 506 cross_site_test_server()->GetURL("/title1.html"))); |
| 534 | 507 |
| 535 predictor()->SetPredictorEnabledForTest(true); | 508 predictor()->SetPredictorEnabledForTest(true); |
| 536 InstallPredictorObserver(embedded_test_server()->base_url(), | 509 InstallPredictorObserver(embedded_test_server()->base_url(), |
| 537 cross_site_test_server()->base_url()); | 510 cross_site_test_server()->base_url()); |
| 538 observer()->set_task_runner(task_runner_); | 511 observer()->set_task_runner(task_runner_); |
| 539 StartInterceptingCrossSiteOnUI(); | 512 StartInterceptingCrossSiteOnUI(); |
| 540 } | 513 } |
| 541 | 514 |
| 542 static void StartInterceptingHostWithCreateJobCallback( | 515 // Intercepts all requests to the specified host and returns a response with |
| 543 const GURL& url, | 516 // an empty body. Needed to prevent requests from actually going to the test |
| 544 const MatchingPortRequestInterceptor::CreateJobCallback& callback) { | 517 // server, to avoid any races related to socket accounting. Note, the |
| 518 // interceptor also looks at the port, to differentiate between the |
| 519 // two test servers. |
| 520 static void StartInterceptingHost(const GURL& url) { |
| 545 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 521 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 546 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( | 522 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( |
| 547 url.scheme(), url.host(), | 523 url.scheme(), url.host(), |
| 548 base::MakeUnique<MatchingPortRequestInterceptor>(url.EffectiveIntPort(), | 524 base::MakeUnique<MatchingPortRequestInterceptor>(url.EffectiveIntPort(), |
| 549 callback)); | 525 callback)); |
| 550 } | 526 } |
| 551 | 527 |
| 552 static void StopInterceptingHost(const GURL& url) { | 528 static void StopInterceptingHost(const GURL& url) { |
| 553 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 529 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 554 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(url.scheme(), | 530 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(url.scheme(), |
| 555 url.host()); | 531 url.host()); |
| 556 } | 532 } |
| 557 | 533 |
| 558 // Intercepts all requests to the specified host and returns a response with | |
| 559 // an empty body. Needed to prevent requests from actually going to the test | |
| 560 // server, to avoid any races related to socket accounting. Note, the | |
| 561 // interceptor also looks at the port, to differentiate between the | |
| 562 // two test servers. | |
| 563 void StartInterceptingCrossSiteOnUI() { | 534 void StartInterceptingCrossSiteOnUI() { |
| 564 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 535 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 565 content::BrowserThread::PostTask( | 536 content::BrowserThread::PostTask( |
| 566 content::BrowserThread::IO, FROM_HERE, | 537 content::BrowserThread::IO, FROM_HERE, |
| 567 base::Bind( | 538 base::Bind(&PredictorBrowserTest::StartInterceptingHost, |
| 568 &PredictorBrowserTest::StartInterceptingHostWithCreateJobCallback, | 539 cross_site_test_server()->base_url())); |
| 569 cross_site_test_server()->base_url(), | |
| 570 base::Bind(&CreateEmptyBodyRequestJob))); | |
| 571 } | 540 } |
| 572 | 541 |
| 573 void StopInterceptingCrossSiteOnUI() { | 542 void StopInterceptingCrossSiteOnUI() { |
| 574 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 543 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 575 content::BrowserThread::PostTask( | 544 content::BrowserThread::PostTask( |
| 576 content::BrowserThread::IO, FROM_HERE, | 545 content::BrowserThread::IO, FROM_HERE, |
| 577 base::Bind(&PredictorBrowserTest::StopInterceptingHost, | 546 base::Bind(&PredictorBrowserTest::StopInterceptingHost, |
| 578 cross_site_test_server()->base_url())); | 547 cross_site_test_server()->base_url())); |
| 579 } | 548 } |
| 580 | 549 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 // embedded test servers have the same host_piece, an extra preconnect is | 908 // embedded test servers have the same host_piece, an extra preconnect is |
| 940 // issued. This results in ceil(2.33) + 1 = 4 preconnects. | 909 // issued. This results in ceil(2.33) + 1 = 4 preconnects. |
| 941 ui_test_utils::NavigateToURL(browser(), | 910 ui_test_utils::NavigateToURL(browser(), |
| 942 embedded_test_server()->GetURL("/title1.html")); | 911 embedded_test_server()->GetURL("/title1.html")); |
| 943 // Just check that predictor has initiated preconnects to the cross site test | 912 // Just check that predictor has initiated preconnects to the cross site test |
| 944 // server. It's tricky to reset the connections to the test server, and | 913 // server. It's tricky to reset the connections to the test server, and |
| 945 // sockets can be reused. | 914 // sockets can be reused. |
| 946 EXPECT_EQ(4, observer()->CrossSitePreconnected()); | 915 EXPECT_EQ(4, observer()->CrossSitePreconnected()); |
| 947 } | 916 } |
| 948 | 917 |
| 949 // 1. Navigate to A.com learning B.com | |
| 950 // 2. Navigate to B.com with subresource from C.com redirecting to A.com. | |
| 951 // 3. Assert that the redirect does not cause us to preconnect to B.com (via | |
| 952 // A.com). | |
| 953 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, DontPredictBasedOnSubresources) { | |
| 954 GURL redirector_url = GURL("http://redirector.com"); | |
| 955 | |
| 956 NavigateToCrossSiteHtmlUrl(1 /* num_cors */, "" /* file_suffix */); | |
| 957 EXPECT_EQ(1, observer()->CrossSiteLearned()); | |
| 958 EXPECT_EQ(0, observer()->CrossSitePreconnected()); | |
| 959 | |
| 960 EXPECT_EQ(0u, cross_site_connection_listener_->GetAcceptedSocketCount()); | |
| 961 | |
| 962 // Stop intercepting so that the test can actually navigate to the cross site | |
| 963 // server. | |
| 964 StopInterceptingCrossSiteOnUI(); | |
| 965 | |
| 966 // All requests with the redirector url as base url should redirect to the | |
| 967 // embedded_test_server_. | |
| 968 content::BrowserThread::PostTask( | |
| 969 content::BrowserThread::IO, FROM_HERE, | |
| 970 base::Bind( | |
| 971 &PredictorBrowserTest::StartInterceptingHostWithCreateJobCallback, | |
| 972 redirector_url, | |
| 973 base::Bind( | |
| 974 &CreateRedirectRequestJob, | |
| 975 embedded_test_server()->GetURL("/predictor/empty.js").spec()))); | |
| 976 | |
| 977 // Reduce the strictness, because the below logic causes the predictor to | |
| 978 // learn cross_site_test_server_ => redirector, as well as | |
| 979 // cross_site_test_server_ => embedded_test_server_ (via referrer header). | |
| 980 observer()->SetStrict(false); | |
| 981 | |
| 982 GURL redirect_requesting_url = | |
| 983 cross_site_test_server()->GetURL(base::StringPrintf( | |
| 984 "/predictor/" | |
| 985 "predictor_cross_site.html?subresourceHost=%s&numCORSResources=1", | |
| 986 redirector_url.spec().c_str())); | |
| 987 ui_test_utils::NavigateToURL(browser(), redirect_requesting_url); | |
| 988 bool result = false; | |
| 989 | |
| 990 int navigation_preconnects = observer()->CrossSitePreconnected(); | |
| 991 EXPECT_EQ(2, navigation_preconnects); | |
| 992 | |
| 993 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( | |
| 994 browser()->tab_strip_model()->GetActiveWebContents(), | |
| 995 "startFetchesAndWaitForReply()", &result)); | |
| 996 EXPECT_TRUE(result); | |
| 997 | |
| 998 // The number of preconnects should not increase. Note that the predictor | |
| 999 // would preconnect 4 sockets if it were doing so based on learning. | |
| 1000 EXPECT_EQ(navigation_preconnects, observer()->CrossSitePreconnected()); | |
| 1001 } | |
| 1002 | |
| 1003 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PredictBasedOnSubframeRedirect) { | |
| 1004 // A test server is needed here because data url navigations with redirect | |
| 1005 // interceptors don't interact well with the ResourceTiming API. | |
| 1006 // TODO(csharrison): Possibly this is a bug in either net or Blink, and it | |
| 1007 // might be worthwhile to investigate. | |
| 1008 std::unique_ptr<net::EmbeddedTestServer> redirector = | |
| 1009 base::MakeUnique<net::EmbeddedTestServer>(); | |
| 1010 ASSERT_TRUE(redirector->Start()); | |
| 1011 | |
| 1012 NavigateToCrossSiteHtmlUrl(1 /* num_cors */, "" /* file_suffix */); | |
| 1013 EXPECT_EQ(1, observer()->CrossSiteLearned()); | |
| 1014 EXPECT_EQ(0u, cross_site_connection_listener_->GetAcceptedSocketCount()); | |
| 1015 | |
| 1016 redirector->RegisterRequestHandler( | |
| 1017 base::Bind(&RedirectForPathHandler, "/", | |
| 1018 embedded_test_server()->GetURL("/title1.html"))); | |
| 1019 | |
| 1020 // Note that the observer will see preconnects to the redirector, and the | |
| 1021 // predictor will learn redirector->embedded_test_server. | |
| 1022 observer()->SetStrict(false); | |
| 1023 | |
| 1024 NavigateToDataURLWithContent(base::StringPrintf( | |
| 1025 "<iframe src='%s'></iframe>", redirector->base_url().spec().c_str())); | |
| 1026 | |
| 1027 EXPECT_EQ(4, observer()->CrossSitePreconnected()); | |
| 1028 cross_site_connection_listener_->WaitForAcceptedConnectionsOnUI(4u); | |
| 1029 } | |
| 1030 | |
| 1031 // Expect that the predictor correctly predicts subframe navigations. | 918 // Expect that the predictor correctly predicts subframe navigations. |
| 1032 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SubframeCrossSitePrediction) { | 919 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SubframeCrossSitePrediction) { |
| 1033 ui_test_utils::NavigateToURL( | 920 ui_test_utils::NavigateToURL( |
| 1034 browser(), embedded_test_server()->GetURL( | 921 browser(), embedded_test_server()->GetURL( |
| 1035 "/predictor/predictor_cross_site_subframe_nav.html")); | 922 "/predictor/predictor_cross_site_subframe_nav.html")); |
| 1036 bool result = false; | 923 bool result = false; |
| 1037 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( | 924 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
| 1038 browser()->tab_strip_model()->GetActiveWebContents(), | 925 browser()->tab_strip_model()->GetActiveWebContents(), |
| 1039 base::StringPrintf( | 926 base::StringPrintf( |
| 1040 "navigateSubframe('%s')", | 927 "navigateSubframe('%s')", |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1414 GetListFromPrefsAsString(prefs::kDnsPrefetchingStartupList, | 1301 GetListFromPrefsAsString(prefs::kDnsPrefetchingStartupList, |
| 1415 &cleared_startup_list); | 1302 &cleared_startup_list); |
| 1416 GetListFromPrefsAsString(prefs::kDnsPrefetchingHostReferralList, | 1303 GetListFromPrefsAsString(prefs::kDnsPrefetchingHostReferralList, |
| 1417 &cleared_referral_list); | 1304 &cleared_referral_list); |
| 1418 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(referring_url_.host()))); | 1305 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(referring_url_.host()))); |
| 1419 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(target_url_.host()))); | 1306 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(target_url_.host()))); |
| 1420 } | 1307 } |
| 1421 | 1308 |
| 1422 // The predictor should not evict recently used (navigated to) referrers. | 1309 // The predictor should not evict recently used (navigated to) referrers. |
| 1423 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, DoNotEvictRecentlyUsed) { | 1310 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, DoNotEvictRecentlyUsed) { |
| 1424 observer()->SetStrict(false); | |
| 1425 for (int i = 0; i < Predictor::kMaxReferrers; ++i) { | 1311 for (int i = 0; i < Predictor::kMaxReferrers; ++i) { |
| 1426 LearnFromNavigation( | 1312 LearnFromNavigation( |
| 1427 GURL(base::StringPrintf("http://www.source%d.test", i)), | 1313 GURL(base::StringPrintf("http://www.source%d.test", i)), |
| 1428 GURL(base::StringPrintf("http://www.target%d.test", i))); | 1314 GURL(base::StringPrintf("http://www.target%d.test", i))); |
| 1429 } | 1315 } |
| 1430 ui_test_utils::NavigateToURL(browser(), GURL("http://source0.test")); | 1316 ui_test_utils::NavigateToURL(browser(), GURL("http://source0.test")); |
| 1431 | 1317 |
| 1432 // This will evict http://source1.test. | 1318 // This will evict http://source1.test. |
| 1433 LearnFromNavigation(GURL("http://new_source"), GURL("http://new_target")); | 1319 LearnFromNavigation(GURL("http://new_source"), GURL("http://new_target")); |
| 1434 | 1320 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1561 // Second navigation to content with an img. | 1447 // Second navigation to content with an img. |
| 1562 std::string img_content = | 1448 std::string img_content = |
| 1563 "<img src=\"" + preconnect_url.spec() + "test.gif\">"; | 1449 "<img src=\"" + preconnect_url.spec() + "test.gif\">"; |
| 1564 NavigateToDataURLWithContent(img_content); | 1450 NavigateToDataURLWithContent(img_content); |
| 1565 connection_listener_->WaitUntilFirstConnectionRead(); | 1451 connection_listener_->WaitUntilFirstConnectionRead(); |
| 1566 EXPECT_EQ(2u, connection_listener_->GetAcceptedSocketCount()); | 1452 EXPECT_EQ(2u, connection_listener_->GetAcceptedSocketCount()); |
| 1567 EXPECT_EQ(1u, connection_listener_->GetReadSocketCount()); | 1453 EXPECT_EQ(1u, connection_listener_->GetReadSocketCount()); |
| 1568 } | 1454 } |
| 1569 | 1455 |
| 1570 } // namespace chrome_browser_net | 1456 } // namespace chrome_browser_net |
| OLD | NEW |