Home | History | Annotate | Download | only in safe_browsing
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // Implementation of the MalwareDetailsRedirectsCollector class.
      6 
      7 #include "chrome/browser/safe_browsing/malware_details_history.h"
      8 
      9 #include "base/bind.h"
     10 #include "base/bind_helpers.h"
     11 #include "chrome/browser/chrome_notification_types.h"
     12 #include "chrome/browser/history/history_service_factory.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/browser/safe_browsing/malware_details.h"
     15 #include "content/public/browser/browser_thread.h"
     16 #include "content/public/browser/notification_details.h"
     17 #include "content/public/browser/notification_source.h"
     18 #include "content/public/browser/render_view_host.h"
     19 #include "content/public/browser/web_contents.h"
     20 
     21 using content::BrowserThread;
     22 
     23 MalwareDetailsRedirectsCollector::MalwareDetailsRedirectsCollector(
     24     Profile* profile)
     25     : profile_(profile),
     26       has_started_(false) {
     27   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     28   if (profile) {
     29     registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
     30                    content::Source<Profile>(profile));
     31   }
     32 }
     33 
     34 void MalwareDetailsRedirectsCollector::StartHistoryCollection(
     35     const std::vector<GURL>& urls,
     36     const base::Closure& callback) {
     37   DVLOG(1) << "Num of urls to check in history service: " << urls.size();
     38   has_started_ = true;
     39   callback_ = callback;
     40 
     41   if (urls.size() == 0) {
     42     AllDone();
     43     return;
     44   }
     45 
     46   BrowserThread::PostTask(
     47       BrowserThread::UI, FROM_HERE,
     48       base::Bind(&MalwareDetailsRedirectsCollector::StartGetRedirects,
     49                  this, urls));
     50 }
     51 
     52 bool MalwareDetailsRedirectsCollector::HasStarted() const {
     53   return has_started_;
     54 }
     55 
     56 const std::vector<safe_browsing::RedirectChain>&
     57 MalwareDetailsRedirectsCollector::GetCollectedUrls() const {
     58   return redirects_urls_;
     59 }
     60 
     61 void MalwareDetailsRedirectsCollector::Observe(
     62     int type,
     63     const content::NotificationSource& source,
     64     const content::NotificationDetails& details) {
     65   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     66   DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_DESTROYED);
     67   DVLOG(1) << "Profile gone.";
     68   profile_ = NULL;
     69 }
     70 
     71 MalwareDetailsRedirectsCollector::~MalwareDetailsRedirectsCollector() {}
     72 
     73 void MalwareDetailsRedirectsCollector::StartGetRedirects(
     74         const std::vector<GURL>& urls) {
     75   // History access from profile needs to happen in UI thread
     76   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     77   for (size_t i = 0; i < urls.size(); ++i) {
     78     urls_.push_back(urls[i]);
     79   }
     80   urls_it_ = urls_.begin();
     81   GetRedirects(*urls_it_);
     82 }
     83 
     84 void MalwareDetailsRedirectsCollector::GetRedirects(const GURL& url) {
     85   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     86   if (!profile_) {
     87     AllDone();
     88     return;
     89   }
     90 
     91   HistoryService* history = HistoryServiceFactory::GetForProfile(
     92       profile_, Profile::EXPLICIT_ACCESS);
     93   if (!history) {
     94     AllDone();
     95     return;
     96   }
     97 
     98   history->QueryRedirectsTo(
     99       url,
    100       &request_consumer_,
    101       base::Bind(&MalwareDetailsRedirectsCollector::OnGotQueryRedirectsTo,
    102                  base::Unretained(this)));
    103 }
    104 
    105 void MalwareDetailsRedirectsCollector::OnGotQueryRedirectsTo(
    106     HistoryService::Handle handle,
    107     GURL url,
    108     bool success,
    109     history::RedirectList* redirect_list) {
    110 
    111   if (success && redirect_list->size() > 0) {
    112     std::vector<GURL> urllist;
    113     urllist.push_back(url);
    114     for (size_t i = 0; i < redirect_list->size(); i++) {
    115       urllist.push_back(redirect_list->at(i));
    116     }
    117     redirects_urls_.push_back(urllist);
    118   }
    119 
    120   // Proceed to next url
    121   ++urls_it_;
    122 
    123   if (urls_it_ == urls_.end()) {
    124     AllDone();
    125     return;
    126   }
    127 
    128   GetRedirects(*urls_it_);
    129 }
    130 
    131 void MalwareDetailsRedirectsCollector::AllDone() {
    132   DVLOG(1) << "AllDone";
    133   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback_);
    134   callback_.Reset();
    135 }
    136