| 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.
|
|
|