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

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: Addressed Chris's comments 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/guid.h"
16 #include "base/location.h"
10 #include "base/logging.h" 17 #include "base/logging.h"
11 #include "base/macros.h" 18 #include "base/macros.h"
19 #include "base/memory/ptr_util.h"
20 #include "base/memory/ref_counted.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/task_runner_util.h"
23 #include "base/task_scheduler/post_task.h"
12 #include "chrome/browser/browser_process.h" 24 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" 25 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
14 #include "components/data_use_measurement/core/data_use_user_data.h" 26 #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" 27 #include "content/public/browser/browser_thread.h"
17 #include "net/base/load_flags.h" 28 #include "net/base/load_flags.h"
18 #include "net/http/http_request_headers.h" 29 #include "net/http/http_request_headers.h"
19 #include "net/http/http_status_code.h" 30 #include "net/http/http_status_code.h"
20 #include "net/url_request/url_fetcher.h" 31 #include "net/url_request/url_fetcher.h"
21 #include "net/url_request/url_fetcher_delegate.h" 32 #include "net/url_request/url_fetcher_delegate.h"
22 #include "net/url_request/url_request_context_getter.h" 33 #include "net/url_request/url_request_context_getter.h"
23 #include "url/gurl.h" 34 #include "url/gurl.h"
24 35
25 namespace safe_browsing { 36 namespace safe_browsing {
26 37
27 namespace { 38 namespace {
28 39
29 // Class that will attempt to download the Chrome Cleaner executable and 40 // Class that will attempt to download the Chrome Cleaner executable and call a
30 // call a given callback when done. Instances of ChromeCleanerFetcher own 41 // given callback when done. Instances of ChromeCleanerFetcher own themselves
31 // themselves and will self-delete on completion of the network request. 42 // and will self-delete if they encounter an error or when the network request
43 // has completed.
32 class ChromeCleanerFetcher : public net::URLFetcherDelegate { 44 class ChromeCleanerFetcher : public net::URLFetcherDelegate {
33 public: 45 public:
34 explicit ChromeCleanerFetcher(ChromeCleanerFetchedCallback fetched_callback); 46 explicit ChromeCleanerFetcher(ChromeCleanerFetchedCallback fetched_callback);
35 47
36 protected: 48 protected:
37 ~ChromeCleanerFetcher() override; 49 ~ChromeCleanerFetcher() override;
38 50
39 private: 51 private:
52 // Must be called on a sequence where IO is allowed.
53 bool CreateTemporaryDirectory();
54 // Will be called back on the same sequence as this object was created on.
55 void OnTemporaryDirectoryCreated(bool success);
56 void PostCallbackAndDeleteSelf(base::FilePath path,
57 ChromeCleanerFetchStatus fetch_status);
58
40 // net::URLFetcherDelegate overrides. 59 // net::URLFetcherDelegate overrides.
41 void OnURLFetchComplete(const net::URLFetcher* source) override; 60 void OnURLFetchComplete(const net::URLFetcher* source) override;
42 61
43 ChromeCleanerFetchedCallback fetched_callback_; 62 ChromeCleanerFetchedCallback fetched_callback_;
63
44 // The underlying URL fetcher. The instance is alive from construction through 64 // The underlying URL fetcher. The instance is alive from construction through
45 // OnURLFetchComplete. 65 // OnURLFetchComplete.
46 std::unique_ptr<net::URLFetcher> url_fetcher_; 66 std::unique_ptr<net::URLFetcher> url_fetcher_;
47 67
68 // Used for file operations such as creating a new temporary directory.
69 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
70
71 // We will take ownership of the scoped temp directory once we know that the
72 // fetch has succeeded. Must be deleted on a sequence where IO is allowed.
73 std::unique_ptr<base::ScopedTempDir, content::BrowserThread::DeleteOnIOThread>
74 scoped_temp_dir_;
75 base::FilePath temp_file_;
76
48 DISALLOW_COPY_AND_ASSIGN(ChromeCleanerFetcher); 77 DISALLOW_COPY_AND_ASSIGN(ChromeCleanerFetcher);
49 }; 78 };
50 79
51 ChromeCleanerFetcher::ChromeCleanerFetcher( 80 ChromeCleanerFetcher::ChromeCleanerFetcher(
52 ChromeCleanerFetchedCallback fetched_callback) 81 ChromeCleanerFetchedCallback fetched_callback)
53 : fetched_callback_(std::move(fetched_callback)), 82 : fetched_callback_(std::move(fetched_callback)),
54 url_fetcher_(net::URLFetcher::Create(0, 83 url_fetcher_(net::URLFetcher::Create(0,
55 GURL(GetSRTDownloadURL()), 84 GURL(GetSRTDownloadURL()),
56 net::URLFetcher::GET, 85 net::URLFetcher::GET,
57 this)) { 86 this)),
87 blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
88 {base::MayBlock(), base::TaskPriority::BACKGROUND,
89 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
90 scoped_temp_dir_(new base::ScopedTempDir()) {
91 base::PostTaskAndReplyWithResult(
92 blocking_task_runner_.get(), FROM_HERE,
93 base::Bind(&ChromeCleanerFetcher::CreateTemporaryDirectory,
94 base::Unretained(this)),
95 base::Bind(&ChromeCleanerFetcher::OnTemporaryDirectoryCreated,
96 base::Unretained(this)));
97 }
98
99 ChromeCleanerFetcher::~ChromeCleanerFetcher() = default;
100
101 bool ChromeCleanerFetcher::CreateTemporaryDirectory() {
102 base::FilePath temp_dir;
103 return base::CreateNewTempDirectory(FILE_PATH_LITERAL("cleaner_"),
104 &temp_dir) &&
105 scoped_temp_dir_->Set(temp_dir);
106 }
107
108 void ChromeCleanerFetcher::OnTemporaryDirectoryCreated(bool success) {
109 if (!success) {
110 PostCallbackAndDeleteSelf(
111 base::FilePath(),
112 ChromeCleanerFetchStatus::kFailedToCreateTemporaryDirectory);
113 return;
114 }
115
116 DCHECK(!scoped_temp_dir_->GetPath().empty());
117
118 temp_file_ = scoped_temp_dir_->GetPath().Append(
119 base::ASCIIToUTF16(base::GenerateGUID()) + L".tmp");
csharp 2017/06/06 19:43:24 Would it make sense to make the file type exe, sin
alito 2017/06/06 19:55:52 As discussed, it might be slightly preferable to a
120
58 data_use_measurement::DataUseUserData::AttachToFetcher( 121 data_use_measurement::DataUseUserData::AttachToFetcher(
59 url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING); 122 url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
60 url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE); 123 url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
61 url_fetcher_->SetMaxRetriesOn5xx(3); 124 url_fetcher_->SetMaxRetriesOn5xx(3);
62 url_fetcher_->SaveResponseToTemporaryFile( 125 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()); 126 url_fetcher_->SetRequestContext(g_browser_process->system_request_context());
66 url_fetcher_->Start(); 127 url_fetcher_->Start();
67 } 128 }
68 129
69 ChromeCleanerFetcher::~ChromeCleanerFetcher() = default; 130 void ChromeCleanerFetcher::PostCallbackAndDeleteSelf(
131 base::FilePath path,
132 ChromeCleanerFetchStatus fetch_status) {
133 DCHECK(fetched_callback_);
70 134
71 void ChromeCleanerFetcher::OnURLFetchComplete(const net::URLFetcher* source) { 135 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 136
86 // Since url_fetcher_ is passed a pointer to this object during construction, 137 // Since url_fetcher_ is passed a pointer to this object during construction,
87 // explicitly destroy the url_fetcher_ to avoid potential destruction races. 138 // explicitly destroy the url_fetcher_ to avoid potential destruction races.
88 url_fetcher_.reset(); 139 url_fetcher_.reset();
89 140
90 // At this point, the url_fetcher_ is gone and this ChromeCleanerFetcher 141 // At this point, the url_fetcher_ is gone and this ChromeCleanerFetcher
91 // instance is no longer needed. 142 // instance is no longer needed.
92 delete this; 143 delete this;
93 } 144 }
94 145
146 void ChromeCleanerFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
147 // Take ownership of the fetcher in this scope (source == url_fetcher_).
148 DCHECK_EQ(url_fetcher_.get(), source);
149 DCHECK(!source->GetStatus().is_io_pending());
150 DCHECK(fetched_callback_);
151
152 if (source->GetResponseCode() == net::HTTP_NOT_FOUND) {
153 PostCallbackAndDeleteSelf(base::FilePath(),
154 ChromeCleanerFetchStatus::kNotFoundOnServer);
155 return;
156 }
157
158 base::FilePath download_path;
159 if (!source->GetStatus().is_success() ||
160 source->GetResponseCode() != net::HTTP_OK ||
161 !source->GetResponseAsFilePath(/*take_ownership=*/true, &download_path)) {
162 PostCallbackAndDeleteSelf(base::FilePath(),
163 ChromeCleanerFetchStatus::kOtherFailure);
164 return;
165 }
166
167 DCHECK(!download_path.empty());
168 DCHECK_EQ(temp_file_.value(), download_path.value());
169
170 // Take ownership of the scoped temp directory so it is not deleted.
171 scoped_temp_dir_->Take();
172
173 PostCallbackAndDeleteSelf(std::move(download_path),
174 ChromeCleanerFetchStatus::kSuccess);
175 }
176
95 } // namespace 177 } // namespace
96 178
97 void FetchChromeCleaner(ChromeCleanerFetchedCallback fetched_callback) { 179 void FetchChromeCleaner(ChromeCleanerFetchedCallback fetched_callback) {
98 new ChromeCleanerFetcher(std::move(fetched_callback)); 180 new ChromeCleanerFetcher(std::move(fetched_callback));
99 } 181 }
100 182
101 } // namespace safe_browsing 183 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698