summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer/safe_browsing/phishing_classifier_delegate.cc')
-rw-r--r--chrome/renderer/safe_browsing/phishing_classifier_delegate.cc124
1 files changed, 124 insertions, 0 deletions
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc b/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc
new file mode 100644
index 0000000..612eb4d
--- /dev/null
+++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "chrome/renderer/navigation_state.h"
+#include "chrome/renderer/render_view.h"
+#include "chrome/renderer/safe_browsing/feature_extractor_clock.h"
+#include "chrome/renderer/safe_browsing/phishing_classifier.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
+
+namespace safe_browsing {
+
+PhishingClassifierDelegate::PhishingClassifierDelegate(
+ RenderView* render_view,
+ PhishingClassifier* classifier)
+ : render_view_(render_view),
+ last_page_id_sent_to_classifier_(-1),
+ pending_classification_(false) {
+ if (!classifier) {
+ classifier = new PhishingClassifier(render_view_,
+ new FeatureExtractorClock());
+ }
+ classifier_.reset(classifier);
+}
+
+PhishingClassifierDelegate::~PhishingClassifierDelegate() {
+ CancelPendingClassification();
+}
+
+void PhishingClassifierDelegate::SetPhishingScorer(
+ const safe_browsing::Scorer* scorer) {
+ classifier_->set_phishing_scorer(scorer);
+
+ if (pending_classification_) {
+ pending_classification_ = false;
+ // If we have a pending classificaton, it should always be true that the
+ // main frame URL and page id have not changed since we queued the
+ // classification. This is because we stop any pending classification on
+ // main frame loads in RenderView::didCommitProvisionalLoad().
+ DCHECK_EQ(StripToplevelUrl(), last_url_sent_to_classifier_);
+ DCHECK_EQ(render_view_->page_id(), last_page_id_sent_to_classifier_);
+ classifier_->BeginClassification(
+ &classifier_page_text_,
+ NewCallback(this, &PhishingClassifierDelegate::ClassificationDone));
+ }
+}
+
+void PhishingClassifierDelegate::CommittedLoadInFrame(
+ WebKit::WebFrame* frame) {
+ // A new page is starting to load. Unless the load is a navigation within
+ // the same page, we need to cancel classification since the content will
+ // now be inconsistent with the phishing model.
+ NavigationState* state = NavigationState::FromDataSource(
+ frame->dataSource());
+ if (!state->was_within_same_page()) {
+ CancelPendingClassification();
+ }
+}
+
+void PhishingClassifierDelegate::FinishedLoad(string16* page_text) {
+ // We check that the page id has incremented so that we don't reclassify
+ // pages as the user moves back and forward in session history. Note: we
+ // don't send every page id to the classifier, only those where the toplevel
+ // URL changed.
+ int load_id = render_view_->page_id();
+ if (load_id <= last_page_id_sent_to_classifier_) {
+ return;
+ }
+
+ GURL url_without_ref = StripToplevelUrl();
+ if (url_without_ref == last_url_sent_to_classifier_) {
+ // The toplevle URL is the same, except for the ref.
+ // Update the last page id we sent, but don't trigger a new classification.
+ last_page_id_sent_to_classifier_ = load_id;
+ return;
+ }
+
+ last_url_sent_to_classifier_ = url_without_ref;
+ last_page_id_sent_to_classifier_ = load_id;
+ classifier_page_text_.swap(*page_text);
+
+ if (classifier_->is_ready()) {
+ classifier_->BeginClassification(
+ &classifier_page_text_,
+ NewCallback(this, &PhishingClassifierDelegate::ClassificationDone));
+ } else {
+ // If there is no phishing classifier yet, we'll begin classification once
+ // SetPhishingScorer() is called by the RenderView.
+ pending_classification_ = true;
+ }
+}
+
+void PhishingClassifierDelegate::CancelPendingClassification() {
+ if (classifier_->is_ready()) {
+ classifier_->CancelPendingClassification();
+ }
+ classifier_page_text_.clear();
+ pending_classification_ = false;
+}
+
+void PhishingClassifierDelegate::ClassificationDone(bool is_phishy,
+ double phishy_score) {
+ // We no longer need the page text.
+ classifier_page_text_.clear();
+ VLOG(2) << "Phishy verdict = " << is_phishy << " score = " << phishy_score;
+
+ // TODO(bryner): Grab a snapshot and send a DetectedPhishingSite message
+ // to the browser.
+}
+
+GURL PhishingClassifierDelegate::StripToplevelUrl() {
+ GURL toplevel_url = render_view_->webview()->mainFrame()->url();
+ GURL::Replacements replacements;
+ replacements.ClearRef();
+ return toplevel_url.ReplaceComponents(replacements);
+}
+
+} // namespace safe_browsing