diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-25 07:31:08 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-25 07:31:08 +0000 |
commit | 7b9eec4beea8695c45bc779b3f84d20afd000a45 (patch) | |
tree | e738d3acf59d58d7bbe4ab47fd9da642112e3142 /chrome/browser/safe_browsing | |
parent | 15c08533b0673aecd9e5ff2af113b37ea26df728 (diff) | |
download | chromium_src-7b9eec4beea8695c45bc779b3f84d20afd000a45.zip chromium_src-7b9eec4beea8695c45bc779b3f84d20afd000a45.tar.gz chromium_src-7b9eec4beea8695c45bc779b3f84d20afd000a45.tar.bz2 |
Safebrowsing download protection: include tab url chain & referrer.
BUG=342617
Review URL: https://codereview.chromium.org/191463002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@259174 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/safe_browsing')
-rw-r--r-- | chrome/browser/safe_browsing/download_protection_service.cc | 74 | ||||
-rw-r--r-- | chrome/browser/safe_browsing/download_protection_service_unittest.cc | 247 |
2 files changed, 320 insertions, 1 deletions
diff --git a/chrome/browser/safe_browsing/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection_service.cc index 26d79f5..3147598 100644 --- a/chrome/browser/safe_browsing/download_protection_service.cc +++ b/chrome/browser/safe_browsing/download_protection_service.cc @@ -18,6 +18,8 @@ #include "base/strings/stringprintf.h" #include "base/threading/sequenced_worker_pool.h" #include "base/time/time.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/download_feedback_service.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" @@ -284,6 +286,8 @@ class DownloadProtectionService::CheckClientDownloadRequest : item_(item), url_chain_(item->GetUrlChain()), referrer_url_(item->GetReferrerUrl()), + tab_url_(item->GetTabUrl()), + tab_referrer_url_(item->GetTabReferrerUrl()), zipped_executable_(false), callback_(callback), service_(service), @@ -602,13 +606,53 @@ class DownloadProtectionService::CheckClientDownloadRequest BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&CheckClientDownloadRequest::SendRequest, this)); + base::Bind(&CheckClientDownloadRequest::GetTabRedirects, this)); #else PostFinishTask(SAFE, REASON_OS_NOT_SUPPORTED); #endif } } + void GetTabRedirects() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!tab_url_.is_valid()) { + SendRequest(); + return; + } + + Profile* profile = Profile::FromBrowserContext(item_->GetBrowserContext()); + HistoryService* history = + HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS); + if (!history) { + SendRequest(); + return; + } + + history->QueryRedirectsTo( + tab_url_, + &request_consumer_, + base::Bind(&CheckClientDownloadRequest::OnGotTabRedirects, + base::Unretained(this))); + } + + void OnGotTabRedirects(HistoryService::Handle handle, + GURL url, + bool success, + history::RedirectList* redirect_list) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK_EQ(url, tab_url_); + + if (success && redirect_list->size() > 0) { + for (history::RedirectList::reverse_iterator i = redirect_list->rbegin(); + i != redirect_list->rend(); + ++i) { + tab_redirects_.push_back(*i); + } + } + + SendRequest(); + } + void SendRequest() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -628,14 +672,36 @@ class DownloadProtectionService::CheckClientDownloadRequest // The last URL in the chain is the download URL. resource->set_type(ClientDownloadRequest::DOWNLOAD_URL); resource->set_referrer(item_->GetReferrerUrl().spec()); + DVLOG(2) << "dl url " << resource->url(); if (!item_->GetRemoteAddress().empty()) { resource->set_remote_ip(item_->GetRemoteAddress()); + DVLOG(2) << " dl url remote addr: " << resource->remote_ip(); } + DVLOG(2) << "dl referrer " << resource->referrer(); } else { + DVLOG(2) << "dl redirect " << i << " " << resource->url(); resource->set_type(ClientDownloadRequest::DOWNLOAD_REDIRECT); } // TODO(noelutz): fill out the remote IP addresses. } + // TODO(mattm): fill out the remote IP addresses for tab resources. + for (size_t i = 0; i < tab_redirects_.size(); ++i) { + ClientDownloadRequest::Resource* resource = request.add_resources(); + DVLOG(2) << "tab redirect " << i << " " << tab_redirects_[i].spec(); + resource->set_url(tab_redirects_[i].spec()); + resource->set_type(ClientDownloadRequest::TAB_REDIRECT); + } + if (tab_url_.is_valid()) { + ClientDownloadRequest::Resource* resource = request.add_resources(); + resource->set_url(tab_url_.spec()); + DVLOG(2) << "tab url " << resource->url(); + resource->set_type(ClientDownloadRequest::TAB_URL); + if (tab_referrer_url_.is_valid()) { + resource->set_referrer(tab_referrer_url_.spec()); + DVLOG(2) << "tab referrer " << resource->referrer(); + } + } + request.set_user_initiated(item_->HasUserGesture()); request.set_file_basename( item_->GetTargetFilePath().BaseName().AsUTF8Unsafe()); @@ -747,6 +813,11 @@ class DownloadProtectionService::CheckClientDownloadRequest // Copies of data from |item_| for access on other threads. std::vector<GURL> url_chain_; GURL referrer_url_; + // URL chain of redirects leading to (but not including) |tab_url|. + std::vector<GURL> tab_redirects_; + // URL and referrer of the window the download was started from. + GURL tab_url_; + GURL tab_referrer_url_; bool zipped_executable_; ClientDownloadRequest_SignatureInfo signature_info_; @@ -762,6 +833,7 @@ class DownloadProtectionService::CheckClientDownloadRequest bool finished_; ClientDownloadRequest::DownloadType type_; std::string client_download_request_data_; + CancelableRequestConsumer request_consumer_; // For HistoryService lookup. base::WeakPtrFactory<CheckClientDownloadRequest> weakptr_factory_; base::TimeTicks start_time_; // Used for stats. diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc index bfd903e..df63d32 100644 --- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc @@ -20,11 +20,14 @@ #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" @@ -107,6 +110,35 @@ class MockBinaryFeatureExtractor : public BinaryFeatureExtractor { 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: + virtual void OnRequestStart(int fetcher_id) OVERRIDE { + fetcher_id_ = fetcher_id; + run_loop_.Quit(); + } + virtual void OnChunkUpload(int fetcher_id) OVERRIDE {} + virtual 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) { @@ -333,6 +365,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) { 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, @@ -348,6 +383,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) { 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, @@ -379,6 +417,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedUrl) { 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)); @@ -466,6 +507,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadFetchFailed) { 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)); @@ -508,6 +552,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSuccess) { 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)); @@ -653,6 +700,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadHTTPS) { 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)); @@ -703,6 +753,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) { 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)); @@ -784,6 +837,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadCorruptZip) { 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)); @@ -830,6 +886,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientCrxDownloadSuccess) { 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)); @@ -869,6 +928,9 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) { 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)); @@ -946,6 +1008,9 @@ TEST_F(DownloadProtectionServiceTest, 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)); @@ -996,6 +1061,182 @@ TEST_F(DownloadProtectionServiceTest, #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, AddObserver(_)).Times(2); + EXPECT_CALL(item, RemoveObserver(_)).Times(2); + 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")); + + // 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) + // SendRequest is not called. Wait for FinishRequest to call our callback. + MessageLoop::current()->Run(); + net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + EXPECT_EQ(NULL, fetcher); +#else + EXPECT_EQ(0, fetcher_watcher.WaitForRequest()); + 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()); + + // 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(), + static_cast<void*>(this), + 0, + GURL(), + redirects, + content::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) + // SendRequest is not called. Wait for FinishRequest to call our callback. + MessageLoop::current()->Run(); + net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + EXPECT_EQ(NULL, fetcher); +#else + EXPECT_EQ(0, fetcher_watcher.WaitForRequest()); + 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/")); @@ -1078,6 +1319,9 @@ TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) { 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)); @@ -1119,6 +1363,9 @@ TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) { 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)); |