Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(337)

Side by Side Diff: chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc

Issue 2929483002: Chrome Cleaner: download the Chrome Cleaner executable in an empty directory. (Closed)
Patch Set: Cleanup Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win .h" 5 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win .h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/location.h"
10 #include "base/logging.h" 16 #include "base/logging.h"
11 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/task_runner_util.h"
21 #include "base/task_scheduler/post_task.h"
12 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" 23 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
14 #include "components/data_use_measurement/core/data_use_user_data.h" 24 #include "components/data_use_measurement/core/data_use_user_data.h"
15 #include "components/variations/net/variations_http_headers.h"
16 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
17 #include "net/base/load_flags.h" 26 #include "net/base/load_flags.h"
18 #include "net/http/http_request_headers.h" 27 #include "net/http/http_request_headers.h"
19 #include "net/http/http_status_code.h" 28 #include "net/http/http_status_code.h"
20 #include "net/url_request/url_fetcher.h" 29 #include "net/url_request/url_fetcher.h"
21 #include "net/url_request/url_fetcher_delegate.h" 30 #include "net/url_request/url_fetcher_delegate.h"
22 #include "net/url_request/url_request_context_getter.h" 31 #include "net/url_request/url_request_context_getter.h"
23 #include "url/gurl.h" 32 #include "url/gurl.h"
24 33
25 namespace safe_browsing { 34 namespace safe_browsing {
26 35
27 namespace { 36 namespace {
28 37
29 // Class that will attempt to download the Chrome Cleaner executable and 38 // Class that will attempt to download the Chrome Cleaner executable and call a
30 // call a given callback when done. Instances of ChromeCleanerFetcher own 39 // given callback when done. Instances of ChromeCleanerFetcher own themselves
31 // themselves and will self-delete on completion of the network request. 40 // and will self-delete if they encounter an error or when the network request
41 // has completed.
32 class ChromeCleanerFetcher : public net::URLFetcherDelegate { 42 class ChromeCleanerFetcher : public net::URLFetcherDelegate {
33 public: 43 public:
34 explicit ChromeCleanerFetcher(ChromeCleanerFetchedCallback fetched_callback); 44 explicit ChromeCleanerFetcher(ChromeCleanerFetchedCallback fetched_callback);
35 45
36 protected: 46 protected:
37 ~ChromeCleanerFetcher() override; 47 ~ChromeCleanerFetcher() override;
38 48
39 private: 49 private:
50 // Must be called on a sequence where IO is allowed.
51 bool CreateTemporaryFile();
52 // Will be called back on the same sequence as this object was created on.
csharp 2017/06/06 19:01:53 nit: sequence -> task runner sequence? or maybe Se
alito 2017/06/06 19:32:44 Sequence seems to be fairly standard lingo now. Ta
53 void OnTemporaryFileCreated(bool success);
54 void PostCallbackAndDeleteSelf(base::FilePath path,
55 ChromeCleanerFetchStatus fetch_status);
56
40 // net::URLFetcherDelegate overrides. 57 // net::URLFetcherDelegate overrides.
41 void OnURLFetchComplete(const net::URLFetcher* source) override; 58 void OnURLFetchComplete(const net::URLFetcher* source) override;
42 59
43 ChromeCleanerFetchedCallback fetched_callback_; 60 ChromeCleanerFetchedCallback fetched_callback_;
61
44 // The underlying URL fetcher. The instance is alive from construction through 62 // The underlying URL fetcher. The instance is alive from construction through
45 // OnURLFetchComplete. 63 // OnURLFetchComplete.
46 std::unique_ptr<net::URLFetcher> url_fetcher_; 64 std::unique_ptr<net::URLFetcher> url_fetcher_;
47 65
66 // Used for file operations such as creating a new temporary directory.
67 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
68
69 // We will take ownership of the scoped temp directory once we know that the
70 // fetch has succeeded. Must be deleted on a sequence where IO is allowed.
71 std::unique_ptr<base::ScopedTempDir, content::BrowserThread::DeleteOnIOThread>
72 scoped_temp_dir_;
73 base::FilePath temp_file_;
74
48 DISALLOW_COPY_AND_ASSIGN(ChromeCleanerFetcher); 75 DISALLOW_COPY_AND_ASSIGN(ChromeCleanerFetcher);
49 }; 76 };
50 77
51 ChromeCleanerFetcher::ChromeCleanerFetcher( 78 ChromeCleanerFetcher::ChromeCleanerFetcher(
52 ChromeCleanerFetchedCallback fetched_callback) 79 ChromeCleanerFetchedCallback fetched_callback)
53 : fetched_callback_(std::move(fetched_callback)), 80 : fetched_callback_(std::move(fetched_callback)),
54 url_fetcher_(net::URLFetcher::Create(0, 81 url_fetcher_(net::URLFetcher::Create(0,
55 GURL(GetSRTDownloadURL()), 82 GURL(GetSRTDownloadURL()),
56 net::URLFetcher::GET, 83 net::URLFetcher::GET,
57 this)) { 84 this)),
85 blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
86 {base::MayBlock(), base::TaskPriority::BACKGROUND,
87 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
88 scoped_temp_dir_(new base::ScopedTempDir()) {
89 base::PostTaskAndReplyWithResult(
90 blocking_task_runner_.get(), FROM_HERE,
91 base::Bind(&ChromeCleanerFetcher::CreateTemporaryFile,
92 base::Unretained(this)),
93 base::Bind(&ChromeCleanerFetcher::OnTemporaryFileCreated,
94 base::Unretained(this)));
95 }
96
97 ChromeCleanerFetcher::~ChromeCleanerFetcher() = default;
98
99 bool ChromeCleanerFetcher::CreateTemporaryFile() {
100 return scoped_temp_dir_->CreateUniqueTempDir() &&
csharp 2017/06/06 19:01:53 AS discussed offline, you should create the path n
alito 2017/06/06 19:32:44 Done.
101 base::CreateTemporaryFileInDir(scoped_temp_dir_->GetPath(),
102 &temp_file_);
csharp 2017/06/06 19:01:54 Does a file need to be created here, or is this ju
alito 2017/06/06 19:32:44 Done.
103 }
104
105 void ChromeCleanerFetcher::OnTemporaryFileCreated(bool success) {
106 if (!success) {
107 PostCallbackAndDeleteSelf(
108 base::FilePath(),
109 ChromeCleanerFetchStatus::kFailedToCreateTemporaryFile);
110 return;
111 }
112
113 DCHECK(!temp_file_.empty());
114
58 data_use_measurement::DataUseUserData::AttachToFetcher( 115 data_use_measurement::DataUseUserData::AttachToFetcher(
59 url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING); 116 url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
60 url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE); 117 url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
61 url_fetcher_->SetMaxRetriesOn5xx(3); 118 url_fetcher_->SetMaxRetriesOn5xx(3);
62 url_fetcher_->SaveResponseToTemporaryFile( 119 url_fetcher_->SaveResponseToFileAtPath(temp_file_, blocking_task_runner_);
63 content::BrowserThread::GetTaskRunnerForThread(
64 content::BrowserThread::FILE));
65 url_fetcher_->SetRequestContext(g_browser_process->system_request_context()); 120 url_fetcher_->SetRequestContext(g_browser_process->system_request_context());
66 url_fetcher_->Start(); 121 url_fetcher_->Start();
67 } 122 }
68 123
69 ChromeCleanerFetcher::~ChromeCleanerFetcher() = default; 124 void ChromeCleanerFetcher::PostCallbackAndDeleteSelf(
125 base::FilePath path,
126 ChromeCleanerFetchStatus fetch_status) {
127 DCHECK(fetched_callback_);
70 128
71 void ChromeCleanerFetcher::OnURLFetchComplete(const net::URLFetcher* source) { 129 std::move(fetched_callback_).Run(std::move(path), fetch_status);
72 // Take ownership of the fetcher in this scope (source == url_fetcher_).
73 DCHECK_EQ(url_fetcher_.get(), source);
74
75 base::FilePath download_path;
76 if (source->GetStatus().is_success() &&
77 source->GetResponseCode() == net::HTTP_OK &&
78 source->GetResponseAsFilePath(true, &download_path)) {
79 DCHECK(!download_path.empty());
80 }
81
82 DCHECK(fetched_callback_);
83 std::move(fetched_callback_)
84 .Run(std::move(download_path), source->GetResponseCode());
85 130
86 // Since url_fetcher_ is passed a pointer to this object during construction, 131 // Since url_fetcher_ is passed a pointer to this object during construction,
87 // explicitly destroy the url_fetcher_ to avoid potential destruction races. 132 // explicitly destroy the url_fetcher_ to avoid potential destruction races.
88 url_fetcher_.reset(); 133 url_fetcher_.reset();
89 134
90 // At this point, the url_fetcher_ is gone and this ChromeCleanerFetcher 135 // At this point, the url_fetcher_ is gone and this ChromeCleanerFetcher
91 // instance is no longer needed. 136 // instance is no longer needed.
92 delete this; 137 delete this;
93 } 138 }
94 139
140 void ChromeCleanerFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
141 // Take ownership of the fetcher in this scope (source == url_fetcher_).
142 DCHECK_EQ(url_fetcher_.get(), source);
143 DCHECK(!source->GetStatus().is_io_pending());
144 DCHECK(fetched_callback_);
145
146 if (source->GetResponseCode() == net::HTTP_NOT_FOUND) {
147 PostCallbackAndDeleteSelf(base::FilePath(),
148 ChromeCleanerFetchStatus::kNotFoundOnServer);
149 return;
150 }
151
152 base::FilePath download_path;
153 if (!source->GetStatus().is_success() ||
154 source->GetResponseCode() != net::HTTP_OK ||
155 !source->GetResponseAsFilePath(/*take_ownership=*/true, &download_path)) {
156 PostCallbackAndDeleteSelf(base::FilePath(),
157 ChromeCleanerFetchStatus::kOtherFailure);
158 return;
159 }
160
161 DCHECK(!download_path.empty());
162 DCHECK_EQ(temp_file_.value(), download_path.value());
163
164 // Take ownership of the scoped temp directory so it is not deleted.
165 scoped_temp_dir_->Take();
166
167 PostCallbackAndDeleteSelf(std::move(download_path),
168 ChromeCleanerFetchStatus::kSuccess);
169 }
170
95 } // namespace 171 } // namespace
96 172
97 void FetchChromeCleaner(ChromeCleanerFetchedCallback fetched_callback) { 173 void FetchChromeCleaner(ChromeCleanerFetchedCallback fetched_callback) {
98 new ChromeCleanerFetcher(std::move(fetched_callback)); 174 new ChromeCleanerFetcher(std::move(fetched_callback));
99 } 175 }
100 176
101 } // namespace safe_browsing 177 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698