summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ssl_blocking_page.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/ssl_blocking_page.cc')
-rw-r--r--chrome/browser/ssl_blocking_page.cc200
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) {