#include <atomic>
#include <iterator>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/sequence_checker.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
#include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
#include "chrome/browser/net/secure_dns_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/captive_portal/content/captive_portal_service.h"
#include "components/captive_portal/content/captive_portal_tab_helper.h"
#include "components/captive_portal/content/captive_portal_tab_reloader.h"
#include "components/captive_portal/core/captive_portal_types.h"
#include "components/embedder_support/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/security_interstitials/content/captive_portal_blocking_page.h"
#include "components/security_interstitials/content/security_interstitial_page.h"
#include "components/security_interstitials/content/security_interstitial_tab_helper.h"
#include "components/security_interstitials/content/ssl_blocking_page.h"
#include "components/security_interstitials/content/ssl_error_handler.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_util.h"
#include "net/http/transport_security_state.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/test_data_directory.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#endif
CaptivePortalResult;
BrowserThread;
WebContents;
WebContentsObserver;
namespace {
const char* const kTestServerLoginPath = …;
const char* const kTestServerIframeTimeoutPath = …;
const char* const kRedirectToMockHttpsPath = …;
const char* const kMockHttpsBadCertPath = …;
const char* const kMockCaptivePortalTestUrl = …;
const char* const kMockCaptivePortal511Url = …;
const char* const kMockHttpsUrl = …;
const char* const kMockHttpsUrl2 = …;
const char* const kMockHttpsQuickTimeoutUrl = …;
const char* const kMockHttpConnectionTimeoutErr = …;
const char* const kMockHttpsConnectionTimeoutErr = …;
const char* const kMockHttpsConnectionUnexpectedErr = …;
const char* const kMockHttpConnectionConnectionClosedErr = …;
const char* const kMockHttpConnectionSecureDnsErr = …;
const char* const kMockHttpsConnectionSecureDnsErr = …;
const char* const kInternetConnectedTitle = …;
const char* const kLoginSecureDnsDisabledTitle = …;
std::string CreateServerRedirect(const std::string& dest_url) { … }
int NumTabs() { … }
int NumLoadingTabs() { … }
bool IsLoginTab(WebContents* web_contents) { … }
struct LoadObserver : public WebContentsObserver { … };
class MultiNavigationObserver : public ui_test_utils::AllTabsObserver,
public LoadObserver::Observer { … };
MultiNavigationObserver::MultiNavigationObserver() { … }
MultiNavigationObserver::~MultiNavigationObserver() = default;
std::unique_ptr<base::CheckedObserver>
MultiNavigationObserver::ProcessOneContents(WebContents* web_contents) { … }
void MultiNavigationObserver::OnWebContentsDestroyed(
WebContents* web_contents) { … }
void MultiNavigationObserver::OnDidStopLoading(WebContents* web_contents) { … }
void MultiNavigationObserver::WaitForNavigations(
int num_navigations_to_wait_for) { … }
int MultiNavigationObserver::NumNavigationsForTab(
WebContents* web_contents) const { … }
class FailLoadsAfterLoginObserver : public LoadObserver::Observer { … };
FailLoadsAfterLoginObserver::FailLoadsAfterLoginObserver()
: … { … }
FailLoadsAfterLoginObserver::~FailLoadsAfterLoginObserver() = default;
void FailLoadsAfterLoginObserver::WaitForNavigations() { … }
void FailLoadsAfterLoginObserver::OnDidStopLoading(WebContents* contents) { … }
class CaptivePortalObserver { … };
CaptivePortalObserver::CaptivePortalObserver(Profile* profile)
: … { … }
void CaptivePortalObserver::WaitForResults(int num_results_to_wait_for) { … }
void CaptivePortalObserver::Observe(
const captive_portal::CaptivePortalService::Results& results) { … }
class SSLInterstitialTimerObserver { … };
SSLInterstitialTimerObserver::SSLInterstitialTimerObserver(
content::WebContents* web_contents)
: … { … }
SSLInterstitialTimerObserver::~SSLInterstitialTimerObserver() { … }
void SSLInterstitialTimerObserver::WaitForTimerStarted() { … }
void SSLInterstitialTimerObserver::OnTimerStarted(
content::WebContents* web_contents) { … }
class TabActivationWaiter : public TabStripModelObserver { … };
}
class CaptivePortalBrowserTest : public InProcessBrowserTest { … };
CaptivePortalBrowserTest::CaptivePortalBrowserTest()
: … { … }
CaptivePortalBrowserTest::~CaptivePortalBrowserTest() = default;
void CaptivePortalBrowserTest::SetUpOnMainThread() { … }
bool CaptivePortalBrowserTest::OnIntercept(
content::URLLoaderInterceptor::RequestParams* params) { … }
void CaptivePortalBrowserTest::TearDownOnMainThread() { … }
void CaptivePortalBrowserTest::EnableCaptivePortalDetection(
Profile* profile, bool enabled) { … }
void CaptivePortalBrowserTest::RespondToProbeRequests(bool enabled) { … }
void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile,
const GURL& test_url) { … }
bool CaptivePortalBrowserTest::CheckPending(Browser* browser) { … }
security_interstitials::SecurityInterstitialPage::TypeID
CaptivePortalBrowserTest::GetInterstitialType(WebContents* contents) const { … }
bool CaptivePortalBrowserTest::IsShowingInterstitial(WebContents* contents) { … }
captive_portal::CaptivePortalTabReloader::State
CaptivePortalBrowserTest::GetStateOfTabReloader(
WebContents* web_contents) const { … }
captive_portal::CaptivePortalTabReloader::State
CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser* browser,
int index) const { … }
int CaptivePortalBrowserTest::NumTabsWithState(
captive_portal::CaptivePortalTabReloader::State state) const { … }
int CaptivePortalBrowserTest::NumBrokenTabs() const { … }
int CaptivePortalBrowserTest::NumNeedReloadTabs() const { … }
void CaptivePortalBrowserTest::NavigateToPageExpectNoTest(Browser* browser,
const GURL& url) { … }
void CaptivePortalBrowserTest::SlowLoadNoCaptivePortal(
Browser* browser,
CaptivePortalResult expected_result) { … }
void CaptivePortalBrowserTest::FastTimeoutNoCaptivePortal(
Browser* browser,
CaptivePortalResult expected_result) { … }
void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
Browser* browser,
bool expect_open_login_tab,
bool expect_new_login_browser,
Browser** out_login_browser) { … }
void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
Browser* browser,
bool expect_open_login_tab,
bool expect_new_login_browser,
const GURL& hanging_url,
int expected_portal_checks,
int expected_login_tab_navigations,
Browser** out_login_browser) { … }
void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal(
Browser* browser,
bool expect_open_login_tab) { … }
void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal(
Browser* browser,
bool expect_open_login_tab,
bool expect_new_login_browser,
const GURL& error_url,
Browser** out_login_browser) { … }
void CaptivePortalBrowserTest::FastErrorWithInterstitialTimer(
Browser* browser,
const GURL& cert_error_url) { … }
void CaptivePortalBrowserTest::NavigateLoginTab(Browser* browser,
int num_loading_tabs,
int num_timed_out_tabs) { … }
void CaptivePortalBrowserTest::Login(Browser* captive_portal_browser,
int num_loading_tabs,
int num_timed_out_tabs,
int expected_portal_checks) { … }
void CaptivePortalBrowserTest::LoginCertError(Browser* browser) { … }
void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser,
int num_loading_tabs) { … }
void CaptivePortalBrowserTest::FailLoadsWithoutLogin(
Browser* browser,
int num_loading_tabs,
Browser* captive_portal_browser) { … }
void CaptivePortalBrowserTest::RunNavigateLoadingTabToTimeoutTest(
Browser* browser,
const GURL& starting_url,
const GURL& hanging_url,
const GURL& timeout_url) { … }
void CaptivePortalBrowserTest::SetSlowSSLLoadTime(
captive_portal::CaptivePortalTabReloader* tab_reloader,
base::TimeDelta slow_ssl_load_time) { … }
captive_portal::CaptivePortalTabReloader*
CaptivePortalBrowserTest::GetTabReloader(WebContents* web_contents) const { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpTimeout) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsNonTimeoutError) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsIframeTimeout) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFails) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFailsFastTimout) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Disabled) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, InternetConnected) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RedirectSSLCertError) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Login) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginIncognito) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginSlow) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
ShowCaptivePortalInterstitialOnCertError) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
CertErrorOnCaptivePortalLoginShowsSSLErrorInterstitial) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
InterstitialTimerStopNavigationWhileLoading) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
InterstitialTimerReloadWhileLoading) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
InterstitialTimerNavigateAwayWhileLoading) { … }
IN_PROC_BROWSER_TEST_F(
CaptivePortalBrowserTest,
InterstitialTimerNavigateWhileLoading_EndWithSSLInterstitial) { … }
IN_PROC_BROWSER_TEST_F(
CaptivePortalBrowserTest,
InterstitialTimerNavigateWhileLoading_EndWithCaptivePortalInterstitial) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, SSLCertErrorLogin) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, CloseLoginTab) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, TwoBrokenTabs) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, AbortLoad) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, NavigateBrokenTab) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
NavigateLoadingTabToTimeoutSingleSite) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
NavigateLoadingTabToTimeoutTwoSites) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
NavigateLoadingTabToTimeoutThreeSites) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBack) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBackToTimeout) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, ReloadTimeout) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, DISABLED_TwoWindows) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpToHttpsRedirectLogin) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsToHttpRedirect) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Status511) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
DISABLED_InterstitialTimerCertErrorAfterSlowLoad) { … }
#if BUILDFLAG(IS_WIN)
#define MAYBE_SecureDnsCaptivePortal …
#else
#define MAYBE_SecureDnsCaptivePortal …
#endif
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, MAYBE_SecureDnsCaptivePortal) { … }
#if BUILDFLAG(IS_WIN)
#define MAYBE_SecureDnsErrorTriggersCheck …
#else
#define MAYBE_SecureDnsErrorTriggersCheck …
#endif
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
MAYBE_SecureDnsErrorTriggersCheck) { … }
#if BUILDFLAG(IS_WIN)
#define MAYBE_SlowLoadSecureDnsErrorWithCaptivePortal …
#else
#define MAYBE_SlowLoadSecureDnsErrorWithCaptivePortal …
#endif
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
MAYBE_SlowLoadSecureDnsErrorWithCaptivePortal) { … }
#if BUILDFLAG(IS_WIN)
#define MAYBE_SlowLoadSecureDnsErrorAfterLogin …
#else
#define MAYBE_SlowLoadSecureDnsErrorAfterLogin …
#endif
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
MAYBE_SlowLoadSecureDnsErrorAfterLogin) { … }
class CaptivePortalForPrerenderingTest : public CaptivePortalBrowserTest { … };
IN_PROC_BROWSER_TEST_F(CaptivePortalForPrerenderingTest,
DontFireOnLoadStartDuringPrerendering) { … }
IN_PROC_BROWSER_TEST_F(CaptivePortalForPrerenderingTest,
DontFireOnRedirectDuringPrerendering) { … }