diff options
Diffstat (limited to 'chrome/browser/ssl_blocking_page.cc')
-rw-r--r-- | chrome/browser/ssl_blocking_page.cc | 200 |
1 files changed, 25 insertions, 175 deletions
diff --git a/chrome/browser/ssl_blocking_page.cc b/chrome/browser/ssl_blocking_page.cc index ba90efe..c92ddc2 100644 --- a/chrome/browser/ssl_blocking_page.cc +++ b/chrome/browser/ssl_blocking_page.cc @@ -11,8 +11,6 @@ #include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/navigation_controller.h" #include "chrome/browser/navigation_entry.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/render_view_host.h" #include "chrome/browser/ssl_error_info.h" #include "chrome/browser/tab_contents.h" #include "chrome/browser/web_contents.h" @@ -24,71 +22,17 @@ #include "generated_resources.h" -// static -SSLBlockingPage::SSLBlockingPageMap* - SSLBlockingPage::tab_to_blocking_page_ = NULL; - +// Note that we always create a navigation entry with SSL errors. +// No error happening loading a sub-resource triggers an interstitial so far. SSLBlockingPage::SSLBlockingPage(SSLManager::CertError* error, Delegate* delegate) - : error_(error), + : InterstitialPage(error->GetTabContents(), true, error->request_url()), + error_(error), delegate_(delegate), - delegate_has_been_notified_(false), - remove_last_entry_(true), - created_nav_entry_(false) { - InitSSLBlockingPageMap(); - // Remember the tab, because we might not be able to get to it later - // via the error. - tab_ = error->GetTabContents(); - DCHECK(tab_); - - // If there's already an interstitial in this tab, then we're about to - // replace it. We should be ok with just deleting the previous - // SSLBlockingPage (not hiding it first), since we're about to be shown. - SSLBlockingPageMap::const_iterator iter = tab_to_blocking_page_->find(tab_); - if (iter != tab_to_blocking_page_->end()) { - // Deleting the SSLBlockingPage will also remove it from the map. - delete iter->second; - - // Since WebContents::InterstitialPageGone won't be called, we need - // to clear the last NavigationEntry manually. - tab_->controller()->RemoveLastEntryForInterstitial(); - } - (*tab_to_blocking_page_)[tab_] = this; - - // Register notifications so we can delete ourself if the tab is closed. - NotificationService::current()->AddObserver(this, - NOTIFY_TAB_CLOSING, - Source<NavigationController>(tab_->controller())); - - NotificationService::current()->AddObserver(this, - NOTIFY_INTERSTITIAL_PAGE_CLOSED, - Source<NavigationController>(tab_->controller())); - - // Register for DOM operations, this is how the blocking page notifies us of - // what the user chooses. - NotificationService::current()->AddObserver(this, - NOTIFY_DOM_OPERATION_RESPONSE, - Source<TabContents>(tab_)); + delegate_has_been_notified_(false) { } SSLBlockingPage::~SSLBlockingPage() { - NotificationService::current()->RemoveObserver(this, - NOTIFY_TAB_CLOSING, - Source<NavigationController>(tab_->controller())); - - NotificationService::current()->RemoveObserver(this, - NOTIFY_INTERSTITIAL_PAGE_CLOSED, - Source<NavigationController>(tab_->controller())); - - NotificationService::current()->RemoveObserver(this, - NOTIFY_DOM_OPERATION_RESPONSE, - Source<TabContents>(tab_)); - - SSLBlockingPageMap::iterator iter = - tab_to_blocking_page_->find(tab_); - DCHECK(iter != tab_to_blocking_page_->end()); - tab_to_blocking_page_->erase(iter); - if (!delegate_has_been_notified_) { // The page is closed without the user having chosen what to do, default to // deny. @@ -96,7 +40,7 @@ SSLBlockingPage::~SSLBlockingPage() { } } -void SSLBlockingPage::Show() { +std::string SSLBlockingPage::GetHTMLContents() { // Let's build the html error page. DictionaryValue strings; SSLErrorInfo error_info = delegate_->GetSSLErrorInfo(error_); @@ -122,31 +66,15 @@ void SSLBlockingPage::Show() { ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_SSL_ROAD_BLOCK_HTML)); - std::string html_text(jstemplate_builder::GetTemplateHtml(html, - &strings, - "template_root")); + return jstemplate_builder::GetTemplateHtml(html, &strings, "template_root"); +} - DCHECK(tab_->type() == TAB_CONTENTS_WEB); - WebContents* tab = tab_->AsWebContents(); +void SSLBlockingPage::UpdateEntry(NavigationEntry* entry) { + DCHECK(tab()->type() == TAB_CONTENTS_WEB); + WebContents* web = tab()->AsWebContents(); const net::SSLInfo& ssl_info = error_->ssl_info(); int cert_id = CertStore::GetSharedInstance()->StoreCert( - ssl_info.cert, tab->render_view_host()->process()->host_id()); - - if (tab_->controller()->GetPendingEntryIndex() == -1) { - // For new navigations, we just create a new navigation entry. - NavigationEntry new_entry(TAB_CONTENTS_WEB); - new_entry.set_url(error_->request_url()); - tab_->controller()->AddDummyEntryForInterstitial(new_entry); - created_nav_entry_ = true; - } else { - // When there is a pending entry index, that means we're doing a - // back/forward navigation. Clone that entry instead. - tab_->controller()->AddDummyEntryForInterstitial( - *tab_->controller()->GetPendingEntry()); - } - - NavigationEntry* entry = tab_->controller()->GetActiveEntry(); - entry->set_page_type(NavigationEntry::INTERSTITIAL_PAGE); + ssl_info.cert, web->render_view_host()->process()->host_id()); entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); entry->ssl().set_cert_id(cert_id); @@ -154,101 +82,35 @@ void SSLBlockingPage::Show() { entry->ssl().set_security_bits(ssl_info.security_bits); NotificationService::current()->Notify( NOTIFY_SSL_STATE_CHANGED, - Source<NavigationController>(tab_->controller()), + Source<NavigationController>(web->controller()), NotificationService::NoDetails()); - - tab->ShowInterstitialPage(html_text, NULL); } -void SSLBlockingPage::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - switch (type) { - case NOTIFY_TAB_CLOSING: - case NOTIFY_INTERSTITIAL_PAGE_CLOSED: { - // We created a navigation entry for the interstitial, remove it. - // Note that we don't remove the entry if we are closing all tabs so that - // the last entry is kept for the restoring on next start-up. - Browser* browser = Browser::GetBrowserForController(tab_->controller(), - NULL); - // We may not have a browser (this is the case for constrained popups), in - // which case it does not matter if we do not remove the temporary entry - // as their navigation history is not saved. - if (remove_last_entry_ && browser && - !browser->tabstrip_model()->closing_all()) { - tab_->controller()->RemoveLastEntryForInterstitial(); - } - delete this; - break; - } - case NOTIFY_DOM_OPERATION_RESPONSE: { - std::string json = - Details<DomOperationNotificationDetails>(details)->json(); - if (json == "1") { - Proceed(); - } else { - DontProceed(); - } - break; - } - default: - NOTREACHED(); +void SSLBlockingPage::CommandReceived(const std::string& command) { + if (command == "1") { + Proceed(); + } else { + DontProceed(); } } void SSLBlockingPage::Proceed() { - // We hide the interstitial page first as allowing the certificate will - // resume the request and we want the WebContents back to showing the - // non interstitial page (otherwise the request completion messages may - // confuse the WebContents if it is still showing the interstitial - // page). - DCHECK(tab_->type() == TAB_CONTENTS_WEB); - tab_->AsWebContents()->HideInterstitialPage(true, true); + // We hide the interstitial page first (by calling Proceed()) as allowing the + // certificate will resume the request and we want the WebContents back to + // showing the non interstitial page (otherwise the request completion + // messages may confuse the WebContents if it is still showing the + // interstitial page). + InterstitialPage::Proceed(); // Accepting the certificate resumes the loading of the page. NotifyAllowCertificate(); - - // Do not remove the navigation entry if we have not created it explicitly - // as in such cases (session restore) the controller would not create a new - // entry on navigation since the page id is less than max page id. - if (!created_nav_entry_) - remove_last_entry_ = false; } void SSLBlockingPage::DontProceed() { NotifyDenyCertificate(); - - // We are navigating, remove the current entry before we mess with it. - remove_last_entry_ = false; - tab_->controller()->RemoveLastEntryForInterstitial(); - - NavigationEntry* entry = tab_->controller()->GetActiveEntry(); - if (!entry) { - // Nothing to go to, default to about:blank. Navigating will cause the - // interstitial to hide which will trigger "this" to be deleted. - tab_->controller()->LoadURL(GURL("about:blank"), - PageTransition::AUTO_BOOKMARK); - } else if (entry->tab_type() != TAB_CONTENTS_WEB) { - // Not a WebContent, reload it so to recreate the TabContents for it. - tab_->controller()->Reload(); - } else { - DCHECK(tab_->type() == TAB_CONTENTS_WEB); - if (entry->restored()) { - // If this page was restored, it is not available, we have to navigate to - // it. - tab_->controller()->GoToOffset(0); - } else { - tab_->AsWebContents()->HideInterstitialPage(false, false); - } - } - // WARNING: we are now deleted! + InterstitialPage::DontProceed(); } -// static -void SSLBlockingPage::InitSSLBlockingPageMap() { - if (!tab_to_blocking_page_) - tab_to_blocking_page_ = new SSLBlockingPageMap; -} void SSLBlockingPage::NotifyDenyCertificate() { DCHECK(!delegate_has_been_notified_); @@ -265,18 +127,6 @@ void SSLBlockingPage::NotifyAllowCertificate() { } // static -SSLBlockingPage* SSLBlockingPage::GetSSLBlockingPage( - TabContents* tab_contents) { - InitSSLBlockingPageMap(); - SSLBlockingPageMap::const_iterator iter = - tab_to_blocking_page_->find(tab_contents); - if (iter == tab_to_blocking_page_->end()) - return NULL; - - return iter->second; -} - -// static void SSLBlockingPage::SetExtraInfo( DictionaryValue* strings, const std::vector<std::wstring>& extra_info) { |