Chromium Code Reviews| 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" |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 else | 37 else |
| 38 Cancel(); // Will delete the file. | 38 Cancel(); // Will delete the file. |
| 39 } | 39 } |
| 40 | 40 |
| 41 DownloadInterruptReason BaseFile::Initialize( | 41 DownloadInterruptReason BaseFile::Initialize( |
| 42 const base::FilePath& full_path, | 42 const base::FilePath& full_path, |
| 43 const base::FilePath& default_directory, | 43 const base::FilePath& default_directory, |
| 44 base::File file, | 44 base::File file, |
| 45 int64_t bytes_so_far, | 45 int64_t bytes_so_far, |
| 46 const std::string& hash_so_far, | 46 const std::string& hash_so_far, |
| 47 std::unique_ptr<crypto::SecureHash> hash_state) { | 47 std::unique_ptr<crypto::SecureHash> hash_state, |
| 48 AccessMode access_mode) { | |
| 48 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 49 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 49 DCHECK(!detached_); | 50 DCHECK(!detached_); |
| 50 | 51 |
| 51 if (full_path.empty()) { | 52 if (full_path.empty()) { |
| 52 base::FilePath initial_directory(default_directory); | 53 base::FilePath initial_directory(default_directory); |
| 53 base::FilePath temp_file; | 54 base::FilePath temp_file; |
| 54 if (initial_directory.empty()) { | 55 if (initial_directory.empty()) { |
| 55 initial_directory = | 56 initial_directory = |
| 56 GetContentClient()->browser()->GetDefaultDownloadDirectory(); | 57 GetContentClient()->browser()->GetDefaultDownloadDirectory(); |
| 57 } | 58 } |
| 58 // |initial_directory| can still be empty if ContentBrowserClient returned | 59 // |initial_directory| can still be empty if ContentBrowserClient returned |
| 59 // an empty path for the downloads directory. | 60 // an empty path for the downloads directory. |
| 60 if ((initial_directory.empty() || | 61 if ((initial_directory.empty() || |
| 61 !base::CreateTemporaryFileInDir(initial_directory, &temp_file)) && | 62 !base::CreateTemporaryFileInDir(initial_directory, &temp_file)) && |
| 62 !base::CreateTemporaryFile(&temp_file)) { | 63 !base::CreateTemporaryFile(&temp_file)) { |
| 63 return LogInterruptReason("Unable to create", 0, | 64 return LogInterruptReason("Unable to create", 0, |
| 64 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 65 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 65 } | 66 } |
| 66 full_path_ = temp_file; | 67 full_path_ = temp_file; |
| 67 } else { | 68 } else { |
| 68 full_path_ = full_path; | 69 full_path_ = full_path; |
| 69 } | 70 } |
| 70 | 71 |
| 71 bytes_so_far_ = bytes_so_far; | 72 bytes_so_far_ = bytes_so_far; |
| 72 secure_hash_ = std::move(hash_state); | 73 secure_hash_ = std::move(hash_state); |
| 74 access_mode_ = access_mode; | |
| 75 DCHECK(access_mode_ == EXCLUSIVE || !secure_hash_); | |
| 73 file_ = std::move(file); | 76 file_ = std::move(file); |
| 74 | 77 |
| 75 return Open(hash_so_far); | 78 return Open(hash_so_far); |
| 76 } | 79 } |
| 77 | 80 |
| 78 DownloadInterruptReason BaseFile::AppendDataToFile(const char* data, | 81 DownloadInterruptReason BaseFile::AppendDataToFile(const char* data, |
| 79 size_t data_len) { | 82 size_t data_len) { |
| 80 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 83 DCHECK_EQ(access_mode_, EXCLUSIVE); |
| 81 DCHECK(!detached_); | 84 return WriteAtCurrentPos(data, data_len); |
| 85 } | |
| 82 | 86 |
| 87 DownloadInterruptReason BaseFile::WriteDataToFile(int64_t offset, | |
| 88 const char* data, | |
| 89 size_t data_len) { | |
| 90 DCHECK_EQ(access_mode_, SHARED); | |
| 91 | |
| 92 if (file_.Seek(base::File::FROM_BEGIN, offset) < 0) { | |
|
asanka
2017/02/16 18:11:24
base::File::Write() can be used to write to a spec
asanka
2017/02/16 18:46:25
Disregard.
qinmin
2017/02/16 21:35:50
I used this seek() to reuse some of code from Appe
asanka
2017/02/16 21:58:02
Probably because this code predates the logic in b
qinmin
2017/02/16 22:20:29
Done. Removed the while loop around the Write() ca
| |
| 93 logging::SystemErrorCode error = logging::GetLastSystemErrorCode(); | |
| 94 return LogSystemError("Unable to seek", error); | |
| 95 } | |
| 96 return WriteAtCurrentPos(data, data_len); | |
| 97 } | |
| 98 | |
| 99 DownloadInterruptReason BaseFile::WriteAtCurrentPos(const char* data, | |
| 100 size_t data_len) { | |
| 83 // NOTE(benwells): The above DCHECK won't be present in release builds, | 101 // NOTE(benwells): The above DCHECK won't be present in release builds, |
| 84 // so we log any occurences to see how common this error is in the wild. | 102 // so we log any occurences to see how common this error is in the wild. |
| 85 if (detached_) | 103 if (detached_) |
| 86 RecordDownloadCount(APPEND_TO_DETACHED_FILE_COUNT); | 104 RecordDownloadCount(APPEND_TO_DETACHED_FILE_COUNT); |
| 87 | 105 |
| 88 if (!file_.IsValid()) | 106 if (!file_.IsValid()) |
| 89 return LogInterruptReason("No file stream on append", 0, | 107 return LogInterruptReason("No file stream on append", 0, |
| 90 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 108 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 91 | 109 |
| 92 // TODO(phajdan.jr): get rid of this check. | 110 // TODO(phajdan.jr): get rid of this check. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 116 } | 134 } |
| 117 net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN, | 135 net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN, |
| 118 net::NetLog::Int64Callback("bytes", data_len)); | 136 net::NetLog::Int64Callback("bytes", data_len)); |
| 119 | 137 |
| 120 if (secure_hash_) | 138 if (secure_hash_) |
| 121 secure_hash_->Update(data, data_len); | 139 secure_hash_->Update(data, data_len); |
| 122 | 140 |
| 123 return DOWNLOAD_INTERRUPT_REASON_NONE; | 141 return DOWNLOAD_INTERRUPT_REASON_NONE; |
| 124 } | 142 } |
| 125 | 143 |
| 126 DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) { | 144 DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) { |
|
asanka
2017/02/16 18:11:24
Methods like Rename() and Annotate...() depend on
asanka
2017/02/16 18:46:26
Disregard. I misunderstood how BaseFile is intende
qinmin
2017/02/16 21:35:50
Yes, the BaseFile will still be owned by a Downloa
| |
| 127 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 145 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 128 DownloadInterruptReason rename_result = DOWNLOAD_INTERRUPT_REASON_NONE; | 146 DownloadInterruptReason rename_result = DOWNLOAD_INTERRUPT_REASON_NONE; |
| 129 | 147 |
| 130 // If the new path is same as the old one, there is no need to perform the | 148 // If the new path is same as the old one, there is no need to perform the |
| 131 // following renaming logic. | 149 // following renaming logic. |
| 132 if (new_path == full_path_) | 150 if (new_path == full_path_) |
| 133 return DOWNLOAD_INTERRUPT_REASON_NONE; | 151 return DOWNLOAD_INTERRUPT_REASON_NONE; |
| 134 | 152 |
| 135 // Save the information whether the download is in progress because | 153 // Save the information whether the download is in progress because |
| 136 // it will be overwritten by closing the file. | 154 // it will be overwritten by closing the file. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 if (!file_.IsValid()) { | 299 if (!file_.IsValid()) { |
| 282 return LogNetError("Open/Initialize File", | 300 return LogNetError("Open/Initialize File", |
| 283 net::FileErrorToNetError(file_.error_details())); | 301 net::FileErrorToNetError(file_.error_details())); |
| 284 } | 302 } |
| 285 } | 303 } |
| 286 | 304 |
| 287 net_log_.BeginEvent( | 305 net_log_.BeginEvent( |
| 288 net::NetLogEventType::DOWNLOAD_FILE_OPENED, | 306 net::NetLogEventType::DOWNLOAD_FILE_OPENED, |
| 289 base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_)); | 307 base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_)); |
| 290 | 308 |
| 309 // For SHARED file, skip hash validation. | |
| 310 if (access_mode_ == SHARED) { | |
| 311 if (file_.GetLength() < bytes_so_far_) { | |
| 312 ClearFile(); | |
| 313 return LogInterruptReason("File has fewer written bytes than expected", 0, | |
| 314 DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); | |
| 315 } | |
| 316 return DOWNLOAD_INTERRUPT_REASON_NONE; | |
| 317 } | |
| 318 | |
| 291 if (!secure_hash_) { | 319 if (!secure_hash_) { |
| 292 DownloadInterruptReason reason = CalculatePartialHash(hash_so_far); | 320 DownloadInterruptReason reason = CalculatePartialHash(hash_so_far); |
| 293 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { | 321 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 294 ClearFile(); | 322 ClearFile(); |
| 295 return reason; | 323 return reason; |
| 296 } | 324 } |
| 297 } | 325 } |
| 298 | 326 |
| 299 int64_t file_size = file_.Seek(base::File::FROM_END, 0); | 327 int64_t file_size = file_.Seek(base::File::FROM_END, 0); |
| 300 if (file_size < 0) { | 328 if (file_size < 0) { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 #else // !OS_WIN && !OS_MACOSX && !OS_LINUX | 484 #else // !OS_WIN && !OS_MACOSX && !OS_LINUX |
| 457 DownloadInterruptReason BaseFile::AnnotateWithSourceInformation( | 485 DownloadInterruptReason BaseFile::AnnotateWithSourceInformation( |
| 458 const std::string& client_guid, | 486 const std::string& client_guid, |
| 459 const GURL& source_url, | 487 const GURL& source_url, |
| 460 const GURL& referrer_url) { | 488 const GURL& referrer_url) { |
| 461 return DOWNLOAD_INTERRUPT_REASON_NONE; | 489 return DOWNLOAD_INTERRUPT_REASON_NONE; |
| 462 } | 490 } |
| 463 #endif | 491 #endif |
| 464 | 492 |
| 465 } // namespace content | 493 } // namespace content |
| OLD | NEW |