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

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: mmenke comments 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 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"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/path_service.h" 14 #include "base/path_service.h"
15 #include "base/prefs/pref_service.h" 15 #include "base/prefs/pref_service.h"
16 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/browser/captive_portal/captive_portal_service.h" 17 #include "chrome/browser/captive_portal/captive_portal_service.h"
18 #include "chrome/browser/captive_portal/captive_portal_service_factory.h" 18 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
19 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h" 19 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
20 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h" 20 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
21 #include "chrome/browser/chrome_notification_types.h" 21 #include "chrome/browser/chrome_notification_types.h"
22 #include "chrome/browser/interstitials/security_interstitial_page.h"
22 #include "chrome/browser/net/url_request_mock_util.h" 23 #include "chrome/browser/net/url_request_mock_util.h"
23 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ssl/captive_portal_blocking_page.h"
26 #include "chrome/browser/ssl/ssl_blocking_page.h"
27 #include "chrome/browser/ssl/ssl_error_handler.h"
24 #include "chrome/browser/ui/browser.h" 28 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h" 29 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_finder.h" 30 #include "chrome/browser/ui/browser_finder.h"
27 #include "chrome/browser/ui/browser_navigator.h" 31 #include "chrome/browser/ui/browser_navigator.h"
28 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 32 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model.h" 33 #include "chrome/browser/ui/tabs/tab_strip_model.h"
30 #include "chrome/common/chrome_paths.h" 34 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h" 35 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/pref_names.h" 36 #include "chrome/common/pref_names.h"
33 #include "chrome/test/base/in_process_browser_test.h" 37 #include "chrome/test/base/in_process_browser_test.h"
34 #include "chrome/test/base/ui_test_utils.h" 38 #include "chrome/test/base/ui_test_utils.h"
35 #include "content/public/browser/browser_thread.h" 39 #include "content/public/browser/browser_thread.h"
40 #include "content/public/browser/interstitial_page.h"
41 #include "content/public/browser/interstitial_page_delegate.h"
36 #include "content/public/browser/navigation_controller.h" 42 #include "content/public/browser/navigation_controller.h"
43 #include "content/public/browser/navigation_entry.h"
37 #include "content/public/browser/notification_observer.h" 44 #include "content/public/browser/notification_observer.h"
38 #include "content/public/browser/notification_registrar.h" 45 #include "content/public/browser/notification_registrar.h"
39 #include "content/public/browser/notification_service.h" 46 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/notification_types.h" 47 #include "content/public/browser/notification_types.h"
41 #include "content/public/browser/render_frame_host.h" 48 #include "content/public/browser/render_frame_host.h"
49 #include "content/public/browser/render_view_host.h"
42 #include "content/public/browser/web_contents.h" 50 #include "content/public/browser/web_contents.h"
43 #include "content/public/common/url_constants.h" 51 #include "content/public/common/url_constants.h"
52 #include "content/public/test/browser_test_utils.h"
44 #include "net/base/net_errors.h" 53 #include "net/base/net_errors.h"
45 #include "net/http/transport_security_state.h" 54 #include "net/http/transport_security_state.h"
46 #include "net/test/url_request/url_request_failed_job.h" 55 #include "net/test/url_request/url_request_failed_job.h"
47 #include "net/test/url_request/url_request_mock_http_job.h" 56 #include "net/test/url_request/url_request_mock_http_job.h"
48 #include "net/url_request/url_request.h" 57 #include "net/url_request/url_request.h"
49 #include "net/url_request/url_request_context.h" 58 #include "net/url_request/url_request_context.h"
50 #include "net/url_request/url_request_context_getter.h" 59 #include "net/url_request/url_request_context_getter.h"
51 #include "net/url_request/url_request_filter.h" 60 #include "net/url_request/url_request_filter.h"
52 #include "net/url_request/url_request_job.h" 61 #include "net/url_request/url_request_job.h"
53 #include "net/url_request/url_request_status.h" 62 #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"; 111 "https://mock.captive.portal.long.timeout2/title2.html";
103 112
104 // Same as kMockHttpsUrl, except the timeout happens instantly. 113 // Same as kMockHttpsUrl, except the timeout happens instantly.
105 const char* const kMockHttpsQuickTimeoutUrl = 114 const char* const kMockHttpsQuickTimeoutUrl =
106 "https://mock.captive.portal.quick.timeout/title2.html"; 115 "https://mock.captive.portal.quick.timeout/title2.html";
107 116
108 // Expected title of a tab once an HTTPS load completes, when not behind a 117 // Expected title of a tab once an HTTPS load completes, when not behind a
109 // captive portal. 118 // captive portal.
110 const char* const kInternetConnectedTitle = "Title Of Awesomeness"; 119 const char* const kInternetConnectedTitle = "Title Of Awesomeness";
111 120
121 // Wait until all <script> tags have executed, including jstemplate.
122 // This isn't ideal, but the same trick is used in
123 // SafeBrowsingBlockingPageBrowserTest to wait for the interstitials.
124 bool WaitForPageReady(content::RenderViewHost* rvh) {
mmenke 2014/12/15 20:46:07 Suggest renaming this WaitForInterstitialReady, an
meacer 2014/12/16 01:23:18 Done.
125 if (!rvh)
126 return false;
127 std::string ready_state;
mmenke 2014/12/15 20:46:08 Should include <string>
meacer 2014/12/16 01:23:19 Done.
128 do {
129 scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue(
mmenke 2014/12/15 20:46:07 Should include the scoped_ptr and base/values head
meacer 2014/12/16 01:23:18 Done.
130 rvh->GetMainFrame(), "document.readyState");
131 if (!value.get() || !value->GetAsString(&ready_state))
132 return false;
133 } while (ready_state != "complete");
mmenke 2014/12/15 20:46:07 Think you mentioned this option earlier, but I'd b
meacer 2014/12/16 01:23:18 Yes, as I mentioned earlier, I was planning to do
134 return true;
135 }
136
112 // A URL request job that hangs until FailJobs() is called. Started jobs 137 // 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 138 // are stored in a static class variable containing a linked list so that
114 // FailJobs() can locate them. 139 // FailJobs() can locate them.
115 class URLRequestTimeoutOnDemandJob : public net::URLRequestJob, 140 class URLRequestTimeoutOnDemandJob : public net::URLRequestJob,
116 public base::NonThreadSafe { 141 public base::NonThreadSafe {
117 public: 142 public:
118 // net::URLRequestJob: 143 // net::URLRequestJob:
119 void Start() override; 144 void Start() override;
120 145
121 // All the public static methods below can be called on any thread. 146 // All the public static methods below can be called on any thread.
122 147
123 // Waits for exactly |num_jobs|. 148 // Waits for exactly |num_jobs|.
124 static void WaitForJobs(int num_jobs); 149 static void WaitForJobs(int num_jobs);
125 150
126 // Fails all active URLRequestTimeoutOnDemandJobs with connection timeouts. 151 // Fails all active URLRequestTimeoutOnDemandJobs with connection timeouts.
127 // There are expected to be exactly |expected_num_jobs| waiting for 152 // 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 153 // 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. 154 // WaitForJobs, so makes sure there has been a matching WaitForJobs call.
130 static void FailJobs(int expected_num_jobs); 155 static void FailJobs(int expected_num_jobs);
131 156
157 // Fails all active URLRequestTimeoutOnDemandJobs with SSL cert errors.
158 // |expected_num_jobs| behaves just as in FailJobs.
159 static void FailJobsWithCertError(int expected_num_jobs);
160
132 // Abandon all active URLRequestTimeoutOnDemandJobs. |expected_num_jobs| 161 // Abandon all active URLRequestTimeoutOnDemandJobs. |expected_num_jobs|
133 // behaves just as in FailJobs. 162 // behaves just as in FailJobs.
134 static void AbandonJobs(int expected_num_jobs); 163 static void AbandonJobs(int expected_num_jobs);
135 164
136 private: 165 private:
137 friend class URLRequestMockCaptivePortalJobFactory; 166 friend class URLRequestMockCaptivePortalJobFactory;
138 167
139 // Operation to perform on jobs when removing them from |job_list_|. 168 // Operation to perform on jobs when removing them from |job_list_|.
140 enum EndJobOperation { 169 enum EndJobOperation {
141 FAIL_JOBS, 170 FAIL_JOBS,
142 ABANDON_JOBS, 171 ABANDON_JOBS,
172 FAIL_JOBS_WITH_CERT_ERROR
143 }; 173 };
144 174
145 URLRequestTimeoutOnDemandJob(net::URLRequest* request, 175 URLRequestTimeoutOnDemandJob(net::URLRequest* request,
146 net::NetworkDelegate* network_delegate); 176 net::NetworkDelegate* network_delegate);
147 ~URLRequestTimeoutOnDemandJob() override; 177 ~URLRequestTimeoutOnDemandJob() override;
148 178
149 // Attempts to removes |this| from |jobs_|. Returns true if it was removed 179 // Attempts to removes |this| from |jobs_|. Returns true if it was removed
150 // from the list. 180 // from the list.
151 bool RemoveFromList(); 181 bool RemoveFromList();
152 182
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 // static 249 // static
220 void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs) { 250 void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs) {
221 content::BrowserThread::PostTask( 251 content::BrowserThread::PostTask(
222 content::BrowserThread::IO, FROM_HERE, 252 content::BrowserThread::IO, FROM_HERE,
223 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread, 253 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
224 expected_num_jobs, 254 expected_num_jobs,
225 FAIL_JOBS)); 255 FAIL_JOBS));
226 } 256 }
227 257
228 // static 258 // static
259 void URLRequestTimeoutOnDemandJob::FailJobsWithCertError(
260 int expected_num_jobs) {
261 content::BrowserThread::PostTask(
262 content::BrowserThread::IO, FROM_HERE,
263 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
264 expected_num_jobs,
265 FAIL_JOBS_WITH_CERT_ERROR));
266 }
267
268 // static
229 void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs) { 269 void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs) {
230 content::BrowserThread::PostTask( 270 content::BrowserThread::PostTask(
231 content::BrowserThread::IO, FROM_HERE, 271 content::BrowserThread::IO, FROM_HERE,
232 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread, 272 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
233 expected_num_jobs, 273 expected_num_jobs,
234 ABANDON_JOBS)); 274 ABANDON_JOBS));
235 } 275 }
236 276
237 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob( 277 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob(
238 net::URLRequest* request, net::NetworkDelegate* network_delegate) 278 net::URLRequest* request, net::NetworkDelegate* network_delegate)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 while (job_list_) { 346 while (job_list_) {
307 ++num_jobs; 347 ++num_jobs;
308 URLRequestTimeoutOnDemandJob* job = job_list_; 348 URLRequestTimeoutOnDemandJob* job = job_list_;
309 // Since the error notification may result in the job's destruction, remove 349 // Since the error notification may result in the job's destruction, remove
310 // it from the job list before the error. 350 // it from the job list before the error.
311 EXPECT_TRUE(job->RemoveFromList()); 351 EXPECT_TRUE(job->RemoveFromList());
312 if (end_job_operation == FAIL_JOBS) { 352 if (end_job_operation == FAIL_JOBS) {
313 job->NotifyStartError(net::URLRequestStatus( 353 job->NotifyStartError(net::URLRequestStatus(
314 net::URLRequestStatus::FAILED, 354 net::URLRequestStatus::FAILED,
315 net::ERR_CONNECTION_TIMED_OUT)); 355 net::ERR_CONNECTION_TIMED_OUT));
356 } else if (end_job_operation == FAIL_JOBS_WITH_CERT_ERROR) {
357 DCHECK(job->request()->url().SchemeIs(url::kHttpsScheme));
mmenke 2014/12/15 20:46:07 Currently this test fixture uses EXPECTs/ASSERTs f
meacer 2014/12/16 01:23:19 Done.
358 net::SSLInfo info;
359 info.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
360 info.cert = new net::X509Certificate(
361 "bad.host", "CA", base::Time::Max(), base::Time::Max());
362 job->NotifySSLCertificateError(info, true);
316 } 363 }
317 } 364 }
318 365
319 EXPECT_EQ(expected_num_jobs, num_jobs_started_); 366 EXPECT_EQ(expected_num_jobs, num_jobs_started_);
320 EXPECT_EQ(expected_num_jobs, num_jobs); 367 EXPECT_EQ(expected_num_jobs, num_jobs);
321 368
322 num_jobs_started_ -= expected_num_jobs; 369 num_jobs_started_ -= expected_num_jobs;
323 } 370 }
324 371
325 // URLRequestCaptivePortalJobFactory emulates captive portal behavior. 372 // URLRequestCaptivePortalJobFactory emulates captive portal behavior.
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 base::MessageLoopForUI::current()->Quit(); 729 base::MessageLoopForUI::current()->Quit();
683 } 730 }
684 } 731 }
685 732
686 // An observer for watching the CaptivePortalService. It tracks the last 733 // An observer for watching the CaptivePortalService. It tracks the last
687 // received result and the total number of received results. 734 // received result and the total number of received results.
688 class CaptivePortalObserver : public content::NotificationObserver { 735 class CaptivePortalObserver : public content::NotificationObserver {
689 public: 736 public:
690 explicit CaptivePortalObserver(Profile* profile); 737 explicit CaptivePortalObserver(Profile* profile);
691 738
692 // Runs the message loop until until at exactly |update_count| capitive portal 739 // Runs the message loop until exactly |update_count| captive portal
693 // results have been received, since this creation of |this|. Expects no 740 // results have been received, since the creation of |this|. Expects no
694 // additional captive portal results. 741 // additional captive portal results.
695 void WaitForResults(int num_results_to_wait_for); 742 void WaitForResults(int num_results_to_wait_for);
696 743
697 int num_results_received() const { return num_results_received_; } 744 int num_results_received() const { return num_results_received_; }
698 745
699 CaptivePortalResult captive_portal_result() const { 746 CaptivePortalResult captive_portal_result() const {
700 return captive_portal_result_; 747 return captive_portal_result_;
701 } 748 }
702 749
703 private: 750 private:
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 CaptivePortalBrowserTest(); 848 CaptivePortalBrowserTest();
802 849
803 // InProcessBrowserTest: 850 // InProcessBrowserTest:
804 void SetUpOnMainThread() override; 851 void SetUpOnMainThread() override;
805 void TearDownOnMainThread() override; 852 void TearDownOnMainThread() override;
806 853
807 // Sets the captive portal checking preference. Does not affect the command 854 // Sets the captive portal checking preference. Does not affect the command
808 // line flag, which is set in SetUpCommandLine. 855 // line flag, which is set in SetUpCommandLine.
809 void EnableCaptivePortalDetection(Profile* profile, bool enabled); 856 void EnableCaptivePortalDetection(Profile* profile, bool enabled);
810 857
858 // Enables or disables actual captive portal probes. Should only be called
859 // after captive portal service setup is done.
mmenke 2014/12/15 20:46:08 Maybe "When disabled, probe requests are are silen
meacer 2014/12/16 01:23:19 Done.
860 void EnablePortalRequests(bool enabled);
mmenke 2014/12/15 20:46:07 Maybe RespondToPortalRequests? Or RespondToProbeR
meacer 2014/12/16 01:23:18 Done.
861
811 // Sets up the captive portal service for the given profile so that 862 // Sets up the captive portal service for the given profile so that
812 // all checks go to |test_url|. Also disables all timers. 863 // all checks go to |test_url|. Also disables all timers.
813 void SetUpCaptivePortalService(Profile* profile, const GURL& test_url); 864 void SetUpCaptivePortalService(Profile* profile, const GURL& test_url);
814 865
815 // Returns true if |browser|'s profile is currently running a captive portal 866 // Returns true if |browser|'s profile is currently running a captive portal
816 // check. 867 // check.
817 bool CheckPending(Browser* browser); 868 bool CheckPending(Browser* browser);
818 869
870 // Returns the type of the interstitial being shown.
871 const void* GetInterstitialType(WebContents* contents) const;
872
819 // Returns the CaptivePortalTabReloader::State of |web_contents|. 873 // Returns the CaptivePortalTabReloader::State of |web_contents|.
820 CaptivePortalTabReloader::State GetStateOfTabReloader( 874 CaptivePortalTabReloader::State GetStateOfTabReloader(
821 WebContents* web_contents) const; 875 WebContents* web_contents) const;
822 876
823 // Returns the CaptivePortalTabReloader::State of the indicated tab. 877 // Returns the CaptivePortalTabReloader::State of the indicated tab.
824 CaptivePortalTabReloader::State GetStateOfTabReloaderAt(Browser* browser, 878 CaptivePortalTabReloader::State GetStateOfTabReloaderAt(Browser* browser,
825 int index) const; 879 int index) const;
826 880
827 // Returns the number of tabs with the given state, across all profiles. 881 // Returns the number of tabs with the given state, across all profiles.
828 int NumTabsWithState(CaptivePortalTabReloader::State state) const; 882 int NumTabsWithState(CaptivePortalTabReloader::State state) const;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 int expected_login_tab_navigations); 943 int expected_login_tab_navigations);
890 944
891 // Just like SlowLoadBehindCaptivePortal, except the navigated tab has 945 // Just like SlowLoadBehindCaptivePortal, except the navigated tab has
892 // a connection timeout rather having its time trigger, and the function 946 // a connection timeout rather having its time trigger, and the function
893 // waits until that timeout occurs. 947 // waits until that timeout occurs.
894 void FastTimeoutBehindCaptivePortal(Browser* browser, 948 void FastTimeoutBehindCaptivePortal(Browser* browser,
895 bool expect_open_login_tab); 949 bool expect_open_login_tab);
896 950
897 // Much as above, but accepts a URL parameter and can be used for errors that 951 // 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 952 // trigger captive portal checks other than timeouts. |error_url| should
899 // result in an error rather than hanging. 953 // result in an error rather than hanging.
mmenke 2014/12/15 20:46:08 disable_portal_check_until_interstitial needs some
meacer 2014/12/16 01:23:19 Done.
900 void FastErrorBehindCaptivePortal(Browser* browser, 954 void FastErrorBehindCaptivePortal(
901 bool expect_open_login_tab, 955 Browser* browser,
902 const GURL& error_url); 956 bool expect_open_login_tab,
957 const GURL& error_url,
958 bool disable_portal_check_until_interstitial);
mmenke 2014/12/15 20:46:08 "disable_portal_check_until_interstitial" could be
meacer 2014/12/16 01:23:18 Done.
959
960 // Navigates the active tab to an SSL error page which triggers an
961 // interstitial timer. Also disables captive portal checks indefinitely, so
962 // the page appears to be hanging.
963 void FastErrorWithInterstitialTimer(Browser* browser,
964 const GURL& cert_error_url);
903 965
904 // Navigates the login tab without logging in. The login tab must be the 966 // 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. 967 // 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 968 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
907 // that nothing has gone wrong prior to the function call. 969 // that nothing has gone wrong prior to the function call.
908 void NavigateLoginTab(Browser* browser, 970 void NavigateLoginTab(Browser* browser,
909 int num_loading_tabs, 971 int num_loading_tabs,
910 int num_timed_out_tabs); 972 int num_timed_out_tabs);
911 973
912 // Simulates a login by updating the URLRequestMockCaptivePortalJob's 974 // Simulates a login by updating the URLRequestMockCaptivePortalJob's
913 // behind captive portal state, and navigating the login tab. Waits for 975 // behind captive portal state, and navigating the login tab. Waits for
914 // all broken but not loading tabs to be reloaded. 976 // all broken but not loading tabs to be reloaded.
915 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks 977 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
916 // that nothing has gone wrong prior to the function call. 978 // that nothing has gone wrong prior to the function call.
917 void Login(Browser* browser, int num_loading_tabs, int num_timed_out_tabs); 979 void Login(Browser* browser, int num_loading_tabs, int num_timed_out_tabs);
918 980
981 // Simulates a login when the broken tab shows an SSL or captive portal
982 // interstitial. Can't use Login() in those cases because the interstitial
983 // tab looks like a cross between a hung tab (Load was never committed) and a
984 // tab at an error page (The load was stopped).
985 void LoginCertError(Browser* browser);
mmenke 2014/12/15 20:46:07 Why wasn't this needed for the cert error test bef
meacer 2014/12/16 01:23:19 It was part of the cert error test, I just pulled
986
919 // Makes the slow SSL loads of all active tabs time out at once, and waits for 987 // 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. 988 // 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. 989 // There should be no timed out tabs when this is called.
922 void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs); 990 void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs);
923 991
924 // Makes the slow SSL loads of all active tabs time out at once, and waits for 992 // 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 993 // 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. 994 // active tab. There should be no timed out tabs when this is called.
927 void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs); 995 void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs);
928 996
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 void CaptivePortalBrowserTest::TearDownOnMainThread() { 1051 void CaptivePortalBrowserTest::TearDownOnMainThread() {
984 // No test should have a captive portal check pending on quit. 1052 // No test should have a captive portal check pending on quit.
985 EXPECT_FALSE(CheckPending(browser())); 1053 EXPECT_FALSE(CheckPending(browser()));
986 } 1054 }
987 1055
988 void CaptivePortalBrowserTest::EnableCaptivePortalDetection( 1056 void CaptivePortalBrowserTest::EnableCaptivePortalDetection(
989 Profile* profile, bool enabled) { 1057 Profile* profile, bool enabled) {
990 profile->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled); 1058 profile->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled);
991 } 1059 }
992 1060
1061 void CaptivePortalBrowserTest::EnablePortalRequests(bool enabled) {
1062 if (enabled) {
1063 EXPECT_EQ(CaptivePortalService::IGNORE_REQUESTS_FOR_TESTING,
1064 CaptivePortalService::get_state_for_testing());
1065 CaptivePortalService::set_state_for_testing(
1066 CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING);
1067 } else {
1068 EXPECT_EQ(CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING,
1069 CaptivePortalService::get_state_for_testing());
1070 CaptivePortalService::set_state_for_testing(
1071 CaptivePortalService::IGNORE_REQUESTS_FOR_TESTING);
1072 }
1073 }
1074
993 void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile, 1075 void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile,
994 const GURL& test_url) { 1076 const GURL& test_url) {
995 CaptivePortalService* captive_portal_service = 1077 CaptivePortalService* captive_portal_service =
996 CaptivePortalServiceFactory::GetForProfile(profile); 1078 CaptivePortalServiceFactory::GetForProfile(profile);
997 captive_portal_service->set_test_url(test_url); 1079 captive_portal_service->set_test_url(test_url);
998 1080
999 // Don't use any non-zero timers. Timers are checked in unit tests. 1081 // Don't use any non-zero timers. Timers are checked in unit tests.
1000 CaptivePortalService::RecheckPolicy* recheck_policy = 1082 CaptivePortalService::RecheckPolicy* recheck_policy =
1001 &captive_portal_service->recheck_policy(); 1083 &captive_portal_service->recheck_policy();
1002 recheck_policy->initial_backoff_no_portal_ms = 0; 1084 recheck_policy->initial_backoff_no_portal_ms = 0;
1003 recheck_policy->initial_backoff_portal_ms = 0; 1085 recheck_policy->initial_backoff_portal_ms = 0;
1004 recheck_policy->backoff_policy.maximum_backoff_ms = 0; 1086 recheck_policy->backoff_policy.maximum_backoff_ms = 0;
1005 } 1087 }
1006 1088
1007 bool CaptivePortalBrowserTest::CheckPending(Browser* browser) { 1089 bool CaptivePortalBrowserTest::CheckPending(Browser* browser) {
1008 CaptivePortalService* captive_portal_service = 1090 CaptivePortalService* captive_portal_service =
1009 CaptivePortalServiceFactory::GetForProfile(browser->profile()); 1091 CaptivePortalServiceFactory::GetForProfile(browser->profile());
1010 1092
1011 return captive_portal_service->DetectionInProgress() || 1093 return captive_portal_service->DetectionInProgress() ||
1012 captive_portal_service->TimerRunning(); 1094 captive_portal_service->TimerRunning();
1013 } 1095 }
1014 1096
1097 const void* CaptivePortalBrowserTest::GetInterstitialType(
1098 WebContents* contents) const {
1099 if (!contents->ShowingInterstitialPage())
1100 return NULL;
1101 SecurityInterstitialPage* blocking_page =
1102 static_cast<SecurityInterstitialPage*>(
1103 contents->GetInterstitialPage()->GetDelegateForTesting());
1104 DCHECK(blocking_page);
1105 return blocking_page->GetTypeForTesting();
1106 }
1107
1015 CaptivePortalTabReloader::State CaptivePortalBrowserTest::GetStateOfTabReloader( 1108 CaptivePortalTabReloader::State CaptivePortalBrowserTest::GetStateOfTabReloader(
1016 WebContents* web_contents) const { 1109 WebContents* web_contents) const {
1017 return GetTabReloader(web_contents)->state(); 1110 return GetTabReloader(web_contents)->state();
1018 } 1111 }
1019 1112
1020 CaptivePortalTabReloader::State 1113 CaptivePortalTabReloader::State
1021 CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser* browser, 1114 CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser* browser,
1022 int index) const { 1115 int index) const {
1023 return GetStateOfTabReloader( 1116 return GetStateOfTabReloader(
1024 browser->tab_strip_model()->GetWebContentsAt(index)); 1117 browser->tab_strip_model()->GetWebContentsAt(index));
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 1330
1238 // Reset the load time to be large, so the timer won't trigger on a reload. 1331 // Reset the load time to be large, so the timer won't trigger on a reload.
1239 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1)); 1332 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
1240 } 1333 }
1241 1334
1242 void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal( 1335 void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal(
1243 Browser* browser, 1336 Browser* browser,
1244 bool expect_open_login_tab) { 1337 bool expect_open_login_tab) {
1245 FastErrorBehindCaptivePortal(browser, 1338 FastErrorBehindCaptivePortal(browser,
1246 expect_open_login_tab, 1339 expect_open_login_tab,
1247 GURL(kMockHttpsQuickTimeoutUrl)); 1340 GURL(kMockHttpsQuickTimeoutUrl),
1341 false);
1248 } 1342 }
1249 1343
1250 void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal( 1344 void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal(
1251 Browser* browser, 1345 Browser* browser,
1252 bool expect_open_login_tab, 1346 bool expect_open_login_tab,
1253 const GURL& error_url) { 1347 const GURL& error_url,
1348 bool disable_portal_check_until_interstitial) {
1254 TabStripModel* tab_strip_model = browser->tab_strip_model(); 1349 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 1350 // Calling this on a tab that's waiting for a load to manually be timed out
1256 // will result in a hang. 1351 // will result in a hang.
1257 ASSERT_FALSE(tab_strip_model->GetActiveWebContents()->IsLoading()); 1352 ASSERT_FALSE(tab_strip_model->GetActiveWebContents()->IsLoading());
1258 1353
1259 // Set the load time to be large, so the timer won't trigger. The value is 1354 // 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. 1355 // not restored at the end of the function.
1261 CaptivePortalTabReloader* tab_reloader = 1356 CaptivePortalTabReloader* tab_reloader =
1262 GetTabReloader(tab_strip_model->GetActiveWebContents()); 1357 GetTabReloader(tab_strip_model->GetActiveWebContents());
1263 ASSERT_TRUE(tab_reloader); 1358 ASSERT_TRUE(tab_reloader);
1264 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1)); 1359 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
1265 1360
1266 // Number of tabs expected to be open after the captive portal checks 1361 // Number of tabs expected to be open after the captive portal checks
1267 // have completed. 1362 // have completed.
1268 int initial_tab_count = tab_strip_model->count(); 1363 int initial_tab_count = tab_strip_model->count();
1269 int initial_active_index = tab_strip_model->active_index(); 1364 int initial_active_index = tab_strip_model->active_index();
1270 int initial_loading_tabs = NumLoadingTabs(); 1365 int initial_loading_tabs = NumLoadingTabs();
1271 int expected_broken_tabs = NumBrokenTabs(); 1366 int expected_broken_tabs = NumBrokenTabs();
1272 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL != 1367 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL !=
1273 GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())) { 1368 GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())) {
1274 ++expected_broken_tabs; 1369 ++expected_broken_tabs;
1275 } 1370 }
1276 1371
1372 CaptivePortalService* captive_portal_service =
1373 CaptivePortalServiceFactory::GetForProfile(browser->profile());
1374 if (disable_portal_check_until_interstitial)
1375 EnablePortalRequests(false);
1376
1277 MultiNavigationObserver navigation_observer; 1377 MultiNavigationObserver navigation_observer;
1278 CaptivePortalObserver portal_observer(browser->profile()); 1378 CaptivePortalObserver portal_observer(browser->profile());
1279 ui_test_utils::NavigateToURLWithDisposition(browser, 1379 ui_test_utils::NavigateToURLWithDisposition(browser,
1280 error_url, 1380 error_url,
1281 CURRENT_TAB, 1381 CURRENT_TAB,
1282 ui_test_utils::BROWSER_TEST_NONE); 1382 ui_test_utils::BROWSER_TEST_NONE);
1383
1384 if (disable_portal_check_until_interstitial) {
1385 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1386 GetStateOfTabReloaderAt(browser, initial_active_index));
1387 // Once the interstitial is attached, probe for captive portal.
1388 WaitForInterstitialAttach(tab_strip_model->GetActiveWebContents());
1389 EnablePortalRequests(true);
1390 captive_portal_service->DetectCaptivePortal();
1391 }
1392
1283 portal_observer.WaitForResults(1); 1393 portal_observer.WaitForResults(1);
1284 1394
1285 if (expect_open_login_tab) { 1395 if (expect_open_login_tab) {
1286 navigation_observer.WaitForNavigations(2); 1396 navigation_observer.WaitForNavigations(2);
1287 ASSERT_EQ(initial_tab_count + 1, tab_strip_model->count()); 1397 ASSERT_EQ(initial_tab_count + 1, tab_strip_model->count());
1288 EXPECT_EQ(initial_tab_count, tab_strip_model->active_index()); 1398 EXPECT_EQ(initial_tab_count, tab_strip_model->active_index());
1289 // Make sure that the originally active tab and the captive portal tab have 1399 // Make sure that the originally active tab and the captive portal tab have
1290 // each loaded once. 1400 // each loaded once.
1291 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( 1401 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1292 tab_strip_model->GetWebContentsAt(initial_active_index))); 1402 tab_strip_model->GetWebContentsAt(initial_active_index)));
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 EXPECT_EQ(initial_tab_count, tab_strip_model->count()); 1510 EXPECT_EQ(initial_tab_count, tab_strip_model->count());
1401 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, 1511 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1402 GetStateOfTabReloaderAt(browser, login_tab_index)); 1512 GetStateOfTabReloaderAt(browser, login_tab_index));
1403 EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index))); 1513 EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
1404 1514
1405 // Make sure there were no unexpected navigations of the login tab. 1515 // Make sure there were no unexpected navigations of the login tab.
1406 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( 1516 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1407 tab_strip_model->GetWebContentsAt(login_tab_index))); 1517 tab_strip_model->GetWebContentsAt(login_tab_index)));
1408 } 1518 }
1409 1519
1520 void CaptivePortalBrowserTest::LoginCertError(Browser* browser) {
mmenke 2014/12/15 20:46:08 Could we order the code here more like CaptivePort
meacer 2014/12/16 01:23:19 Done.
1521 TabStripModel* tab_strip_model = browser->tab_strip_model();
1522 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1523 MultiNavigationObserver navigation_observer;
1524 CaptivePortalObserver portal_observer(browser->profile());
1525
1526 content::RenderFrameHost* render_frame_host =
1527 tab_strip_model->GetActiveWebContents()->GetMainFrame();
1528 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
1529
1530 // The captive portal tab navigation will trigger a captive portal check,
1531 // and reloading the original tab will bring up the interstitial page again,
1532 // triggering a second captive portal check.
1533 portal_observer.WaitForResults(2);
1534
1535 // Wait for both tabs to finish loading.
1536 navigation_observer.WaitForNavigations(2);
1537 EXPECT_EQ(2, portal_observer.num_results_received());
1538 EXPECT_FALSE(CheckPending(browser));
1539 EXPECT_EQ(captive_portal::RESULT_INTERNET_CONNECTED,
1540 portal_observer.captive_portal_result());
1541
1542 // Check state of tabs. While the first tab is still displaying an
1543 // interstitial page, since no portal was found, it should be in STATE_NONE,
1544 // as should the login tab.
1545 ASSERT_EQ(2, tab_strip_model->count());
1546 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1547 GetStateOfTabReloaderAt(browser, 0));
1548 EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
1549 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1550 GetStateOfTabReloaderAt(browser, 1));
1551
1552 // Make sure only one navigation was for the login tab.
1553 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1554 tab_strip_model->GetWebContentsAt(1)));
1555 }
1556
1410 void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser, 1557 void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser,
1411 int num_loading_tabs) { 1558 int num_loading_tabs) {
1412 ASSERT_EQ(num_loading_tabs, NumLoadingTabs()); 1559 ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
1413 ASSERT_EQ(num_loading_tabs, NumNeedReloadTabs()); 1560 ASSERT_EQ(num_loading_tabs, NumNeedReloadTabs());
1414 EXPECT_EQ(0, NumBrokenTabs()); 1561 EXPECT_EQ(0, NumBrokenTabs());
1415 1562
1416 TabStripModel* tab_strip_model = browser->tab_strip_model(); 1563 TabStripModel* tab_strip_model = browser->tab_strip_model();
1417 int initial_num_tabs = tab_strip_model->count(); 1564 int initial_num_tabs = tab_strip_model->count();
1418 int initial_active_tab = tab_strip_model->active_index(); 1565 int initial_active_tab = tab_strip_model->active_index();
1419 1566
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 } 1845 }
1699 1846
1700 // Checks the unlikely case that the tab times out before the timer triggers. 1847 // Checks the unlikely case that the tab times out before the timer triggers.
1701 // This most likely won't happen, but should still work: 1848 // This most likely won't happen, but should still work:
1702 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) { 1849 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) {
1703 FastTimeoutBehindCaptivePortal(browser(), true); 1850 FastTimeoutBehindCaptivePortal(browser(), true);
1704 Login(browser(), 0, 1); 1851 Login(browser(), 0, 1);
1705 } 1852 }
1706 1853
1707 // A cert error triggers a captive portal check and results in opening a login 1854 // 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. 1855 // tab.
1709 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, SSLCertErrorLogin) { 1856 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
1710 // Need an HTTP TestServer to handle a dynamically created server redirect. 1857 ShowCaptivePortalInterstitialOnCertError) {
1711 ASSERT_TRUE(test_server()->Start());
1712
1713 net::SpawnedTestServer::SSLOptions https_options; 1858 net::SpawnedTestServer::SSLOptions https_options;
1714 https_options.server_certificate = 1859 https_options.server_certificate =
1715 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME; 1860 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
1716 net::SpawnedTestServer https_server( 1861 net::SpawnedTestServer https_server(
1717 net::SpawnedTestServer::TYPE_HTTPS, https_options, 1862 net::SpawnedTestServer::TYPE_HTTPS, https_options,
1718 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 1863 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1719 ASSERT_TRUE(https_server.Start()); 1864 ASSERT_TRUE(https_server.Start());
1720 1865
1721 // The path does not matter. 1866 // Set SSL interstitial delay long enough so that a captive portal result
1722 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath); 1867 // is guaranteed to arrive during this window, and a captive portal
1868 // error page is displayed instead of an SSL interstitial.
1869 SSLErrorHandler::SetInterstitialDisplayDelayForTest(
1870 base::TimeDelta::FromHours(1));
mmenke 2014/12/15 20:46:08 Suggest moving this into the constructor for the t
meacer 2014/12/16 01:23:19 Done.
1871 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1872 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
1873
1874 // The path does not matter.
1875 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
1876 int cert_error_tab_index = tab_strip_model->active_index();
1723 // The interstitial should trigger a captive portal check when it opens, just 1877 // The interstitial should trigger a captive portal check when it opens, just
1724 // like navigating to kMockHttpsQuickTimeoutUrl. 1878 // like navigating to kMockHttpsQuickTimeoutUrl.
1725 FastErrorBehindCaptivePortal(browser(), true, cert_error_url); 1879 FastErrorBehindCaptivePortal(browser(), true, cert_error_url, false);
1726 1880
1727 // Simulate logging in. Can't use Login() because the interstitial tab looks 1881 EXPECT_EQ(CaptivePortalBlockingPage::kTypeForTesting,
1728 // like a cross between a hung tab (Load was never committed) and a tab at an 1882 GetInterstitialType(broken_tab_contents));
1729 // error page (The load was stopped). 1883
1730 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false); 1884 int login_tab_index = tab_strip_model->active_index();
mmenke 2014/12/15 20:46:07 Suggest moving this below the comment.
meacer 2014/12/16 01:23:19 Done.
1731 MultiNavigationObserver navigation_observer; 1885 // Switch to the interstitial and click the "Connect" button. Should switch
1886 // active tab to the captive portal landing page.
1887 tab_strip_model->ActivateTabAt(cert_error_tab_index, false);
1888
mmenke 2014/12/15 20:46:08 Remove this line break (The comment above applies
meacer 2014/12/16 01:23:19 Done.
1889 content::RenderViewHost* rvh =
1890 broken_tab_contents->GetInterstitialPage()->GetRenderViewHostForTesting();
1891 EXPECT_TRUE(WaitForPageReady(rvh));
mmenke 2014/12/15 20:46:08 Suggest a comment above this line, about having to
meacer 2014/12/16 01:23:19 Done.
1892 EXPECT_TRUE(
1893 content::ExecuteScript(
1894 rvh->GetMainFrame(),
1895 "document.getElementById('primary-button').click();"));
1896 EXPECT_EQ(login_tab_index, tab_strip_model->active_index());
mmenke 2014/12/15 20:46:07 Should we have a test where this opens another tab
meacer 2014/12/16 01:23:19 Added that scenario here: After the first click on
1897
1898 LoginCertError(browser());
1899
1900 // Once logged in, broken tab should reload and display the SSL interstitial.
1901 WaitForInterstitialAttach(broken_tab_contents);
1902 tab_strip_model->ActivateTabAt(cert_error_tab_index, false);
1903
1904 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
1905 GetInterstitialType(tab_strip_model->GetActiveWebContents()));
1906
1907 // Trigger another captive portal check while the SSL interstitial is showing.
1908 // At this point the user is logged in to the captive portal, so the captive
1909 // portal interstitial shouldn't get recreated.
1732 CaptivePortalObserver portal_observer(browser()->profile()); 1910 CaptivePortalObserver portal_observer(browser()->profile());
1733 1911 CaptivePortalService* captive_portal_service =
1734 TabStripModel* tab_strip_model = browser()->tab_strip_model(); 1912 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
1735 content::RenderFrameHost* render_frame_host = 1913 captive_portal_service->DetectCaptivePortal();
1736 tab_strip_model->GetActiveWebContents()->GetMainFrame(); 1914 portal_observer.WaitForResults(1);
1737 render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()")); 1915 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
1738 1916 GetInterstitialType(broken_tab_contents));
1739 // The captive portal tab navigation will trigger a captive portal check, 1917
1740 // and reloading the original tab will bring up the interstitial page again, 1918 // A captive portal appears. Trigger a final captive portal check. The
1741 // triggering a second captive portal check. 1919 // captive portal interstitial should still not get recreated.
1742 portal_observer.WaitForResults(2); 1920 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
1743 1921 CaptivePortalObserver final_portal_observer(browser()->profile());
1744 // Wait for both tabs to finish loading. 1922 captive_portal_service->DetectCaptivePortal();
1745 navigation_observer.WaitForNavigations(2); 1923 final_portal_observer.WaitForResults(1);
1746 EXPECT_EQ(2, portal_observer.num_results_received()); 1924 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
1747 EXPECT_FALSE(CheckPending(browser())); 1925 GetInterstitialType(broken_tab_contents));
1748 EXPECT_EQ(captive_portal::RESULT_INTERNET_CONNECTED, 1926 }
1749 portal_observer.captive_portal_result()); 1927
1750 1928 void CaptivePortalBrowserTest::FastErrorWithInterstitialTimer(
mmenke 2014/12/15 20:46:07 This should go up with the other CaptivePortalBrow
meacer 2014/12/16 01:23:18 Done.
1751 // Check state of tabs. While the first tab is still displaying an 1929 Browser* browser,
1752 // interstitial page, since no portal was found, it should be in STATE_NONE, 1930 const GURL& cert_error_url) {
1753 // as should the login tab. 1931 TabStripModel* tab_strip_model = browser->tab_strip_model();
1754 ASSERT_EQ(2, tab_strip_model->count()); 1932 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
1755 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, 1933
1756 GetStateOfTabReloaderAt(browser(), 0)); 1934 // Disable captive portal checks indefinitely.
1757 EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(1))); 1935 EnablePortalRequests(false);
1758 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, 1936
1759 GetStateOfTabReloaderAt(browser(), 1)); 1937 content::WindowedNotificationObserver signal(
1760 1938 chrome::NOTIFICATION_SSL_INTERSTITIAL_TIMER_FIRED,
1761 // Make sure only one navigation was for the login tab. 1939 content::Source<WebContents>(broken_tab_contents));
1762 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( 1940 ui_test_utils::NavigateToURLWithDisposition(browser,
1763 tab_strip_model->GetWebContentsAt(1))); 1941 cert_error_url,
1942 CURRENT_TAB,
1943 ui_test_utils::BROWSER_TEST_NONE);
1944 signal.Wait();
1945 ASSERT_EQ(broken_tab_contents,
1946 content::Source<WebContents>(signal.source()).ptr());
1947
1948 // The tab should be in loading state, waiting for the interstitial timer to
1949 // expire or a captive portal result to arrive. Since captive portal checks
1950 // are disabled and timer set to expire after a very long time, the tab should
1951 // hang indefinitely.
1952 EXPECT_TRUE(broken_tab_contents->IsLoading());
1953 EXPECT_EQ(1, NumLoadingTabs());
1954 }
1955
1956 // Tests this scenario:
1957 // - Portal checks are disabled.
mmenke 2014/12/15 20:46:08 Should clarify this - The CaptivePortalService has
meacer 2014/12/16 01:23:18 Done.
1958 // - A cert error triggers an interstitial timer with a very long timeout.
1959 // - No captive portal results arrive, causing the tab to appear as loading
1960 // indefinitely.
1961 // - Stopping the page load shouldn't result in any interstitials.
1962 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
1963 InterstitialTimerStopNavigationWhileLoading) {
1964 net::SpawnedTestServer::SSLOptions https_options;
1965 https_options.server_certificate =
1966 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
1967 net::SpawnedTestServer https_server(
1968 net::SpawnedTestServer::TYPE_HTTPS, https_options,
1969 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1970 ASSERT_TRUE(https_server.Start());
1971 // The path does not matter.
1972 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
1973
1974 SSLErrorHandler::SetInterstitialDisplayDelayForTest(
1975 base::TimeDelta::FromHours(1));
1976 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1977 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
1978
1979 CaptivePortalObserver portal_observer1(browser()->profile());
1980 FastErrorWithInterstitialTimer(browser(), cert_error_url);
1981
1982 // Page appears loading. Stop the navigation. There should be no interstitial.
1983 MultiNavigationObserver test_navigation_observer;
1984 broken_tab_contents->Stop();
1985 test_navigation_observer.WaitForNavigations(1);
1986
1987 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
1988 EXPECT_FALSE(broken_tab_contents->IsLoading());
1989 EXPECT_EQ(0, portal_observer1.num_results_received());
1990 EXPECT_EQ(0, NumLoadingTabs());
1991 EXPECT_FALSE(CheckPending(browser()));
1992 EXPECT_EQ(1, browser()->tab_strip_model()->count());
1993 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1994 GetStateOfTabReloaderAt(browser(), 0));
1995
1996 // Re-enable captive portal checks and fire one. The result should be ignored.
1997 EnablePortalRequests(true);
1998 CaptivePortalObserver portal_observer2(browser()->profile());
1999 CaptivePortalService* captive_portal_service =
2000 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
2001 captive_portal_service->DetectCaptivePortal();
2002 portal_observer2.WaitForResults(1);
2003
2004 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2005 EXPECT_FALSE(broken_tab_contents->IsLoading());
2006 EXPECT_EQ(1, portal_observer2.num_results_received());
2007 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
2008 portal_observer2.captive_portal_result());
2009 EXPECT_EQ(0, NumLoadingTabs());
2010 EXPECT_FALSE(CheckPending(browser()));
2011 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2012 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2013 GetStateOfTabReloaderAt(browser(), 0));
2014 }
2015
2016 // Same as above, but instead of stopping, the loading page is reloaded. The end
2017 // result is the same. (i.e. page load stops, no interstitials shown)
2018 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
2019 InterstitialTimerReloadWhileLoading) {
2020 net::SpawnedTestServer::SSLOptions https_options;
2021 https_options.server_certificate =
2022 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2023 net::SpawnedTestServer https_server(
2024 net::SpawnedTestServer::TYPE_HTTPS, https_options,
2025 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2026 ASSERT_TRUE(https_server.Start());
2027 // The path does not matter.
2028 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
2029
2030 // Set SSL interstitial delay long enough so that a captive portal result
2031 // is guaranteed to arrive during this window, and a captive portal
2032 // error page is displayed instead of an SSL interstitial.
2033 SSLErrorHandler::SetInterstitialDisplayDelayForTest(
2034 base::TimeDelta::FromHours(1));
2035 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2036 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2037
2038 CaptivePortalObserver portal_observer(browser()->profile());
2039 FastErrorWithInterstitialTimer(browser(), cert_error_url);
2040
2041 // Page appears loading. Reloading should cancel the navigation and there
2042 // should be no interstitial.
2043 MultiNavigationObserver test_navigation_observer;
2044 chrome::Reload(browser(), CURRENT_TAB);
2045 test_navigation_observer.WaitForNavigations(2);
2046
2047 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2048 EXPECT_FALSE(broken_tab_contents->IsLoading());
2049 EXPECT_EQ(0, portal_observer.num_results_received());
2050 EXPECT_EQ(2, test_navigation_observer.num_navigations());
2051 EXPECT_EQ(0, NumLoadingTabs());
2052 EXPECT_FALSE(CheckPending(browser()));
2053 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2054 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2055 GetStateOfTabReloaderAt(browser(), 0));
2056
2057 // Re-enable captive portal checks and fire one. The result should be ignored.
2058 EnablePortalRequests(true);
mmenke 2014/12/15 20:46:08 Why don't we have a new SSLErrorHandler waiting on
meacer 2014/12/16 01:23:19 Reloading effectively stops the navigation (this i
2059 CaptivePortalObserver portal_observer2(browser()->profile());
2060 CaptivePortalService* captive_portal_service =
2061 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
2062 captive_portal_service->DetectCaptivePortal();
2063 portal_observer2.WaitForResults(1);
2064
2065 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2066 EXPECT_FALSE(broken_tab_contents->IsLoading());
2067 EXPECT_EQ(1, portal_observer2.num_results_received());
2068 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
2069 portal_observer2.captive_portal_result());
2070 EXPECT_EQ(0, NumLoadingTabs());
2071 EXPECT_FALSE(CheckPending(browser()));
2072 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2073 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2074 GetStateOfTabReloaderAt(browser(), 0));
2075 }
2076
2077 // Same as above, but instead of reloading, the page is navigated away. The new
2078 // page should load, and no interstitials shoudl be shown.
mmenke 2014/12/15 20:46:08 nit: shoudl -> should
meacer 2014/12/16 01:23:18 Done.
2079 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
2080 InterstitialTimerNavigateAwayWhileLoading) {
2081 net::SpawnedTestServer::SSLOptions https_options;
2082 https_options.server_certificate =
2083 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2084 net::SpawnedTestServer https_server(
2085 net::SpawnedTestServer::TYPE_HTTPS, https_options,
2086 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2087 ASSERT_TRUE(https_server.Start());
2088 // The path does not matter.
2089 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
2090
2091 // Set SSL interstitial delay long enough so that a captive portal result
2092 // is guaranteed to arrive during this window, and a captive portal
2093 // error page is displayed instead of an SSL interstitial.
2094 SSLErrorHandler::SetInterstitialDisplayDelayForTest(
2095 base::TimeDelta::FromHours(1));
2096 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2097 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2098
2099 CaptivePortalObserver portal_observer(browser()->profile());
2100 FastErrorWithInterstitialTimer(browser(), cert_error_url);
2101
2102 // Page appears loading. Navigating away shouldn't result in any interstitial.
2103 // Can't use ui_test_utils::NavigateToURLWithDisposition because it waits for
2104 // a load stop notification before starting a new navigation.
2105 MultiNavigationObserver test_navigation_observer;
2106 browser()->OpenURL(content::OpenURLParams(
2107 URLRequestMockHTTPJob::GetMockUrl(
2108 base::FilePath(FILE_PATH_LITERAL("title2.html"))),
2109 content::Referrer(),
2110 CURRENT_TAB,
2111 ui::PAGE_TRANSITION_TYPED, false));
2112 test_navigation_observer.WaitForNavigations(2);
mmenke 2014/12/15 20:46:08 Why are there two navigations here?
meacer 2014/12/16 01:23:19 First one is for stopping the hanging navigation,
2113
2114 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2115 EXPECT_FALSE(broken_tab_contents->IsLoading());
2116 EXPECT_EQ(0, portal_observer.num_results_received());
2117 EXPECT_EQ(2, test_navigation_observer.num_navigations());
2118 EXPECT_EQ(0, NumLoadingTabs());
2119 EXPECT_FALSE(CheckPending(browser()));
2120 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2121 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2122 GetStateOfTabReloaderAt(browser(), 0));
2123
2124 // Re-enable captive portal checks and fire one. The result should be ignored.
2125 EnablePortalRequests(true);
2126 CaptivePortalObserver portal_observer2(browser()->profile());
2127 CaptivePortalService* captive_portal_service =
2128 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
2129 captive_portal_service->DetectCaptivePortal();
2130 portal_observer2.WaitForResults(1);
2131
2132 EXPECT_FALSE(broken_tab_contents->ShowingInterstitialPage());
2133 EXPECT_FALSE(broken_tab_contents->IsLoading());
2134 EXPECT_EQ(1, portal_observer2.num_results_received());
2135 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
2136 portal_observer2.captive_portal_result());
2137 EXPECT_EQ(0, NumLoadingTabs());
2138 EXPECT_FALSE(CheckPending(browser()));
2139 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2140 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
2141 GetStateOfTabReloaderAt(browser(), 0));
2142 }
2143
2144 // A cert error triggers a captive portal check and results in opening a login
2145 // tab. The user then logs in and the page with the error is reloaded.
2146 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, SSLCertErrorLogin) {
2147 // Need an HTTP TestServer to handle a dynamically created server redirect.
2148 ASSERT_TRUE(test_server()->Start());
2149
2150 net::SpawnedTestServer::SSLOptions https_options;
2151 https_options.server_certificate =
2152 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
2153 net::SpawnedTestServer https_server(
2154 net::SpawnedTestServer::TYPE_HTTPS, https_options,
2155 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2156 ASSERT_TRUE(https_server.Start());
2157
2158 // Set SSL interstitial delay to zero so that a captive portal result can not
2159 // arrive during this window, so an SSL interstitial is displayed instead
2160 // of a captive portal error page.
2161 SSLErrorHandler::SetInterstitialDisplayDelayForTest(base::TimeDelta());
2162 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2163 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2164
2165 // Setting the delay to zero above has a race condition: A captive portal
2166 // result triggered by a cert error can arrive before the SSL interstitial
2167 // display timer is fired, even though it's set to zero.
2168 // To avoid this, disable captive portal checks until the SSL interstitial is
2169 // displayed. Once it's displayed, enable portal checks and fire one.
2170 bool disable_portal_check_until_interstitial = true;
2171
2172 // The path does not matter.
2173 GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
2174 // The interstitial should trigger a captive portal check when it opens, just
2175 // like navigating to kMockHttpsQuickTimeoutUrl.
mmenke 2014/12/15 20:46:07 Wonder about this comment - we actually trigger th
meacer 2014/12/16 01:23:19 The comment is from the current SSLCertErrorLogin
2176 FastErrorBehindCaptivePortal(
2177 browser(),
2178 true,
2179 cert_error_url,
2180 disable_portal_check_until_interstitial);
2181
2182 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
2183 GetInterstitialType(broken_tab_contents));
2184
2185 LoginCertError(browser());
1764 } 2186 }
1765 2187
1766 // Tries navigating both the tab that encounters an SSL timeout and the 2188 // Tries navigating both the tab that encounters an SSL timeout and the
1767 // login tab twice, only logging in the second time. 2189 // login tab twice, only logging in the second time.
1768 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) { 2190 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) {
1769 FastTimeoutBehindCaptivePortal(browser(), true); 2191 FastTimeoutBehindCaptivePortal(browser(), true);
1770 2192
1771 // Activate the timed out tab and navigate it to a timeout again. 2193 // Activate the timed out tab and navigate it to a timeout again.
1772 TabStripModel* tab_strip_model = browser()->tab_strip_model(); 2194 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1773 tab_strip_model->ActivateTabAt(0, true); 2195 tab_strip_model->ActivateTabAt(0, true);
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 content::BrowserThread::PostTask( 2628 content::BrowserThread::PostTask(
2207 content::BrowserThread::IO, FROM_HERE, 2629 content::BrowserThread::IO, FROM_HERE,
2208 base::Bind(&AddHstsHost, 2630 base::Bind(&AddHstsHost,
2209 make_scoped_refptr(browser()->profile()->GetRequestContext()), 2631 make_scoped_refptr(browser()->profile()->GetRequestContext()),
2210 http_timeout_url.host())); 2632 http_timeout_url.host()));
2211 2633
2212 SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url, 1, 1); 2634 SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url, 1, 1);
2213 Login(browser(), 1, 0); 2635 Login(browser(), 1, 0);
2214 FailLoadsAfterLogin(browser(), 1); 2636 FailLoadsAfterLogin(browser(), 1);
2215 } 2637 }
2638
2639 // A slow SSL load starts. The reloader triggers a captive portal check, finds a
2640 // captive portal. The SSL commits with a cert error, triggering another captive
2641 // portal check.
2642 // The second check finds no captive portal. The reloader triggers a reload at
2643 // the same time SSL error handler tries to show an interstitial. Should result
2644 // in an SSL interstitial.
2645 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
2646 InterstitialTimerCertErrorAfterSlowLoad) {
2647 // Use a url that triggers a slow load, instead of creating an https server.
2648 GURL cert_error_url = GURL(kMockHttpsUrl);
2649
2650 TabStripModel* tab_strip_model = browser()->tab_strip_model();
2651 int broken_tab_index = tab_strip_model->active_index();
2652 WebContents* broken_tab_contents = tab_strip_model->GetActiveWebContents();
2653 CaptivePortalTabReloader* tab_reloader = GetTabReloader(broken_tab_contents);
2654 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
mmenke 2014/12/15 20:46:07 Shouldn't we be setting the 1 hour time here?
meacer 2014/12/16 01:23:18 This is the timeout for the slow ssl timer, not th
2655
2656 SlowLoadBehindCaptivePortal(browser(), true, cert_error_url, 1, 1);
2657
2658 // No longer behind a captive portal. Committing the SSL page should trigger
2659 // an SSL interstitial which triggers a new captive portal check. Since there
2660 // is no captive portal anymore, should end up with an SSL interstitial.
2661 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
2662
2663 CaptivePortalObserver portal_observer(browser()->profile());
2664 MultiNavigationObserver navigation_observer;
2665 URLRequestTimeoutOnDemandJob::FailJobsWithCertError(1);
2666 navigation_observer.WaitForNavigations(1);
2667
2668 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
2669 GetStateOfTabReloaderAt(browser(), broken_tab_index));
2670
2671 WaitForInterstitialAttach(broken_tab_contents);
2672 portal_observer.WaitForResults(1);
2673
2674 EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
2675 GetInterstitialType(broken_tab_contents));
2676 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698