blob: 4824e3fa3bc6fff26748916f19f6ad06094f6e65 [file] [log] [blame]
[email protected]de0fdca22014-08-19 05:26:091// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]afa378f22013-12-02 03:37:542// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
sorin52ac0882015-01-24 01:15:005#ifndef COMPONENTS_UPDATE_CLIENT_CRX_DOWNLOADER_H_
6#define COMPONENTS_UPDATE_CLIENT_CRX_DOWNLOADER_H_
[email protected]afa378f22013-12-02 03:37:547
sorin5cb1f5492014-09-23 04:07:448#include <stdint.h>
dchengd0fc6aa92016-04-22 18:03:129
10#include <memory>
sorin74e70672016-02-03 03:13:1011#include <string>
[email protected]afa378f22013-12-02 03:37:5412#include <vector>
[email protected]bf46313712014-01-02 22:56:1613
[email protected]afa378f22013-12-02 03:37:5414#include "base/callback.h"
15#include "base/files/file_path.h"
sorin5cb1f5492014-09-23 04:07:4416#include "base/macros.h"
[email protected]afa378f22013-12-02 03:37:5417#include "base/memory/ref_counted.h"
Sorin Jianuebd652462017-07-23 02:00:5818#include "base/single_thread_task_runner.h"
[email protected]ed6fb982014-07-23 16:56:5219#include "base/threading/thread_checker.h"
[email protected]afa378f22013-12-02 03:37:5420#include "url/gurl.h"
21
sorin52ac0882015-01-24 01:15:0022namespace update_client {
[email protected]afa378f22013-12-02 03:37:5423
Sorin Jianu75e6bf22019-02-12 16:07:1224class NetworkFetcherFactory;
25
[email protected]afa378f22013-12-02 03:37:5426// Defines a download interface for downloading components, with retrying on
27// fallback urls in case of errors. This class implements a chain of
28// responsibility design pattern. It can give successors in the chain a chance
29// to handle a download request, until one of them succeeds, or there are no
30// more urls or successors to try. A callback is always called at the end of
31// the download, one time only.
32// When multiple urls and downloaders exists, first all the urls are tried, in
33// the order they are provided in the StartDownload function argument. After
34// that, the download request is routed to the next downloader in the chain.
[email protected]ed6fb982014-07-23 16:56:5235// The members of this class expect to be called from the main thread only.
[email protected]afa378f22013-12-02 03:37:5436class CrxDownloader {
[email protected]3cb2a4f2013-12-07 21:54:3437 public:
[email protected]3a0092d2013-12-18 03:04:3538 struct DownloadMetrics {
[email protected]d0c8b8b42014-05-06 05:11:4539 enum Downloader { kNone = 0, kUrlFetcher, kBits };
[email protected]3a0092d2013-12-18 03:04:3540
41 DownloadMetrics();
42
43 GURL url;
44
45 Downloader downloader;
46
47 int error;
48
sorin5cb1f5492014-09-23 04:07:4449 int64_t downloaded_bytes; // -1 means that the byte count is unknown.
50 int64_t total_bytes;
[email protected]3a0092d2013-12-18 03:04:3551
sorin5cb1f5492014-09-23 04:07:4452 uint64_t download_time_ms;
[email protected]3a0092d2013-12-18 03:04:3553 };
54
[email protected]8a5ebd432014-05-02 00:21:2255 // Contains the progress or the outcome of the download.
[email protected]3cb2a4f2013-12-07 21:54:3456 struct Result {
[email protected]3cb2a4f2013-12-07 21:54:3457 // Download error: 0 indicates success.
Antonio Gomes31237fb2018-08-27 19:11:0358 int error = 0;
[email protected]3cb2a4f2013-12-07 21:54:3459
[email protected]3cb2a4f2013-12-07 21:54:3460 // Path of the downloaded file if the download was successful.
61 base::FilePath response;
62 };
63
[email protected]afa378f22013-12-02 03:37:5464 // The callback fires only once, regardless of how many urls are tried, and
65 // how many successors in the chain of downloaders have handled the
66 // download. The callback interface can be extended if needed to provide
67 // more visibility into how the download has been handled, including
68 // specific error codes and download metrics.
Sorin Jianua8ef73d2017-11-02 16:55:1769 using DownloadCallback = base::OnceCallback<void(const Result& result)>;
[email protected]afa378f22013-12-02 03:37:5470
Antonio Gomes31237fb2018-08-27 19:11:0371 // The callback may fire 0 or once during a download. Since this
[email protected]8a5ebd432014-05-02 00:21:2272 // class implements a chain of responsibility, the callback can fire for
Antonio Gomes31237fb2018-08-27 19:11:0373 // different urls and different downloaders.
74 using ProgressCallback = base::RepeatingCallback<void()>;
sorin9797aba2015-04-17 17:15:0375
Sorin Jianu75e6bf22019-02-12 16:07:1276 using Factory =
77 std::unique_ptr<CrxDownloader> (*)(bool,
78 scoped_refptr<NetworkFetcherFactory>);
[email protected]8a5ebd432014-05-02 00:21:2279
[email protected]afa378f22013-12-02 03:37:5480 // Factory method to create an instance of this class and build the
[email protected]3cb2a4f2013-12-07 21:54:3481 // chain of responsibility. |is_background_download| specifies that a
82 // background downloader be used, if the platform supports it.
sorin74e70672016-02-03 03:13:1083 // |task_runner| should be a task runner able to run blocking
84 // code such as file IO operations.
dchengd0fc6aa92016-04-22 18:03:1285 static std::unique_ptr<CrxDownloader> Create(
[email protected]3cb2a4f2013-12-07 21:54:3486 bool is_background_download,
Sorin Jianu75e6bf22019-02-12 16:07:1287 scoped_refptr<NetworkFetcherFactory> network_fetcher_factory);
[email protected]afa378f22013-12-02 03:37:5488 virtual ~CrxDownloader();
89
[email protected]8a5ebd432014-05-02 00:21:2290 void set_progress_callback(const ProgressCallback& progress_callback);
91
[email protected]afa378f22013-12-02 03:37:5492 // Starts the download. One instance of the class handles one download only.
[email protected]da37c1d2013-12-19 01:04:3893 // One instance of CrxDownloader can only be started once, otherwise the
94 // behavior is undefined. The callback gets invoked if the download can't
sorin74e70672016-02-03 03:13:1095 // be started. |expected_hash| represents the SHA256 cryptographic hash of
96 // the download payload, represented as a hexadecimal string.
[email protected]1b6587dc52014-04-26 00:38:5597 void StartDownloadFromUrl(const GURL& url,
sorin74e70672016-02-03 03:13:1098 const std::string& expected_hash,
Sorin Jianua8ef73d2017-11-02 16:55:1799 DownloadCallback download_callback);
[email protected]1b6587dc52014-04-26 00:38:55100 void StartDownload(const std::vector<GURL>& urls,
sorin74e70672016-02-03 03:13:10101 const std::string& expected_hash,
Sorin Jianua8ef73d2017-11-02 16:55:17102 DownloadCallback download_callback);
[email protected]afa378f22013-12-02 03:37:54103
[email protected]3a0092d2013-12-18 03:04:35104 const std::vector<DownloadMetrics> download_metrics() const;
105
[email protected]afa378f22013-12-02 03:37:54106 protected:
Sorin Jianu72d8fe0d2017-07-11 18:42:16107 explicit CrxDownloader(std::unique_ptr<CrxDownloader> successor);
[email protected]afa378f22013-12-02 03:37:54108
[email protected]3cb2a4f2013-12-07 21:54:34109 // Handles the fallback in the case of multiple urls and routing of the
110 // download to the following successor in the chain. Derived classes must call
111 // this function after each attempt at downloading the urls provided
112 // in the StartDownload function.
113 // In case of errors, |is_handled| indicates that a server side error has
114 // occured for the current url and the url should not be retried down
115 // the chain to avoid DDOS of the server. This url will be removed from the
116 // list of url and never tried again.
[email protected]3a0092d2013-12-18 03:04:35117 void OnDownloadComplete(bool is_handled,
118 const Result& result,
119 const DownloadMetrics& download_metrics);
120
[email protected]8a5ebd432014-05-02 00:21:22121 // Calls the callback when progress is made.
Antonio Gomes31237fb2018-08-27 19:11:03122 void OnDownloadProgress();
[email protected]8a5ebd432014-05-02 00:21:22123
124 // Returns the url which is currently being downloaded from.
[email protected]3a0092d2013-12-18 03:04:35125 GURL url() const;
[email protected]afa378f22013-12-02 03:37:54126
Sorin Jianuebd652462017-07-23 02:00:58127 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const {
sorin74e70672016-02-03 03:13:10128 return main_task_runner_;
129 }
130
[email protected]afa378f22013-12-02 03:37:54131 private:
132 virtual void DoStartDownload(const GURL& url) = 0;
133
sorin74e70672016-02-03 03:13:10134 void VerifyResponse(bool is_handled,
135 Result result,
136 DownloadMetrics download_metrics);
137
138 void HandleDownloadError(bool is_handled,
139 const Result& result,
140 const DownloadMetrics& download_metrics);
141
[email protected]ed6fb982014-07-23 16:56:52142 base::ThreadChecker thread_checker_;
143
sorin74e70672016-02-03 03:13:10144 // Used to post callbacks to the main thread.
Sorin Jianuebd652462017-07-23 02:00:58145 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
sorin74e70672016-02-03 03:13:10146
[email protected]afa378f22013-12-02 03:37:54147 std::vector<GURL> urls_;
sorin74e70672016-02-03 03:13:10148
149 // The SHA256 hash of the download payload in hexadecimal format.
150 std::string expected_hash_;
dchengd0fc6aa92016-04-22 18:03:12151 std::unique_ptr<CrxDownloader> successor_;
[email protected]afa378f22013-12-02 03:37:54152 DownloadCallback download_callback_;
[email protected]8a5ebd432014-05-02 00:21:22153 ProgressCallback progress_callback_;
[email protected]afa378f22013-12-02 03:37:54154
[email protected]3cb2a4f2013-12-07 21:54:34155 std::vector<GURL>::iterator current_url_;
[email protected]afa378f22013-12-02 03:37:54156
[email protected]3a0092d2013-12-18 03:04:35157 std::vector<DownloadMetrics> download_metrics_;
158
[email protected]afa378f22013-12-02 03:37:54159 DISALLOW_COPY_AND_ASSIGN(CrxDownloader);
160};
161
sorin52ac0882015-01-24 01:15:00162} // namespace update_client
[email protected]afa378f22013-12-02 03:37:54163
sorin52ac0882015-01-24 01:15:00164#endif // COMPONENTS_UPDATE_CLIENT_CRX_DOWNLOADER_H_