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

Side by Side Diff: chrome/browser/safe_browsing/two_phase_uploader.cc

Issue 2851083002: Bind TwoPhaseUploader to a sequence, not a thread.
Patch Set: Created 3 years, 7 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
« no previous file with comments | « chrome/browser/safe_browsing/two_phase_uploader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/two_phase_uploader.h" 5 #include "chrome/browser/safe_browsing/two_phase_uploader.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <limits> 9 #include <limits>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/sequence_checker.h"
14 #include "base/task_runner.h" 15 #include "base/task_runner.h"
15 #include "components/data_use_measurement/core/data_use_user_data.h" 16 #include "components/data_use_measurement/core/data_use_user_data.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 #include "net/http/http_response_headers.h" 18 #include "net/http/http_response_headers.h"
19 #include "net/url_request/url_fetcher.h" 19 #include "net/url_request/url_fetcher.h"
20 #include "net/url_request/url_fetcher_delegate.h" 20 #include "net/url_request/url_fetcher_delegate.h"
21 #include "net/url_request/url_request_status.h" 21 #include "net/url_request/url_request_status.h"
22 22
23 namespace { 23 namespace {
24 24
25 // Header sent on initial request to start the two phase upload process. 25 // Header sent on initial request to start the two phase upload process.
26 const char kStartHeader[] = "x-goog-resumable: start"; 26 const char kStartHeader[] = "x-goog-resumable: start";
27 27
28 // Header returned on initial response with URL to use for the second phase. 28 // Header returned on initial response with URL to use for the second phase.
29 const char kLocationHeader[] = "Location"; 29 const char kLocationHeader[] = "Location";
30 30
31 const char kUploadContentType[] = "application/octet-stream"; 31 const char kUploadContentType[] = "application/octet-stream";
32 32
33 class TwoPhaseUploaderImpl : public net::URLFetcherDelegate, 33 class TwoPhaseUploaderImpl : public net::URLFetcherDelegate,
34 public TwoPhaseUploader { 34 public TwoPhaseUploader {
35 public: 35 public:
36 TwoPhaseUploaderImpl( 36 TwoPhaseUploaderImpl(
37 net::URLRequestContextGetter* url_request_context_getter, 37 net::URLRequestContextGetter* url_request_context_getter,
38 base::TaskRunner* file_task_runner, 38 base::TaskRunner* file_task_runner,
39 const GURL& base_url, 39 const GURL& base_url,
40 const std::string& metadata, 40 const std::string& metadata,
41 const base::FilePath& file_path, 41 const base::FilePath& file_path,
42 const ProgressCallback& progress_callback, 42 const ProgressCallback& progress_callback,
43 const FinishCallback& finish_callback, 43 const FinishCallback& finish_callback,
44 const net::NetworkTrafficAnnotationTag& traffic_annotation); 44 const net::NetworkTrafficAnnotationTag& traffic_annotation);
45 ~TwoPhaseUploaderImpl() override; 45 ~TwoPhaseUploaderImpl() override = default;
46 46
47 // Begins the upload process. 47 // Begins the upload process.
48 void Start() override; 48 void Start() override;
49 49
50 // net::URLFetcherDelegate implementation: 50 // net::URLFetcherDelegate implementation:
51 void OnURLFetchComplete(const net::URLFetcher* source) override; 51 void OnURLFetchComplete(const net::URLFetcher* source) override;
52 void OnURLFetchUploadProgress(const net::URLFetcher* source, 52 void OnURLFetchUploadProgress(const net::URLFetcher* source,
53 int64_t current, 53 int64_t current,
54 int64_t total) override; 54 int64_t total) override;
55 55
56 private: 56 private:
57 void UploadMetadata(); 57 void UploadMetadata();
58 void UploadFile(); 58 void UploadFile();
59 void Finish(int net_error, int response_code, const std::string& response); 59 void Finish(int net_error, int response_code, const std::string& response);
60 60
61 State state_; 61 State state_;
62 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; 62 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
63 scoped_refptr<base::TaskRunner> file_task_runner_; 63 scoped_refptr<base::TaskRunner> file_task_runner_;
64 GURL base_url_; 64 GURL base_url_;
65 GURL upload_url_; 65 GURL upload_url_;
66 std::string metadata_; 66 std::string metadata_;
67 const base::FilePath file_path_; 67 const base::FilePath file_path_;
68 ProgressCallback progress_callback_; 68 ProgressCallback progress_callback_;
69 FinishCallback finish_callback_; 69 FinishCallback finish_callback_;
70 net::NetworkTrafficAnnotationTag traffic_annotation_; 70 net::NetworkTrafficAnnotationTag traffic_annotation_;
71 71
72 std::unique_ptr<net::URLFetcher> url_fetcher_; 72 std::unique_ptr<net::URLFetcher> url_fetcher_;
73 73
74 // Ensure access to the state_ variable is sequenced, and that callbacks are
75 // invoked on the same sequence as Start.
76 base::SequenceChecker sequence_checker_;
77
74 DISALLOW_COPY_AND_ASSIGN(TwoPhaseUploaderImpl); 78 DISALLOW_COPY_AND_ASSIGN(TwoPhaseUploaderImpl);
75 }; 79 };
76 80
77 TwoPhaseUploaderImpl::TwoPhaseUploaderImpl( 81 TwoPhaseUploaderImpl::TwoPhaseUploaderImpl(
78 net::URLRequestContextGetter* url_request_context_getter, 82 net::URLRequestContextGetter* url_request_context_getter,
79 base::TaskRunner* file_task_runner, 83 base::TaskRunner* file_task_runner,
80 const GURL& base_url, 84 const GURL& base_url,
81 const std::string& metadata, 85 const std::string& metadata,
82 const base::FilePath& file_path, 86 const base::FilePath& file_path,
83 const ProgressCallback& progress_callback, 87 const ProgressCallback& progress_callback,
84 const FinishCallback& finish_callback, 88 const FinishCallback& finish_callback,
85 const net::NetworkTrafficAnnotationTag& traffic_annotation) 89 const net::NetworkTrafficAnnotationTag& traffic_annotation)
86 : state_(STATE_NONE), 90 : state_(STATE_NONE),
87 url_request_context_getter_(url_request_context_getter), 91 url_request_context_getter_(url_request_context_getter),
88 file_task_runner_(file_task_runner), 92 file_task_runner_(file_task_runner),
89 base_url_(base_url), 93 base_url_(base_url),
90 metadata_(metadata), 94 metadata_(metadata),
91 file_path_(file_path), 95 file_path_(file_path),
92 progress_callback_(progress_callback), 96 progress_callback_(progress_callback),
93 finish_callback_(finish_callback), 97 finish_callback_(finish_callback),
94 traffic_annotation_(traffic_annotation) { 98 traffic_annotation_(traffic_annotation) {
95 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 99 // The callbacks must be invoked on the same sequence as Start, but that
96 } 100 // doesn't need to be the same sequence the TwoPhaseUploaderImpl was
97 101 // constructed on.
98 TwoPhaseUploaderImpl::~TwoPhaseUploaderImpl() { 102 sequence_checker_.DetachFromSequence();
99 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
100 } 103 }
101 104
102 void TwoPhaseUploaderImpl::Start() { 105 void TwoPhaseUploaderImpl::Start() {
103 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 106 // Bind the sequence checker to the current sequence.
107 DCHECK(sequence_checker_.CalledOnValidSequence());
104 DCHECK_EQ(STATE_NONE, state_); 108 DCHECK_EQ(STATE_NONE, state_);
105 109
106 UploadMetadata(); 110 UploadMetadata();
107 } 111 }
108 112
109 void TwoPhaseUploaderImpl::OnURLFetchComplete(const net::URLFetcher* source) { 113 void TwoPhaseUploaderImpl::OnURLFetchComplete(const net::URLFetcher* source) {
110 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 114 DCHECK(sequence_checker_.CalledOnValidSequence());
111 net::URLRequestStatus status = source->GetStatus(); 115 net::URLRequestStatus status = source->GetStatus();
112 int response_code = source->GetResponseCode(); 116 int response_code = source->GetResponseCode();
113 117
114 DVLOG(1) << __func__ << " " << source->GetURL().spec() << " " 118 DVLOG(1) << __func__ << " " << source->GetURL().spec() << " "
115 << status.status() << " " << response_code; 119 << status.status() << " " << response_code;
116 120
117 if (!status.is_success()) { 121 if (!status.is_success()) {
118 LOG(ERROR) << "URLFetcher failed, status=" << status.status() 122 LOG(ERROR) << "URLFetcher failed, status=" << status.status()
119 << " err=" << status.error(); 123 << " err=" << status.error();
120 Finish(status.error(), response_code, std::string()); 124 Finish(status.error(), response_code, std::string());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 return; 160 return;
157 default: 161 default:
158 NOTREACHED(); 162 NOTREACHED();
159 } 163 }
160 } 164 }
161 165
162 void TwoPhaseUploaderImpl::OnURLFetchUploadProgress( 166 void TwoPhaseUploaderImpl::OnURLFetchUploadProgress(
163 const net::URLFetcher* source, 167 const net::URLFetcher* source,
164 int64_t current, 168 int64_t current,
165 int64_t total) { 169 int64_t total) {
166 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 170 DCHECK(sequence_checker_.CalledOnValidSequence());
167 DVLOG(3) << __func__ << " " << source->GetURL().spec() << " " << current 171 DVLOG(3) << __func__ << " " << source->GetURL().spec() << " " << current
168 << "/" << total; 172 << "/" << total;
169 if (state_ == UPLOAD_FILE && !progress_callback_.is_null()) 173 if (state_ == UPLOAD_FILE && !progress_callback_.is_null())
170 progress_callback_.Run(current, total); 174 progress_callback_.Run(current, total);
171 } 175 }
172 176
173 void TwoPhaseUploaderImpl::UploadMetadata() { 177 void TwoPhaseUploaderImpl::UploadMetadata() {
174 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 178 DCHECK(sequence_checker_.CalledOnValidSequence());
175 state_ = UPLOAD_METADATA; 179 state_ = UPLOAD_METADATA;
176 url_fetcher_ = net::URLFetcher::Create(base_url_, net::URLFetcher::POST, this, 180 url_fetcher_ = net::URLFetcher::Create(base_url_, net::URLFetcher::POST, this,
177 traffic_annotation_); 181 traffic_annotation_);
178 182
179 data_use_measurement::DataUseUserData::AttachToFetcher( 183 data_use_measurement::DataUseUserData::AttachToFetcher(
180 url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING); 184 url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
181 url_fetcher_->SetRequestContext(url_request_context_getter_.get()); 185 url_fetcher_->SetRequestContext(url_request_context_getter_.get());
182 url_fetcher_->SetExtraRequestHeaders(kStartHeader); 186 url_fetcher_->SetExtraRequestHeaders(kStartHeader);
183 url_fetcher_->SetUploadData(kUploadContentType, metadata_); 187 url_fetcher_->SetUploadData(kUploadContentType, metadata_);
184 url_fetcher_->Start(); 188 url_fetcher_->Start();
185 } 189 }
186 190
187 void TwoPhaseUploaderImpl::UploadFile() { 191 void TwoPhaseUploaderImpl::UploadFile() {
188 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 192 DCHECK(sequence_checker_.CalledOnValidSequence());
189 state_ = UPLOAD_FILE; 193 state_ = UPLOAD_FILE;
190 194
191 url_fetcher_ = net::URLFetcher::Create(upload_url_, net::URLFetcher::PUT, 195 url_fetcher_ = net::URLFetcher::Create(upload_url_, net::URLFetcher::PUT,
192 this, traffic_annotation_); 196 this, traffic_annotation_);
193 data_use_measurement::DataUseUserData::AttachToFetcher( 197 data_use_measurement::DataUseUserData::AttachToFetcher(
194 url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING); 198 url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
195 url_fetcher_->SetRequestContext(url_request_context_getter_.get()); 199 url_fetcher_->SetRequestContext(url_request_context_getter_.get());
196 url_fetcher_->SetUploadFilePath(kUploadContentType, file_path_, 0, 200 url_fetcher_->SetUploadFilePath(kUploadContentType, file_path_, 0,
197 std::numeric_limits<uint64_t>::max(), 201 std::numeric_limits<uint64_t>::max(),
198 file_task_runner_); 202 file_task_runner_);
199 url_fetcher_->Start(); 203 url_fetcher_->Start();
200 } 204 }
201 205
202 void TwoPhaseUploaderImpl::Finish(int net_error, 206 void TwoPhaseUploaderImpl::Finish(int net_error,
203 int response_code, 207 int response_code,
204 const std::string& response) { 208 const std::string& response) {
205 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 209 DCHECK(sequence_checker_.CalledOnValidSequence());
206 finish_callback_.Run(state_, net_error, response_code, response); 210 finish_callback_.Run(state_, net_error, response_code, response);
207 } 211 }
208 212
209 } // namespace 213 } // namespace
210 214
211 // static 215 // static
212 TwoPhaseUploaderFactory* TwoPhaseUploader::factory_ = nullptr; 216 TwoPhaseUploaderFactory* TwoPhaseUploader::factory_ = nullptr;
213 217
214 // static 218 // static
215 std::unique_ptr<TwoPhaseUploader> TwoPhaseUploader::Create( 219 std::unique_ptr<TwoPhaseUploader> TwoPhaseUploader::Create(
216 net::URLRequestContextGetter* url_request_context_getter, 220 net::URLRequestContextGetter* url_request_context_getter,
217 base::TaskRunner* file_task_runner, 221 base::TaskRunner* file_task_runner,
218 const GURL& base_url, 222 const GURL& base_url,
219 const std::string& metadata, 223 const std::string& metadata,
220 const base::FilePath& file_path, 224 const base::FilePath& file_path,
221 const ProgressCallback& progress_callback, 225 const ProgressCallback& progress_callback,
222 const FinishCallback& finish_callback, 226 const FinishCallback& finish_callback,
223 const net::NetworkTrafficAnnotationTag& traffic_annotation) { 227 const net::NetworkTrafficAnnotationTag& traffic_annotation) {
224 if (!factory_) { 228 if (!factory_) {
225 return base::WrapUnique(new TwoPhaseUploaderImpl( 229 return base::WrapUnique(new TwoPhaseUploaderImpl(
226 url_request_context_getter, file_task_runner, base_url, metadata, 230 url_request_context_getter, file_task_runner, base_url, metadata,
227 file_path, progress_callback, finish_callback, traffic_annotation)); 231 file_path, progress_callback, finish_callback, traffic_annotation));
228 } 232 }
229 return TwoPhaseUploader::factory_->CreateTwoPhaseUploader( 233 return TwoPhaseUploader::factory_->CreateTwoPhaseUploader(
230 url_request_context_getter, file_task_runner, base_url, metadata, 234 url_request_context_getter, file_task_runner, base_url, metadata,
231 file_path, progress_callback, finish_callback, traffic_annotation); 235 file_path, progress_callback, finish_callback, traffic_annotation);
232 } 236 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/two_phase_uploader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698