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 <map> | 5 #include <map> |
6 #include <set> | 6 #include <set> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 "http://mock.captive.portal.test/login.html"; | 81 "http://mock.captive.portal.test/login.html"; |
82 | 82 |
83 // When behind a captive portal, this URL hangs without committing until a call | 83 // When behind a captive portal, this URL hangs without committing until a call |
84 // to URLRequestTimeoutOnDemandJob::FailJobs. When that function is called, | 84 // to URLRequestTimeoutOnDemandJob::FailJobs. When that function is called, |
85 // the request will time out. | 85 // the request will time out. |
86 // | 86 // |
87 // When connected to the Internet, this URL returns a non-error page. | 87 // When connected to the Internet, this URL returns a non-error page. |
88 const char* const kMockHttpsUrl = | 88 const char* const kMockHttpsUrl = |
89 "https://mock.captive.portal.long.timeout/title2.html"; | 89 "https://mock.captive.portal.long.timeout/title2.html"; |
90 | 90 |
| 91 // Same as above, but different domain, so can be used to trigger cross-site |
| 92 // navigations. |
| 93 const char* const kMockHttpsUrl2 = |
| 94 "https://mock.captive.portal.long.timeout2/title2.html"; |
| 95 |
91 // Same as kMockHttpsUrl, except the timeout happens instantly. | 96 // Same as kMockHttpsUrl, except the timeout happens instantly. |
92 const char* const kMockHttpsQuickTimeoutUrl = | 97 const char* const kMockHttpsQuickTimeoutUrl = |
93 "https://mock.captive.portal.quick.timeout/title2.html"; | 98 "https://mock.captive.portal.quick.timeout/title2.html"; |
94 | 99 |
95 // Expected title of a tab once an HTTPS load completes, when not behind a | 100 // Expected title of a tab once an HTTPS load completes, when not behind a |
96 // captive portal. | 101 // captive portal. |
97 const char* const kInternetConnectedTitle = "Title Of Awesomeness"; | 102 const char* const kInternetConnectedTitle = "Title Of Awesomeness"; |
98 | 103 |
99 // A URL request job that hangs until FailJobs() is called. Started jobs | 104 // A URL request job that hangs until FailJobs() is called. Started jobs |
100 // are stored in a static class variable containing a linked list so that | 105 // are stored in a static class variable containing a linked list so that |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread() { | 375 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread() { |
371 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 376 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
372 | 377 |
373 // Handle only exact matches, so any related requests, such as those for | 378 // Handle only exact matches, so any related requests, such as those for |
374 // favicons, are not handled by the factory. | 379 // favicons, are not handled by the factory. |
375 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); | 380 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); |
376 filter->AddUrlHandler(GURL(kMockCaptivePortalTestUrl), | 381 filter->AddUrlHandler(GURL(kMockCaptivePortalTestUrl), |
377 URLRequestMockCaptivePortalJobFactory::Factory); | 382 URLRequestMockCaptivePortalJobFactory::Factory); |
378 filter->AddUrlHandler(GURL(kMockHttpsUrl), | 383 filter->AddUrlHandler(GURL(kMockHttpsUrl), |
379 URLRequestMockCaptivePortalJobFactory::Factory); | 384 URLRequestMockCaptivePortalJobFactory::Factory); |
| 385 filter->AddUrlHandler(GURL(kMockHttpsUrl2), |
| 386 URLRequestMockCaptivePortalJobFactory::Factory); |
380 filter->AddUrlHandler(GURL(kMockHttpsQuickTimeoutUrl), | 387 filter->AddUrlHandler(GURL(kMockHttpsQuickTimeoutUrl), |
381 URLRequestMockCaptivePortalJobFactory::Factory); | 388 URLRequestMockCaptivePortalJobFactory::Factory); |
382 } | 389 } |
383 | 390 |
384 // static | 391 // static |
385 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread( | 392 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread( |
386 bool behind_captive_portal) { | 393 bool behind_captive_portal) { |
387 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 394 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
388 behind_captive_portal_ = behind_captive_portal; | 395 behind_captive_portal_ = behind_captive_portal; |
389 } | 396 } |
390 | 397 |
391 // static | 398 // static |
392 net::URLRequestJob* URLRequestMockCaptivePortalJobFactory::Factory( | 399 net::URLRequestJob* URLRequestMockCaptivePortalJobFactory::Factory( |
393 net::URLRequest* request, | 400 net::URLRequest* request, |
394 const std::string& scheme) { | 401 const std::string& scheme) { |
395 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 402 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
396 | 403 |
397 // The PathService is threadsafe. | 404 // The PathService is threadsafe. |
398 FilePath root_http; | 405 FilePath root_http; |
399 PathService::Get(chrome::DIR_TEST_DATA, &root_http); | 406 PathService::Get(chrome::DIR_TEST_DATA, &root_http); |
400 | 407 |
401 if (request->url() == GURL(kMockHttpsUrl)) { | 408 if (request->url() == GURL(kMockHttpsUrl) || |
| 409 request->url() == GURL(kMockHttpsUrl2)) { |
402 if (behind_captive_portal_) | 410 if (behind_captive_portal_) |
403 return new URLRequestTimeoutOnDemandJob(request); | 411 return new URLRequestTimeoutOnDemandJob(request); |
404 // Once logged in to the portal, HTTPS requests return the page that was | 412 // Once logged in to the portal, HTTPS requests return the page that was |
405 // actually requested. | 413 // actually requested. |
406 return new URLRequestMockHTTPJob( | 414 return new URLRequestMockHTTPJob( |
407 request, | 415 request, |
408 root_http.Append(FILE_PATH_LITERAL("title2.html"))); | 416 root_http.Append(FILE_PATH_LITERAL("title2.html"))); |
409 } else if (request->url() == GURL(kMockHttpsQuickTimeoutUrl)) { | 417 } else if (request->url() == GURL(kMockHttpsQuickTimeoutUrl)) { |
410 if (behind_captive_portal_) | 418 if (behind_captive_portal_) |
411 return new URLRequestFailedJob(request, net::ERR_CONNECTION_TIMED_OUT); | 419 return new URLRequestFailedJob(request, net::ERR_CONNECTION_TIMED_OUT); |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 // Makes the slow SSL loads of all active tabs time out at once, and waits for | 877 // Makes the slow SSL loads of all active tabs time out at once, and waits for |
870 // them to finish both that load and the automatic reload it should trigger. | 878 // them to finish both that load and the automatic reload it should trigger. |
871 // There should be no timed out tabs when this is called. | 879 // There should be no timed out tabs when this is called. |
872 void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs); | 880 void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs); |
873 | 881 |
874 // Makes the slow SSL loads of all active tabs time out at once, and waits for | 882 // Makes the slow SSL loads of all active tabs time out at once, and waits for |
875 // them to finish displaying their error pages. The login tab should be the | 883 // them to finish displaying their error pages. The login tab should be the |
876 // active tab. There should be no timed out tabs when this is called. | 884 // active tab. There should be no timed out tabs when this is called. |
877 void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs); | 885 void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs); |
878 | 886 |
| 887 // Navigates |browser|'s active tab to |starting_url| while not behind a |
| 888 // captive portal. Then navigates to |interrupted_url|, which should create |
| 889 // a URLRequestTimeoutOnDemandJob, which is then abandoned. The load should |
| 890 // trigger a captive portal check, which finds a captive portal and opens a |
| 891 // tab. |
| 892 // |
| 893 // Then the navigation is interrupted by a navigation to |timeout_url|, which |
| 894 // should trigger a captive portal check, and finally the test simulates |
| 895 // logging in. |
| 896 // |
| 897 // The purpose of this test is to make sure the TabHelper triggers a captive |
| 898 // portal check when a load is interrupted by another load, particularly in |
| 899 // the case of cross-process navigations. |
| 900 void RunNavigateLoadingTabToTimeoutTest(Browser* browser, |
| 901 const GURL& starting_url, |
| 902 const GURL& interrupted_url, |
| 903 const GURL& timeout_url); |
| 904 |
879 // Sets the timeout used by a CaptivePortalTabReloader on slow SSL loads | 905 // Sets the timeout used by a CaptivePortalTabReloader on slow SSL loads |
880 // before a captive portal check. | 906 // before a captive portal check. |
881 void SetSlowSSLLoadTime(CaptivePortalTabReloader* tab_reloader, | 907 void SetSlowSSLLoadTime(CaptivePortalTabReloader* tab_reloader, |
882 base::TimeDelta slow_ssl_load_time); | 908 base::TimeDelta slow_ssl_load_time); |
883 | 909 |
884 CaptivePortalTabReloader* GetTabReloader(TabContents* tab_contents) const; | 910 CaptivePortalTabReloader* GetTabReloader(TabContents* tab_contents) const; |
885 | 911 |
886 private: | 912 private: |
887 DISALLOW_COPY_AND_ASSIGN(CaptivePortalBrowserTest); | 913 DISALLOW_COPY_AND_ASSIGN(CaptivePortalBrowserTest); |
888 }; | 914 }; |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 EXPECT_EQ(num_loading_tabs, NumBrokenTabs()); | 1424 EXPECT_EQ(num_loading_tabs, NumBrokenTabs()); |
1399 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | 1425 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, |
1400 GetStateOfTabReloader(chrome::GetActiveTabContents(browser))); | 1426 GetStateOfTabReloader(chrome::GetActiveTabContents(browser))); |
1401 EXPECT_TRUE(IsLoginTab(chrome::GetActiveTabContents(browser))); | 1427 EXPECT_TRUE(IsLoginTab(chrome::GetActiveTabContents(browser))); |
1402 EXPECT_EQ(login_tab, browser->active_index()); | 1428 EXPECT_EQ(login_tab, browser->active_index()); |
1403 | 1429 |
1404 EXPECT_EQ(0, navigation_observer.NumNavigationsForTab( | 1430 EXPECT_EQ(0, navigation_observer.NumNavigationsForTab( |
1405 chrome::GetWebContentsAt(browser, login_tab))); | 1431 chrome::GetWebContentsAt(browser, login_tab))); |
1406 } | 1432 } |
1407 | 1433 |
| 1434 void CaptivePortalBrowserTest::RunNavigateLoadingTabToTimeoutTest( |
| 1435 Browser* browser, |
| 1436 const GURL& starting_url, |
| 1437 const GURL& hanging_url, |
| 1438 const GURL& timeout_url) { |
| 1439 // Temporarily disable the captive portal and navigate to the starting |
| 1440 // URL, which may be a URL that will hang when behind a captive portal. |
| 1441 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false); |
| 1442 NavigateToPageExpectNoTest(browser, starting_url, 1); |
| 1443 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true); |
| 1444 |
| 1445 // Go to the first hanging url. |
| 1446 SlowLoadBehindCaptivePortal(browser, true, hanging_url); |
| 1447 |
| 1448 // Abandon the request. |
| 1449 URLRequestTimeoutOnDemandJob::WaitForJobs(1); |
| 1450 URLRequestTimeoutOnDemandJob::AbandonJobs(1); |
| 1451 |
| 1452 CaptivePortalTabReloader* tab_reloader = |
| 1453 GetTabReloader(chrome::GetTabContentsAt(browser, 0)); |
| 1454 ASSERT_TRUE(tab_reloader); |
| 1455 |
| 1456 // A non-zero delay makes it more likely that CaptivePortalTabHelper will |
| 1457 // be confused by events relating to canceling the old navigation. |
| 1458 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromSeconds(2)); |
| 1459 CaptivePortalObserver portal_observer(browser->profile()); |
| 1460 |
| 1461 // Navigate the error tab to another slow loading page. Can't have |
| 1462 // ui_test_utils do the navigation because it will wait for loading tabs to |
| 1463 // stop loading before navigating. |
| 1464 // |
| 1465 // This may result in either 0 or 1 DidStopLoading events. If there is one, |
| 1466 // it must happen before the CaptivePortalService sends out its test request, |
| 1467 // so waiting for PortalObserver to see that request prevents it from |
| 1468 // confusing the MultiNavigationObservers used later. |
| 1469 chrome::ActivateTabAt(browser, 0, true); |
| 1470 browser->OpenURL(content::OpenURLParams(timeout_url, |
| 1471 content::Referrer(), |
| 1472 CURRENT_TAB, |
| 1473 content::PAGE_TRANSITION_TYPED, |
| 1474 false)); |
| 1475 portal_observer.WaitForResults(1); |
| 1476 EXPECT_FALSE(CheckPending(browser)); |
| 1477 EXPECT_EQ(1, NumLoadingTabs()); |
| 1478 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, |
| 1479 GetStateOfTabReloaderAt(browser, 0)); |
| 1480 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, |
| 1481 GetStateOfTabReloader(chrome::GetTabContentsAt(browser, 1))); |
| 1482 ASSERT_TRUE(IsLoginTab(chrome::GetTabContentsAt(browser, 1))); |
| 1483 |
| 1484 // Need to make sure the request has been issued before logging in. |
| 1485 URLRequestTimeoutOnDemandJob::WaitForJobs(1); |
| 1486 |
| 1487 // Simulate logging in. |
| 1488 chrome::ActivateTabAt(browser, 1, true); |
| 1489 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1)); |
| 1490 Login(browser, 1, 0); |
| 1491 |
| 1492 // Timeout occurs, and page is automatically reloaded. |
| 1493 FailLoadsAfterLogin(browser, 1); |
| 1494 } |
| 1495 |
1408 void CaptivePortalBrowserTest::SetSlowSSLLoadTime( | 1496 void CaptivePortalBrowserTest::SetSlowSSLLoadTime( |
1409 CaptivePortalTabReloader* tab_reloader, | 1497 CaptivePortalTabReloader* tab_reloader, |
1410 base::TimeDelta slow_ssl_load_time) { | 1498 base::TimeDelta slow_ssl_load_time) { |
1411 tab_reloader->set_slow_ssl_load_time(slow_ssl_load_time); | 1499 tab_reloader->set_slow_ssl_load_time(slow_ssl_load_time); |
1412 } | 1500 } |
1413 | 1501 |
1414 CaptivePortalTabReloader* CaptivePortalBrowserTest::GetTabReloader( | 1502 CaptivePortalTabReloader* CaptivePortalBrowserTest::GetTabReloader( |
1415 TabContents* tab_contents) const { | 1503 TabContents* tab_contents) const { |
1416 return tab_contents->captive_portal_tab_helper()->GetTabReloaderForTest(); | 1504 return tab_contents->captive_portal_tab_helper()->GetTabReloaderForTest(); |
1417 } | 1505 } |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1678 URLRequestMockHTTPJob::GetMockUrl( | 1766 URLRequestMockHTTPJob::GetMockUrl( |
1679 FilePath(FILE_PATH_LITERAL("title2.html")))); | 1767 FilePath(FILE_PATH_LITERAL("title2.html")))); |
1680 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | 1768 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, |
1681 GetStateOfTabReloaderAt(browser(), 0)); | 1769 GetStateOfTabReloaderAt(browser(), 0)); |
1682 | 1770 |
1683 // Simulate logging in. | 1771 // Simulate logging in. |
1684 chrome::ActivateTabAt(browser(), 1, true); | 1772 chrome::ActivateTabAt(browser(), 1, true); |
1685 Login(browser(), 0, 0); | 1773 Login(browser(), 0, 0); |
1686 } | 1774 } |
1687 | 1775 |
1688 // Navigates a broken, but still loading, tab to another such page before | 1776 // Checks that captive portal detection triggers correctly when a same-site |
1689 // logging in. | 1777 // navigation is cancelled by a navigation to the same site. |
1690 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, | 1778 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, |
1691 NavigateBrokenToTimeoutTabWhileLoading) { | 1779 NavigateLoadingTabToTimeoutSingleSite) { |
1692 // Go to the error page. | 1780 RunNavigateLoadingTabToTimeoutTest( |
1693 SlowLoadBehindCaptivePortal(browser(), true); | 1781 browser(), |
| 1782 GURL(kMockHttpsUrl), |
| 1783 GURL(kMockHttpsUrl), |
| 1784 GURL(kMockHttpsUrl)); |
| 1785 } |
1694 | 1786 |
1695 // Abandon the request. | 1787 // Checks that captive portal detection triggers correctly when a same-site |
1696 URLRequestTimeoutOnDemandJob::WaitForJobs(1); | 1788 // navigation is cancelled by a navigation to another site. |
1697 URLRequestTimeoutOnDemandJob::AbandonJobs(1); | 1789 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, |
| 1790 NavigateLoadingTabToTimeoutTwoSites) { |
| 1791 RunNavigateLoadingTabToTimeoutTest( |
| 1792 browser(), |
| 1793 GURL(kMockHttpsUrl), |
| 1794 GURL(kMockHttpsUrl), |
| 1795 GURL(kMockHttpsUrl2)); |
| 1796 } |
1698 | 1797 |
1699 CaptivePortalTabReloader* tab_reloader = | 1798 // Checks that captive portal detection triggers correctly when a cross-site |
1700 GetTabReloader(chrome::GetTabContentsAt(browser(), 0)); | 1799 // navigation is cancelled by a navigation to yet another site. |
1701 ASSERT_TRUE(tab_reloader); | 1800 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, |
1702 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta()); | 1801 NavigateLoadingTabToTimeoutThreeSites) { |
1703 | 1802 RunNavigateLoadingTabToTimeoutTest( |
1704 CaptivePortalObserver portal_observer(browser()->profile()); | 1803 browser(), |
1705 MultiNavigationObserver navigation_observer; | 1804 URLRequestMockHTTPJob::GetMockUrl( |
1706 | 1805 FilePath(FILE_PATH_LITERAL("title.html"))), |
1707 // Navigate the error tab to another slow loading page. Can't have | 1806 GURL(kMockHttpsUrl), |
1708 // ui_test_utils do the navigation because it will wait for loading tabs to | 1807 GURL(kMockHttpsUrl2)); |
1709 // stop loading before navigating. | |
1710 chrome::ActivateTabAt(browser(), 0, true); | |
1711 browser()->OpenURL(content::OpenURLParams(GURL(kMockHttpsUrl), | |
1712 content::Referrer(), | |
1713 CURRENT_TAB, | |
1714 content::PAGE_TRANSITION_TYPED, | |
1715 false)); | |
1716 navigation_observer.WaitForNavigations(1); | |
1717 portal_observer.WaitForResults(1); | |
1718 EXPECT_FALSE(CheckPending(browser())); | |
1719 EXPECT_EQ(1, NumLoadingTabs()); | |
1720 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, | |
1721 GetStateOfTabReloaderAt(browser(), 0)); | |
1722 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
1723 GetStateOfTabReloader(chrome::GetTabContentsAt(browser(), 1))); | |
1724 ASSERT_TRUE(IsLoginTab(chrome::GetTabContentsAt(browser(), 1))); | |
1725 | |
1726 // Need to make sure the request has been issued before logging in. | |
1727 URLRequestTimeoutOnDemandJob::WaitForJobs(1); | |
1728 | |
1729 // Simulate logging in. | |
1730 chrome::ActivateTabAt(browser(), 1, true); | |
1731 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1)); | |
1732 Login(browser(), 1, 0); | |
1733 | |
1734 // Timeout occurs, and page is automatically reloaded. | |
1735 FailLoadsAfterLogin(browser(), 1); | |
1736 } | 1808 } |
1737 | 1809 |
1738 // Checks that navigating a timed out tab back clears its state. | 1810 // Checks that navigating a timed out tab back clears its state. |
1739 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBack) { | 1811 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBack) { |
1740 // Navigate to a working page. | 1812 // Navigate to a working page. |
1741 ui_test_utils::NavigateToURL( | 1813 ui_test_utils::NavigateToURL( |
1742 browser(), | 1814 browser(), |
1743 URLRequestMockHTTPJob::GetMockUrl( | 1815 URLRequestMockHTTPJob::GetMockUrl( |
1744 FilePath(FILE_PATH_LITERAL("title2.html")))); | 1816 FilePath(FILE_PATH_LITERAL("title2.html")))); |
1745 | 1817 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 base::Bind(&AddHstsHost, | 2068 base::Bind(&AddHstsHost, |
1997 make_scoped_refptr(browser()->profile()->GetRequestContext()), | 2069 make_scoped_refptr(browser()->profile()->GetRequestContext()), |
1998 http_timeout_url.host())); | 2070 http_timeout_url.host())); |
1999 | 2071 |
2000 SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url); | 2072 SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url); |
2001 Login(browser(), 1, 0); | 2073 Login(browser(), 1, 0); |
2002 FailLoadsAfterLogin(browser(), 1); | 2074 FailLoadsAfterLogin(browser(), 1); |
2003 } | 2075 } |
2004 | 2076 |
2005 } // namespace captive_portal | 2077 } // namespace captive_portal |
OLD | NEW |