// Copyright (c) 2012 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/browser/safe_browsing/download_protection_service.h"

#include <map>
#include <string>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/safe_browsing/binary_feature_extractor.h"
#include "chrome/browser/safe_browsing/database_manager.h"
#include "chrome/browser/safe_browsing/download_feedback_service.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/common/safe_browsing/csd.pb.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/mock_download_item.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "net/cert/x509_certificate.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_status.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/zlib/google/zip.h"
#include "url/gurl.h"

#if defined(OS_MACOSX)
#include "base/metrics/field_trial.h"
#include "components/variations/entropy_provider.h"
#endif

using ::testing::Assign;
using ::testing::ContainerEq;
using ::testing::DoAll;
using ::testing::ElementsAre;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SaveArg;
using ::testing::StrictMock;
using ::testing::_;
using base::MessageLoop;
using content::BrowserThread;
namespace safe_browsing {
namespace {
// A SafeBrowsingDatabaseManager implementation that returns a fixed result for
// a given URL.
class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
 public:
  explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService* service)
      : SafeBrowsingDatabaseManager(service) { }

  MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL&));
  MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string&));
  MOCK_METHOD2(CheckDownloadUrl, bool(
      const std::vector<GURL>& url_chain,
      SafeBrowsingDatabaseManager::Client* client));

 private:
  virtual ~MockSafeBrowsingDatabaseManager() {}
  DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
};

class FakeSafeBrowsingService : public SafeBrowsingService {
 public:
  FakeSafeBrowsingService() { }

  // Returned pointer has the same lifespan as the database_manager_ refcounted
  // object.
  MockSafeBrowsingDatabaseManager* mock_database_manager() {
    return mock_database_manager_;
  }

 protected:
  ~FakeSafeBrowsingService() override {}

  SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
    mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this);
    return mock_database_manager_;
  }

  void RegisterAllDelayedAnalysis() override {}

 private:
  MockSafeBrowsingDatabaseManager* mock_database_manager_;

  DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
};

class MockBinaryFeatureExtractor : public BinaryFeatureExtractor {
 public:
  MockBinaryFeatureExtractor() {}
  MOCK_METHOD2(CheckSignature, void(const base::FilePath&,
                                    ClientDownloadRequest_SignatureInfo*));
  MOCK_METHOD2(ExtractImageHeaders, void(const base::FilePath&,
                                         ClientDownloadRequest_ImageHeaders*));

 protected:
  virtual ~MockBinaryFeatureExtractor() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor);
};

class TestURLFetcherWatcher : public net::TestURLFetcherDelegateForTests {
 public:
  explicit TestURLFetcherWatcher(net::TestURLFetcherFactory* factory)
      : factory_(factory), fetcher_id_(-1) {
    factory_->SetDelegateForTests(this);
  }
  ~TestURLFetcherWatcher() {
    factory_->SetDelegateForTests(NULL);
  }

  // TestURLFetcherDelegateForTests impl:
  void OnRequestStart(int fetcher_id) override {
    fetcher_id_ = fetcher_id;
    run_loop_.Quit();
  }
  void OnChunkUpload(int fetcher_id) override {}
  void OnRequestEnd(int fetcher_id) override {}

  int WaitForRequest() {
    run_loop_.Run();
    return fetcher_id_;
  }

 private:
  net::TestURLFetcherFactory* factory_;
  int fetcher_id_;
  base::RunLoop run_loop_;
};
}  // namespace

ACTION_P(SetCertificateContents, contents) {
  arg1->add_certificate_chain()->add_element()->set_certificate(contents);
}

ACTION_P(SetDosHeaderContents, contents) {
  arg1->mutable_pe_headers()->set_dos_header(contents);
}

ACTION_P(TrustSignature, certificate_file) {
  arg1->set_trusted(true);
  // Add a certificate chain.  Note that we add the certificate twice so that
  // it appears as its own issuer.
  std::string cert_data;
  ASSERT_TRUE(base::ReadFileToString(certificate_file, &cert_data));
  ClientDownloadRequest_CertificateChain* chain =
      arg1->add_certificate_chain();
  chain->add_element()->set_certificate(cert_data);
  chain->add_element()->set_certificate(cert_data);
}

// We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does
// not have any copy constructor which means it can't be stored in a callback
// easily.  Note: check will be deleted automatically when the callback is
// deleted.
void OnSafeBrowsingResult(
    SafeBrowsingDatabaseManager::SafeBrowsingCheck* check) {
  check->client->OnSafeBrowsingResult(*check);
}

ACTION_P(CheckDownloadUrlDone, threat_type) {
  SafeBrowsingDatabaseManager::SafeBrowsingCheck* check =
      new SafeBrowsingDatabaseManager::SafeBrowsingCheck(
          arg0,
          std::vector<SBFullHash>(),
          arg1,
          safe_browsing_util::BINURL,
          std::vector<SBThreatType>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL));
  for (size_t i = 0; i < check->url_results.size(); ++i)
    check->url_results[i] = threat_type;
  BrowserThread::PostTask(BrowserThread::IO,
                          FROM_HERE,
                          base::Bind(&OnSafeBrowsingResult,
                                     base::Owned(check)));
}

class DownloadProtectionServiceTest : public testing::Test {
 protected:
  DownloadProtectionServiceTest()
      : test_browser_thread_bundle_(
            content::TestBrowserThreadBundle::IO_MAINLOOP) {
  }
  void SetUp() override {
#if defined(OS_MACOSX)
    field_trial_list_.reset(new base::FieldTrialList(
          new metrics::SHA1EntropyProvider("42")));
    ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
          "SafeBrowsingOSXClientDownloadPings",
          "Enabled"));
#endif
    // Start real threads for the IO and File threads so that the DCHECKs
    // to test that we're on the correct thread work.
    sb_service_ = new StrictMock<FakeSafeBrowsingService>();
    sb_service_->Initialize();
    binary_feature_extractor_ = new StrictMock<MockBinaryFeatureExtractor>();
    download_service_ = sb_service_->download_protection_service();
    download_service_->binary_feature_extractor_ = binary_feature_extractor_;
    download_service_->SetEnabled(true);
    client_download_request_subscription_ =
        download_service_->RegisterClientDownloadRequestCallback(
            base::Bind(&DownloadProtectionServiceTest::OnClientDownloadRequest,
                       base::Unretained(this)));
    base::RunLoop().RunUntilIdle();
    has_result_ = false;

    base::FilePath source_path;
    ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_path));
    testdata_path_ = source_path
        .AppendASCII("chrome")
        .AppendASCII("test")
        .AppendASCII("data")
        .AppendASCII("safe_browsing")
        .AppendASCII("download_protection");
  }

  void TearDown() override {
    client_download_request_subscription_.reset();
    sb_service_->ShutDown();
    // Flush all of the thread message loops to ensure that there are no
    // tasks currently running.
    FlushThreadMessageLoops();
    sb_service_ = NULL;
  }

  bool RequestContainsResource(const ClientDownloadRequest& request,
                               ClientDownloadRequest::ResourceType type,
                               const std::string& url,
                               const std::string& referrer) {
    for (int i = 0; i < request.resources_size(); ++i) {
      if (request.resources(i).url() == url &&
          request.resources(i).type() == type &&
          (referrer.empty() || request.resources(i).referrer() == referrer)) {
        return true;
      }
    }
    return false;
  }

  // At this point we only set the server IP for the download itself.
  bool RequestContainsServerIp(const ClientDownloadRequest& request,
                               const std::string& remote_address) {
    for (int i = 0; i < request.resources_size(); ++i) {
      // We want the last DOWNLOAD_URL in the chain.
      if (request.resources(i).type() == ClientDownloadRequest::DOWNLOAD_URL &&
          (i + 1 == request.resources_size() ||
           request.resources(i + 1).type() !=
           ClientDownloadRequest::DOWNLOAD_URL)) {
        return remote_address == request.resources(i).remote_ip();
      }
    }
    return false;
  }

  // Flushes any pending tasks in the message loops of all threads.
  void FlushThreadMessageLoops() {
    BrowserThread::GetBlockingPool()->FlushForTesting();
    FlushMessageLoop(BrowserThread::IO);
    base::RunLoop().RunUntilIdle();
  }

  // Proxy for private method.
  static void GetCertificateWhitelistStrings(
      const net::X509Certificate& certificate,
      const net::X509Certificate& issuer,
      std::vector<std::string>* whitelist_strings) {
    DownloadProtectionService::GetCertificateWhitelistStrings(
        certificate, issuer, whitelist_strings);
  }

  // Reads a single PEM-encoded certificate from the testdata directory.
  // Returns NULL on failure.
  scoped_refptr<net::X509Certificate> ReadTestCertificate(
      const std::string& filename) {
    std::string cert_data;
    if (!base::ReadFileToString(testdata_path_.AppendASCII(filename),
                                &cert_data)) {
      return NULL;
    }
    net::CertificateList certs =
        net::X509Certificate::CreateCertificateListFromBytes(
            cert_data.data(),
            cert_data.size(),
            net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
    return certs.empty() ? NULL : certs[0];
  }

  const ClientDownloadRequest* GetClientDownloadRequest() const {
    return last_client_download_request_.get();
  }

  bool HasClientDownloadRequest() const {
    return last_client_download_request_.get() != NULL;
  }

  void ClearClientDownloadRequest() { last_client_download_request_.reset(); }

 private:
  // Helper functions for FlushThreadMessageLoops.
  void RunAllPendingAndQuitUI() {
    base::MessageLoop::current()->RunUntilIdle();
    BrowserThread::PostTask(
        BrowserThread::UI,
        FROM_HERE,
        base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop,
                   base::Unretained(this)));
  }

  void QuitMessageLoop() {
    base::MessageLoop::current()->Quit();
  }

  void PostRunMessageLoopTask(BrowserThread::ID thread) {
    BrowserThread::PostTask(
        thread,
        FROM_HERE,
        base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI,
                   base::Unretained(this)));
  }

  void FlushMessageLoop(BrowserThread::ID thread) {
    BrowserThread::PostTask(
        BrowserThread::UI,
        FROM_HERE,
        base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask,
                   base::Unretained(this), thread));
    MessageLoop::current()->Run();
  }

  void OnClientDownloadRequest(content::DownloadItem* download,
                               const ClientDownloadRequest* request) {
    if (request)
      last_client_download_request_.reset(new ClientDownloadRequest(*request));
    else
      last_client_download_request_.reset();
  }

 public:
  void CheckDoneCallback(
      DownloadProtectionService::DownloadCheckResult result) {
    result_ = result;
    has_result_ = true;
    MessageLoop::current()->Quit();
  }

  void SyncCheckDoneCallback(
      DownloadProtectionService::DownloadCheckResult result) {
    result_ = result;
    has_result_ = true;
  }

  void SendURLFetchComplete(net::TestURLFetcher* fetcher) {
    fetcher->delegate()->OnURLFetchComplete(fetcher);
  }

  testing::AssertionResult IsResult(
      DownloadProtectionService::DownloadCheckResult expected) {
    if (!has_result_)
      return testing::AssertionFailure() << "No result";
    has_result_ = false;
    return result_ == expected ?
        testing::AssertionSuccess() :
        testing::AssertionFailure() << "Expected " << expected <<
                                       ", got " << result_;
  }

 protected:
  scoped_refptr<FakeSafeBrowsingService> sb_service_;
  scoped_refptr<MockBinaryFeatureExtractor> binary_feature_extractor_;
  DownloadProtectionService* download_service_;
  DownloadProtectionService::DownloadCheckResult result_;
  bool has_result_;
  content::TestBrowserThreadBundle test_browser_thread_bundle_;
  content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
  base::FilePath testdata_path_;
#if defined(OS_MACOSX)
  scoped_ptr<base::FieldTrialList> field_trial_list_;
#endif
  DownloadProtectionService::ClientDownloadRequestSubscription
      client_download_request_subscription_;
  scoped_ptr<ClientDownloadRequest> last_client_download_request_;
};

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) {
  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
  std::vector<GURL> url_chain;
  GURL referrer("http://www.google.com/");

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
  EXPECT_FALSE(HasClientDownloadRequest());
  Mock::VerifyAndClearExpectations(&item);

  url_chain.push_back(GURL("file://www.google.com/"));
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
  EXPECT_FALSE(HasClientDownloadRequest());
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadNotABinary) {
  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_txt(FILE_PATH_LITERAL("a.txt"));
  std::vector<GURL> url_chain;
  GURL referrer("http://www.google.com/");

  content::MockDownloadItem item;
  url_chain.push_back(GURL("http://www.example.com/foo"));
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_txt));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
  EXPECT_FALSE(HasClientDownloadRequest());
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedUrl) {
  // Response to any requests will be DANGEROUS.
  ClientDownloadResponse response;
  response.set_verdict(ClientDownloadResponse::DANGEROUS);
  net::FakeURLFetcherFactory factory(NULL);
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  std::string hash = "hash";
  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
  std::vector<GURL> url_chain;
  GURL referrer;

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
      .Times(4);
  EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
      .Times(4);

  // We should not get whilelist checks for other URLs than specified below.
  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_)).Times(0);
  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
      .WillRepeatedly(Return(true));

  // With no referrer and just the bad url, should be marked DANGEROUS.
  url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif

  // Check that the referrer is not matched against the whitelist.
  referrer = GURL("http://www.google.com/");
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif

  // Redirect from a site shouldn't be checked either.
  url_chain.insert(url_chain.begin(), GURL("http://www.google.com/redirect"));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif

  // Only if the final url is whitelisted should it be SAFE.
  url_chain.push_back(GURL("http://www.google.com/a.exe"));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_MACOSX)
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
  // TODO(grt): Make the service produce the request even when the URL is
  // whitelisted.
  EXPECT_FALSE(HasClientDownloadRequest());
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadFetchFailed) {
  net::FakeURLFetcherFactory factory(NULL);
  // HTTP request will fail.
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
      net::HTTP_INTERNAL_SERVER_ERROR, net::URLRequestStatus::FAILED);

  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/a.exe"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _));
  EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _));

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSuccess) {
  ClientDownloadResponse response;
  response.set_verdict(ClientDownloadResponse::SAFE);
  net::FakeURLFetcherFactory factory(NULL);
  // Empty response means SAFE.
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/a.exe"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
      .Times(6);
  EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
      .Times(6);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#else
  // On !OS_WIN, no file types are currently supported. Hence all requests to
  // CheckClientDownload() result in a verdict of UNKNOWN.
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif

  // Invalid response should result in UNKNOWN.
  response.Clear();
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializePartialAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#if defined(OS_WIN) || defined(OS_MACOSX)
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif
  std::string feedback_ping;
  std::string feedback_response;
  EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
      item, &feedback_ping, &feedback_response));

  // If the response is dangerous the result should also be marked as dangerous.
  response.set_verdict(ClientDownloadResponse::DANGEROUS);
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
      item, &feedback_ping, &feedback_response));
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif

  // If the response is uncommon the result should also be marked as uncommon.
  response.set_verdict(ClientDownloadResponse::UNCOMMON);
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON));
  EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
      item, &feedback_ping, &feedback_response));
  ClientDownloadRequest decoded_request;
  EXPECT_TRUE(decoded_request.ParseFromString(feedback_ping));
  EXPECT_EQ(url_chain.back().spec(), decoded_request.url());
  EXPECT_EQ(response.SerializeAsString(), feedback_response);
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

  // If the response is dangerous_host the result should also be marked as
  // dangerous_host.
  response.set_verdict(ClientDownloadResponse::DANGEROUS_HOST);
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST));
  EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
      item, &feedback_ping, &feedback_response));
  EXPECT_EQ(response.SerializeAsString(), feedback_response);
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

  // If the response is POTENTIALLY_UNWANTED the result should also be marked as
  // POTENTIALLY_UNWANTED.
  response.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED);
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadHTTPS) {
  ClientDownloadResponse response;
  response.set_verdict(ClientDownloadResponse::DANGEROUS);
  net::FakeURLFetcherFactory factory(NULL);
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/a.exe"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
      .Times(1);
  EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
      .Times(1);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadBlob) {
  ClientDownloadResponse response;
  response.set_verdict(ClientDownloadResponse::DANGEROUS);
  net::FakeURLFetcherFactory factory(NULL);
  factory.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
                          response.SerializeAsString(), net::HTTP_OK,
                          net::URLRequestStatus::SUCCESS);

  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(
      GURL("blob:http://www.evil.com/50b85f60-71e4-11e4-82f8-0800200c9a66"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_)).WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
      .Times(1);
  EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
      .Times(1);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadData) {
  ClientDownloadResponse response;
  response.set_verdict(ClientDownloadResponse::DANGEROUS);
  net::FakeURLFetcherFactory factory(NULL);
  factory.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
                          response.SerializeAsString(), net::HTTP_OK,
                          net::URLRequestStatus::SUCCESS);

  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(
      GURL("data:text/html:base64,"));
  url_chain.push_back(
      GURL("data:text/html:base64,blahblahblah"));
  url_chain.push_back(
      GURL("data:application/octet-stream:base64,blahblah"));
  GURL referrer("data:text/html:base64,foobar");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_)).WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
      .Times(1);
  EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
      .Times(1);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  ASSERT_TRUE(HasClientDownloadRequest());
  const ClientDownloadRequest& request = *GetClientDownloadRequest();
  const char kExpectedUrl[] =
      "data:application/octet-stream:base64,"
      "ACBF6DFC6F907662F566CA0241DFE8690C48661F440BA1BBD0B86C582845CCC8";
  const char kExpectedRedirect1[] = "data:text/html:base64,";
  const char kExpectedRedirect2[] =
      "data:text/html:base64,"
      "620680767E15717A57DB11D94D1BEBD32B3344EBC5994DF4FB07B0D473F4EF6B";
  const char kExpectedReferrer[] =
      "data:text/html:base64,"
      "06E2C655B9F7130B508FFF86FD19B57E6BF1A1CFEFD6EFE1C3EB09FE24EF456A";
  EXPECT_EQ(hash, request.digests().sha256());
  EXPECT_EQ(kExpectedUrl, request.url());
  EXPECT_EQ(3, request.resources_size());
  EXPECT_TRUE(RequestContainsResource(request,
                                      ClientDownloadRequest::DOWNLOAD_REDIRECT,
                                      kExpectedRedirect1, ""));
  EXPECT_TRUE(RequestContainsResource(request,
                                      ClientDownloadRequest::DOWNLOAD_REDIRECT,
                                      kExpectedRedirect2, ""));
  EXPECT_TRUE(RequestContainsResource(request,
                                      ClientDownloadRequest::DOWNLOAD_URL,
                                      kExpectedUrl, kExpectedReferrer));
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) {
  ClientDownloadResponse response;
  response.set_verdict(ClientDownloadResponse::SAFE);
  net::FakeURLFetcherFactory factory(NULL);
  // Empty response means SAFE.
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  base::ScopedTempDir download_dir;
  ASSERT_TRUE(download_dir.CreateUniqueTempDir());

  base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
  base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/a.zip"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  // Write out a zip archive to the temporary file.  In this case, it
  // only contains a text file.
  base::ScopedTempDir zip_source_dir;
  ASSERT_TRUE(zip_source_dir.CreateUniqueTempDir());
  std::string file_contents = "dummy file";
  ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
      zip_source_dir.path().Append(FILE_PATH_LITERAL("file.txt")),
      file_contents.data(), file_contents.size()));
  ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
  EXPECT_FALSE(HasClientDownloadRequest());
  Mock::VerifyAndClearExpectations(sb_service_.get());
  Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());

  // Now check with an executable in the zip file as well.
  ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
      zip_source_dir.path().Append(FILE_PATH_LITERAL("file.exe")),
      file_contents.data(), file_contents.size()));
  ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#else
  // For !OS_WIN, no file types are currently supported. Hence the resulting
  // verdict is UNKNOWN.
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif
  Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());

  // If the response is dangerous the result should also be marked as
  // dangerous.
  response.set_verdict(ClientDownloadResponse::DANGEROUS);
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
#if defined(OS_WIN)
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#endif

#if defined(OS_WIN) || defined(OS_MACOSX)
  // OSX sends pings for evaluation purposes.
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif
  Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
}

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadCorruptZip) {
  base::ScopedTempDir download_dir;
  ASSERT_TRUE(download_dir.CreateUniqueTempDir());

  base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
  base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/a.zip"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  std::string file_contents = "corrupt zip file";
  ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
      a_tmp, file_contents.data(), file_contents.size()));

  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
  EXPECT_FALSE(HasClientDownloadRequest());
  Mock::VerifyAndClearExpectations(sb_service_.get());
  Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
}

TEST_F(DownloadProtectionServiceTest, CheckClientCrxDownloadSuccess) {
  ClientDownloadResponse response;
  // Even if the server verdict is dangerous we should return SAFE because
  // DownloadProtectionService::IsSupportedDownload() will return false
  // for crx downloads.
  response.set_verdict(ClientDownloadResponse::DANGEROUS);
  net::FakeURLFetcherFactory factory(NULL);
  // Empty response means SAFE.
  factory.SetFakeResponse(
      DownloadProtectionService::GetDownloadRequestUrl(),
      response.SerializeAsString(),
      net::HTTP_OK, net::URLRequestStatus::SUCCESS);

  base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath a_crx(FILE_PATH_LITERAL("a.crx"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/a.crx"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
      .Times(1);
  EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
      .Times(1);

  EXPECT_FALSE(download_service_->IsSupportedDownload(item, a_crx));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
}

#if defined(OS_MACOSX)
// TODO(mattm): remove this (see crbug.com/414834).
TEST_F(DownloadProtectionServiceTest,
       CheckClientDownloadPingOnOSXRequiresFieldTrial) {
  // Clear the field trial that was set in SetUp().
  field_trial_list_.reset();

  net::TestURLFetcherFactory factory;

  base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
  base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.google.com/"));
  url_chain.push_back(GURL("http://www.google.com/bla.exe"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";
  std::string remote_address = "10.11.12.13";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
      .WillOnce(SetCertificateContents("dummy cert data"));
  EXPECT_CALL(*binary_feature_extractor_.get(),
              ExtractImageHeaders(tmp_path, _))
      .WillOnce(SetDosHeaderContents("dummy dos header"));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));

  // SendRequest is not called.  Wait for FinishRequest to call our callback.
  MessageLoop::current()->Run();
  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
  EXPECT_EQ(NULL, fetcher);
  EXPECT_FALSE(HasClientDownloadRequest());
}
#endif

TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) {
  net::TestURLFetcherFactory factory;

  base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
  base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.google.com/"));
  url_chain.push_back(GURL("http://www.google.com/bla.exe"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";
  std::string remote_address = "10.11.12.13";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
      .WillOnce(SetCertificateContents("dummy cert data"));
  EXPECT_CALL(*binary_feature_extractor_.get(),
              ExtractImageHeaders(tmp_path, _))
      .WillOnce(SetDosHeaderContents("dummy dos header"));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));

#if !defined(OS_WIN) && !defined(OS_MACOSX)
  // SendRequest is not called.  Wait for FinishRequest to call our callback.
  MessageLoop::current()->Run();
  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
  EXPECT_EQ(NULL, fetcher);
  EXPECT_FALSE(HasClientDownloadRequest());
#else
  // Run the message loop(s) until SendRequest is called.
  FlushThreadMessageLoops();
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
  ASSERT_TRUE(fetcher);
  ClientDownloadRequest request;
  EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
  EXPECT_EQ("http://www.google.com/bla.exe", request.url());
  EXPECT_EQ(hash, request.digests().sha256());
  EXPECT_EQ(item.GetReceivedBytes(), request.length());
  EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
  EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
  EXPECT_EQ(2, request.resources_size());
  EXPECT_TRUE(RequestContainsResource(request,
                                      ClientDownloadRequest::DOWNLOAD_REDIRECT,
                                      "http://www.google.com/", ""));
  EXPECT_TRUE(RequestContainsResource(request,
                                      ClientDownloadRequest::DOWNLOAD_URL,
                                      "http://www.google.com/bla.exe",
                                      referrer.spec()));
  EXPECT_TRUE(request.has_signature());
  ASSERT_EQ(1, request.signature().certificate_chain_size());
  const ClientDownloadRequest_CertificateChain& chain =
      request.signature().certificate_chain(0);
  ASSERT_EQ(1, chain.element_size());
  EXPECT_EQ("dummy cert data", chain.element(0).certificate());
  EXPECT_TRUE(request.has_image_headers());
  const ClientDownloadRequest_ImageHeaders& headers =
      request.image_headers();
  EXPECT_TRUE(headers.has_pe_headers());
  EXPECT_TRUE(headers.pe_headers().has_dos_header());
  EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());

  // Simulate the request finishing.
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
                 base::Unretained(this), fetcher));
  MessageLoop::current()->Run();
#endif
}

// Similar to above, but with an unsigned binary.
TEST_F(DownloadProtectionServiceTest,
       CheckClientDownloadValidateRequestNoSignature) {
  net::TestURLFetcherFactory factory;

  base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
  base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.google.com/"));
  url_chain.push_back(GURL("ftp://www.google.com/bla.exe"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";
  std::string remote_address = "10.11.12.13";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
  EXPECT_CALL(*binary_feature_extractor_.get(),
              ExtractImageHeaders(tmp_path, _));
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));

#if !defined(OS_WIN) && !defined(OS_MACOSX)
  // SendRequest is not called.  Wait for FinishRequest to call our callback.
  MessageLoop::current()->Run();
  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
  EXPECT_EQ(NULL, fetcher);
  EXPECT_FALSE(HasClientDownloadRequest());
#else
  // Run the message loop(s) until SendRequest is called.
  FlushThreadMessageLoops();
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
  ASSERT_TRUE(fetcher);
  ClientDownloadRequest request;
  EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
  EXPECT_EQ("ftp://www.google.com/bla.exe", request.url());
  EXPECT_EQ(hash, request.digests().sha256());
  EXPECT_EQ(item.GetReceivedBytes(), request.length());
  EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
  EXPECT_EQ(2, request.resources_size());
  EXPECT_TRUE(RequestContainsResource(request,
                                      ClientDownloadRequest::DOWNLOAD_REDIRECT,
                                      "http://www.google.com/", ""));
  EXPECT_TRUE(RequestContainsResource(request,
                                      ClientDownloadRequest::DOWNLOAD_URL,
                                      "ftp://www.google.com/bla.exe",
                                      referrer.spec()));
  EXPECT_TRUE(request.has_signature());
  EXPECT_EQ(0, request.signature().certificate_chain_size());

  // Simulate the request finishing.
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
                 base::Unretained(this), fetcher));
  MessageLoop::current()->Run();
#endif
}

// Similar to above, but with tab history.
TEST_F(DownloadProtectionServiceTest,
       CheckClientDownloadValidateRequestTabHistory) {
  net::TestURLFetcherFactory factory;

  base::ScopedTempDir profile_dir;
  ASSERT_TRUE(profile_dir.CreateUniqueTempDir());
  TestingProfile profile(profile_dir.path());
  ASSERT_TRUE(
      profile.CreateHistoryService(true /* delete_file */, false /* no_db */));

  base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
  base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.google.com/"));
  url_chain.push_back(GURL("http://www.google.com/bla.exe"));
  GURL referrer("http://www.google.com/");
  GURL tab_url("http://tab.com/final");
  GURL tab_referrer("http://tab.com/referrer");
  std::string hash = "hash";
  std::string remote_address = "10.11.12.13";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(tab_referrer));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
  EXPECT_CALL(item, GetBrowserContext()).WillRepeatedly(Return(&profile));
  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
      .WillRepeatedly(SetCertificateContents("dummy cert data"));
  EXPECT_CALL(*binary_feature_extractor_.get(),
              ExtractImageHeaders(tmp_path, _))
      .WillRepeatedly(SetDosHeaderContents("dummy dos header"));

  // First test with no history match for the tab URL.
  {
    TestURLFetcherWatcher fetcher_watcher(&factory);
    download_service_->CheckClientDownload(
        &item,
        base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                   base::Unretained(this)));

#if !defined(OS_WIN) && !defined(OS_MACOSX)
    // SendRequest is not called.  Wait for FinishRequest to call our callback.
    MessageLoop::current()->Run();
    net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
    EXPECT_EQ(NULL, fetcher);
    EXPECT_FALSE(HasClientDownloadRequest());
#else
    EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
    EXPECT_TRUE(HasClientDownloadRequest());
    ClearClientDownloadRequest();
    net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
    ASSERT_TRUE(fetcher);
    ClientDownloadRequest request;
    EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
    EXPECT_EQ("http://www.google.com/bla.exe", request.url());
    EXPECT_EQ(hash, request.digests().sha256());
    EXPECT_EQ(item.GetReceivedBytes(), request.length());
    EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
    EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
    EXPECT_EQ(3, request.resources_size());
    EXPECT_TRUE(
        RequestContainsResource(request,
                                ClientDownloadRequest::DOWNLOAD_REDIRECT,
                                "http://www.google.com/",
                                ""));
    EXPECT_TRUE(RequestContainsResource(request,
                                        ClientDownloadRequest::DOWNLOAD_URL,
                                        "http://www.google.com/bla.exe",
                                        referrer.spec()));
    EXPECT_TRUE(RequestContainsResource(request,
                                        ClientDownloadRequest::TAB_URL,
                                        tab_url.spec(),
                                        tab_referrer.spec()));
    EXPECT_TRUE(request.has_signature());
    ASSERT_EQ(1, request.signature().certificate_chain_size());
    const ClientDownloadRequest_CertificateChain& chain =
        request.signature().certificate_chain(0);
    ASSERT_EQ(1, chain.element_size());
    EXPECT_EQ("dummy cert data", chain.element(0).certificate());
    EXPECT_TRUE(request.has_image_headers());
    const ClientDownloadRequest_ImageHeaders& headers =
        request.image_headers();
    EXPECT_TRUE(headers.has_pe_headers());
    EXPECT_TRUE(headers.pe_headers().has_dos_header());
    EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());

    // Simulate the request finishing.
    base::MessageLoop::current()->PostTask(
        FROM_HERE,
        base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
                   base::Unretained(this),
                   fetcher));
    MessageLoop::current()->Run();
#endif
  }

  // Now try with a history match.
  {
    history::RedirectList redirects;
    redirects.push_back(GURL("http://tab.com/ref1"));
    redirects.push_back(GURL("http://tab.com/ref2"));
    redirects.push_back(tab_url);
    HistoryServiceFactory::GetForProfile(&profile, Profile::EXPLICIT_ACCESS)
        ->AddPage(tab_url,
                  base::Time::Now(),
                  reinterpret_cast<history::ContextID>(1),
                  0,
                  GURL(),
                  redirects,
                  ui::PAGE_TRANSITION_TYPED,
                  history::SOURCE_BROWSED,
                  false);

    TestURLFetcherWatcher fetcher_watcher(&factory);
    download_service_->CheckClientDownload(
        &item,
        base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                   base::Unretained(this)));
#if !defined(OS_WIN) && !defined(OS_MACOSX)
    // SendRequest is not called.  Wait for FinishRequest to call our callback.
    MessageLoop::current()->Run();
    net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
    EXPECT_EQ(NULL, fetcher);
    EXPECT_FALSE(HasClientDownloadRequest());
#else
    EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
    EXPECT_TRUE(HasClientDownloadRequest());
    ClearClientDownloadRequest();
    net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
    ASSERT_TRUE(fetcher);
    ClientDownloadRequest request;
    EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
    EXPECT_EQ("http://www.google.com/bla.exe", request.url());
    EXPECT_EQ(hash, request.digests().sha256());
    EXPECT_EQ(item.GetReceivedBytes(), request.length());
    EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
    EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
    EXPECT_EQ(5, request.resources_size());
    EXPECT_TRUE(
        RequestContainsResource(request,
                                ClientDownloadRequest::DOWNLOAD_REDIRECT,
                                "http://www.google.com/",
                                ""));
    EXPECT_TRUE(RequestContainsResource(request,
                                        ClientDownloadRequest::DOWNLOAD_URL,
                                        "http://www.google.com/bla.exe",
                                        referrer.spec()));
    EXPECT_TRUE(RequestContainsResource(request,
                                        ClientDownloadRequest::TAB_REDIRECT,
                                        "http://tab.com/ref1",
                                        ""));
    EXPECT_TRUE(RequestContainsResource(request,
                                        ClientDownloadRequest::TAB_REDIRECT,
                                        "http://tab.com/ref2",
                                        ""));
    EXPECT_TRUE(RequestContainsResource(request,
                                        ClientDownloadRequest::TAB_URL,
                                        tab_url.spec(),
                                        tab_referrer.spec()));
    EXPECT_TRUE(request.has_signature());
    ASSERT_EQ(1, request.signature().certificate_chain_size());
    const ClientDownloadRequest_CertificateChain& chain =
        request.signature().certificate_chain(0);
    ASSERT_EQ(1, chain.element_size());
    EXPECT_EQ("dummy cert data", chain.element(0).certificate());

    // Simulate the request finishing.
    base::MessageLoop::current()->PostTask(
        FROM_HERE,
        base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
                   base::Unretained(this),
                   fetcher));
    MessageLoop::current()->Run();
#endif
  }
}

TEST_F(DownloadProtectionServiceTest, TestCheckDownloadUrl) {
  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.google.com/"));
  url_chain.push_back(GURL("http://www.google.com/bla.exe"));
  GURL referrer("http://www.google.com/");
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));

  // CheckDownloadURL returns immediately which means the client object callback
  // will never be called.  Nevertheless the callback provided to
  // CheckClientDownload must still be called.
  EXPECT_CALL(*sb_service_->mock_database_manager(),
              CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
      .WillOnce(Return(true));
  download_service_->CheckDownloadUrl(
      item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
  Mock::VerifyAndClearExpectations(sb_service_.get());

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
      .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE),
                      Return(false)));
  download_service_->CheckDownloadUrl(
      item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
  Mock::VerifyAndClearExpectations(sb_service_.get());

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
      .WillOnce(DoAll(
          CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE),
          Return(false)));
  download_service_->CheckDownloadUrl(
      item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
  Mock::VerifyAndClearExpectations(sb_service_.get());

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              CheckDownloadUrl(ContainerEq(url_chain),
                               NotNull()))
      .WillOnce(DoAll(
          CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL),
          Return(false)));
  download_service_->CheckDownloadUrl(
      item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
}

TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) {
  net::TestURLFetcherFactory factory;

  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
  GURL referrer("http://www.google.com/");
  base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
  std::string hash = "hash";

  content::MockDownloadItem item;
  EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
  EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
  EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
  EXPECT_CALL(*binary_feature_extractor_.get(),
              ExtractImageHeaders(tmp_path, _));

  download_service_->download_request_timeout_ms_ = 10;
  download_service_->CheckClientDownload(
      &item,
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));

  // The request should time out because the HTTP request hasn't returned
  // anything yet.
  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
#if defined(OS_WIN) || defined(OS_MACOSX)
  EXPECT_TRUE(HasClientDownloadRequest());
  ClearClientDownloadRequest();
#else
  EXPECT_FALSE(HasClientDownloadRequest());
#endif
}

TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) {
  net::TestURLFetcherFactory factory;

  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
  GURL referrer("http://www.google.com/");
  GURL tab_url("http://www.google.com/tab");
  base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
  std::string hash = "hash";

  {
    content::MockDownloadItem item;
    EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
    EXPECT_CALL(item, GetTargetFilePath())
        .WillRepeatedly(ReturnRef(final_path));
    EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
    EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
    EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
    EXPECT_CALL(item, GetTabReferrerUrl())
        .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
    EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
    EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
    EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
    EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));

    EXPECT_CALL(*sb_service_->mock_database_manager(),
                MatchDownloadWhitelistUrl(_))
        .WillRepeatedly(Return(false));
    EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
    EXPECT_CALL(*binary_feature_extractor_.get(),
                ExtractImageHeaders(tmp_path, _));

    download_service_->CheckClientDownload(
        &item,
        base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback,
                   base::Unretained(this)));
    // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
    // notification.
  }

  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
  EXPECT_FALSE(HasClientDownloadRequest());
}

TEST_F(DownloadProtectionServiceTest,
       TestDownloadItemDestroyedDuringWhitelistCheck) {
  net::TestURLFetcherFactory factory;

  std::vector<GURL> url_chain;
  url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
  GURL referrer("http://www.google.com/");
  GURL tab_url("http://www.google.com/tab");
  base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
  base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
  std::string hash = "hash";

  scoped_ptr<content::MockDownloadItem> item(new content::MockDownloadItem);
  EXPECT_CALL(*item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
  EXPECT_CALL(*item, GetTargetFilePath())
      .WillRepeatedly(ReturnRef(final_path));
  EXPECT_CALL(*item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
  EXPECT_CALL(*item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
  EXPECT_CALL(*item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
  EXPECT_CALL(*item, GetTabReferrerUrl())
      .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
  EXPECT_CALL(*item, GetHash()).WillRepeatedly(ReturnRef(hash));
  EXPECT_CALL(*item, GetReceivedBytes()).WillRepeatedly(Return(100));
  EXPECT_CALL(*item, HasUserGesture()).WillRepeatedly(Return(true));
  EXPECT_CALL(*item, GetRemoteAddress()).WillRepeatedly(Return(""));

  EXPECT_CALL(*sb_service_->mock_database_manager(),
              MatchDownloadWhitelistUrl(_))
      .WillRepeatedly(Invoke([&item](const GURL&) {
        item.reset();
        return false;
      }));
  EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
  EXPECT_CALL(*binary_feature_extractor_.get(),
              ExtractImageHeaders(tmp_path, _));

  download_service_->CheckClientDownload(
      item.get(),
      base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                 base::Unretained(this)));

  MessageLoop::current()->Run();
  EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
  EXPECT_FALSE(HasClientDownloadRequest());
}

TEST_F(DownloadProtectionServiceTest, GetCertificateWhitelistStrings) {
  // We'll pass this cert in as the "issuer", even though it isn't really
  // used to sign the certs below.  GetCertificateWhitelistStirngs doesn't care
  // about this.
  scoped_refptr<net::X509Certificate> issuer_cert(
      ReadTestCertificate("issuer.pem"));
  ASSERT_TRUE(issuer_cert.get());
  std::string cert_base = "cert/" + base::HexEncode(
      issuer_cert->fingerprint().data,
      sizeof(issuer_cert->fingerprint().data));

  scoped_refptr<net::X509Certificate> cert(ReadTestCertificate("test_cn.pem"));
  ASSERT_TRUE(cert.get());
  std::vector<std::string> whitelist_strings;
  GetCertificateWhitelistStrings(
      *cert.get(), *issuer_cert.get(), &whitelist_strings);
  // This also tests escaping of characters in the certificate attributes.
  EXPECT_THAT(whitelist_strings, ElementsAre(
      cert_base + "/CN=subject%2F%251"));

  cert = ReadTestCertificate("test_cn_o.pem");
  ASSERT_TRUE(cert.get());
  whitelist_strings.clear();
  GetCertificateWhitelistStrings(
      *cert.get(), *issuer_cert.get(), &whitelist_strings);
  EXPECT_THAT(whitelist_strings,
              ElementsAre(cert_base + "/CN=subject",
                          cert_base + "/CN=subject/O=org",
                          cert_base + "/O=org"));

  cert = ReadTestCertificate("test_cn_o_ou.pem");
  ASSERT_TRUE(cert.get());
  whitelist_strings.clear();
  GetCertificateWhitelistStrings(
      *cert.get(), *issuer_cert.get(), &whitelist_strings);
  EXPECT_THAT(whitelist_strings,
              ElementsAre(cert_base + "/CN=subject",
                          cert_base + "/CN=subject/O=org",
                          cert_base + "/CN=subject/O=org/OU=unit",
                          cert_base + "/CN=subject/OU=unit",
                          cert_base + "/O=org",
                          cert_base + "/O=org/OU=unit",
                          cert_base + "/OU=unit"));

  cert = ReadTestCertificate("test_cn_ou.pem");
  ASSERT_TRUE(cert.get());
  whitelist_strings.clear();
  GetCertificateWhitelistStrings(
      *cert.get(), *issuer_cert.get(), &whitelist_strings);
  EXPECT_THAT(whitelist_strings,
              ElementsAre(cert_base + "/CN=subject",
                          cert_base + "/CN=subject/OU=unit",
                          cert_base + "/OU=unit"));

  cert = ReadTestCertificate("test_o.pem");
  ASSERT_TRUE(cert.get());
  whitelist_strings.clear();
  GetCertificateWhitelistStrings(
      *cert.get(), *issuer_cert.get(), &whitelist_strings);
  EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/O=org"));

  cert = ReadTestCertificate("test_o_ou.pem");
  ASSERT_TRUE(cert.get());
  whitelist_strings.clear();
  GetCertificateWhitelistStrings(
      *cert.get(), *issuer_cert.get(), &whitelist_strings);
  EXPECT_THAT(whitelist_strings,
              ElementsAre(cert_base + "/O=org",
                          cert_base + "/O=org/OU=unit",
                          cert_base + "/OU=unit"));

  cert = ReadTestCertificate("test_ou.pem");
  ASSERT_TRUE(cert.get());
  whitelist_strings.clear();
  GetCertificateWhitelistStrings(
      *cert.get(), *issuer_cert.get(), &whitelist_strings);
  EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/OU=unit"));

  cert = ReadTestCertificate("test_c.pem");
  ASSERT_TRUE(cert.get());
  whitelist_strings.clear();
  GetCertificateWhitelistStrings(
      *cert.get(), *issuer_cert.get(), &whitelist_strings);
  EXPECT_THAT(whitelist_strings, ElementsAre());
}
}  // namespace safe_browsing
