Index: chrome/browser/renderer_host/download_resource_handler.cc |
diff --git a/chrome/browser/renderer_host/download_resource_handler.cc b/chrome/browser/renderer_host/download_resource_handler.cc |
index 5e83478c97efe4978277b11b96015faec1afe377..9a2c1294dd719d2a7d542b7415b4fc8fbfa9c994 100644 |
--- a/chrome/browser/renderer_host/download_resource_handler.cc |
+++ b/chrome/browser/renderer_host/download_resource_handler.cc |
@@ -4,13 +4,16 @@ |
#include "chrome/browser/renderer_host/download_resource_handler.h" |
+#include "base/file_util.h" |
#include "base/logging.h" |
#include "chrome/browser/chrome_thread.h" |
#include "chrome/browser/download/download_item.h" |
#include "chrome/browser/download/download_file_manager.h" |
+#include "chrome/browser/download/download_util.h" |
#include "chrome/browser/history/download_create_info.h" |
#include "chrome/browser/renderer_host/global_request_id.h" |
#include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
+#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" |
#include "chrome/common/resource_response.h" |
#include "net/base/io_buffer.h" |
#include "net/http/http_response_headers.h" |
@@ -64,13 +67,26 @@ bool DownloadResourceHandler::OnResponseStarted(int request_id, |
set_content_disposition(content_disposition); |
set_content_length(response->response_head.content_length); |
- download_id_ = download_file_manager_->GetNextId(); |
+ ResourceDispatcherHostRequestInfo* req_info = |
+ ResourceDispatcherHost::InfoForRequest(request_); |
+ download_id_ = -1; |
+ if (req_info->was_interrupted()) { |
+ FilePath orig_path = save_info_.file_path; |
+ download_id_ = download_file_manager_->GetDownloadId(url_, orig_path); |
+ if (download_id_ == -1) { |
+ orig_path = download_util::RemoveCrDownloadPath(save_info_.file_path); |
+ download_id_ = download_file_manager_->GetDownloadId(url_, orig_path); |
+ } |
+ } |
+ if (download_id_ == -1) |
+ download_id_ = download_file_manager_->GetNextId(); |
// |download_file_manager_| consumes (deletes): |
DownloadCreateInfo* info = new DownloadCreateInfo; |
info->url = url_; |
info->referrer_url = GURL(request_->referrer()); |
info->start_time = base::Time::Now(); |
- info->received_bytes = 0; |
+ info->received_bytes = |
+ req_info->was_interrupted() ? req_info->interrupted_bytes() : 0; |
info->total_bytes = content_length_; |
info->state = DownloadItem::IN_PROGRESS; |
info->download_id = download_id_; |
@@ -79,6 +95,37 @@ bool DownloadResourceHandler::OnResponseStarted(int request_id, |
info->request_id = global_id_.request_id; |
info->content_disposition = content_disposition_; |
info->mime_type = response->response_head.mime_type; |
+ info->is_partial_download = req_info->was_interrupted(); |
+ |
+ // Handle server's response codes. |
+ int status = request_->response_headers()->response_code(); |
+ switch (status) { |
+ // Continue with download: |
+ case 200: // OK |
+ // Downloading the full file, even if we asked for a range. |
+ info->received_bytes = 0; |
+ if (info->is_partial_download) { |
+ // Delete the crdownload file explicitly. |
+ FilePath crpath = |
+ download_util::GetCrDownloadPath(save_info_.file_path); |
+ file_util::Delete(crpath, false); |
+ } |
+ // Fall through. |
+ |
+ case 206: // Partial content. Leave alone. |
+ break; |
+ |
+ case 412: // Precondition failed. Fails 'If-Unmodified-Since'. |
+ case 204: // No content. File not present. |
+ default: // All other errors. |
+ // TODO(ahendrickson) -- Cancel, and notify user. |
+ break; |
+ |
+ // Retry by downloading from the start automatically: |
+ case 416: // Range not available. Fails 'Content-Range'. |
+ // TODO(ahendrickson) -- Submit another request for the whole file. |
+ break; |
+ } |
std::string content_type_header; |
if (!response->response_head.headers || |
@@ -92,7 +139,8 @@ bool DownloadResourceHandler::OnResponseStarted(int request_id, |
info->referrer_charset = request_->context()->referrer_charset(); |
info->save_info = save_info_; |
ChromeThread::PostTask( |
- ChromeThread::UI, FROM_HERE, |
+ ChromeThread::UI, |
+ FROM_HERE, |
NewRunnableMethod( |
download_file_manager_, &DownloadFileManager::StartDownload, info)); |
@@ -155,12 +203,17 @@ bool DownloadResourceHandler::OnResponseCompleted( |
int request_id, |
const URLRequestStatus& status, |
const std::string& security_info) { |
+ int error_code = |
+ (status.status() == URLRequestStatus::FAILED) ? status.os_error() : 0; |
ChromeThread::PostTask( |
- ChromeThread::FILE, FROM_HERE, |
+ ChromeThread::FILE, |
+ FROM_HERE, |
NewRunnableMethod(download_file_manager_, |
&DownloadFileManager::OnResponseCompleted, |
download_id_, |
- buffer_)); |
+ buffer_, |
+ error_code, |
+ security_info)); |
read_buffer_ = NULL; |
// 'buffer_' is deleted by the DownloadFileManager. |