172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/download_resource_handler.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include <string>
8201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/metrics/histogram.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/metrics/stats_counters.h"
12201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/stringprintf.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_item.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_file_manager.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/download/download_util.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/history/download_create_info.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/global_request_id.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/resource_response.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/io_buffer.h"
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/http/http_response_headers.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDownloadResourceHandler::DownloadResourceHandler(
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ResourceDispatcherHost* rdh,
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int render_process_host_id,
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int render_view_id,
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int request_id,
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& url,
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DownloadFileManager* download_file_manager,
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    net::URLRequest* request,
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool save_as,
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const DownloadSaveInfo& save_info)
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : download_id_(-1),
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      global_id_(render_process_host_id, request_id),
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      render_view_id_(render_view_id),
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      content_length_(0),
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      download_file_manager_(download_file_manager),
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_(request),
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      save_as_(save_as),
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      save_info_(save_info),
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      buffer_(new DownloadBuffer),
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      rdh_(rdh),
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      is_paused_(false) {
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_util::RecordDownloadCount(download_util::UNTHROTTLED_COUNT);
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DownloadResourceHandler::OnUploadProgress(int request_id,
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                               uint64 position,
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                               uint64 size) {
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Not needed, as this event handler ought to be the final resource.
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DownloadResourceHandler::OnRequestRedirected(int request_id,
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                  const GURL& url,
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                  ResourceResponse* response,
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                  bool* defer) {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Send the download creation information to the download thread.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DownloadResourceHandler::OnResponseStarted(int request_id,
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                ResourceResponse* response) {
67201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  VLOG(20) << __FUNCTION__ << "()" << DebugString()
68201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch           << " request_id = " << request_id;
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  download_start_time_ = base::TimeTicks::Now();
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string content_disposition;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request_->GetResponseHeaderByName("content-disposition",
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    &content_disposition);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_content_disposition(content_disposition);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_content_length(response->response_head.content_length);
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const ResourceDispatcherHostRequestInfo* request_info =
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResourceDispatcherHost::InfoForRequest(request_);
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  download_id_ = download_file_manager_->GetNextId();
80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Deleted in DownloadManager.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DownloadCreateInfo* info = new DownloadCreateInfo;
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  info->url_chain = request_->url_chain();
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->referrer_url = GURL(request_->referrer());
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->start_time = base::Time::Now();
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->received_bytes = 0;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->total_bytes = content_length_;
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->state = DownloadItem::IN_PROGRESS;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->download_id = download_id_;
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  info->has_user_gesture = request_info->has_user_gesture();
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->child_id = global_id_.child_id;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->render_view_id = render_view_id_;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->request_id = global_id_.request_id;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->content_disposition = content_disposition_;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->mime_type = response->response_head.mime_type;
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(ahendrickson) -- Get the last modified time and etag, so we can
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // resume downloading.
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string content_type_header;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!response->response_head.headers ||
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !response->response_head.headers->GetMimeType(&content_type_header))
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    content_type_header = "";
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->original_mime_type = content_type_header;
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->prompt_user_for_save_location =
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      save_as_ && save_info_.file_path.empty();
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  info->is_dangerous_file = false;
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  info->is_dangerous_url = false;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->referrer_charset = request_->context()->referrer_charset();
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info->save_info = save_info_;
111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          download_file_manager_, &DownloadFileManager::StartDownload, info));
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We can't start saving the data before we create the file on disk.
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The request will be un-paused in DownloadFileManager::CreateDownloadFile.
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, true);
1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DownloadResourceHandler::OnWillStart(int request_id,
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          const GURL& url,
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          bool* defer) {
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Create a new buffer, which will be handed to the download thread for file
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// writing and deletion.
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DownloadResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int* buf_size, int min_size) {
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(buf && buf_size);
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!read_buffer_) {
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *buf_size = min_size < 0 ? kReadBufSize : min_size;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    read_buffer_ = new net::IOBuffer(*buf_size);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *buf = read_buffer_.get();
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Pass the buffer to the download file writer.
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DownloadResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!*bytes_read)
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(read_buffer_);
14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock auto_lock(buffer_->lock);
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool need_update = buffer_->contents.empty();
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We are passing ownership of this buffer to the download file manager.
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::IOBuffer* buffer = NULL;
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  read_buffer_.swap(&buffer);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  buffer_->contents.push_back(std::make_pair(buffer, *bytes_read));
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (need_update) {
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::FILE, FROM_HERE,
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        NewRunnableMethod(download_file_manager_,
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          &DownloadFileManager::UpdateDownload,
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          download_id_,
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          buffer_.get()));
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We schedule a pause outside of the read loop if there is too much file
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // writing work to do.
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (buffer_->contents.size() > kLoadsToWrite)
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    StartPauseTimer();
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DownloadResourceHandler::OnResponseCompleted(
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int request_id,
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const net::URLRequestStatus& status,
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& security_info) {
175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  VLOG(20) << __FUNCTION__ << "()" << DebugString()
176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch           << " request_id = " << request_id
177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch           << " status.status() = " << status.status()
178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch           << " status.os_error() = " << status.os_error();
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int error_code = (status.status() == net::URLRequestStatus::FAILED) ?
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      status.os_error() : 0;
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We transfer ownership to |DownloadFileManager| to delete |buffer_|,
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // so that any functions queued up on the FILE thread are executed
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // before deletion.
184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::FILE, FROM_HERE,
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NewRunnableMethod(download_file_manager_,
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &DownloadFileManager::OnResponseCompleted,
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        download_id_,
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        buffer_.release(),
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        error_code,
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        security_info));
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  read_buffer_ = NULL;
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadResourceHandler::OnRequestClosed() {
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UMA_HISTOGRAM_TIMES("SB2.DownloadDuration",
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                      base::TimeTicks::Now() - download_start_time_);
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// If the content-length header is not present (or contains something other
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// than numbers), the incoming content_length is -1 (unknown size).
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Set the content length to 0 to indicate unknown size to DownloadManager.
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadResourceHandler::set_content_length(const int64& content_length) {
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_length_ = 0;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (content_length > 0)
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    content_length_ = content_length;
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadResourceHandler::set_content_disposition(
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& content_disposition) {
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_disposition_ = content_disposition;
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadResourceHandler::CheckWriteProgress() {
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!buffer_.get())
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;  // The download completed while we were waiting to run.
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t contents_size;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::AutoLock lock(buffer_->lock);
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    contents_size = buffer_->contents.size();
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool should_pause = contents_size > kLoadsToWrite;
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We'll come back later and see if it's okay to unpause the request.
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (should_pause)
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    StartPauseTimer();
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_paused_ != should_pause) {
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rdh_->PauseRequest(global_id_.child_id, global_id_.request_id,
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       should_pause);
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    is_paused_ = should_pause;
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDownloadResourceHandler::~DownloadResourceHandler() {
2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadResourceHandler::StartPauseTimer() {
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!pause_timer_.IsRunning())
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pause_timer_.Start(base::TimeDelta::FromMilliseconds(kThrottleTimeMs), this,
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       &DownloadResourceHandler::CheckWriteProgress);
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
246201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
247201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstd::string DownloadResourceHandler::DebugString() const {
248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return base::StringPrintf("{"
249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            " url_ = " "\"%s\""
250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            " download_id_ = " "%d"
251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            " global_id_ = {"
252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            " child_id = " "%d"
253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            " request_id = " "%d"
254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            " }"
255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            " render_view_id_ = " "%d"
25621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                            " save_info_.file_path = \"%" PRFilePath "\""
257201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            " }",
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            request_->url().spec().c_str(),
259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            download_id_,
260201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            global_id_.child_id,
261201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            global_id_.request_id,
262201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            render_view_id_,
263201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            save_info_.file_path.value().c_str());
264201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
265