Index: content/browser/download/download_browsertest.cc |
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc |
index 94c43082c32314d2458fd530c01ce3441e710801..4f1f6f88eee2e353fb24c5fb48480992e1bf2dfc 100644 |
--- a/content/browser/download/download_browsertest.cc |
+++ b/content/browser/download/download_browsertest.cc |
@@ -31,6 +31,7 @@ |
#include "content/browser/download/download_resource_handler.h" |
#include "content/browser/loader/resource_dispatcher_host_impl.h" |
#include "content/browser/web_contents/web_contents_impl.h" |
+#include "content/public/browser/download_danger_type.h" |
#include "content/public/browser/power_save_blocker.h" |
#include "content/public/browser/resource_dispatcher_host_delegate.h" |
#include "content/public/browser/resource_throttle.h" |
@@ -121,12 +122,8 @@ static DownloadManagerImpl* DownloadManagerForShell(Shell* shell) { |
class DownloadFileWithDelay : public DownloadFileImpl { |
public: |
- DownloadFileWithDelay(const DownloadSaveInfo& save_info, |
+ DownloadFileWithDelay(scoped_ptr<DownloadSaveInfo> save_info, |
const base::FilePath& default_download_directory, |
- const GURL& url, |
- const GURL& referrer_url, |
- bool calculate_hash, |
- base::File file, |
scoped_ptr<ByteStreamReader> stream, |
const net::BoundNetLog& bound_net_log, |
scoped_ptr<PowerSaveBlocker> power_save_blocker, |
@@ -141,6 +138,9 @@ class DownloadFileWithDelay : public DownloadFileImpl { |
void RenameAndUniquify(const base::FilePath& full_path, |
const RenameCompletionCallback& callback) override; |
void RenameAndAnnotate(const base::FilePath& full_path, |
+ const std::string& client_guid, |
+ const GURL& source_url, |
+ const GURL& referrer_url, |
const RenameCompletionCallback& callback) override; |
private: |
@@ -168,12 +168,8 @@ class DownloadFileWithDelayFactory : public DownloadFileFactory { |
// DownloadFileFactory interface. |
DownloadFile* CreateFile( |
- const DownloadSaveInfo& save_info, |
+ scoped_ptr<DownloadSaveInfo> save_info, |
const base::FilePath& default_download_directory, |
- const GURL& url, |
- const GURL& referrer_url, |
- bool calculate_hash, |
- base::File file, |
scoped_ptr<ByteStreamReader> stream, |
const net::BoundNetLog& bound_net_log, |
base::WeakPtr<DownloadDestinationObserver> observer) override; |
@@ -193,23 +189,15 @@ class DownloadFileWithDelayFactory : public DownloadFileFactory { |
}; |
DownloadFileWithDelay::DownloadFileWithDelay( |
- const DownloadSaveInfo& save_info, |
+ scoped_ptr<DownloadSaveInfo> save_info, |
const base::FilePath& default_download_directory, |
- const GURL& url, |
- const GURL& referrer_url, |
- bool calculate_hash, |
- base::File file, |
scoped_ptr<ByteStreamReader> stream, |
const net::BoundNetLog& bound_net_log, |
scoped_ptr<PowerSaveBlocker> power_save_blocker, |
base::WeakPtr<DownloadDestinationObserver> observer, |
base::WeakPtr<DownloadFileWithDelayFactory> owner) |
- : DownloadFileImpl(save_info, |
+ : DownloadFileImpl(std::move(save_info), |
default_download_directory, |
- url, |
- referrer_url, |
- calculate_hash, |
- std::move(file), |
std::move(stream), |
bound_net_log, |
observer), |
@@ -227,11 +215,19 @@ void DownloadFileWithDelay::RenameAndUniquify( |
} |
void DownloadFileWithDelay::RenameAndAnnotate( |
- const base::FilePath& full_path, const RenameCompletionCallback& callback) { |
+ const base::FilePath& full_path, |
+ const std::string& client_guid, |
+ const GURL& source_url, |
+ const GURL& referrer_url, |
+ const RenameCompletionCallback& callback) { |
DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
DownloadFileImpl::RenameAndAnnotate( |
- full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper, |
- owner_, callback)); |
+ full_path, |
+ client_guid, |
+ source_url, |
+ referrer_url, |
+ base::Bind( |
+ DownloadFileWithDelay::RenameCallbackWrapper, owner_, callback)); |
} |
// static |
@@ -253,22 +249,21 @@ DownloadFileWithDelayFactory::DownloadFileWithDelayFactory() |
DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {} |
DownloadFile* DownloadFileWithDelayFactory::CreateFile( |
- const DownloadSaveInfo& save_info, |
+ scoped_ptr<DownloadSaveInfo> save_info, |
const base::FilePath& default_download_directory, |
- const GURL& url, |
- const GURL& referrer_url, |
- bool calculate_hash, |
- base::File file, |
scoped_ptr<ByteStreamReader> stream, |
const net::BoundNetLog& bound_net_log, |
base::WeakPtr<DownloadDestinationObserver> observer) { |
scoped_ptr<PowerSaveBlocker> psb(PowerSaveBlocker::Create( |
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, |
PowerSaveBlocker::kReasonOther, "Download in progress")); |
- return new DownloadFileWithDelay( |
- save_info, default_download_directory, url, referrer_url, calculate_hash, |
- std::move(file), std::move(stream), bound_net_log, std::move(psb), |
- observer, weak_ptr_factory_.GetWeakPtr()); |
+ return new DownloadFileWithDelay(std::move(save_info), |
+ default_download_directory, |
+ std::move(stream), |
+ bound_net_log, |
+ std::move(psb), |
+ observer, |
+ weak_ptr_factory_.GetWeakPtr()); |
} |
void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) { |
@@ -296,22 +291,14 @@ void DownloadFileWithDelayFactory::WaitForSomeCallback() { |
class CountingDownloadFile : public DownloadFileImpl { |
public: |
- CountingDownloadFile(const DownloadSaveInfo& save_info, |
+ CountingDownloadFile(scoped_ptr<DownloadSaveInfo> save_info, |
const base::FilePath& default_downloads_directory, |
- const GURL& url, |
- const GURL& referrer_url, |
- bool calculate_hash, |
- base::File file, |
scoped_ptr<ByteStreamReader> stream, |
const net::BoundNetLog& bound_net_log, |
scoped_ptr<PowerSaveBlocker> power_save_blocker, |
base::WeakPtr<DownloadDestinationObserver> observer) |
- : DownloadFileImpl(save_info, |
+ : DownloadFileImpl(std::move(save_info), |
default_downloads_directory, |
- url, |
- referrer_url, |
- calculate_hash, |
- std::move(file), |
std::move(stream), |
bound_net_log, |
observer) {} |
@@ -358,22 +345,20 @@ class CountingDownloadFileFactory : public DownloadFileFactory { |
// DownloadFileFactory interface. |
DownloadFile* CreateFile( |
- const DownloadSaveInfo& save_info, |
+ scoped_ptr<DownloadSaveInfo> save_info, |
const base::FilePath& default_downloads_directory, |
- const GURL& url, |
- const GURL& referrer_url, |
- bool calculate_hash, |
- base::File file, |
scoped_ptr<ByteStreamReader> stream, |
const net::BoundNetLog& bound_net_log, |
base::WeakPtr<DownloadDestinationObserver> observer) override { |
scoped_ptr<PowerSaveBlocker> psb(PowerSaveBlocker::Create( |
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, |
PowerSaveBlocker::kReasonOther, "Download in progress")); |
- return new CountingDownloadFile(save_info, default_downloads_directory, url, |
- referrer_url, calculate_hash, |
- std::move(file), std::move(stream), |
- bound_net_log, std::move(psb), observer); |
+ return new CountingDownloadFile(std::move(save_info), |
+ default_downloads_directory, |
+ std::move(stream), |
+ bound_net_log, |
+ std::move(psb), |
+ observer); |
} |
}; |
@@ -592,6 +577,10 @@ class DownloadContentTest : public ContentBrowserTest { |
return test_delegate_.get(); |
} |
+ const base::FilePath& GetDownloadDirectory() const { |
+ return downloads_directory_.path(); |
+ } |
+ |
// Create a DownloadTestObserverTerminal that will wait for the |
// specified number of downloads to finish. |
DownloadTestObserver* CreateWaiter( |
@@ -1812,6 +1801,415 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumedDownload) { |
EXPECT_TRUE(EnsureNoPendingDownloads()); |
} |
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_NoFile) { |
+ TestDownloadRequestHandler request_handler; |
+ TestDownloadRequestHandler::Parameters parameters; |
+ request_handler.StartServing(parameters); |
+ |
+ base::FilePath intermediate_file_path = |
+ GetDownloadDirectory().AppendASCII("intermediate"); |
+ std::vector<GURL> url_chain; |
+ |
+ const int kIntermediateSize = 1331; |
+ url_chain.push_back(request_handler.url()); |
+ |
+ DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem( |
+ "F7FB1F59-7DE1-4845-AFDB-8A688F70F583", |
+ 1, |
+ intermediate_file_path, |
+ base::FilePath(), |
+ url_chain, |
+ GURL(), |
+ "application/octet-stream", |
+ "application/octet-stream", |
+ base::Time::Now(), |
+ base::Time(), |
+ parameters.etag, |
+ std::string(), |
+ kIntermediateSize, |
+ parameters.size, |
+ std::string(), |
+ DownloadItem::INTERRUPTED, |
+ DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
+ DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, |
+ false); |
+ |
+ download->Resume(); |
+ WaitForCompletion(download); |
+ |
+ EXPECT_FALSE(base::PathExists(intermediate_file_path)); |
+ ReadAndVerifyFileContents(parameters.pattern_generator_seed, |
+ parameters.size, |
+ download->GetTargetFilePath()); |
+ |
+ TestDownloadRequestHandler::CompletedRequests completed_requests; |
+ request_handler.GetCompletedRequestInfo(&completed_requests); |
+ |
+ // There will be two requests. The first one is issued optimistically assuming |
+ // that the intermediate file exists and matches the size expectations set |
+ // forth in the download metadata (i.e. assuming that a 1331 byte file exists |
+ // at |intermediate_file_path|. |
+ // |
+ // However, once the response is received, DownloadFile will report that the |
+ // intermediate file doesn't exist and hence the download is marked |
+ // interrupted again. |
+ // |
+ // The second request reads the entire entity. |
+ // |
+ // N.b. we can't make any assumptions about how many bytes are transferred by |
+ // the first request since response data will be bufferred until DownloadFile |
+ // is done initializing. |
+ // |
+ // TODO(asanka): Ideally we'll check that the intermediate file matches |
+ // expectations prior to issuing the first resumption request. |
+ ASSERT_EQ(2u, completed_requests.size()); |
+ EXPECT_EQ(parameters.size, completed_requests[1].transferred_byte_count); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_NoHash) { |
+ TestDownloadRequestHandler request_handler; |
+ TestDownloadRequestHandler::Parameters parameters; |
+ request_handler.StartServing(parameters); |
+ |
+ base::FilePath intermediate_file_path = |
+ GetDownloadDirectory().AppendASCII("intermediate"); |
+ std::vector<GURL> url_chain; |
+ |
+ const int kIntermediateSize = 1331; |
+ std::vector<char> buffer(kIntermediateSize); |
+ request_handler.GetPatternBytes( |
+ parameters.pattern_generator_seed, 0, buffer.size(), buffer.data()); |
+ ASSERT_EQ( |
+ kIntermediateSize, |
+ base::WriteFile(intermediate_file_path, buffer.data(), buffer.size())); |
+ |
+ url_chain.push_back(request_handler.url()); |
+ |
+ DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem( |
+ "F7FB1F59-7DE1-4845-AFDB-8A688F70F583", |
+ 1, |
+ intermediate_file_path, |
+ base::FilePath(), |
+ url_chain, |
+ GURL(), |
+ "application/octet-stream", |
+ "application/octet-stream", |
+ base::Time::Now(), |
+ base::Time(), |
+ parameters.etag, |
+ std::string(), |
+ kIntermediateSize, |
+ parameters.size, |
+ std::string(), |
+ DownloadItem::INTERRUPTED, |
+ DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
+ DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, |
+ false); |
+ |
+ download->Resume(); |
+ WaitForCompletion(download); |
+ |
+ EXPECT_FALSE(base::PathExists(intermediate_file_path)); |
+ ReadAndVerifyFileContents(parameters.pattern_generator_seed, |
+ parameters.size, |
+ download->GetTargetFilePath()); |
+ |
+ TestDownloadRequestHandler::CompletedRequests completed_requests; |
+ request_handler.GetCompletedRequestInfo(&completed_requests); |
+ |
+ // There's only one network request issued, and that is for the remainder of |
+ // the file. |
+ ASSERT_EQ(1u, completed_requests.size()); |
+ EXPECT_EQ(parameters.size - kIntermediateSize, |
+ completed_requests[0].transferred_byte_count); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, |
+ ResumeRestoredDownload_EtagMismatch) { |
+ TestDownloadRequestHandler request_handler; |
+ TestDownloadRequestHandler::Parameters parameters; |
+ request_handler.StartServing(parameters); |
+ |
+ base::FilePath intermediate_file_path = |
+ GetDownloadDirectory().AppendASCII("intermediate"); |
+ std::vector<GURL> url_chain; |
+ |
+ const int kIntermediateSize = 1331; |
+ std::vector<char> buffer(kIntermediateSize); |
+ request_handler.GetPatternBytes( |
+ parameters.pattern_generator_seed + 1, 0, buffer.size(), buffer.data()); |
+ ASSERT_EQ( |
+ kIntermediateSize, |
+ base::WriteFile(intermediate_file_path, buffer.data(), buffer.size())); |
+ |
+ url_chain.push_back(request_handler.url()); |
+ |
+ DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem( |
+ "F7FB1F59-7DE1-4845-AFDB-8A688F70F583", |
+ 1, |
+ intermediate_file_path, |
+ base::FilePath(), |
+ url_chain, |
+ GURL(), |
+ "application/octet-stream", |
+ "application/octet-stream", |
+ base::Time::Now(), |
+ base::Time(), |
+ "fake-etag", |
+ std::string(), |
+ kIntermediateSize, |
+ parameters.size, |
+ std::string(), |
+ DownloadItem::INTERRUPTED, |
+ DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
+ DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, |
+ false); |
+ |
+ download->Resume(); |
+ WaitForCompletion(download); |
+ |
+ EXPECT_FALSE(base::PathExists(intermediate_file_path)); |
+ ReadAndVerifyFileContents(parameters.pattern_generator_seed, |
+ parameters.size, |
+ download->GetTargetFilePath()); |
+ |
+ TestDownloadRequestHandler::CompletedRequests completed_requests; |
+ request_handler.GetCompletedRequestInfo(&completed_requests); |
+ |
+ // There's only one network request issued. The If-Range header allows the |
+ // server to respond with the entire entity in one go. The existing contents |
+ // of the file should be discarded, and overwritten by the new contents. |
+ ASSERT_EQ(1u, completed_requests.size()); |
+ EXPECT_EQ(parameters.size, completed_requests[0].transferred_byte_count); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, |
+ ResumeRestoredDownload_CorrectHash) { |
+ TestDownloadRequestHandler request_handler; |
+ TestDownloadRequestHandler::Parameters parameters; |
+ request_handler.StartServing(parameters); |
+ |
+ base::FilePath intermediate_file_path = |
+ GetDownloadDirectory().AppendASCII("intermediate"); |
+ std::vector<GURL> url_chain; |
+ |
+ const int kIntermediateSize = 1331; |
+ std::vector<char> buffer(kIntermediateSize); |
+ request_handler.GetPatternBytes( |
+ parameters.pattern_generator_seed, 0, buffer.size(), buffer.data()); |
+ ASSERT_EQ( |
+ kIntermediateSize, |
+ base::WriteFile(intermediate_file_path, buffer.data(), buffer.size())); |
+ // SHA-256 hash of the pattern bytes in buffer. |
+ static const uint8_t kPartialHash[] = { |
+ 0x77, 0x14, 0xfd, 0x83, 0x06, 0x15, 0x10, 0x7a, 0x47, 0x15, 0xd3, |
+ 0xcf, 0xdd, 0x46, 0xa2, 0x61, 0x96, 0xff, 0xc3, 0xbb, 0x49, 0x30, |
+ 0xaf, 0x31, 0x3a, 0x64, 0x0b, 0xd5, 0xfa, 0xb1, 0xe3, 0x81}; |
+ |
+ url_chain.push_back(request_handler.url()); |
+ |
+ DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem( |
+ "F7FB1F59-7DE1-4845-AFDB-8A688F70F583", |
+ 1, |
+ intermediate_file_path, |
+ base::FilePath(), |
+ url_chain, |
+ GURL(), |
+ "application/octet-stream", |
+ "application/octet-stream", |
+ base::Time::Now(), |
+ base::Time(), |
+ parameters.etag, |
+ std::string(), |
+ kIntermediateSize, |
+ parameters.size, |
+ std::string(std::begin(kPartialHash), std::end(kPartialHash)), |
+ DownloadItem::INTERRUPTED, |
+ DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
+ DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, |
+ false); |
+ |
+ download->Resume(); |
+ WaitForCompletion(download); |
+ |
+ EXPECT_FALSE(base::PathExists(intermediate_file_path)); |
+ ReadAndVerifyFileContents(parameters.pattern_generator_seed, |
+ parameters.size, |
+ download->GetTargetFilePath()); |
+ |
+ TestDownloadRequestHandler::CompletedRequests completed_requests; |
+ request_handler.GetCompletedRequestInfo(&completed_requests); |
+ |
+ // There's only one network request issued, and that is for the remainder of |
+ // the file. |
+ ASSERT_EQ(1u, completed_requests.size()); |
+ EXPECT_EQ(parameters.size - kIntermediateSize, |
+ completed_requests[0].transferred_byte_count); |
+ |
+ // SHA-256 hash of the entire 102400 bytes in the target file. |
+ static const uint8_t kFullHash[] = { |
+ 0xa7, 0x44, 0x49, 0x86, 0x24, 0xc6, 0x84, 0x6c, 0x89, 0xdf, 0xd8, |
+ 0xec, 0xa0, 0xe0, 0x61, 0x12, 0xdc, 0x80, 0x13, 0xf2, 0x83, 0x49, |
+ 0xa9, 0x14, 0x52, 0x32, 0xf0, 0x95, 0x20, 0xca, 0x5b, 0x30}; |
+ EXPECT_EQ(std::string(std::begin(kFullHash), std::end(kFullHash)), |
+ download->GetHash()); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_WrongHash) { |
+ TestDownloadRequestHandler request_handler; |
+ TestDownloadRequestHandler::Parameters parameters; |
+ request_handler.StartServing(parameters); |
+ |
+ base::FilePath intermediate_file_path = |
+ GetDownloadDirectory().AppendASCII("intermediate"); |
+ std::vector<GURL> url_chain; |
+ |
+ const int kIntermediateSize = 1331; |
+ std::vector<char> buffer(kIntermediateSize); |
+ ASSERT_EQ( |
+ kIntermediateSize, |
+ base::WriteFile(intermediate_file_path, buffer.data(), buffer.size())); |
+ // SHA-256 hash of the expected pattern bytes in buffer. This doesn't match |
+ // the current contents of the intermediate file which should all be 0. |
+ static const uint8_t kPartialHash[] = { |
+ 0x77, 0x14, 0xfd, 0x83, 0x06, 0x15, 0x10, 0x7a, 0x47, 0x15, 0xd3, |
+ 0xcf, 0xdd, 0x46, 0xa2, 0x61, 0x96, 0xff, 0xc3, 0xbb, 0x49, 0x30, |
+ 0xaf, 0x31, 0x3a, 0x64, 0x0b, 0xd5, 0xfa, 0xb1, 0xe3, 0x81}; |
+ |
+ url_chain.push_back(request_handler.url()); |
+ |
+ DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem( |
+ "F7FB1F59-7DE1-4845-AFDB-8A688F70F583", |
+ 1, |
+ intermediate_file_path, |
+ base::FilePath(), |
+ url_chain, |
+ GURL(), |
+ "application/octet-stream", |
+ "application/octet-stream", |
+ base::Time::Now(), |
+ base::Time(), |
+ parameters.etag, |
+ std::string(), |
+ kIntermediateSize, |
+ parameters.size, |
+ std::string(std::begin(kPartialHash), std::end(kPartialHash)), |
+ DownloadItem::INTERRUPTED, |
+ DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
+ DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, |
+ false); |
+ |
+ download->Resume(); |
+ WaitForCompletion(download); |
+ |
+ EXPECT_FALSE(base::PathExists(intermediate_file_path)); |
+ ReadAndVerifyFileContents(parameters.pattern_generator_seed, |
+ parameters.size, |
+ download->GetTargetFilePath()); |
+ |
+ TestDownloadRequestHandler::CompletedRequests completed_requests; |
+ request_handler.GetCompletedRequestInfo(&completed_requests); |
+ |
+ // There will be two requests. The first one is issued optimistically assuming |
+ // that the intermediate file exists and matches the size expectations set |
+ // forth in the download metadata (i.e. assuming that a 1331 byte file exists |
+ // at |intermediate_file_path|. |
+ // |
+ // However, once the response is received, DownloadFile will report that the |
+ // intermediate file doesn't match the expected hash. |
+ // |
+ // The second request reads the entire entity. |
+ // |
+ // N.b. we can't make any assumptions about how many bytes are transferred by |
+ // the first request since response data will be bufferred until DownloadFile |
+ // is done initializing. |
+ // |
+ // TODO(asanka): Ideally we'll check that the intermediate file matches |
+ // expectations prior to issuing the first resumption request. |
+ ASSERT_EQ(2u, completed_requests.size()); |
+ EXPECT_EQ(parameters.size, completed_requests[1].transferred_byte_count); |
+ |
+ // SHA-256 hash of the entire 102400 bytes in the target file. |
+ static const uint8_t kFullHash[] = { |
+ 0xa7, 0x44, 0x49, 0x86, 0x24, 0xc6, 0x84, 0x6c, 0x89, 0xdf, 0xd8, |
+ 0xec, 0xa0, 0xe0, 0x61, 0x12, 0xdc, 0x80, 0x13, 0xf2, 0x83, 0x49, |
+ 0xa9, 0x14, 0x52, 0x32, 0xf0, 0x95, 0x20, 0xca, 0x5b, 0x30}; |
+ EXPECT_EQ(std::string(std::begin(kFullHash), std::end(kFullHash)), |
+ download->GetHash()); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_ShortFile) { |
+ TestDownloadRequestHandler request_handler; |
+ TestDownloadRequestHandler::Parameters parameters; |
+ request_handler.StartServing(parameters); |
+ |
+ base::FilePath intermediate_file_path = |
+ GetDownloadDirectory().AppendASCII("intermediate"); |
+ std::vector<GURL> url_chain; |
+ |
+ const int kIntermediateSize = 1331; |
+ // Size of file is slightly shorter than the size known to DownloadItem. |
+ std::vector<char> buffer(kIntermediateSize - 100); |
+ request_handler.GetPatternBytes( |
+ parameters.pattern_generator_seed, 0, buffer.size(), buffer.data()); |
+ ASSERT_EQ( |
+ kIntermediateSize - 100, |
+ base::WriteFile(intermediate_file_path, buffer.data(), buffer.size())); |
+ url_chain.push_back(request_handler.url()); |
+ |
+ DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem( |
+ "F7FB1F59-7DE1-4845-AFDB-8A688F70F583", |
+ 1, |
+ intermediate_file_path, |
+ base::FilePath(), |
+ url_chain, |
+ GURL(), |
+ "application/octet-stream", |
+ "application/octet-stream", |
+ base::Time::Now(), |
+ base::Time(), |
+ parameters.etag, |
+ std::string(), |
+ kIntermediateSize, |
+ parameters.size, |
+ std::string(), |
+ DownloadItem::INTERRUPTED, |
+ DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
+ DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, |
+ false); |
+ |
+ download->Resume(); |
+ WaitForCompletion(download); |
+ |
+ EXPECT_FALSE(base::PathExists(intermediate_file_path)); |
+ ReadAndVerifyFileContents(parameters.pattern_generator_seed, |
+ parameters.size, |
+ download->GetTargetFilePath()); |
+ |
+ TestDownloadRequestHandler::CompletedRequests completed_requests; |
+ request_handler.GetCompletedRequestInfo(&completed_requests); |
+ |
+ // There will be two requests. The first one is issued optimistically assuming |
+ // that the intermediate file exists and matches the size expectations set |
+ // forth in the download metadata (i.e. assuming that a 1331 byte file exists |
+ // at |intermediate_file_path|. |
+ // |
+ // However, once the response is received, DownloadFile will report that the |
+ // intermediate file is too short and hence the download is marked interrupted |
+ // again. |
+ // |
+ // The second request reads the entire entity. |
+ // |
+ // N.b. we can't make any assumptions about how many bytes are transferred by |
+ // the first request since response data will be bufferred until DownloadFile |
+ // is done initializing. |
+ // |
+ // TODO(asanka): Ideally we'll check that the intermediate file matches |
+ // expectations prior to issuing the first resumption request. |
+ ASSERT_EQ(2u, completed_requests.size()); |
+ EXPECT_EQ(parameters.size, completed_requests[1].transferred_byte_count); |
+} |
+ |
// Check that the cookie policy is correctly updated when downloading a file |
// that redirects cross origin. |
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) { |