Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(701)

Side by Side Diff: chrome/browser/captive_portal/captive_portal_browsertest.cc

Issue 318213002: Add custom interstitial for captive portals. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: bauerb and mmenke comments - make SSLErrorHandler a WebContentsUserData Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include <string>
7 8
8 #include "base/basictypes.h" 9 #include "base/basictypes.h"
9 #include "base/bind.h" 10 #include "base/bind.h"
10 #include "base/command_line.h" 11 #include "base/command_line.h"
11 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
12 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
14 #include "base/path_service.h" 16 #include "base/path_service.h"
15 #include "base/prefs/pref_service.h" 17 #include "base/prefs/pref_service.h"
16 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h"
17 #include "chrome/browser/captive_portal/captive_portal_service.h" 20 #include "chrome/browser/captive_portal/captive_portal_service.h"
18 #include "chrome/browser/captive_portal/captive_portal_service_factory.h" 21 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
19 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h" 22 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
20 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h" 23 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
21 #include "chrome/browser/chrome_notification_types.h" 24 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/interstitials/security_interstitial_page.h"
22 #include "chrome/browser/net/url_request_mock_util.h" 26 #include "chrome/browser/net/url_request_mock_util.h"
23 #include "chrome/browser/profiles/profile.h" 27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/ssl/captive_portal_blocking_page.h"
29 #include "chrome/browser/ssl/ssl_blocking_page.h"
30 #include "chrome/browser/ssl/ssl_error_handler.h"
24 #include "chrome/browser/ui/browser.h" 31 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h" 32 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_finder.h" 33 #include "chrome/browser/ui/browser_finder.h"
27 #include "chrome/browser/ui/browser_navigator.h" 34 #include "chrome/browser/ui/browser_navigator.h"
28 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 35 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model.h" 36 #include "chrome/browser/ui/tabs/tab_strip_model.h"
30 #include "chrome/common/chrome_paths.h" 37 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h" 38 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/pref_names.h" 39 #include "chrome/common/pref_names.h"
33 #include "chrome/test/base/in_process_browser_test.h" 40 #include "chrome/test/base/in_process_browser_test.h"
34 #include "chrome/test/base/ui_test_utils.h" 41 #include "chrome/test/base/ui_test_utils.h"
35 #include "content/public/browser/browser_thread.h" 42 #include "content/public/browser/browser_thread.h"
43 #include "content/public/browser/interstitial_page.h"
44 #include "content/public/browser/interstitial_page_delegate.h"
36 #include "content/public/browser/navigation_controller.h" 45 #include "content/public/browser/navigation_controller.h"
46 #include "content/public/browser/navigation_entry.h"
37 #include "content/public/browser/notification_observer.h" 47 #include "content/public/browser/notification_observer.h"
38 #include "content/public/browser/notification_registrar.h" 48 #include "content/public/browser/notification_registrar.h"
39 #include "content/public/browser/notification_service.h" 49 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/notification_types.h" 50 #include "content/public/browser/notification_types.h"
41 #include "content/public/browser/render_frame_host.h" 51 #include "content/public/browser/render_frame_host.h"
52 #include "content/public/browser/render_view_host.h"
42 #include "content/public/browser/web_contents.h" 53 #include "content/public/browser/web_contents.h"
43 #include "content/public/common/url_constants.h" 54 #include "content/public/common/url_constants.h"
55 #include "content/public/test/browser_test_utils.h"
44 #include "net/base/net_errors.h" 56 #include "net/base/net_errors.h"
45 #include "net/http/transport_security_state.h" 57 #include "net/http/transport_security_state.h"
46 #include "net/test/url_request/url_request_failed_job.h" 58 #include "net/test/url_request/url_request_failed_job.h"
47 #include "net/test/url_request/url_request_mock_http_job.h" 59 #include "net/test/url_request/url_request_mock_http_job.h"
48 #include "net/url_request/url_request.h" 60 #include "net/url_request/url_request.h"
49 #include "net/url_request/url_request_context.h" 61 #include "net/url_request/url_request_context.h"
50 #include "net/url_request/url_request_context_getter.h" 62 #include "net/url_request/url_request_context_getter.h"
51 #include "net/url_request/url_request_filter.h" 63 #include "net/url_request/url_request_filter.h"
52 #include "net/url_request/url_request_job.h" 64 #include "net/url_request/url_request_job.h"
53 #include "net/url_request/url_request_status.h" 65 #include "net/url_request/url_request_status.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 "https://mock.captive.portal.long.timeout2/title2.html"; 114 "https://mock.captive.portal.long.timeout2/title2.html";
103 115
104 // Same as kMockHttpsUrl, except the timeout happens instantly. 116 // Same as kMockHttpsUrl, except the timeout happens instantly.
105 const char* const kMockHttpsQuickTimeoutUrl = 117 const char* const kMockHttpsQuickTimeoutUrl =
106 "https://mock.captive.portal.quick.timeout/title2.html"; 118 "https://mock.captive.portal.quick.timeout/title2.html";
107 119
108 // Expected title of a tab once an HTTPS load completes, when not behind a 120 // Expected title of a tab once an HTTPS load completes, when not behind a
109 // captive portal. 121 // captive portal.
110 const char* const kInternetConnectedTitle = "Title Of Awesomeness"; 122 const char* const kInternetConnectedTitle = "Title Of Awesomeness";
111 123
124 // Wait until all resources have loaded in an interstitial page.
125 bool WaitForInterstitialReady(content::InterstitialPage* interstitial) {
126 content::RenderViewHost* rvh = interstitial->GetRenderViewHostForTesting();
127 if (!rvh)
128 return false;
129 bool load_complete = false;
130 EXPECT_TRUE(
131 content::ExecuteScriptAndExtractBool(
132 rvh->GetMainFrame(),
133 "(function() {"
134 " var done = false;"
135 " function checkState() {"
136 " if (!done && document.readyState == 'complete') {"
137 " done = true;"
138 " window.domAutomationController.send(true);"
139 " }"
140 " }"
141 " checkState();"
142 " document.addEventListener('readystatechange', checkState);"
143 "})();",
144 &load_complete));
145 return load_complete;
146 }
147
112 // A URL request job that hangs until FailJobs() is called. Started jobs 148 // A URL request job that hangs until FailJobs() is called. Started jobs
113 // are stored in a static class variable containing a linked list so that 149 // are stored in a static class variable containing a linked list so that
114 // FailJobs() can locate them. 150 // FailJobs() can locate them.
115 class URLRequestTimeoutOnDemandJob : public net::URLRequestJob, 151 class URLRequestTimeoutOnDemandJob : public net::URLRequestJob,
116 public base::NonThreadSafe { 152 public base::NonThreadSafe {
117 public: 153 public:
118 // net::URLRequestJob: 154 // net::URLRequestJob:
119 void Start() override; 155 void Start() override;
120 156
121 // All the public static methods below can be called on any thread. 157 // All the public static methods below can be called on any thread.
122 158
123 // Waits for exactly |num_jobs|. 159 // Waits for exactly |num_jobs|.
124 static void WaitForJobs(int num_jobs); 160 static void WaitForJobs(int num_jobs);
125 161
126 // Fails all active URLRequestTimeoutOnDemandJobs with connection timeouts. 162 // Fails all active URLRequestTimeoutOnDemandJobs with connection timeouts.
127 // There are expected to be exactly |expected_num_jobs| waiting for 163 // There are expected to be exactly |expected_num_jobs| waiting for
128 // failure. The only way to gaurantee this is with an earlier call to 164 // failure. The only way to guarantee this is with an earlier call to
129 // WaitForJobs, so makes sure there has been a matching WaitForJobs call. 165 // WaitForJobs, so makes sure there has been a matching WaitForJobs call.
130 static void FailJobs(int expected_num_jobs); 166 static void FailJobs(int expected_num_jobs);
131 167
168 // Fails all active URLRequestTimeoutOnDemandJobs with SSL cert errors.
169 // |expected_num_jobs| behaves just as in FailJobs.
170 static void FailJobsWithCertError(int expected_num_jobs);
171
132 // Abandon all active URLRequestTimeoutOnDemandJobs. |expected_num_jobs| 172 // Abandon all active URLRequestTimeoutOnDemandJobs. |expected_num_jobs|
133 // behaves just as in FailJobs. 173 // behaves just as in FailJobs.
134 static void AbandonJobs(int expected_num_jobs); 174 static void AbandonJobs(int expected_num_jobs);
135 175
136 private: 176 private:
137 friend class URLRequestMockCaptivePortalJobFactory; 177 friend class URLRequestMockCaptivePortalJobFactory;
138 178
139 // Operation to perform on jobs when removing them from |job_list_|. 179 // Operation to perform on jobs when removing them from |job_list_|.
140 enum EndJobOperation { 180 enum EndJobOperation {
141 FAIL_JOBS, 181 FAIL_JOBS,
142 ABANDON_JOBS, 182 ABANDON_JOBS,
183 FAIL_JOBS_WITH_CERT_ERROR
143 }; 184 };
144 185
145 URLRequestTimeoutOnDemandJob(net::URLRequest* request, 186 URLRequestTimeoutOnDemandJob(net::URLRequest* request,
146 net::NetworkDelegate* network_delegate); 187 net::NetworkDelegate* network_delegate);
147 ~URLRequestTimeoutOnDemandJob() override; 188 ~URLRequestTimeoutOnDemandJob() override;
148 189
149 // Attempts to removes |this| from |jobs_|. Returns true if it was removed 190 // Attempts to removes |this| from |jobs_|. Returns true if it was removed
150 // from the list. 191 // from the list.
151 bool RemoveFromList(); 192 bool RemoveFromList();
152 193
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 // static 260 // static
220 void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs) { 261 void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs) {
221 content::BrowserThread::PostTask( 262 content::BrowserThread::PostTask(
222 content::BrowserThread::IO, FROM_HERE, 263 content::BrowserThread::IO, FROM_HERE,
223 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread, 264 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
224 expected_num_jobs, 265 expected_num_jobs,
225 FAIL_JOBS)); 266 FAIL_JOBS));
226 } 267 }
227 268
228 // static 269 // static
270 void URLRequestTimeoutOnDemandJob::FailJobsWithCertError(
271 int expected_num_jobs) {
272 content::BrowserThread::PostTask(
273 content::BrowserThread::IO, FROM_HERE,
274 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
275 expected_num_jobs,
276 FAIL_JOBS_WITH_CERT_ERROR));
277 }
278
279 // static
229 void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs) { 280 void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs) {
230 content::BrowserThread::PostTask( 281 content::BrowserThread::PostTask(
231 content::BrowserThread::IO, FROM_HERE, 282 content::BrowserThread::IO, FROM_HERE,
232 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread, 283 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
233 expected_num_jobs, 284 expected_num_jobs,
234 ABANDON_JOBS)); 285 ABANDON_JOBS));
235 } 286 }
236 287
237 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob( 288 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob(
238 net::URLRequest* request, net::NetworkDelegate* network_delegate) 289 net::URLRequest* request, net::NetworkDelegate* network_delegate)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 while (job_list_) { 357 while (job_list_) {
307 ++num_jobs; 358 ++num_jobs;
308 URLRequestTimeoutOnDemandJob* job = job_list_; 359 URLRequestTimeoutOnDemandJob* job = job_list_;
309 // Since the error notification may result in the job's destruction, remove 360 // Since the error notification may result in the job's destruction, remove
310 // it from the job list before the error. 361 // it from the job list before the error.
311 EXPECT_TRUE(job->RemoveFromList()); 362 EXPECT_TRUE(job->RemoveFromList());
312 if (end_job_operation == FAIL_JOBS) { 363 if (end_job_operation == FAIL_JOBS) {
313 job->NotifyStartError(net::URLRequestStatus( 364 job->NotifyStartError(net::URLRequestStatus(
314 net::URLRequestStatus::FAILED, 365 net::URLRequestStatus::FAILED,
315 net::ERR_CONNECTION_TIMED_OUT)); 366 net::ERR_CONNECTION_TIMED_OUT));
367 } else if (end_job_operation == FAIL_JOBS_WITH_CERT_ERROR) {
368 ASSERT_TRUE(job->request()->url().SchemeIs(url::kHttpsScheme));
369 net::SSLInfo info;
370 info.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
371 info.cert = new net::X509Certificate(
372 "bad.host", "CA", base::Time::Max(), base::Time::Max());
373 job->NotifySSLCertificateError(info, true);
316 } 374 }
317 } 375 }
318 376
319 EXPECT_EQ(expected_num_jobs, num_jobs_started_); 377 EXPECT_EQ(expected_num_jobs, num_jobs_started_);
320 EXPECT_EQ(expected_num_jobs, num_jobs); 378 EXPECT_EQ(expected_num_jobs, num_jobs);
321 379
322 num_jobs_started_ -= expected_num_jobs; 380 num_jobs_started_ -= expected_num_jobs;
323 } 381 }
324 382
325 // URLRequestCaptivePortalJobFactory emulates captive portal behavior. 383 // URLRequestCaptivePortalJobFactory emulates captive portal behavior.
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 base::MessageLoopForUI::current()->Quit(); 740 base::MessageLoopForUI::current()->Quit();
683 } 741 }
684 } 742 }
685 743
686 // An observer for watching the CaptivePortalService. It tracks the last 744 // An observer for watching the CaptivePortalService. It tracks the last
687 // received result and the total number of received results. 745 // received result and the total number of received results.
688 class CaptivePortalObserver : public content::NotificationObserver { 746 class CaptivePortalObserver : public content::NotificationObserver {
689 public: 747 public:
690 explicit CaptivePortalObserver(Profile* profile); 748 explicit CaptivePortalObserver(Profile* profile);
691 749
692 // Runs the message loop until until at exactly |update_count| capitive portal 750 // Runs the message loop until exactly |update_count| captive portal
693 // results have been received, since this creation of |this|. Expects no 751 // results have been received, since the creation of |this|. Expects no
694 // additional captive portal results. 752 // additional captive portal results.
695 void WaitForResults(int num_results_to_wait_for); 753 void WaitForResults(int num_results_to_wait_for);
696 754
697 int num_results_received() const { return num_results_received_; } 755 int num_results_received() const { return num_results_received_; }
698 756
699 CaptivePortalResult captive_portal_result() const { 757 CaptivePortalResult captive_portal_result() const {
700 return captive_portal_result_; 758 return captive_portal_result_;
701 } 759 }
702 760
703 private: 761 private:
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 captive_portal_result_ = results->result; 828 captive_portal_result_ = results->result;
771 ++num_results_received_; 829 ++num_results_received_;
772 830
773 if (waiting_for_result_ && 831 if (waiting_for_result_ &&
774 num_results_to_wait_for_ == num_results_received_) { 832 num_results_to_wait_for_ == num_results_received_) {
775 waiting_for_result_ = false; 833 waiting_for_result_ = false;
776 base::MessageLoop::current()->Quit(); 834 base::MessageLoop::current()->Quit();
777 } 835 }
778 } 836 }
779 837
838 // This observer waits for the SSLErrorHandler to fire an interstitial timer for
839 // the given web contents.
840 class SSLInterstitialTimerObserver {
841 public:
842 explicit SSLInterstitialTimerObserver(content::WebContents* web_contents);
843 ~SSLInterstitialTimerObserver();
844
845 // Waits until the interstitial delay timer in SSLErrorHandler is fired.
846 void WaitForTimerFired();
847
848 private:
849 void OnTimerFired(content::WebContents* web_contents);
850
851 const content::WebContents* web_contents_;
852 SSLErrorHandler::TimerFiredCallback callback_;
853
854 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
855
856 DISALLOW_COPY_AND_ASSIGN(SSLInterstitialTimerObserver);
857 };
858
859 SSLInterstitialTimerObserver::SSLInterstitialTimerObserver(
860 content::WebContents* web_contents)
861 : web_contents_(web_contents) {
862 callback_ = base::Bind(&SSLInterstitialTimerObserver::OnTimerFired,
863 base::Unretained(this));
864 SSLErrorHandler::SetInterstitialTimerFiredCallbackForTest(&callback_);
865 }
866
867 SSLInterstitialTimerObserver::~SSLInterstitialTimerObserver() {
868 SSLErrorHandler::SetInterstitialTimerFiredCallbackForTest(nullptr);
869 }
870
871 void SSLInterstitialTimerObserver::WaitForTimerFired() {
872 message_loop_runner_ = new content::MessageLoopRunner;
Bernhard Bauer 2014/12/19 10:14:25 You may want to initialize the message loop runner
meacer 2014/12/19 19:04:23 Done.
873 message_loop_runner_->Run();
874 }
875
876 void SSLInterstitialTimerObserver::OnTimerFired(
877 content::WebContents* web_contents) {
878 if (web_contents_ == web_contents && message_loop_runner_.get())
879 message_loop_runner_->Quit();
880 }
881
780 // Adds an HSTS rule for |host|, so that all HTTP requests sent to it will 882 // Adds an HSTS rule for |host|, so that all HTTP requests sent to it will
781 // be switched to HTTPS requests. 883 // be switched to HTTPS requests.
782 void AddHstsHost(net::URLRequestContextGetter* context_getter, 884 void AddHstsHost(net::URLRequestContextGetter* context_getter,
783 const std::string& host) { 885 const std::string& host) {
784 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 886 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
785 net::TransportSecurityState* transport_security_state = 887 net::TransportSecurityState* transport_security_state =
786 context_getter->GetURLRequestContext()->transport_security_state(); 888 context_getter->GetURLRequestContext()->transport_security_state();
787 if (!transport_security_state) { 889 if (!transport_security_state) {
788 FAIL(); 890 FAIL();
789 return; 891 return;
(...skipping 11 matching lines...) Expand all
801 CaptivePortalBrowserTest(); 903 CaptivePortalBrowserTest();
802 904
803 // InProcessBrowserTest: 905 // InProcessBrowserTest:
804 void SetUpOnMainThread() override; 906 void SetUpOnMainThread() override;
805 void TearDownOnMainThread() override; 907 void TearDownOnMainThread() override;
806 908
807 // Sets the captive portal checking preference. Does not affect the command 909 // Sets the captive portal checking preference. Does not affect the command
808 // line flag, which is set in SetUpCommandLine. 910 // line flag, which is set in SetUpCommandLine.
809 void EnableCaptivePortalDetection(Profile* profile, bool enabled); 911 void EnableCaptivePortalDetection(Profile* profile, bool enabled);
810 912
913 // Enables or disables actual captive portal probes. Should only be called
914 // after captive portal service setup is done. When disabled, probe requests
915 // are silently ignored, never receiving a response.
916 void RespondToProbeRequests(bool enabled);
917
811 // Sets up the captive portal service for the given profile so that 918 // Sets up the captive portal service for the given profile so that
812 // all checks go to |test_url|. Also disables all timers. 919 // all checks go to |test_url|. Also disables all timers.
813 void SetUpCaptivePortalService(Profile* profile, const GURL& test_url); 920 void SetUpCaptivePortalService(Profile* profile, const GURL& test_url);
814 921
815 // Returns true if |browser|'s profile is currently running a captive portal 922 // Returns true if |browser|'s profile is currently running a captive portal
816 // check. 923 // check.
817 bool CheckPending(Browser* browser); 924 bool CheckPending(Browser* browser);
818 925
926 // Returns the type of the interstitial being shown.
927 const void* GetInterstitialType(WebContents* contents) const;
928
819 // Returns the CaptivePortalTabReloader::State of |web_contents|. 929 // Returns the CaptivePortalTabReloader::State of |web_contents|.
820 CaptivePortalTabReloader::State GetStateOfTabReloader( 930 CaptivePortalTabReloader::State GetStateOfTabReloader(
821 WebContents* web_contents) const; 931 WebContents* web_contents) const;
822 932
823 // Returns the CaptivePortalTabReloader::State of the indicated tab. 933 // Returns the CaptivePortalTabReloader::State of the indicated tab.
824 CaptivePortalTabReloader::State GetStateOfTabReloaderAt(Browser* browser, 934 CaptivePortalTabReloader::State GetStateOfTabReloaderAt(Browser* browser,
825 int index) const; 935 int index) const;
826 936
827 // Returns the number of tabs with the given state, across all profiles. 937 // Returns the number of tabs with the given state, across all profiles.
828 int NumTabsWithState(CaptivePortalTabReloader::State state) const; 938 int NumTabsWithState(CaptivePortalTabReloader::State state) const;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 1000
891 // Just like SlowLoadBehindCaptivePortal, except the navigated tab has 1001 // Just like SlowLoadBehindCaptivePortal, except the navigated tab has
892 // a connection timeout rather having its time trigger, and the function 1002 // a connection timeout rather having its time trigger, and the function
893 // waits until that timeout occurs. 1003 // waits until that timeout occurs.
894 void FastTimeoutBehindCaptivePortal(Browser* browser, 1004 void FastTimeoutBehindCaptivePortal(Browser* browser,
895 bool expect_open_login_tab); 1005 bool expect_open_login_tab);
896 1006
897 // Much as above, but accepts a URL parameter and can be used for errors that 1007 // Much as above, but accepts a URL parameter and can be used for errors that
898 // trigger captive portal checks other than timeouts. |error_url| should 1008 // trigger captive portal checks other than timeouts. |error_url| should
899 // result in an error rather than hanging. 1009 // result in an error rather than hanging.
900 void FastErrorBehindCaptivePortal(Browser* browser, 1010 // If |delay_portal_response_until_interstital| is true, captive portal probe
901 bool expect_open_login_tab, 1011 // request are ignored until the interstitial is shown, at which point a
902 const GURL& error_url); 1012 // captive portal result is sent. This allows testing in conjunction with the
1013 // certificate error interstitial.
1014 void FastErrorBehindCaptivePortal(
1015 Browser* browser,
1016 bool expect_open_login_tab,
1017 const GURL& error_url,
1018 bool delay_portal_response_until_interstital);
1019
1020 // Navigates the active tab to an SSL error page which triggers an
1021 // interstitial timer. Also disables captive portal checks indefinitely, so
1022 // the page appears to be hanging.
1023 void FastErrorWithInterstitialTimer(Browser* browser,
1024 const GURL& cert_error_url);
903 1025
904 // Navigates the login tab without logging in. The login tab must be the 1026 // Navigates the login tab without logging in. The login tab must be the
905 // specified browser's active tab. Expects no other tab to change state. 1027 // specified browser's active tab. Expects no other tab to change state.
906 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks 1028 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
907 // that nothing has gone wrong prior to the function call. 1029 // that nothing has gone wrong prior to the function call.
908 void NavigateLoginTab(Browser* browser, 1030 void NavigateLoginTab(Browser* browser,
909 int num_loading_tabs, 1031 int num_loading_tabs,
910 int num_timed_out_tabs); 1032 int num_timed_out_tabs);
911 1033
912 // Simulates a login by updating the URLRequestMockCaptivePortalJob's 1034 // Simulates a login by updating the URLRequestMockCaptivePortalJob's
913 // behind captive portal state, and navigating the login tab. Waits for 1035 // behind captive portal state, and navigating the login tab. Waits for
914 // all broken but not loading tabs to be reloaded. 1036 // all broken but not loading tabs to be reloaded.
915 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks 1037 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
916 // that nothing has gone wrong prior to the function call. 1038 // that nothing has gone wrong prior to the function call.
917 void Login(Browser* browser, int num_loading_tabs, int num_timed_out_tabs); 1039 void Login(Browser* browser, int num_loading_tabs, int num_timed_out_tabs);
918 1040
1041 // Simulates a login when the broken tab shows an SSL or captive portal
1042 // interstitial. Can't use Login() in those cases because the interstitial
1043 // tab looks like a cross between a hung tab (Load was never committed) and a
1044 // tab at an error page (The load was stopped).
1045 void LoginCertError(Browser* browser);
1046
919 // Makes the slow SSL loads of all active tabs time out at once, and waits for 1047 // Makes the slow SSL loads of all active tabs time out at once, and waits for
920 // them to finish both that load and the automatic reload it should trigger. 1048 // them to finish both that load and the automatic reload it should trigger.
921 // There should be no timed out tabs when this is called. 1049 // There should be no timed out tabs when this is called.
922 void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs); 1050 void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs);
923 1051
924 // Makes the slow SSL loads of all active tabs time out at once, and waits for 1052 // Makes the slow SSL loads of all active tabs time out at once, and waits for
925 // them to finish displaying their error pages. The login tab should be the 1053 // them to finish displaying their error pages. The login tab should be the
926 // active tab. There should be no timed out tabs when this is called. 1054 // active tab. There should be no timed out tabs when this is called.
927 void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs); 1055 void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs);
928 1056
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 CaptivePortalService::get_state_for_testing()); 1099 CaptivePortalService::get_state_for_testing());
972 1100
973 CaptivePortalService::set_state_for_testing( 1101 CaptivePortalService::set_state_for_testing(
974 CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING); 1102 CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING);
975 EnableCaptivePortalDetection(browser()->profile(), true); 1103 EnableCaptivePortalDetection(browser()->profile(), true);
976 1104
977 // Set the captive portal service to use URLRequestMockCaptivePortalJob's 1105 // Set the captive portal service to use URLRequestMockCaptivePortalJob's
978 // mock URL, by default. 1106 // mock URL, by default.
979 SetUpCaptivePortalService(browser()->profile(), 1107 SetUpCaptivePortalService(browser()->profile(),
980 GURL(kMockCaptivePortalTestUrl)); 1108 GURL(kMockCaptivePortalTestUrl));
1109
1110 // Set SSL interstitial delay long enough so that a captive portal result
1111 // is guaranteed to arrive during this window, and a captive portal
1112 // error page is displayed instead of an SSL interstitial.
1113 SSLErrorHandler::SetInterstitialDisplayDelayForTest(
1114 base::TimeDelta::FromHours(1));
981 } 1115 }
982 1116
983 void CaptivePortalBrowserTest::TearDownOnMainThread() { 1117 void CaptivePortalBrowserTest::TearDownOnMainThread() {
984 // No test should have a captive portal check pending on quit. 1118 // No test should have a captive portal check pending on quit.
985 EXPECT_FALSE(CheckPending(browser())); 1119 EXPECT_FALSE(CheckPending(browser()));
986 } 1120 }
987 1121
988 void CaptivePortalBrowserTest::EnableCaptivePortalDetection( 1122 void CaptivePortalBrowserTest::EnableCaptivePortalDetection(
989 Profile* profile, bool enabled) { 1123 Profile* profile, bool enabled) {
990 profile->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled); 1124 profile->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled);
991 } 1125 }
992 1126
1127 void CaptivePortalBrowserTest::RespondToProbeRequests(bool enabled) {
1128 if (enabled) {
1129 EXPECT_EQ(CaptivePortalService::IGNORE_REQUESTS_FOR_TESTING,
1130 CaptivePortalService::get_state_for_testing());
1131 CaptivePortalService::set_state_for_testing(
1132 CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING);
1133 } else {
1134 EXPECT_EQ(CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING,
1135 CaptivePortalService::get_state_for_testing());
1136 CaptivePortalService::set_state_for_testing(
1137 CaptivePortalService::IGNORE_REQUESTS_FOR_TESTING);
1138 }
1139 }
1140
993 void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile, 1141 void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile,
994 const GURL& test_url) { 1142 const GURL& test_url) {
995 CaptivePortalService* captive_portal_service = 1143 CaptivePortalService* captive_portal_service =
996 CaptivePortalServiceFactory::GetForProfile(profile); 1144 CaptivePortalServiceFactory::GetForProfile(profile);
997 captive_portal_service->set_test_url(test_url); 1145 captive_portal_service->set_test_url(test_url);
998 1146
999 // Don't use any non-zero timers. Timers are checked in unit tests. 1147 // Don't use any non-zero timers. Timers are checked in unit tests.
1000 CaptivePortalService::RecheckPolicy* recheck_policy = 1148 CaptivePortalService::RecheckPolicy* recheck_policy =
1001 &captive_portal_service->recheck_policy(); 1149 &captive_portal_service->recheck_policy();
1002 recheck_policy->initial_backoff_no_portal_ms = 0; 1150 recheck_policy->initial_backoff_no_portal_ms = 0;
1003 recheck_policy->initial_backoff_portal_ms = 0; 1151 recheck_policy->initial_backoff_portal_ms = 0;
1004 recheck_policy->backoff_policy.maximum_backoff_ms = 0; 1152 recheck_policy->backoff_policy.maximum_backoff_ms = 0;
1005 } 1153 }
1006 1154
1007 bool CaptivePortalBrowserTest::CheckPending(Browser* browser) { 1155 bool CaptivePortalBrowserTest::CheckPending(Browser* browser) {
1008 CaptivePortalService* captive_portal_service = 1156 CaptivePortalService* captive_portal_service =
1009 CaptivePortalServiceFactory::GetForProfile(browser->profile()); 1157 CaptivePortalServiceFactory::GetForProfile(browser->profile());
1010 1158
1011 return captive_portal_service->DetectionInProgress() || 1159 return captive_portal_service->DetectionInProgress() ||
1012 captive_portal_service->TimerRunning(); 1160 captive_portal_service->TimerRunning();
1013 } 1161 }
1014 1162
1163 const void* CaptivePortalBrowserTest::GetInterstitialType(
1164 WebContents* contents) const {
1165 if (!contents->ShowingInterstitialPage())
1166 return nullptr;
1167 SecurityInterstitialPage* blocking_page =
1168 static_cast<SecurityInterstitialPage*>(
1169 contents->GetInterstitialPage()->GetDelegateForTesting());
1170 return blocking_page->GetTypeForTesting();
1171 }
1172
1015 CaptivePortalTabReloader::State CaptivePortalBrowserTest::GetStateOfTabReloader( 1173 CaptivePortalTabReloader::State CaptivePortalBrowserTest::GetStateOfTabReloader(
1016 WebContents* web_contents) const { 1174 WebContents* web_contents) const {
1017 return GetTabReloader(web_contents)->state(); 1175 return GetTabReloader(web_contents)->state();
1018 } 1176 }
1019 1177
1020 CaptivePortalTabReloader::State 1178 CaptivePortalTabReloader::State
1021 CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser* browser, 1179 CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser* browser,
1022 int index) const { 1180 int index) const {
1023 return GetStateOfTabReloader( 1181 return GetStateOfTabReloader(
1024 browser->tab_strip_model()->GetWebContentsAt(index)); 1182 browser->tab_strip_model()->GetWebContentsAt(index));
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 1395
1238 // Reset the load time to be large, so the timer won't trigger on a reload. 1396 // Reset the load time to be large, so the timer won't trigger on a reload.
1239 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1)); 1397 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
1240 } 1398 }
1241 1399
1242 void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal( 1400 void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal(
1243 Browser* browser, 1401 Browser* browser,
1244 bool expect_open_login_tab) { 1402 bool expect_open_login_tab) {
1245 FastErrorBehindCaptivePortal(browser, 1403 FastErrorBehindCaptivePortal(browser,
1246 expect_open_login_tab, 1404 expect_open_login_tab,
1247 GURL(kMockHttpsQuickTimeoutUrl)); 1405 GURL(kMockHttpsQuickTimeoutUrl),
1406 false);
1248 } 1407 }
1249 1408
1250 void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal( 1409 void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal(
1251 Browser* browser, 1410 Browser* browser,
1252 bool expect_open_login_tab, 1411 bool expect_open_login_tab,
1253 const GURL& error_url) { 1412 const GURL& error_url,
1413 bool delay_portal_response_until_interstital) {
1254 TabStripModel* tab_strip_model = browser->tab_strip_model(); 1414 TabStripModel* tab_strip_model = browser->tab_strip_model();
1255 // Calling this on a tab that's waiting for a load to manually be timed out 1415 // Calling this on a tab that's waiting for a load to manually be timed out
1256 // will result in a hang. 1416 // will result in a hang.
1257 ASSERT_FALSE(tab_strip_model->GetActiveWebContents()->IsLoading()); 1417 ASSERT_FALSE(tab_strip_model->GetActiveWebContents()->IsLoading());
1258 1418
1259 // Set the load time to be large, so the timer won't trigger. The value is 1419 // Set the load time to be large, so the timer won't trigger. The value is
1260 // not restored at the end of the function. 1420 // not restored at the end of the function.
1261 CaptivePortalTabReloader* tab_reloader = 1421 CaptivePortalTabReloader* tab_reloader =
1262 GetTabReloader(tab_strip_model->GetActiveWebContents()); 1422 GetTabReloader(tab_strip_model->GetActiveWebContents());
1263 ASSERT_TRUE(tab_reloader); 1423 ASSERT_TRUE(tab_reloader);
1264 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1)); 1424 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
1265 1425
1266 // Number of tabs expected to be open after the captive portal checks 1426 // Number of tabs expected to be open after the captive portal checks
1267 // have completed. 1427 // have completed.
1268 int initial_tab_count = tab_strip_model->count(); 1428 int initial_tab_count = tab_strip_model->count();
1269 int initial_active_index = tab_strip_model->active_index(); 1429 int initial_active_index = tab_strip_model->active_index();
1270 int initial_loading_tabs = NumLoadingTabs(); 1430 int initial_loading_tabs = NumLoadingTabs();
1271 int expected_broken_tabs = NumBrokenTabs(); 1431 int expected_broken_tabs = NumBrokenTabs();
1272 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL != 1432 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL !=
1273 GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())) { 1433 GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())) {
1274 ++expected_broken_tabs; 1434 ++expected_broken_tabs;
1275 } 1435 }
1276 1436
1437 CaptivePortalService* captive_portal_service =
1438 CaptivePortalServiceFactory::GetForProfile(browser->profile());
1439 if (delay_portal_response_until_interstital)
1440 RespondToProbeRequests(false);
1441
1277 MultiNavigationObserver navigation_observer; 1442 MultiNavigationObserver navigation_observer;
1278 CaptivePortalObserver portal_observer(browser->profile()); 1443 CaptivePortalObserver portal_observer(browser->profile());
1279 ui_test_utils::NavigateToURLWithDisposition(browser, 1444 ui_test_utils::NavigateToURLWithDisposition(browser,
1280 error_url, 1445 error_url,
1281 CURRENT_TAB, 1446 CURRENT_TAB,
1282 ui_test_utils::BROWSER_TEST_NONE); 1447 ui_test_utils::BROWSER_TEST_NONE);
1448
1449 if (delay_portal_response_until_interstital) {
1450 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1451 GetStateOfTabReloaderAt(browser, initial_active_index));
1452 // Once the interstitial is attached, probe for captive portal.
1453 WaitForInterstitialAttach(tab_strip_model->GetActiveWebContents());
1454 RespondToProbeRequests(true);
1455 captive_portal_service->DetectCaptivePortal();
1456 }
1457
1283 portal_observer.WaitForResults(1); 1458 portal_observer.WaitForResults(1);
1284 1459
1285 if (expect_open_login_tab) { 1460 if (expect_open_login_tab) {
1286 navigation_observer.WaitForNavigations(2); 1461 navigation_observer.WaitForNavigations(2);
1287 ASSERT_EQ(initial_tab_count + 1, tab_strip_model->count()); 1462 ASSERT_EQ(initial_tab_count + 1, tab_strip_model->count());
1288 EXPECT_EQ(initial_tab_count, tab_strip_model->active_index()); 1463 EXPECT_EQ(initial_tab_count, tab_strip_model->active_index());
1289 // Make sure that the originally active tab and the captive portal tab have 1464 // Make sure that the originally active tab and the captive portal tab have
1290 // each loaded once. 1465 // each loaded once.
1291 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( 1466 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1292 tab_strip_model->GetWebContentsAt(initial_active_index))); 1467 tab_strip_model->GetWebContentsAt(initial_active_index)));
(...skipping 15 matching lines...) Expand all
1308 EXPECT_EQ(expected_broken_tabs, NumBrokenTabs()); 1483 EXPECT_EQ(expected_broken_tabs, NumBrokenTabs());
1309 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL, 1484 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
1310 portal_observer.captive_portal_result()); 1485 portal_observer.captive_portal_result());
1311 EXPECT_EQ(1, portal_observer.num_results_received()); 1486 EXPECT_EQ(1, portal_observer.num_results_received());
1312 EXPECT_FALSE(CheckPending(browser)); 1487 EXPECT_FALSE(CheckPending(browser));
1313 1488
1314 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, 1489 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
1315 GetStateOfTabReloaderAt(browser, initial_active_index)); 1490 GetStateOfTabReloaderAt(browser, initial_active_index));
1316 } 1491 }
1317 1492
1493 void CaptivePortalBrowserTest::FastErrorWithInterstitialTimer(
1494 Browser* browser,
1495 const GURL& cert_error_url) {
1496 TabStripModel* tab_strip_model = browser->tab_strip_model();
1497 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
1498
1499 // Disable captive portal checks indefinitely.
1500 RespondToProbeRequests(false);
1501
1502 SSLInterstitialTimerObserver interstitial_timer_observer(broken_tab_contents);
1503 ui_test_utils::NavigateToURLWithDisposition(browser,
1504 cert_error_url,
1505 CURRENT_TAB,
1506 ui_test_utils::BROWSER_TEST_NONE);
1507 interstitial_timer_observer.WaitForTimerFired();
1508
1509 // The tab should be in loading state, waiting for the interstitial timer to
1510 // expire or a captive portal result to arrive. Since captive portal checks
1511 // are disabled and timer set to expire after a very long time, the tab should
1512 // hang indefinitely.
1513 EXPECT_TRUE(broken_tab_contents->IsLoading());
1514 EXPECT_EQ(1, NumLoadingTabs());
1515 }
1516
1318 void CaptivePortalBrowserTest::NavigateLoginTab(Browser* browser, 1517 void CaptivePortalBrowserTest::NavigateLoginTab(Browser* browser,
1319 int num_loading_tabs, 1518 int num_loading_tabs,
1320 int num_timed_out_tabs) { 1519 int num_timed_out_tabs) {
1321 MultiNavigationObserver navigation_observer; 1520 MultiNavigationObserver navigation_observer;
1322 CaptivePortalObserver portal_observer(browser->profile()); 1521 CaptivePortalObserver portal_observer(browser->profile());
1323 1522
1324 TabStripModel* tab_strip_model = browser->tab_strip_model(); 1523 TabStripModel* tab_strip_model = browser->tab_strip_model();
1325 int initial_tab_count = tab_strip_model->count(); 1524 int initial_tab_count = tab_strip_model->count();
1326 EXPECT_EQ(num_loading_tabs, NumLoadingTabs()); 1525 EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
1327 EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs()); 1526 EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs());
1328 1527
1329 int login_tab_index = tab_strip_model->active_index(); 1528 int login_tab_index = tab_strip_model->active_index();
1330 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, 1529 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1331 GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())); 1530 GetStateOfTabReloader(tab_strip_model->GetActiveWebContents()));
1332 ASSERT_TRUE(IsLoginTab(browser->tab_strip_model()->GetActiveWebContents())); 1531 ASSERT_TRUE(IsLoginTab(browser->tab_strip_model()->GetActiveWebContents()));
1333 1532
1334 // Do the navigation. 1533 // Do the navigation.
1335 content::RenderFrameHost* render_frame_host = 1534 EXPECT_TRUE(content::ExecuteScript(tab_strip_model->GetActiveWebContents(),
1336 tab_strip_model->GetActiveWebContents()->GetMainFrame(); 1535 "submitForm()"));
1337 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
1338 1536
1339 portal_observer.WaitForResults(1); 1537 portal_observer.WaitForResults(1);
1340 navigation_observer.WaitForNavigations(1); 1538 navigation_observer.WaitForNavigations(1);
1341 1539
1342 // Check the captive portal result. 1540 // Check the captive portal result.
1343 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL, 1541 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
1344 portal_observer.captive_portal_result()); 1542 portal_observer.captive_portal_result());
1345 EXPECT_EQ(1, portal_observer.num_results_received()); 1543 EXPECT_EQ(1, portal_observer.num_results_received());
1346 EXPECT_FALSE(CheckPending(browser)); 1544 EXPECT_FALSE(CheckPending(browser));
1347 1545
(...skipping 24 matching lines...) Expand all
1372 ASSERT_EQ(num_loading_tabs, NumLoadingTabs()); 1570 ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
1373 EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs()); 1571 EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs());
1374 1572
1375 // Verify that the login page is on top. 1573 // Verify that the login page is on top.
1376 int login_tab_index = tab_strip_model->active_index(); 1574 int login_tab_index = tab_strip_model->active_index();
1377 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, 1575 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1378 GetStateOfTabReloaderAt(browser, login_tab_index)); 1576 GetStateOfTabReloaderAt(browser, login_tab_index));
1379 ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index))); 1577 ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
1380 1578
1381 // Trigger a navigation. 1579 // Trigger a navigation.
1382 content::RenderFrameHost* render_frame_host = 1580 EXPECT_TRUE(content::ExecuteScript(tab_strip_model->GetActiveWebContents(),
1383 tab_strip_model->GetActiveWebContents()->GetMainFrame(); 1581 "submitForm()"));
1384 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
1385 1582
1386 portal_observer.WaitForResults(1); 1583 portal_observer.WaitForResults(1);
1387 1584
1388 // Wait for all the timed out tabs to reload. 1585 // Wait for all the timed out tabs to reload.
1389 navigation_observer.WaitForNavigations(1 + num_timed_out_tabs); 1586 navigation_observer.WaitForNavigations(1 + num_timed_out_tabs);
1390 EXPECT_EQ(1, portal_observer.num_results_received()); 1587 EXPECT_EQ(1, portal_observer.num_results_received());
1391 1588
1392 // The tabs that were loading before should still be loading, and now be in 1589 // The tabs that were loading before should still be loading, and now be in
1393 // STATE_NEEDS_RELOAD. 1590 // STATE_NEEDS_RELOAD.
1394 EXPECT_EQ(0, NumBrokenTabs()); 1591 EXPECT_EQ(0, NumBrokenTabs());
1395 EXPECT_EQ(num_loading_tabs, NumLoadingTabs()); 1592 EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
1396 EXPECT_EQ(num_loading_tabs, NumNeedReloadTabs()); 1593 EXPECT_EQ(num_loading_tabs, NumNeedReloadTabs());
1397 1594
1398 // Make sure that the broken tabs have reloaded, and there's no more 1595 // Make sure that the broken tabs have reloaded, and there's no more
1399 // captive portal tab. 1596 // captive portal tab.
1400 EXPECT_EQ(initial_tab_count, tab_strip_model->count()); 1597 EXPECT_EQ(initial_tab_count, tab_strip_model->count());
1401 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, 1598 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1402 GetStateOfTabReloaderAt(browser, login_tab_index)); 1599 GetStateOfTabReloaderAt(browser, login_tab_index));
1403 EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index))); 1600 EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
1404 1601
1405 // Make sure there were no unexpected navigations of the login tab. 1602 // Make sure there were no unexpected navigations of the login tab.
1406 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( 1603 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1407 tab_strip_model->GetWebContentsAt(login_tab_index))); 1604 tab_strip_model->GetWebContentsAt(login_tab_index)));
1408 } 1605 }
1409 1606
1607 void CaptivePortalBrowserTest::LoginCertError(Browser* browser) {
1608 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1609
1610 MultiNavigationObserver navigation_observer;
1611 CaptivePortalObserver portal_observer(browser->profile());
1612
1613 TabStripModel* tab_strip_model = browser->tab_strip_model();
1614
1615 // Verify that the login page is on top.
1616 int login_tab_index = tab_strip_model->active_index();
1617 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1618 GetStateOfTabReloaderAt(browser, login_tab_index));
1619 ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
1620
1621 // Trigger a navigation.
1622 EXPECT_TRUE(content::ExecuteScript(tab_strip_model->GetActiveWebContents(),
1623 "submitForm()"));
1624
1625 // The captive portal tab navigation will trigger a captive portal check,
1626 // and reloading the original tab will bring up the interstitial page again,
1627 // triggering a second captive portal check.
1628 portal_observer.WaitForResults(2);
1629
1630 // Wait for both tabs to finish loading.
1631 navigation_observer.WaitForNavigations(2);
1632 EXPECT_EQ(2, portal_observer.num_results_received());
1633 EXPECT_FALSE(CheckPending(browser));
1634 EXPECT_EQ(captive_portal::RESULT_INTERNET_CONNECTED,
1635 portal_observer.captive_portal_result());
1636
1637 // Check state of tabs. While the first tab is still displaying an
1638 // interstitial page, since no portal was found, it should be in STATE_NONE,
1639 // as should the login tab.
1640 ASSERT_EQ(2, tab_strip_model->count());
1641 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1642 GetStateOfTabReloaderAt(browser, 0));
1643 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1644 GetStateOfTabReloaderAt(browser, login_tab_index));
1645 EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
1646
1647 // Make sure only one navigation was for the login tab.
1648 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1649 tab_strip_model->GetWebContentsAt(login_tab_index)));
1650 }
1651
1410 void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser, 1652 void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser,
1411 int num_loading_tabs) { 1653 int num_loading_tabs) {
1412 ASSERT_EQ(num_loading_tabs, NumLoadingTabs()); 1654 ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
1413 ASSERT_EQ(num_loading_tabs, NumNeedReloadTabs()); 1655 ASSERT_EQ(num_loading_tabs, NumNeedReloadTabs());
1414 EXPECT_EQ(0, NumBrokenTabs()); 1656 EXPECT_EQ(0, NumBrokenTabs());
1415 1657
1416 TabStripModel* tab_strip_model = browser->tab_strip_model(); 1658 TabStripModel* tab_strip_model = browser->tab_strip_model();
1417 int initial_num_tabs = tab_strip_model->count(); 1659 int initial_num_tabs = tab_strip_model->count();
1418 int initial_active_tab = tab_strip_model->active_index(); 1660 int initial_active_tab = tab_strip_model->active_index();
1419 1661
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 } 1940 }
1699 1941
1700 // Checks the unlikely case that the tab times out before the timer triggers. 1942 // Checks the unlikely case that the tab times out before the timer triggers.
1701 // This most likely won't happen, but should still work: 1943 // This most likely won't happen, but should still work:
1702 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) { 1944 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) {
1703 FastTimeoutBehindCaptivePortal(browser(), true); 1945 FastTimeoutBehindCaptivePortal(browser(), true);
1704 Login(browser(), 0, 1); 1946 Login(browser(), 0, 1);
1705 } 1947 }
1706 1948
1707 // A cert error triggers a captive portal check and results in opening a login 1949 // A cert error triggers a captive portal check and results in opening a login
1708 // tab. The user then logs in and the page with the error is reloaded. 1950 // tab.
1709 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, SSLCertErrorLogin) { 1951 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
1710 // Need an HTTP TestServer to handle a dynamically created server redirect. 1952 ShowCaptivePortalInterstitialOnCertError) {
1711 ASSERT_TRUE(test_server()->Start());
1712
1713 net::SpawnedTestServer::SSLOptions https_options; 1953 net::SpawnedTestServer::SSLOptions https_options;
1714 https_options.server_certificate = 1954 https_options.server_certificate =
1715 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 1955 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
1716 net::SpawnedTestServer https_server( 1956 net::SpawnedTestServer https_server(
1717 net::SpawnedTestServer::TYPE_HTTPS, https_options, 1957 net::SpawnedTestServer::TYPE_HTTPS, https_options,
1718 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1958 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1719 ASSERT_TRUE(https_server.Start()); 1959 ASSERT_TRUE(https_server.Start());
1720 1960
1721 // The path does not matter. 1961 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1722 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath); 1962 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
1963
1964 // The path does not matter.
1965 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
1966 int cert_error_tab_index = tab_strip_model->active_index();
1723 // The interstitial should trigger a captive portal check when it opens, just 1967 // The interstitial should trigger a captive portal check when it opens, just
1724 // like navigating to kMockHttpsQuickTimeoutUrl. 1968 // like navigating to kMockHttpsQuickTimeoutUrl.
1725 FastErrorBehindCaptivePortal(browser(), true, cert_error_url); 1969 FastErrorBehindCaptivePortal(browser(), true, cert_error_url, false);
1726 1970 EXPECT_EQ(CaptivePortalBlockingPage::kTypeForTesting,
1727 // Simulate logging in. Can't use Login() because the interstitial tab looks 1971 GetInterstitialType(broken_tab_contents));
1728 // like a cross between a hung tab (Load was never committed) and a tab at an 1972
1729 // error page (The load was stopped). 1973 // Switch to the interstitial and click the |Connect| button. Should switch
1730 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false); 1974 // active tab to the captive portal landing page.
1975 int login_tab_index = tab_strip_model->active_index();
1976 tab_strip_model->ActivateTabAt(cert_error_tab_index, false);
1977 // Wait for the interstitial to load all the JavaScript code. Otherwise,
1978 // trying to click on a button will fail.
1979 EXPECT_TRUE(WaitForInterstitialReady(
1980 broken_tab_contents->GetInterstitialPage()));
1981 content::RenderViewHost* rvh =
1982 broken_tab_contents->GetInterstitialPage()->GetRenderViewHostForTesting();
1983 const char kClickConnectButtonJS[] =
1984 "document.getElementById('primary-button').click();";
1985 EXPECT_TRUE(
1986 content::ExecuteScript(rvh->GetMainFrame(), kClickConnectButtonJS));
1987 EXPECT_EQ(login_tab_index, tab_strip_model->active_index());
1988
1989 // For completeness, close the login tab and try clicking |Connect| again.
1990 // A new login tab should open.
1991 EXPECT_EQ(1, login_tab_index);
1992 content::WebContentsDestroyedWatcher destroyed_watcher(
1993 tab_strip_model->GetActiveWebContents());
1994 EXPECT_TRUE(
1995 tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0));
1996 destroyed_watcher.Wait();
1731 MultiNavigationObserver navigation_observer; 1997 MultiNavigationObserver navigation_observer;
1998 EXPECT_TRUE(
1999 content::ExecuteScript(rvh->GetMainFrame(), kClickConnectButtonJS));
2000 navigation_observer.WaitForNavigations(1);
2001 EXPECT_EQ(login_tab_index, tab_strip_model->active_index());
2002
2003 LoginCertError(browser());
2004
2005 // Once logged in, broken tab should reload and display the SSL interstitial.
2006 WaitForInterstitialAttach(broken_tab_contents);
2007 tab_strip_model->ActivateTabAt(cert_error_tab_index, false);
2008
2009 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
2010 GetInterstitialType(tab_strip_model->GetActiveWebContents()));
2011
2012 // Trigger another captive portal check while the SSL interstitial is showing.
2013 // At this point the user is logged in to the captive portal, so the captive
2014 // portal interstitial shouldn't get recreated.
1732 CaptivePortalObserver portal_observer(browser()->profile()); 2015 CaptivePortalObserver portal_observer(browser()->profile());
1733 2016 CaptivePortalService* captive_portal_service =
1734 TabStripModel* tab_strip_model = browser()->tab_strip_model(); 2017 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
1735 content::RenderFrameHost* render_frame_host = 2018 captive_portal_service->DetectCaptivePortal();
1736 tab_strip_model->GetActiveWebContents()->GetMainFrame(); 2019 portal_observer.WaitForResults(1);
1737 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()")); 2020 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
1738 2021 GetInterstitialType(broken_tab_contents));
1739 // The captive portal tab navigation will trigger a captive portal check, 2022
1740 // and reloading the original tab will bring up the interstitial page again, 2023 // A captive portal appears. Trigger a final captive portal check. The
1741 // triggering a second captive portal check. 2024 // captive portal interstitial should still not get recreated.
1742 portal_observer.WaitForResults(2); 2025 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
1743 2026 CaptivePortalObserver final_portal_observer(browser()->profile());
1744 // Wait for both tabs to finish loading. 2027 captive_portal_service->DetectCaptivePortal();
1745 navigation_observer.WaitForNavigations(2); 2028 final_portal_observer.WaitForResults(1);
1746 EXPECT_EQ(2, portal_observer.num_results_received()); 2029 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
1747 EXPECT_FALSE(CheckPending(browser())); 2030 GetInterstitialType(broken_tab_contents));
1748 EXPECT_EQ(captive_portal::RESULT_INTERNET_CONNECTED, 2031 }
1749 portal_observer.captive_portal_result()); 2032
1750 2033 // Tests this scenario:
1751 // Check state of tabs. While the first tab is still displaying an 2034 // - Portal probe requests are ignored, so that no captive portal result can
1752 // interstitial page, since no portal was found, it should be in STATE_NONE, 2035 // arrive.
1753 // as should the login tab. 2036 // - A cert error triggers an interstitial timer with a very long timeout.
1754 ASSERT_EQ(2, tab_strip_model->count()); 2037 // - No captive portal results arrive, causing the tab to appear as loading
1755 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, 2038 // indefinitely (because probe requests are ignored).
1756 GetStateOfTabReloaderAt(browser(), 0)); 2039 // - Stopping the page load shouldn't result in any interstitials.
1757 EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(1))); 2040 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
1758 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, 2041 InterstitialTimerStopNavigationWhileLoading) {
1759 GetStateOfTabReloaderAt(browser(), 1)); 2042 net::SpawnedTestServer::SSLOptions https_options;
1760 2043 https_options.server_certificate =
1761 // Make sure only one navigation was for the login tab. 2044 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
1762 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( 2045 net::SpawnedTestServer https_server(
1763 tab_strip_model->GetWebContentsAt(1))); 2046 net::SpawnedTestServer::TYPE_HTTPS, https_options,
2047 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2048 ASSERT_TRUE(https_server.Start());
2049 // The path does not matter.
2050 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
2051
2052 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2053 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2054
2055 CaptivePortalObserver portal_observer1(browser()->profile());
2056 FastErrorWithInterstitialTimer(browser(), cert_error_url);
2057
2058 // Page appears loading. Stop the navigation. There should be no interstitial.
2059 MultiNavigationObserver test_navigation_observer;
2060 broken_tab_contents->Stop();
2061 test_navigation_observer.WaitForNavigations(1);
2062
2063 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2064 EXPECT_FALSE(broken_tab_contents->IsLoading());
2065 EXPECT_EQ(0, portal_observer1.num_results_received());
2066 EXPECT_EQ(0, NumLoadingTabs());
2067 EXPECT_FALSE(CheckPending(browser()));
2068 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2069 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2070 GetStateOfTabReloaderAt(browser(), 0));
2071
2072 // Re-enable captive portal checks and fire one. The result should be ignored.
2073 RespondToProbeRequests(true);
2074 CaptivePortalObserver portal_observer2(browser()->profile());
2075 CaptivePortalService* captive_portal_service =
2076 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
2077 captive_portal_service->DetectCaptivePortal();
2078 portal_observer2.WaitForResults(1);
2079
2080 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2081 EXPECT_FALSE(broken_tab_contents->IsLoading());
2082 EXPECT_EQ(1, portal_observer2.num_results_received());
2083 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
2084 portal_observer2.captive_portal_result());
2085 EXPECT_EQ(0, NumLoadingTabs());
2086 EXPECT_FALSE(CheckPending(browser()));
2087 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2088 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2089 GetStateOfTabReloaderAt(browser(), 0));
2090 }
2091
2092 // Same as above, but instead of stopping, the loading page is reloaded. The end
2093 // result is the same. (i.e. page load stops, no interstitials shown)
2094 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
2095 InterstitialTimerReloadWhileLoading) {
2096 net::SpawnedTestServer::SSLOptions https_options;
2097 https_options.server_certificate =
2098 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2099 net::SpawnedTestServer https_server(
2100 net::SpawnedTestServer::TYPE_HTTPS, https_options,
2101 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2102 ASSERT_TRUE(https_server.Start());
2103 // The path does not matter.
2104 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
2105
2106 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2107 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2108
2109 CaptivePortalObserver portal_observer(browser()->profile());
2110 FastErrorWithInterstitialTimer(browser(), cert_error_url);
2111
2112 // Page appears loading. Reloading it cancels the page load. Since the load is
2113 // stopped, no cert error occurs and SSLErrorHandler isn't instantiated.
2114 MultiNavigationObserver test_navigation_observer;
2115 chrome::Reload(browser(), CURRENT_TAB);
2116 test_navigation_observer.WaitForNavigations(2);
2117
2118 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2119 EXPECT_FALSE(broken_tab_contents->IsLoading());
2120 EXPECT_EQ(0, portal_observer.num_results_received());
2121 EXPECT_EQ(2, test_navigation_observer.num_navigations());
2122 EXPECT_EQ(0, NumLoadingTabs());
2123 EXPECT_FALSE(CheckPending(browser()));
2124 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2125 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2126 GetStateOfTabReloaderAt(browser(), 0));
2127
2128 // Re-enable captive portal checks and fire one. The result should be ignored.
2129 RespondToProbeRequests(true);
2130 CaptivePortalObserver portal_observer2(browser()->profile());
2131 CaptivePortalService* captive_portal_service =
2132 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
2133 captive_portal_service->DetectCaptivePortal();
2134 portal_observer2.WaitForResults(1);
2135
2136 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2137 EXPECT_FALSE(broken_tab_contents->IsLoading());
2138 EXPECT_EQ(1, portal_observer2.num_results_received());
2139 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
2140 portal_observer2.captive_portal_result());
2141 EXPECT_EQ(0, NumLoadingTabs());
2142 EXPECT_FALSE(CheckPending(browser()));
2143 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2144 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2145 GetStateOfTabReloaderAt(browser(), 0));
2146 }
2147
2148 // Same as above, but instead of reloading, the page is navigated away. The new
2149 // page should load, and no interstitials should be shown.
2150 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
2151 InterstitialTimerNavigateAwayWhileLoading) {
2152 net::SpawnedTestServer::SSLOptions https_options;
2153 https_options.server_certificate =
2154 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2155 net::SpawnedTestServer https_server(
2156 net::SpawnedTestServer::TYPE_HTTPS, https_options,
2157 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2158 ASSERT_TRUE(https_server.Start());
2159 // The path does not matter.
2160 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
2161
2162 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2163 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2164
2165 CaptivePortalObserver portal_observer(browser()->profile());
2166 FastErrorWithInterstitialTimer(browser(), cert_error_url);
2167
2168 // Page appears loading. Navigating away shouldn't result in any interstitial.
2169 // Can't use ui_test_utils::NavigateToURLWithDisposition because it waits for
2170 // a load stop notification before starting a new navigation.
2171 MultiNavigationObserver test_navigation_observer;
2172 browser()->OpenURL(content::OpenURLParams(
2173 URLRequestMockHTTPJob::GetMockUrl(
2174 base::FilePath(FILE_PATH_LITERAL("title2.html"))),
2175 content::Referrer(),
2176 CURRENT_TAB,
2177 ui::PAGE_TRANSITION_TYPED, false));
2178 // Expect two navigations: First one for stopping the hanging page, second one
2179 // for completing the load of the above navigation.
2180 test_navigation_observer.WaitForNavigations(2);
2181
2182 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2183 EXPECT_FALSE(broken_tab_contents->IsLoading());
2184 EXPECT_EQ(0, portal_observer.num_results_received());
2185 EXPECT_EQ(2, test_navigation_observer.num_navigations());
2186 EXPECT_EQ(0, NumLoadingTabs());
2187 EXPECT_FALSE(CheckPending(browser()));
2188 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2189 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2190 GetStateOfTabReloaderAt(browser(), 0));
2191
2192 // Re-enable captive portal checks and fire one. The result should be ignored.
2193 RespondToProbeRequests(true);
2194 CaptivePortalObserver portal_observer2(browser()->profile());
2195 CaptivePortalService* captive_portal_service =
2196 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
2197 captive_portal_service->DetectCaptivePortal();
2198 portal_observer2.WaitForResults(1);
2199
2200 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2201 EXPECT_FALSE(broken_tab_contents->IsLoading());
2202 EXPECT_EQ(1, portal_observer2.num_results_received());
2203 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
2204 portal_observer2.captive_portal_result());
2205 EXPECT_EQ(0, NumLoadingTabs());
2206 EXPECT_FALSE(CheckPending(browser()));
2207 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2208 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2209 GetStateOfTabReloaderAt(browser(), 0));
2210 }
2211
2212 // A cert error triggers a captive portal check and results in opening a login
2213 // tab. The user then logs in and the page with the error is reloaded.
2214 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, SSLCertErrorLogin) {
2215 // Need an HTTP TestServer to handle a dynamically created server redirect.
2216 ASSERT_TRUE(test_server()->Start());
2217
2218 net::SpawnedTestServer::SSLOptions https_options;
2219 https_options.server_certificate =
2220 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2221 net::SpawnedTestServer https_server(
2222 net::SpawnedTestServer::TYPE_HTTPS, https_options,
2223 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2224 ASSERT_TRUE(https_server.Start());
2225
2226 // Set SSL interstitial delay to zero so that a captive portal result can not
2227 // arrive during this window, so an SSL interstitial is displayed instead
2228 // of a captive portal error page.
2229 SSLErrorHandler::SetInterstitialDisplayDelayForTest(base::TimeDelta());
2230 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2231 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2232
2233 // Setting the delay to zero above has a race condition: A captive portal
2234 // result triggered by a cert error can arrive before the SSL interstitial
2235 // display timer is fired, even though it's set to zero.
2236 // To avoid this, disable captive portal checks until the SSL interstitial is
2237 // displayed. Once it's displayed, enable portal checks and fire one.
2238 bool delay_portal_response_until_interstital = true;
2239
2240 // The path does not matter.
2241 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
2242 // A captive portal check is triggered in FastErrorBehindCaptivePortal.
2243 FastErrorBehindCaptivePortal(
2244 browser(),
2245 true,
2246 cert_error_url,
2247 delay_portal_response_until_interstital);
2248
2249 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
2250 GetInterstitialType(broken_tab_contents));
2251
2252 LoginCertError(browser());
1764 } 2253 }
1765 2254
1766 // Tries navigating both the tab that encounters an SSL timeout and the 2255 // Tries navigating both the tab that encounters an SSL timeout and the
1767 // login tab twice, only logging in the second time. 2256 // login tab twice, only logging in the second time.
1768 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) { 2257 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) {
1769 FastTimeoutBehindCaptivePortal(browser(), true); 2258 FastTimeoutBehindCaptivePortal(browser(), true);
1770 2259
1771 // Activate the timed out tab and navigate it to a timeout again. 2260 // Activate the timed out tab and navigate it to a timeout again.
1772 TabStripModel* tab_strip_model = browser()->tab_strip_model(); 2261 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1773 tab_strip_model->ActivateTabAt(0, true); 2262 tab_strip_model->ActivateTabAt(0, true);
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 content::BrowserThread::PostTask( 2695 content::BrowserThread::PostTask(
2207 content::BrowserThread::IO, FROM_HERE, 2696 content::BrowserThread::IO, FROM_HERE,
2208 base::Bind(&AddHstsHost, 2697 base::Bind(&AddHstsHost,
2209 make_scoped_refptr(browser()->profile()->GetRequestContext()), 2698 make_scoped_refptr(browser()->profile()->GetRequestContext()),
2210 http_timeout_url.host())); 2699 http_timeout_url.host()));
2211 2700
2212 SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url, 1, 1); 2701 SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url, 1, 1);
2213 Login(browser(), 1, 0); 2702 Login(browser(), 1, 0);
2214 FailLoadsAfterLogin(browser(), 1); 2703 FailLoadsAfterLogin(browser(), 1);
2215 } 2704 }
2705
2706 // A slow SSL load starts. The reloader triggers a captive portal check, finds a
2707 // captive portal. The SSL commits with a cert error, triggering another captive
2708 // portal check.
2709 // The second check finds no captive portal. The reloader triggers a reload at
2710 // the same time SSL error handler tries to show an interstitial. Should result
2711 // in an SSL interstitial.
2712 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
2713 InterstitialTimerCertErrorAfterSlowLoad) {
2714 // Use a url that triggers a slow load, instead of creating an https server.
2715 GURL cert_error_url = GURL(kMockHttpsUrl);
2716
2717 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2718 int broken_tab_index = tab_strip_model->active_index();
2719 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2720 SlowLoadBehindCaptivePortal(browser(), true, cert_error_url, 1, 1);
2721
2722 // No longer behind a captive portal. Committing the SSL page should trigger
2723 // an SSL interstitial which triggers a new captive portal check. Since there
2724 // is no captive portal anymore, should end up with an SSL interstitial.
2725 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
2726
2727 CaptivePortalObserver portal_observer(browser()->profile());
2728 MultiNavigationObserver navigation_observer;
2729 URLRequestTimeoutOnDemandJob::FailJobsWithCertError(1);
2730 navigation_observer.WaitForNavigations(1);
2731
2732 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
2733 GetStateOfTabReloaderAt(browser(), broken_tab_index));
2734
2735 WaitForInterstitialAttach(broken_tab_contents);
2736 portal_observer.WaitForResults(1);
2737
2738 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
2739 GetInterstitialType(broken_tab_contents));
2740 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698