summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host/download_resource_handler.cc
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-23 01:07:32 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-23 01:07:32 +0000
commite3c404b92dcfc8e45225039ad5d2a9cff844cb4e (patch)
tree8fb6075ad3e6635b81f233b8f426043c31e38cf3 /chrome/browser/renderer_host/download_resource_handler.cc
parentabb4b8b2f338aa7579bda790f94b88923a3d9fea (diff)
downloadchromium_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.cc169
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);
+}