15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/captive_portal_tab_reloader.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/captive_portal_service.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/captive_portal_service_factory.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/interstitial_page.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace captive_portal { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The time to wait for a slow loading SSL page before triggering a captive 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// portal check. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDefaultSlowSSLTimeSeconds = 30; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if an SSL request resulting in |error| may indicate a captive 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// portal. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SslNetErrorMayImplyCaptivePortal(int error) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May be returned when a captive portal silently blocks an SSL request. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error == net::ERR_CONNECTION_TIMED_OUT) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May be returned when a captive portal lets SSL requests connect, but 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disconnects Chrome after Chrome starts SSL negotiation, or sends an 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HTTP response. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error == net::ERR_SSL_PROTOCOL_ERROR) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptivePortalTabReloader::CaptivePortalTabReloader( 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OpenLoginTabCallback& open_login_tab_callback) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents_(web_contents), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(STATE_NONE), 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provisional_main_frame_load_(false), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_url_in_redirect_chain_(false), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slow_ssl_load_time_( 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(kDefaultSlowSSLTimeSeconds)), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open_login_tab_callback_(open_login_tab_callback), 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptivePortalTabReloader::~CaptivePortalTabReloader() { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::OnLoadStart(bool is_ssl) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provisional_main_frame_load_ = true; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_url_in_redirect_chain_ = is_ssl; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_NONE); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the slow load timer for SSL pages. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mmenke): Should this look at the port instead? The reason the 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request never connects is because of the port, not the 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // protocol. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_ssl) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_TIMER_RUNNING); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::OnLoadCommitted(int net_error) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provisional_main_frame_load_ = false; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_url_in_redirect_chain_ = false; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_NONE) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |net_error| is not an error code that could indicate there's a captive 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // portal, reset the state. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SslNetErrorMayImplyCaptivePortal(net_error)) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mmenke): If the new URL is the same as the old broken URL, and the 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request succeeds, should probably trigger another 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // captive portal check. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_NONE); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The page returned an error out before the timer triggered. Go ahead and 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // try to detect a portal now, rather than waiting for the timer. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_TIMER_RUNNING) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSlowSSLConnect(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the tab needs to reload, do so asynchronously, to avoid reentrancy 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // issues. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_NEEDS_RELOAD) { 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CaptivePortalTabReloader::ReloadTabIfNeeded, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::OnAbort() { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provisional_main_frame_load_ = false; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_url_in_redirect_chain_ = false; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_NONE); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::OnRedirect(bool is_ssl) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_NONE); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_ssl) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only start the SSL timer running if no SSL URL has been seen in the current 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // redirect chain. If we've already successfully downloaded one SSL URL, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // assume we're not behind a captive portal. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_url_in_redirect_chain_) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_TIMER_RUNNING); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_url_in_redirect_chain_ = true; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::OnCaptivePortalResults( 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result previous_result, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result result) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == RESULT_BEHIND_CAPTIVE_PORTAL) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_MAYBE_BROKEN_BY_PORTAL) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_BROKEN_BY_PORTAL); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeOpenCaptivePortalLoginTab(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_MAYBE_BROKEN_BY_PORTAL: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TIMER_RUNNING: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the previous result was BEHIND_CAPTIVE_PORTAL, and the state is 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either STATE_MAYBE_BROKEN_BY_PORTAL or STATE_TIMER_RUNNING, reload the 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tab. In the latter case, the tab has yet to commit, but is an SSL 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // page, so if the page ends up at an error caused by a captive portal, it 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be reloaded. If not, the state will just be reset. The helps in 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the case that a user tries to reload a tab, and then quickly logs in. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (previous_result == RESULT_BEHIND_CAPTIVE_PORTAL) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_NEEDS_RELOAD); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_NONE); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_BROKEN_BY_PORTAL: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Either reload the tab now, if an error page has already been committed 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or an interstitial is being displayed, or reload it if and when a 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeout commits. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_NEEDS_RELOAD); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_NEEDS_RELOAD: 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_NONE: 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the tab needs to reload or is in STATE_NONE, do nothing. The reload 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // case shouldn't be very common, since it only lasts until a tab times 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // out, but it's still possible. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::OnSSLCertError(const net::SSLInfo& ssl_info) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mmenke): Figure out if any cert errors should be ignored. The 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // most common errors when behind captive portals are likely 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ERR_CERT_COMMON_NAME_INVALID and ERR_CERT_AUTHORITY_INVALID. It's unclear 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if captive portals cause any others. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_TIMER_RUNNING) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_MAYBE_BROKEN_BY_PORTAL); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::OnSlowSSLConnect() { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_MAYBE_BROKEN_BY_PORTAL); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::SetState(State new_state) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop the timer even when old and new states are the same. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_TIMER_RUNNING) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slow_ssl_load_timer_.Stop(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!slow_ssl_load_timer_.IsRunning()); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for unexpected state transitions. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_NONE: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_state == STATE_NONE || 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_state == STATE_TIMER_RUNNING); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TIMER_RUNNING: 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_state == STATE_NONE || 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_state == STATE_MAYBE_BROKEN_BY_PORTAL || 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_state == STATE_NEEDS_RELOAD); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_MAYBE_BROKEN_BY_PORTAL: 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_state == STATE_NONE || 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_state == STATE_BROKEN_BY_PORTAL || 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_state == STATE_NEEDS_RELOAD); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_BROKEN_BY_PORTAL: 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_state == STATE_NONE || 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_state == STATE_NEEDS_RELOAD); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_NEEDS_RELOAD: 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, new_state); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = new_state; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TIMER_RUNNING: 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slow_ssl_load_timer_.Start( 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slow_ssl_load_time_, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CaptivePortalTabReloader::OnSlowSSLConnect); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_MAYBE_BROKEN_BY_PORTAL: 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckForCaptivePortal(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_NEEDS_RELOAD: 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to reload the tab now. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReloadTabIfNeeded(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::ReloadTabIfNeeded() { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the page no longer needs to be reloaded, do nothing. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ != STATE_NEEDS_RELOAD) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there's still a provisional load going, do nothing unless there's an 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interstitial page. Reloading when displaying an interstitial page will 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reload the underlying page, even if it hasn't yet committed. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (provisional_main_frame_load_ && 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !content::InterstitialPage::GetInterstitialPage(web_contents_)) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(STATE_NONE); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReloadTab(); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::ReloadTab() { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NavigationController* controller = &web_contents_->GetController(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!controller->GetActiveEntry()->GetHasPostData()) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->Reload(true); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::MaybeOpenCaptivePortalLoginTab() { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open_login_tab_callback_.Run(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalTabReloader::CheckForCaptivePortal() { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CaptivePortalService* service = 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CaptivePortalServiceFactory::GetForProfile(profile_); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->DetectCaptivePortal(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace captive_portal 284