summaryrefslogtreecommitdiffstats
path: root/content/browser/download/download_resource_handler.h
blob: 042a6ed1a351c30d0084cfc5913479ae12714a9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (c) 2012 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.

#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_RESOURCE_HANDLER_H_
#pragma once

#include <string>

#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer.h"
#include "content/browser/download/download_types.h"
#include "content/browser/renderer_host/resource_handler.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_id.h"
#include "content/public/browser/global_request_id.h"
#include "net/base/net_errors.h"

class DownloadFileManager;
class DownloadRequestHandle;
struct DownloadCreateInfo;

namespace content {
class DownloadBuffer;
}

namespace net {
class URLRequest;
}  // namespace net

// Forwards data to the download thread.
class DownloadResourceHandler : public ResourceHandler {
 public:
  typedef content::DownloadManager::OnStartedCallback OnStartedCallback;

  static const size_t kLoadsToWrite = 100;  // number of data buffers queued

  // started_cb will be called exactly once on the UI thread.
  DownloadResourceHandler(int render_process_host_id,
                          int render_view_id,
                          int request_id,
                          const GURL& url,
                          DownloadFileManager* download_file_manager,
                          net::URLRequest* request,
                          const OnStartedCallback& started_cb,
                          const DownloadSaveInfo& save_info);

  virtual bool OnUploadProgress(int request_id,
                                uint64 position,
                                uint64 size) OVERRIDE;

  // Not needed, as this event handler ought to be the final resource.
  virtual bool OnRequestRedirected(int request_id,
                                   const GURL& url,
                                   content::ResourceResponse* response,
                                   bool* defer) OVERRIDE;

  // Send the download creation information to the download thread.
  virtual bool OnResponseStarted(int request_id,
                                 content::ResourceResponse* response) OVERRIDE;

  // Pass-through implementation.
  virtual bool OnWillStart(int request_id,
                           const GURL& url,
                           bool* defer) OVERRIDE;

  // Create a new buffer, which will be handed to the download thread for file
  // writing and deletion.
  virtual bool OnWillRead(int request_id,
                          net::IOBuffer** buf,
                          int* buf_size,
                          int min_size) OVERRIDE;

  virtual bool OnReadCompleted(int request_id, int* bytes_read) OVERRIDE;

  virtual bool OnResponseCompleted(int request_id,
                                   const net::URLRequestStatus& status,
                                   const std::string& security_info) OVERRIDE;
  virtual void OnRequestClosed() OVERRIDE;

  // 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 set_content_length(const int64& content_length);

  void set_content_disposition(const std::string& content_disposition);

  void CheckWriteProgress();

  std::string DebugString() const;

 private:
  virtual ~DownloadResourceHandler();

  void OnResponseCompletedInternal(int request_id,
                                   const net::URLRequestStatus& status,
                                   const std::string& security_info);

  void StartPauseTimer();
  void CallStartedCB(content::DownloadId id, net::Error error);

  // Generates a DownloadId and calls DownloadFileManager.
  void StartOnUIThread(scoped_ptr<DownloadCreateInfo> info,
                       const DownloadRequestHandle& handle);
  void set_download_id(content::DownloadId id);

  content::DownloadId download_id_;
  content::GlobalRequestID global_id_;
  int render_view_id_;
  scoped_refptr<net::IOBuffer> read_buffer_;
  std::string content_disposition_;
  int64 content_length_;
  DownloadFileManager* download_file_manager_;
  net::URLRequest* request_;
  // This is used only on the UI thread.
  OnStartedCallback started_cb_;
  DownloadSaveInfo save_info_;
  scoped_refptr<content::DownloadBuffer> buffer_;
  bool is_paused_;
  base::OneShotTimer<DownloadResourceHandler> pause_timer_;

  // The following are used to collect stats.
  base::TimeTicks download_start_time_;
  base::TimeTicks last_read_time_;
  size_t last_buffer_size_;
  int64 bytes_read_;
  std::string accept_ranges_;

  static const int kReadBufSize = 32768;  // bytes
  static const int kThrottleTimeMs = 200;  // milliseconds

  DISALLOW_COPY_AND_ASSIGN(DownloadResourceHandler);
};

#endif  // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_RESOURCE_HANDLER_H_