diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-23 01:07:32 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-23 01:07:32 +0000 |
commit | e3c404b92dcfc8e45225039ad5d2a9cff844cb4e (patch) | |
tree | 8fb6075ad3e6635b81f233b8f426043c31e38cf3 /chrome/browser/renderer_host/download_resource_handler.cc | |
parent | abb4b8b2f338aa7579bda790f94b88923a3d9fea (diff) | |
download | chromium_src-e3c404b92dcfc8e45225039ad5d2a9cff844cb4e.zip chromium_src-e3c404b92dcfc8e45225039ad5d2a9cff844cb4e.tar.gz chromium_src-e3c404b92dcfc8e45225039ad5d2a9cff844cb4e.tar.bz2 |
New attempt at landing the resource_dispatcher_host.cc splitting (broke the build on Friday).
TBR=darin
Review URL: http://codereview.chromium.org/15801
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7400 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host/download_resource_handler.cc')
-rw-r--r-- | chrome/browser/renderer_host/download_resource_handler.cc | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/chrome/browser/renderer_host/download_resource_handler.cc b/chrome/browser/renderer_host/download_resource_handler.cc new file mode 100644 index 0000000..13e7457 --- /dev/null +++ b/chrome/browser/renderer_host/download_resource_handler.cc @@ -0,0 +1,169 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/renderer_host/download_resource_handler.h" + +#include "chrome/browser/download/download_file.h" +#include "chrome/browser/download/download_manager.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" + +DownloadResourceHandler::DownloadResourceHandler(ResourceDispatcherHost* rdh, + int render_process_host_id, + int render_view_id, + int request_id, + const std::string& url, + DownloadFileManager* manager, + URLRequest* request, + bool save_as) + : download_id_(-1), + global_id_(ResourceDispatcherHost::GlobalRequestID(render_process_host_id, + request_id)), + render_view_id_(render_view_id), + read_buffer_(NULL), + url_(UTF8ToWide(url)), + content_length_(0), + download_manager_(manager), + request_(request), + save_as_(save_as), + buffer_(new DownloadBuffer), + rdh_(rdh), + is_paused_(false) { +} + +// Not needed, as this event handler ought to be the final resource. +bool DownloadResourceHandler::OnRequestRedirected(int request_id, + const GURL& url) { + url_ = UTF8ToWide(url.spec()); + return true; +} + +// Send the download creation information to the download thread. +bool DownloadResourceHandler::OnResponseStarted(int request_id, + ResourceResponse* response) { + std::string content_disposition; + request_->GetResponseHeaderByName("content-disposition", + &content_disposition); + set_content_disposition(content_disposition); + set_content_length(response->response_head.content_length); + + download_id_ = download_manager_->GetNextId(); + // |download_manager_| consumes (deletes): + DownloadCreateInfo* info = new DownloadCreateInfo; + info->url = url_; + info->start_time = base::Time::Now(); + info->received_bytes = 0; + info->total_bytes = content_length_; + info->state = DownloadItem::IN_PROGRESS; + info->download_id = download_id_; + info->render_process_id = global_id_.render_process_host_id; + info->render_view_id = render_view_id_; + info->request_id = global_id_.request_id; + info->content_disposition = content_disposition_; + info->mime_type = response->response_head.mime_type; + info->save_as = save_as_; + info->is_dangerous = false; + download_manager_->file_loop()->PostTask(FROM_HERE, + NewRunnableMethod(download_manager_, + &DownloadFileManager::StartDownload, + info)); + return true; +} + +// Create a new buffer, which will be handed to the download thread for file +// writing and deletion. +bool DownloadResourceHandler::OnWillRead(int request_id, + char** buf, int* buf_size, + int min_size) { + DCHECK(buf && buf_size); + if (!read_buffer_) { + *buf_size = min_size < 0 ? kReadBufSize : min_size; + read_buffer_ = new char[*buf_size]; + } + *buf = read_buffer_; + return true; +} + +// Pass the buffer to the download file writer. +bool DownloadResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { + if (!*bytes_read) + return true; + DCHECK(read_buffer_); + AutoLock auto_lock(buffer_->lock); + bool need_update = buffer_->contents.empty(); + buffer_->contents.push_back(std::make_pair(read_buffer_, *bytes_read)); + if (need_update) { + download_manager_->file_loop()->PostTask(FROM_HERE, + NewRunnableMethod(download_manager_, + &DownloadFileManager::UpdateDownload, + download_id_, + buffer_)); + } + read_buffer_ = NULL; + + // We schedule a pause outside of the read loop if there is too much file + // writing work to do. + if (buffer_->contents.size() > kLoadsToWrite) + StartPauseTimer(); + + return true; +} + +bool DownloadResourceHandler::OnResponseCompleted( + int request_id, + const URLRequestStatus& status) { + download_manager_->file_loop()->PostTask(FROM_HERE, + NewRunnableMethod(download_manager_, + &DownloadFileManager::DownloadFinished, + download_id_, + buffer_)); + delete [] read_buffer_; + + // 'buffer_' is deleted by the DownloadFileManager. + buffer_ = NULL; + return true; +} + +// If the content-length header is not present (or contains something other +// than numbers), the incoming content_length is -1 (unknown size). +// Set the content length to 0 to indicate unknown size to DownloadManager. +void DownloadResourceHandler::set_content_length(const int64& content_length) { + content_length_ = 0; + if (content_length > 0) + content_length_ = content_length; +} + +void DownloadResourceHandler::set_content_disposition( + const std::string& content_disposition) { + content_disposition_ = content_disposition; +} + +void DownloadResourceHandler::CheckWriteProgress() { + if (!buffer_) + return; // The download completed while we were waiting to run. + + size_t contents_size; + { + AutoLock lock(buffer_->lock); + contents_size = buffer_->contents.size(); + } + + bool should_pause = contents_size > kLoadsToWrite; + + // We'll come back later and see if it's okay to unpause the request. + if (should_pause) + StartPauseTimer(); + + if (is_paused_ != should_pause) { + rdh_->PauseRequest(global_id_.render_process_host_id, + global_id_.request_id, + should_pause); + is_paused_ = should_pause; + } +} + +void DownloadResourceHandler::StartPauseTimer() { + if (!pause_timer_.IsRunning()) + pause_timer_.Start(base::TimeDelta::FromMilliseconds(kThrottleTimeMs), this, + &DownloadResourceHandler::CheckWriteProgress); +} |