OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/download/base_file.h" | 5 #include "content/browser/download/base_file.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/file.h" | 10 #include "base/files/file.h" |
11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/pickle.h" | 14 #include "base/pickle.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/threading/thread_restrictions.h" | 16 #include "base/threading/thread_restrictions.h" |
17 #include "build/build_config.h" | 17 #include "build/build_config.h" |
18 #include "content/browser/download/download_interrupt_reasons_impl.h" | 18 #include "content/browser/download/download_interrupt_reasons_impl.h" |
19 #include "content/browser/download/download_net_log_parameters.h" | 19 #include "content/browser/download/download_net_log_parameters.h" |
20 #include "content/browser/download/download_stats.h" | 20 #include "content/browser/download/download_stats.h" |
21 #include "content/public/browser/browser_thread.h" | |
22 #include "content/public/browser/content_browser_client.h" | 21 #include "content/public/browser/content_browser_client.h" |
23 #include "content/public/common/quarantine.h" | 22 #include "content/public/common/quarantine.h" |
24 #include "crypto/secure_hash.h" | 23 #include "crypto/secure_hash.h" |
25 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
26 #include "net/log/net_log.h" | 25 #include "net/log/net_log.h" |
27 #include "net/log/net_log_event_type.h" | 26 #include "net/log/net_log_event_type.h" |
28 | 27 |
29 namespace content { | 28 namespace content { |
30 | 29 |
31 BaseFile::BaseFile(const net::NetLogWithSource& net_log) : net_log_(net_log) {} | 30 BaseFile::BaseFile(const net::NetLogWithSource& net_log) : net_log_(net_log) { |
| 31 DETACH_FROM_SEQUENCE(sequence_checker_); |
| 32 } |
32 | 33 |
33 BaseFile::~BaseFile() { | 34 BaseFile::~BaseFile() { |
34 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 35 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
35 if (detached_) | 36 if (detached_) |
36 Close(); | 37 Close(); |
37 else | 38 else |
38 Cancel(); // Will delete the file. | 39 Cancel(); // Will delete the file. |
39 } | 40 } |
40 | 41 |
41 DownloadInterruptReason BaseFile::Initialize( | 42 DownloadInterruptReason BaseFile::Initialize( |
42 const base::FilePath& full_path, | 43 const base::FilePath& full_path, |
43 const base::FilePath& default_directory, | 44 const base::FilePath& default_directory, |
44 base::File file, | 45 base::File file, |
45 int64_t bytes_so_far, | 46 int64_t bytes_so_far, |
46 const std::string& hash_so_far, | 47 const std::string& hash_so_far, |
47 std::unique_ptr<crypto::SecureHash> hash_state, | 48 std::unique_ptr<crypto::SecureHash> hash_state, |
48 bool is_sparse_file) { | 49 bool is_sparse_file) { |
49 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 50 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
50 DCHECK(!detached_); | 51 DCHECK(!detached_); |
51 | 52 |
52 if (full_path.empty()) { | 53 if (full_path.empty()) { |
53 base::FilePath initial_directory(default_directory); | 54 base::FilePath initial_directory(default_directory); |
54 base::FilePath temp_file; | 55 base::FilePath temp_file; |
55 if (initial_directory.empty()) { | 56 if (initial_directory.empty()) { |
56 initial_directory = | 57 initial_directory = |
57 GetContentClient()->browser()->GetDefaultDownloadDirectory(); | 58 GetContentClient()->browser()->GetDefaultDownloadDirectory(); |
58 } | 59 } |
59 // |initial_directory| can still be empty if ContentBrowserClient returned | 60 // |initial_directory| can still be empty if ContentBrowserClient returned |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN, | 121 net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN, |
121 net::NetLog::Int64Callback("bytes", data_len)); | 122 net::NetLog::Int64Callback("bytes", data_len)); |
122 | 123 |
123 if (secure_hash_) | 124 if (secure_hash_) |
124 secure_hash_->Update(data, data_len); | 125 secure_hash_->Update(data, data_len); |
125 | 126 |
126 return DOWNLOAD_INTERRUPT_REASON_NONE; | 127 return DOWNLOAD_INTERRUPT_REASON_NONE; |
127 } | 128 } |
128 | 129 |
129 DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) { | 130 DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) { |
130 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 131 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
131 DownloadInterruptReason rename_result = DOWNLOAD_INTERRUPT_REASON_NONE; | 132 DownloadInterruptReason rename_result = DOWNLOAD_INTERRUPT_REASON_NONE; |
132 | 133 |
133 // If the new path is same as the old one, there is no need to perform the | 134 // If the new path is same as the old one, there is no need to perform the |
134 // following renaming logic. | 135 // following renaming logic. |
135 if (new_path == full_path_) | 136 if (new_path == full_path_) |
136 return DOWNLOAD_INTERRUPT_REASON_NONE; | 137 return DOWNLOAD_INTERRUPT_REASON_NONE; |
137 | 138 |
138 // Save the information whether the download is in progress because | 139 // Save the information whether the download is in progress because |
139 // it will be overwritten by closing the file. | 140 // it will be overwritten by closing the file. |
140 bool was_in_progress = in_progress(); | 141 bool was_in_progress = in_progress(); |
(...skipping 24 matching lines...) Expand all Loading... |
165 return rename_result == DOWNLOAD_INTERRUPT_REASON_NONE ? open_result | 166 return rename_result == DOWNLOAD_INTERRUPT_REASON_NONE ? open_result |
166 : rename_result; | 167 : rename_result; |
167 } | 168 } |
168 | 169 |
169 void BaseFile::Detach() { | 170 void BaseFile::Detach() { |
170 detached_ = true; | 171 detached_ = true; |
171 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_DETACHED); | 172 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_DETACHED); |
172 } | 173 } |
173 | 174 |
174 void BaseFile::Cancel() { | 175 void BaseFile::Cancel() { |
175 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 176 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
176 DCHECK(!detached_); | 177 DCHECK(!detached_); |
177 | 178 |
178 net_log_.AddEvent(net::NetLogEventType::CANCELLED); | 179 net_log_.AddEvent(net::NetLogEventType::CANCELLED); |
179 | 180 |
180 Close(); | 181 Close(); |
181 | 182 |
182 if (!full_path_.empty()) { | 183 if (!full_path_.empty()) { |
183 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_DELETED); | 184 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_DELETED); |
184 base::DeleteFile(full_path_, false); | 185 base::DeleteFile(full_path_, false); |
185 } | 186 } |
186 | 187 |
187 Detach(); | 188 Detach(); |
188 } | 189 } |
189 | 190 |
190 std::unique_ptr<crypto::SecureHash> BaseFile::Finish() { | 191 std::unique_ptr<crypto::SecureHash> BaseFile::Finish() { |
191 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 192 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
192 | 193 |
193 // TODO(qinmin): verify that all the holes have been filled. | 194 // TODO(qinmin): verify that all the holes have been filled. |
194 if (is_sparse_file_) | 195 if (is_sparse_file_) |
195 CalculatePartialHash(std::string()); | 196 CalculatePartialHash(std::string()); |
196 Close(); | 197 Close(); |
197 return std::move(secure_hash_); | 198 return std::move(secure_hash_); |
198 } | 199 } |
199 | 200 |
200 std::string BaseFile::DebugString() const { | 201 std::string BaseFile::DebugString() const { |
201 return base::StringPrintf( | 202 return base::StringPrintf( |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 return LogInterruptReason("Verifying prefix hash", | 270 return LogInterruptReason("Verifying prefix hash", |
270 0, | 271 0, |
271 DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); | 272 DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); |
272 } | 273 } |
273 } | 274 } |
274 | 275 |
275 return DOWNLOAD_INTERRUPT_REASON_NONE; | 276 return DOWNLOAD_INTERRUPT_REASON_NONE; |
276 } | 277 } |
277 | 278 |
278 DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far) { | 279 DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far) { |
279 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 280 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
280 DCHECK(!detached_); | 281 DCHECK(!detached_); |
281 DCHECK(!full_path_.empty()); | 282 DCHECK(!full_path_.empty()); |
282 | 283 |
283 // Create a new file if it is not provided. | 284 // Create a new file if it is not provided. |
284 if (!file_.IsValid()) { | 285 if (!file_.IsValid()) { |
285 file_.Initialize(full_path_, | 286 file_.Initialize(full_path_, |
286 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE | | 287 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE | |
287 base::File::FLAG_READ); | 288 base::File::FLAG_READ); |
288 if (!file_.IsValid()) { | 289 if (!file_.IsValid()) { |
289 return LogNetError("Open/Initialize File", | 290 return LogNetError("Open/Initialize File", |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 // The file is shorter than we expected. Our hashes won't be valid. | 333 // The file is shorter than we expected. Our hashes won't be valid. |
333 ClearFile(); | 334 ClearFile(); |
334 return LogInterruptReason("Unable to seek to last written point", 0, | 335 return LogInterruptReason("Unable to seek to last written point", 0, |
335 DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); | 336 DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); |
336 } | 337 } |
337 | 338 |
338 return DOWNLOAD_INTERRUPT_REASON_NONE; | 339 return DOWNLOAD_INTERRUPT_REASON_NONE; |
339 } | 340 } |
340 | 341 |
341 void BaseFile::Close() { | 342 void BaseFile::Close() { |
342 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 343 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
343 | 344 |
344 if (file_.IsValid()) { | 345 if (file_.IsValid()) { |
345 // Currently we don't really care about the return value, since if it fails | 346 // Currently we don't really care about the return value, since if it fails |
346 // theres not much we can do. But we might in the future. | 347 // theres not much we can do. But we might in the future. |
347 file_.Flush(); | 348 file_.Flush(); |
348 ClearFile(); | 349 ClearFile(); |
349 } | 350 } |
350 } | 351 } |
351 | 352 |
352 void BaseFile::ClearFile() { | 353 void BaseFile::ClearFile() { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 | 420 |
420 return GURL(); | 421 return GURL(); |
421 } | 422 } |
422 | 423 |
423 } // namespace | 424 } // namespace |
424 | 425 |
425 DownloadInterruptReason BaseFile::AnnotateWithSourceInformation( | 426 DownloadInterruptReason BaseFile::AnnotateWithSourceInformation( |
426 const std::string& client_guid, | 427 const std::string& client_guid, |
427 const GURL& source_url, | 428 const GURL& source_url, |
428 const GURL& referrer_url) { | 429 const GURL& referrer_url) { |
429 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 430 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
430 DCHECK(!detached_); | 431 DCHECK(!detached_); |
431 DCHECK(!full_path_.empty()); | 432 DCHECK(!full_path_.empty()); |
432 | 433 |
433 net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_FILE_ANNOTATED); | 434 net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_FILE_ANNOTATED); |
434 QuarantineFileResult result = QuarantineFile( | 435 QuarantineFileResult result = QuarantineFile( |
435 full_path_, GetEffectiveAuthorityURL(source_url, referrer_url), | 436 full_path_, GetEffectiveAuthorityURL(source_url, referrer_url), |
436 referrer_url, client_guid); | 437 referrer_url, client_guid); |
437 net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_ANNOTATED); | 438 net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_ANNOTATED); |
438 switch (result) { | 439 switch (result) { |
439 case QuarantineFileResult::OK: | 440 case QuarantineFileResult::OK: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 #else // !OS_WIN && !OS_MACOSX && !OS_LINUX | 474 #else // !OS_WIN && !OS_MACOSX && !OS_LINUX |
474 DownloadInterruptReason BaseFile::AnnotateWithSourceInformation( | 475 DownloadInterruptReason BaseFile::AnnotateWithSourceInformation( |
475 const std::string& client_guid, | 476 const std::string& client_guid, |
476 const GURL& source_url, | 477 const GURL& source_url, |
477 const GURL& referrer_url) { | 478 const GURL& referrer_url) { |
478 return DOWNLOAD_INTERRUPT_REASON_NONE; | 479 return DOWNLOAD_INTERRUPT_REASON_NONE; |
479 } | 480 } |
480 #endif | 481 #endif |
481 | 482 |
482 } // namespace content | 483 } // namespace content |
OLD | NEW |