| Index: chrome/browser/safe_browsing/client_side_detection_service.cc
|
| diff --git a/chrome/browser/safe_browsing/client_side_detection_service.cc b/chrome/browser/safe_browsing/client_side_detection_service.cc
|
| index 3d55132c39d1cc8c174f63b5d191886bf2c83f35..9d2bb07bcfd5ef2bab4d8af1279050c1609887c7 100644
|
| --- a/chrome/browser/safe_browsing/client_side_detection_service.cc
|
| +++ b/chrome/browser/safe_browsing/client_side_detection_service.cc
|
| @@ -16,10 +16,16 @@
|
| #include "base/task.h"
|
| #include "base/time.h"
|
| #include "chrome/browser/browser_thread.h"
|
| +#include "chrome/browser/renderer_host/render_view_host.h"
|
| #include "chrome/browser/safe_browsing/csd.pb.h"
|
| +#include "chrome/browser/tab_contents/provisional_load_details.h"
|
| +#include "chrome/browser/tab_contents/tab_contents.h"
|
| #include "chrome/common/net/http_return.h"
|
| #include "chrome/common/net/url_fetcher.h"
|
| #include "chrome/common/net/url_request_context_getter.h"
|
| +#include "chrome/common/notification_service.h"
|
| +#include "chrome/common/notification_type.h"
|
| +#include "chrome/common/render_messages.h"
|
| #include "googleurl/src/gurl.h"
|
| #include "net/base/load_flags.h"
|
| #include "net/url_request/url_request_status.h"
|
| @@ -38,6 +44,73 @@ struct ClientSideDetectionService::ClientReportInfo {
|
| GURL phishing_url;
|
| };
|
|
|
| +// ShouldClassifyUrlRequest tracks the pre-classification checks for a
|
| +// toplevel URL that has started loading into a renderer. When these
|
| +// checks are complete, the renderer is notified if it should run
|
| +// client-side phishing classification, then the ShouldClassifyUrlRequest
|
| +// deletes itself.
|
| +class ClientSideDetectionService::ShouldClassifyUrlRequest
|
| + : public NotificationObserver {
|
| + public:
|
| + ShouldClassifyUrlRequest(const GURL& url, TabContents* tab_contents)
|
| + : url_(url),
|
| + tab_contents_(tab_contents),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + registrar_.Add(this,
|
| + NotificationType::TAB_CONTENTS_DESTROYED,
|
| + Source<TabContents>(tab_contents));
|
| + }
|
| +
|
| + virtual void Observe(NotificationType type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details) {
|
| + switch (type.value) {
|
| + case NotificationType::TAB_CONTENTS_DESTROYED:
|
| + Cancel();
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + };
|
| + }
|
| +
|
| + void Start() {
|
| + // TODO(bryner): add pre-classification checks here.
|
| + // For now we just call Finish() asynchronously for consistency,
|
| + // since the pre-classification checks are asynchronous.
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + BrowserThread::PostTask(BrowserThread::UI,
|
| + FROM_HERE,
|
| + method_factory_.NewRunnableMethod(
|
| + &ShouldClassifyUrlRequest::Finish));
|
| + }
|
| +
|
| + private:
|
| + // This object always deletes itself, so make the destructor private.
|
| + virtual ~ShouldClassifyUrlRequest() {}
|
| +
|
| + void Cancel() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + tab_contents_ = NULL;
|
| + Finish();
|
| + }
|
| +
|
| + void Finish() {
|
| + if (tab_contents_) {
|
| + RenderViewHost* rvh = tab_contents_->render_view_host();
|
| + rvh->Send(new ViewMsg_StartPhishingDetection(rvh->routing_id(), url_));
|
| + }
|
| + delete this;
|
| + }
|
| +
|
| + GURL url_;
|
| + TabContents* tab_contents_;
|
| + NotificationRegistrar registrar_;
|
| + ScopedRunnableMethodFactory<ShouldClassifyUrlRequest> method_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ShouldClassifyUrlRequest);
|
| +};
|
| +
|
| ClientSideDetectionService::ClientSideDetectionService(
|
| const FilePath& model_path,
|
| URLRequestContextGetter* request_context_getter)
|
| @@ -47,6 +120,11 @@ ClientSideDetectionService::ClientSideDetectionService(
|
| ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
|
| ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
|
| request_context_getter_(request_context_getter) {
|
| + // Register to find out when pages begin loading into a renderer.
|
| + // When this happens, we'll start our pre-classificaton checks.
|
| + registrar_.Add(this,
|
| + NotificationType::FRAME_PROVISIONAL_LOAD_COMMITTED,
|
| + NotificationService::AllSources());
|
| }
|
|
|
| ClientSideDetectionService::~ClientSideDetectionService() {
|
| @@ -118,6 +196,32 @@ void ClientSideDetectionService::OnURLFetchComplete(
|
| }
|
| }
|
|
|
| +void ClientSideDetectionService::Observe(NotificationType type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details) {
|
| + switch (type.value) {
|
| + case NotificationType::FRAME_PROVISIONAL_LOAD_COMMITTED: {
|
| + // Check whether the load should trigger a phishing classification.
|
| + // This is true if the navigation happened in the main frame and was
|
| + // not an in-page navigation.
|
| + ProvisionalLoadDetails* load_details =
|
| + Details<ProvisionalLoadDetails>(details).ptr();
|
| +
|
| + if (load_details->main_frame() && !load_details->in_page_navigation()) {
|
| + NavigationController* controller =
|
| + Source<NavigationController>(source).ptr();
|
| + ShouldClassifyUrlRequest* request =
|
| + new ShouldClassifyUrlRequest(load_details->url(),
|
| + controller->tab_contents());
|
| + request->Start(); // the request will delete itself on completion
|
| + }
|
| + break;
|
| + }
|
| + default:
|
| + NOTREACHED();
|
| + };
|
| +}
|
| +
|
| void ClientSideDetectionService::SetModelStatus(ModelStatus status) {
|
| DCHECK_NE(READY_STATUS, model_status_);
|
| model_status_ = status;
|
|
|