Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(971)

Unified Diff: content/browser/download/download_file_manager.cc

Issue 7646025: Detect file system errors during downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged with trunk. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/download/download_file_manager.cc
diff --git a/content/browser/download/download_file_manager.cc b/content/browser/download/download_file_manager.cc
index fb80d2feb4ce9c54d976ec87054a445694f72ed9..e0bfb03899f0735028460bfe4acbb4ffcb83f730 100644
--- a/content/browser/download/download_file_manager.cc
+++ b/content/browser/download/download_file_manager.cc
@@ -168,11 +168,37 @@ void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) {
}
DownloadFile* download_file = GetDownloadFile(id);
+ bool had_error = false;
for (size_t i = 0; i < contents.size(); ++i) {
net::IOBuffer* data = contents[i].first;
const int data_len = contents[i].second;
- if (download_file)
- download_file->AppendDataToFile(data->data(), data_len);
+ if (!had_error && download_file) {
+ bool write_succeeded =
+ download_file->AppendDataToFile(data->data(), data_len);
+ if (!write_succeeded) {
+ // Write failed: interrupt the download.
+ std::string hash;
cbentzel 2011/08/19 18:44:21 hash does not appear to be used.
ahendrickson 2011/08/22 14:53:30 Ah, leftover from a refactor. Removed.
+ DownloadManager* download_manager = download_file->GetDownloadManager();
+ had_error = true;
+
+ // Calling this here in case we get more data, to avoid calling
cbentzel 2011/08/19 18:44:21 Update this comment to discuss the issue with writ
Randy Smith (Not in Mondays) 2011/08/19 20:09:13 I'd suggest "this"->"CancelDownload" in the commen
ahendrickson 2011/08/22 14:53:30 Moved the comment.
ahendrickson 2011/08/22 14:53:30 Done.
+ // |OnDownloadError()| more than once.
+ int64 bytes_downloaded = download_file->bytes_so_far();
+ CancelDownload(id);
+
cbentzel 2011/08/19 18:44:21 Perhaps you should do a download_file = NULL; a
ahendrickson 2011/08/22 14:53:30 Done.
+ if (download_manager) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ NewRunnableMethod(
+ download_manager,
+ &DownloadManager::OnDownloadError,
+ id,
+ bytes_downloaded,
+ net::ERR_FAILED));
+ }
+ }
+ }
data->Release();
}
}
@@ -180,10 +206,10 @@ void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) {
void DownloadFileManager::OnResponseCompleted(
int id,
DownloadBuffer* buffer,
- int os_error,
+ int net_error,
const std::string& security_info) {
VLOG(20) << __FUNCTION__ << "()" << " id = " << id
- << " os_error = " << os_error
+ << " net_error = " << net_error
<< " security_info = \"" << security_info << "\"";
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
delete buffer;
@@ -203,11 +229,32 @@ void DownloadFileManager::OnResponseCompleted(
if (!download_file->GetSha256Hash(&hash))
hash.clear();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- download_manager, &DownloadManager::OnResponseCompleted,
- id, download_file->bytes_so_far(), os_error, hash));
+ // ERR_CONNECTION_CLOSED is allowed since a number of servers in the wild
+ // advertise a larger Content-Length than the amount of bytes in the message
+ // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1,
+ // and Safari 5.0.4 - treat the download as complete in this case, so we
+ // follow their lead.
+ if (net_error == net::OK || net_error == net::ERR_CONNECTION_CLOSED) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ NewRunnableMethod(
+ download_manager,
+ &DownloadManager::OnResponseCompleted,
+ id,
+ download_file->bytes_so_far(),
+ hash));
+ } else {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ NewRunnableMethod(
+ download_manager,
+ &DownloadManager::OnDownloadError,
+ id,
+ download_file->bytes_so_far(),
+ net_error));
+ }
// We need to keep the download around until the UI thread has finalized
// the name.
}
@@ -293,7 +340,7 @@ void DownloadFileManager::RenameInProgressDownloadFile(
if (!download_file->Rename(full_path)) {
// Error. Between the time the UI thread generated 'full_path' to the time
// this code runs, something happened that prevents us from renaming.
- CancelDownloadOnRename(id);
+ CancelDownloadOnRename(id, net::ERR_FAILED);
}
}
@@ -341,7 +388,7 @@ void DownloadFileManager::RenameCompletingDownloadFile(
if (!download_file->Rename(new_path)) {
// Error. Between the time the UI thread generated 'full_path' to the time
// this code runs, something happened that prevents us from renaming.
- CancelDownloadOnRename(id);
+ CancelDownloadOnRename(id, net::ERR_FAILED);
return;
}
@@ -360,7 +407,7 @@ void DownloadFileManager::RenameCompletingDownloadFile(
// Called only from RenameInProgressDownloadFile and
// RenameCompletingDownloadFile on the FILE thread.
-void DownloadFileManager::CancelDownloadOnRename(int id) {
+void DownloadFileManager::CancelDownloadOnRename(int id, int rename_error) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
DownloadFile* download_file = GetDownloadFile(id);
@@ -371,7 +418,7 @@ void DownloadFileManager::CancelDownloadOnRename(int id) {
if (!download_manager) {
// Without a download manager, we can't cancel the request normally, so we
// need to do it here. The normal path will also update the download
- // history before cancelling the request.
+ // history before canceling the request.
download_file->CancelDownloadRequest();
return;
}
@@ -379,7 +426,10 @@ void DownloadFileManager::CancelDownloadOnRename(int id) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(download_manager,
- &DownloadManager::DownloadCancelled, id));
+ &DownloadManager::OnDownloadError,
+ id,
+ download_file->bytes_so_far(),
+ rename_error));
}
void DownloadFileManager::EraseDownload(int id) {

Powered by Google App Engine
This is Rietveld 408576698