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

Side by Side Diff: chrome/browser/ssl/ssl_error_handler.cc

Issue 318213002: Add custom interstitial for captive portals. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Expand browser tests 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
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ssl/ssl_error_handler.h"
6
7 #include "base/metrics/histogram.h"
8 #include "base/time/time.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ssl/ssl_blocking_page.h"
11 #include "content/public/browser/notification_service.h"
12 #include "content/public/browser/notification_source.h"
13 #include "content/public/browser/web_contents.h"
14
15 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
16 #include "chrome/browser/captive_portal/captive_portal_service.h"
17 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
18 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
19 #include "chrome/browser/ssl/captive_portal_blocking_page.h"
20 #endif
21
22 namespace {
23
24 // Events for UMA.
25 enum SSLErrorHandlerEvent {
26 HANDLE_ALL,
27 SHOW_CAPTIVE_PORTAL_INTERSTITIAL,
28 SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE,
29 SHOW_SSL_INTERSTITIAL,
30 SHOW_SSL_INTERSTITIAL_OVERRIDABLE,
31 SSL_ERROR_HANDLER_EVENT_COUNT
32 };
33
34 void RecordUMA(SSLErrorHandlerEvent event) {
35 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_handler",
36 event,
37 SSL_ERROR_HANDLER_EVENT_COUNT);
38 }
39
40 } // namespace
41
42 SSLErrorHandler::SSLErrorHandler(content::WebContents* web_contents,
43 int cert_error,
44 const net::SSLInfo& ssl_info,
45 const GURL& request_url,
46 const int options_mask,
47 const base::TimeDelta ssl_error_delay,
48 const base::Callback<void(bool)>& callback)
49 : content::WebContentsObserver(web_contents),
50 cert_error_(cert_error),
51 ssl_info_(ssl_info),
52 request_url_(request_url),
53 options_mask_(options_mask),
54 callback_(callback),
55 ssl_interstitial_display_delay_(ssl_error_delay) {
56 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
57 Profile* profile = Profile::FromBrowserContext(
58 web_contents->GetBrowserContext());
59 registrar_.Add(this,
60 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
61 content::Source<Profile>(profile));
62 #endif
63 }
64
65 SSLErrorHandler::~SSLErrorHandler() {
66 }
67
68 void SSLErrorHandler::HandleSSLError(
69 content::WebContents* web_contents,
70 int cert_error,
71 const net::SSLInfo& ssl_info,
72 const GURL& request_url,
73 int options_mask,
74 const base::Callback<void(bool)>& callback) {
75 // SSL interstitials aren't delayed if captive portal detection is disabled.
76 base::TimeDelta ssl_error_delay;
77 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
78 CaptivePortalTabHelper* captive_portal_tab_helper =
79 CaptivePortalTabHelper::FromWebContents(web_contents);
80 if (captive_portal_tab_helper) {
81 ssl_error_delay = captive_portal_tab_helper->GetSSLErrorDelay();
82 captive_portal_tab_helper->OnSSLCertError(ssl_info);
83 }
84 #endif
85 (new SSLErrorHandler(web_contents, cert_error, ssl_info, request_url,
86 options_mask, ssl_error_delay,
87 callback))->StartHandlingError();
88 }
89
90 void SSLErrorHandler::StartHandlingError() {
91 RecordUMA(HANDLE_ALL);
92
93 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
94 CheckForCaptivePortal();
95 timer_.Start(FROM_HERE, ssl_interstitial_display_delay_,
96 base::Bind(&SSLErrorHandler::OnTimerExpired,
97 base::Unretained(this)));
98 content::NotificationService* service =
99 content::NotificationService::current();
100 service->Notify(chrome::NOTIFICATION_SSL_INTERSTITIAL_TIMER_FIRED,
101 content::Source<content::WebContents>(web_contents()),
102 content::NotificationService::NoDetails());
103 return;
104 #endif
105 // Display an SSL interstitial.
106 ShowSSLInterstitial();
107 }
108
109 void SSLErrorHandler::OnTimerExpired() {
110 ShowSSLInterstitial();
111 }
112
113 void SSLErrorHandler::CheckForCaptivePortal() {
114 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
115 Profile* profile = Profile::FromBrowserContext(
116 web_contents()->GetBrowserContext());
117 CaptivePortalService* captive_portal_service =
118 CaptivePortalServiceFactory::GetForProfile(profile);
119 captive_portal_service->DetectCaptivePortal();
120 #else
121 NOTREACHED();
122 #endif
123 }
124
125 void SSLErrorHandler::ShowCaptivePortalInterstitial() {
126 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
127 // Show captive portal blocking page. The interstitial owns the blocking page.
128 RecordUMA(SSLBlockingPage::IsOverridable(options_mask_) ?
129 SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE :
130 SHOW_CAPTIVE_PORTAL_INTERSTITIAL);
131 (new CaptivePortalBlockingPage(web_contents(), request_url_))->Show();
132 delete this;
133 #else
134 NOTREACHED();
135 #endif
136 }
137
138 void SSLErrorHandler::ShowSSLInterstitial() {
139 // Show SSL blocking page. The interstitial owns the blocking page.
140 RecordUMA(SSLBlockingPage::IsOverridable(options_mask_) ?
141 SHOW_SSL_INTERSTITIAL_OVERRIDABLE :
142 SHOW_SSL_INTERSTITIAL);
143 (new SSLBlockingPage(web_contents(), cert_error_, ssl_info_, request_url_,
144 options_mask_, callback_))->Show();
145 delete this;
146 }
147
148 void SSLErrorHandler::Observe(
149 int type,
150 const content::NotificationSource& source,
151 const content::NotificationDetails& details) {
152 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
153 if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
154 timer_.Stop();
155 CaptivePortalService::Results* results =
156 content::Details<CaptivePortalService::Results>(details).ptr();
157 if (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL)
158 ShowCaptivePortalInterstitial();
159 else
160 ShowSSLInterstitial();
161 }
162 #endif
163 }
164
165 void SSLErrorHandler::DidStartNavigationToPendingEntry(
166 const GURL& url,
167 content::NavigationController::ReloadType reload_type) {
168 delete this;
169 }
170
171 void SSLErrorHandler::DidStopLoading(
172 content::RenderViewHost* render_view_host) {
173 delete this;
174 }
175
176 void SSLErrorHandler::WebContentsDestroyed() {
177 delete this;
178 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698