summaryrefslogtreecommitdiff
path: root/chromium/components/download/public/common/download_url_parameters.h
blob: 2460b37210a683783a30de00bd304daeea8d2359 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
// Copyright 2018 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 COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_URL_PARAMETERS_H_
#define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_URL_PARAMETERS_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/optional.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_save_info.h"
#include "components/download/public/common/download_source.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace download {

class DownloadItem;

// Pass an instance of DownloadUrlParameters to DownloadManager::DownloadUrl()
// to download the content at |url|. All parameters with setters are optional.
// |referrer| and |referrer_encoding| are the referrer for the download. If
// |prefer_cache| is true, then if the response to |url| is in the HTTP cache it
// will be used without revalidation. If |post_id| is non-negative, then it
// identifies the post transaction used to originally retrieve the |url|
// resource - it also requires |prefer_cache| to be |true| since re-post'ing is
// not done.  |save_info| specifies where the downloaded file should be saved,
// and whether the user should be prompted about the download.  If not null,
// |callback| will be called when the download starts, or if an error occurs
// that prevents a download item from being created.  We send a pointer to
// content::ResourceContext instead of the usual reference so that a copy of the
// object isn't made.

class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters {
 public:
  // An OnStartedCallback is invoked when a response is available for the
  // download request. For new downloads, this callback is invoked after the
  // OnDownloadCreated notification is issued by the DownloadManager. If the
  // download fails, then the DownloadInterruptReason parameter will indicate
  // the failure.
  //
  // DownloadItem* may be nullptr if no DownloadItem was created. DownloadItems
  // are not created when a resource throttle or a resource handler blocks the
  // download request. I.e. the download triggered a warning of some sort and
  // the user chose to not to proceed with the download as a result.
  typedef base::Callback<void(DownloadItem*, DownloadInterruptReason)>
      OnStartedCallback;

  typedef std::pair<std::string, std::string> RequestHeadersNameValuePair;
  typedef std::vector<RequestHeadersNameValuePair> RequestHeadersType;

  using BlobStorageContextGetter =
      base::OnceCallback<storage::BlobStorageContext*()>;
  using UploadProgressCallback =
      base::RepeatingCallback<void(uint64_t bytes_uploaded)>;

  // Constructs a download not associated with a frame.
  //
  // It is not safe to have downloads not associated with a frame and
  // this should only be done in a limited set of cases where the download URL
  // has been previously vetted. A download that's initiated without
  // associating it with a frame don't receive the same security checks
  // as a request that's associated with one. Hence, downloads that are not
  // associated with a frame should only be made for URLs that are either
  // trusted or URLs that have previously been successfully issued using a
  // non-privileged frame.
  DownloadUrlParameters(
      const GURL& url,
      const net::NetworkTrafficAnnotationTag& traffic_annotation);

  // The RenderView routing ID must correspond to the RenderView of the
  // RenderFrame, both of which share the same RenderProcess. This may be a
  // different RenderView than the WebContents' main RenderView.
  DownloadUrlParameters(
      const GURL& url,
      int render_process_host_id,
      int render_view_host_routing_id,
      int render_frame_host_routing_id,
      const net::NetworkTrafficAnnotationTag& traffic_annotation);

  ~DownloadUrlParameters();

  // Should be set to true if the download was initiated by a script or a web
  // page. I.e. if the download request cannot be attributed to an explicit user
  // request for a download, then set this value to true.
  void set_content_initiated(bool content_initiated) {
    content_initiated_ = content_initiated;
  }
  void add_request_header(const std::string& name, const std::string& value) {
    request_headers_.push_back(make_pair(name, value));
  }

  // HTTP Referrer, referrer policy and encoding.
  void set_referrer(const GURL& referrer) { referrer_ = referrer; }
  void set_referrer_policy(net::URLRequest::ReferrerPolicy referrer_policy) {
    referrer_policy_ = referrer_policy;
  }
  void set_referrer_encoding(const std::string& referrer_encoding) {
    referrer_encoding_ = referrer_encoding;
  }

  // The origin of the context which initiated the request. See
  // net::URLRequest::initiator().
  void set_initiator(const base::Optional<url::Origin>& initiator) {
    initiator_ = initiator;
  }

  // If this is a request for resuming an HTTP/S download, |last_modified|
  // should be the value of the last seen Last-Modified response header.
  void set_last_modified(const std::string& last_modified) {
    last_modified_ = last_modified;
  }

  // If this is a request for resuming an HTTP/S download, |etag| should be the
  // last seen Etag response header.
  void set_etag(const std::string& etag) { etag_ = etag; }

  // If the "If-Range" header is used in a partial request.
  void set_use_if_range(bool use_if_range) { use_if_range_ = use_if_range; }

  // HTTP method to use.
  void set_method(const std::string& method) { method_ = method; }

  // Body of the HTTP POST request.
  void set_post_body(scoped_refptr<network::ResourceRequestBody> post_body) {
    post_body_ = post_body;
  }

  // The blob storage context to be used for uploading blobs, if any.
  void set_blob_storage_context_getter(BlobStorageContextGetter blob_getter) {
    blob_storage_context_getter_ = std::move(blob_getter);
  }

  // If |prefer_cache| is true and the response to |url| is in the HTTP cache,
  // it will be used without validation. If |method| is POST, then |post_id_|
  // shoud be set via |set_post_id()| below to the identifier of the POST
  // transaction used to originally retrieve the resource.
  void set_prefer_cache(bool prefer_cache) { prefer_cache_ = prefer_cache; }

  // See set_prefer_cache() above.
  void set_post_id(int64_t post_id) { post_id_ = post_id; }

  // See OnStartedCallback above.
  void set_callback(const OnStartedCallback& callback) { callback_ = callback; }

  // If not empty, specifies the full target path for the download. This value
  // overrides the filename suggested by a Content-Disposition headers. It
  // should only be set for programmatic downloads where the caller can verify
  // the safety of the filename and the resulting download.
  void set_file_path(const base::FilePath& file_path) {
    save_info_.file_path = file_path;
  }

  // Suggested filename for the download. The suggestion can be overridden by
  // either a Content-Disposition response header or a |file_path|.
  void set_suggested_name(const base::string16& suggested_name) {
    save_info_.suggested_name = suggested_name;
  }

  // If |offset| is non-zero, then a byte range request will be issued to fetch
  // the range of bytes starting at |offset|.
  // Use |set_length| to specify the last byte position, or the range
  // request will be "Range:bytes={offset}-" to retrieve the rest of the file.
  void set_offset(int64_t offset) { save_info_.offset = offset; }

  // When |length| > 0, the range of bytes will be from
  // |save_info_.offset| to |save_info_.offset| + |length| - 1.
  // See |DownloadSaveInfo.length|.
  void set_length(int64_t length) { save_info_.length = length; }

  // Sets the offset to start writing to the file. If set, The data received
  // before |file_offset| are discarded or are used for validation purpose.
  void set_file_offset(int64_t file_offset) {
    save_info_.file_offset = file_offset;
  }

  // If |offset| is non-zero, then |hash_of_partial_file| contains the raw
  // SHA-256 hash of the first |offset| bytes of the target file. Only
  // meaningful if a partial file exists and is identified by either the
  // |file_path()| or |file()|.
  void set_hash_of_partial_file(const std::string& hash_of_partial_file) {
    save_info_.hash_of_partial_file = hash_of_partial_file;
  }

  // If |offset| is non-zero, then |hash_state| indicates the SHA-256 hash state
  // of the first |offset| bytes of the target file. In this case, the prefix
  // hash will be ignored since the |hash_state| is assumed to be correct if
  // provided.
  void set_hash_state(std::unique_ptr<crypto::SecureHash> hash_state) {
    save_info_.hash_state = std::move(hash_state);
  }

  // If |prompt| is true, then the user will be prompted for a filename. Ignored
  // if |file_path| is non-empty.
  void set_prompt(bool prompt) { save_info_.prompt_for_save_location = prompt; }
  void set_file(base::File file) { save_info_.file = std::move(file); }
  void set_do_not_prompt_for_login(bool do_not_prompt) {
    do_not_prompt_for_login_ = do_not_prompt;
  }

  // If |cross_origin_redirects| is kFollow, we will follow cross origin
  // redirects while downloading.  If it is kManual, then we'll attempt to
  // navigate to the URL or cancel the download.  If it is kError, then we will
  // fail the download (kFail).
  void set_cross_origin_redirects(
      network::mojom::RedirectMode cross_origin_redirects) {
    cross_origin_redirects_ = cross_origin_redirects;
  }

  // Sets whether to download the response body even if the server returns
  // non-successful HTTP response code, like "HTTP NOT FOUND".
  void set_fetch_error_body(bool fetch_error_body) {
    fetch_error_body_ = fetch_error_body;
  }

  // A transient download will not be shown in the UI, and will not prompt
  // to user for target file path determination. Transient download should be
  // cleared properly through DownloadManager to avoid the database and
  // in-memory DownloadItem objects accumulated for the user.
  void set_transient(bool transient) { transient_ = transient; }

  // Sets the optional guid for the download, the guid serves as the unique
  // identitfier for the download item. If no guid is provided, download
  // system will automatically generate one.
  void set_guid(const std::string& guid) { guid_ = guid; }

  // For downloads originating from custom tabs, this records the origin
  // of the custom tab.
  void set_request_origin(const std::string& origin) {
    request_origin_ = origin;
  }

  // Sets the download source, which will be used in metrics recording.
  void set_download_source(DownloadSource download_source) {
    download_source_ = download_source;
  }

  // Sets the callback to run if there are upload progress updates.
  void set_upload_progress_callback(
      const UploadProgressCallback& upload_callback) {
    upload_callback_ = upload_callback;
  }

  // Sets whether the download will require safety checks for its URL chain and
  // downloaded content.
  void set_require_safety_checks(bool require_safety_checks) {
    require_safety_checks_ = require_safety_checks;
  }

  // Sets whether to ignore content length mismatch errors.
  void set_ignore_content_length_mismatch(bool ignore_content_length_mismatch) {
    ignore_content_length_mismatch_ = ignore_content_length_mismatch;
  }

  const OnStartedCallback& callback() const { return callback_; }
  bool content_initiated() const { return content_initiated_; }
  const std::string& last_modified() const { return last_modified_; }
  const std::string& etag() const { return etag_; }
  bool use_if_range() const { return use_if_range_; }
  const std::string& method() const { return method_; }
  scoped_refptr<network::ResourceRequestBody> post_body() { return post_body_; }
  int64_t post_id() const { return post_id_; }
  bool prefer_cache() const { return prefer_cache_; }
  const GURL& referrer() const { return referrer_; }
  net::URLRequest::ReferrerPolicy referrer_policy() const {
    return referrer_policy_;
  }
  const std::string& referrer_encoding() const { return referrer_encoding_; }
  const base::Optional<url::Origin>& initiator() const { return initiator_; }
  const std::string& request_origin() const { return request_origin_; }
  BlobStorageContextGetter get_blob_storage_context_getter() {
    return std::move(blob_storage_context_getter_);
  }

  // These will be -1 if the request is not associated with a frame. See
  // the constructors for more.
  int render_process_host_id() const { return render_process_host_id_; }
  int render_view_host_routing_id() const {
    return render_view_host_routing_id_;
  }
  int render_frame_host_routing_id() const {
    return render_frame_host_routing_id_;
  }

  void set_frame_tree_node_id(int id) { frame_tree_node_id_ = id; }
  int frame_tree_node_id() const { return frame_tree_node_id_; }

  const RequestHeadersType& request_headers() const { return request_headers_; }
  const base::FilePath& file_path() const { return save_info_.file_path; }
  const base::string16& suggested_name() const {
    return save_info_.suggested_name;
  }
  int64_t offset() const { return save_info_.offset; }
  int64_t length() const { return save_info_.length; }
  const std::string& hash_of_partial_file() const {
    return save_info_.hash_of_partial_file;
  }
  bool prompt() const { return save_info_.prompt_for_save_location; }
  const GURL& url() const { return url_; }
  bool do_not_prompt_for_login() const { return do_not_prompt_for_login_; }
  network::mojom::RedirectMode cross_origin_redirects() const {
    return cross_origin_redirects_;
  }
  bool fetch_error_body() const { return fetch_error_body_; }
  bool is_transient() const { return transient_; }
  std::string guid() const { return guid_; }
  bool require_safety_checks() const { return require_safety_checks_; }
  bool ignore_content_length_mismatch() const {
    return ignore_content_length_mismatch_;
  }

  // STATE CHANGING: All save_info_ sub-objects will be in an indeterminate
  // state following this call.
  DownloadSaveInfo GetSaveInfo() { return std::move(save_info_); }

  const net::NetworkTrafficAnnotationTag& GetNetworkTrafficAnnotation() {
    return traffic_annotation_;
  }

  DownloadSource download_source() const { return download_source_; }

  const UploadProgressCallback& upload_callback() const {
    return upload_callback_;
  }

 private:
  OnStartedCallback callback_;
  bool content_initiated_;
  RequestHeadersType request_headers_;
  std::string last_modified_;
  std::string etag_;
  bool use_if_range_;
  std::string method_;
  scoped_refptr<network::ResourceRequestBody> post_body_;
  BlobStorageContextGetter blob_storage_context_getter_;
  int64_t post_id_;
  bool prefer_cache_;
  GURL referrer_;
  net::URLRequest::ReferrerPolicy referrer_policy_;
  base::Optional<url::Origin> initiator_;
  std::string referrer_encoding_;
  int render_process_host_id_;
  int render_view_host_routing_id_;
  int render_frame_host_routing_id_;
  int frame_tree_node_id_;
  DownloadSaveInfo save_info_;
  GURL url_;
  bool do_not_prompt_for_login_;
  network::mojom::RedirectMode cross_origin_redirects_;
  bool fetch_error_body_;
  bool transient_;
  std::string guid_;
  const net::NetworkTrafficAnnotationTag traffic_annotation_;
  std::string request_origin_;
  DownloadSource download_source_;
  UploadProgressCallback upload_callback_;
  bool require_safety_checks_;
  bool ignore_content_length_mismatch_;

  DISALLOW_COPY_AND_ASSIGN(DownloadUrlParameters);
};

}  // namespace download

#endif  // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_URL_PARAMETERS_H_