| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/download/base_file.h" | 5 #include "chrome/browser/download/base_file.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/secure_hash.h" |
| 9 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 10 #include "base/third_party/nss/blapi.h" | |
| 11 #include "base/third_party/nss/sha256.h" | |
| 12 #include "net/base/file_stream.h" | 11 #include "net/base/file_stream.h" |
| 13 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
| 14 #include "chrome/browser/browser_thread.h" | 13 #include "chrome/browser/browser_thread.h" |
| 15 #include "chrome/browser/download/download_util.h" | 14 #include "chrome/browser/download/download_util.h" |
| 16 | 15 |
| 17 #if defined(OS_WIN) | 16 #if defined(OS_WIN) |
| 18 #include "app/win/win_util.h" | 17 #include "app/win/win_util.h" |
| 19 #include "chrome/common/win_safe_util.h" | 18 #include "chrome/common/win_safe_util.h" |
| 20 #elif defined(OS_MACOSX) | 19 #elif defined(OS_MACOSX) |
| 21 #include "chrome/browser/ui/cocoa/file_metadata.h" | 20 #include "chrome/browser/ui/cocoa/file_metadata.h" |
| 22 #endif | 21 #endif |
| 23 | 22 |
| 24 BaseFile::BaseFile(const FilePath& full_path, | 23 BaseFile::BaseFile(const FilePath& full_path, |
| 25 const GURL& source_url, | 24 const GURL& source_url, |
| 26 const GURL& referrer_url, | 25 const GURL& referrer_url, |
| 27 int64 received_bytes, | 26 int64 received_bytes, |
| 28 const linked_ptr<net::FileStream>& file_stream) | 27 const linked_ptr<net::FileStream>& file_stream) |
| 29 : full_path_(full_path), | 28 : full_path_(full_path), |
| 30 path_renamed_(false), | 29 path_renamed_(false), |
| 31 source_url_(source_url), | 30 source_url_(source_url), |
| 32 referrer_url_(referrer_url), | 31 referrer_url_(referrer_url), |
| 33 file_stream_(file_stream), | 32 file_stream_(file_stream), |
| 34 bytes_so_far_(received_bytes), | 33 bytes_so_far_(received_bytes), |
| 35 power_save_blocker_(true), | 34 power_save_blocker_(true), |
| 36 calculate_hash_(false), | 35 calculate_hash_(false) { |
| 37 sha_context_(NULL) { | |
| 38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 39 } | 37 } |
| 40 | 38 |
| 41 BaseFile::~BaseFile() { | 39 BaseFile::~BaseFile() { |
| 42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 43 if (in_progress()) | 41 if (in_progress()) |
| 44 Cancel(); | 42 Cancel(); |
| 45 Close(); | 43 Close(); |
| 46 } | 44 } |
| 47 | 45 |
| 48 bool BaseFile::Initialize(bool calculate_hash) { | 46 bool BaseFile::Initialize(bool calculate_hash) { |
| 49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 50 | 48 |
| 51 calculate_hash_ = calculate_hash; | 49 calculate_hash_ = calculate_hash; |
| 52 | 50 |
| 53 if (calculate_hash_) { | 51 if (calculate_hash_) |
| 54 sha_context_.reset(new SHA256Context); | 52 secure_hash_.reset(base::SecureHash::Create(base::SecureHash::TYPE_SHA256)); |
| 55 SHA256_Begin(sha_context_.get()); | |
| 56 } | |
| 57 | 53 |
| 58 if (!full_path_.empty() || | 54 if (!full_path_.empty() || |
| 59 download_util::CreateTemporaryFileForDownload(&full_path_)) | 55 download_util::CreateTemporaryFileForDownload(&full_path_)) |
| 60 return Open(); | 56 return Open(); |
| 61 return false; | 57 return false; |
| 62 } | 58 } |
| 63 | 59 |
| 64 bool BaseFile::AppendDataToFile(const char* data, size_t data_len) { | 60 bool BaseFile::AppendDataToFile(const char* data, size_t data_len) { |
| 65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 66 | 62 |
| 67 if (!file_stream_.get()) | 63 if (!file_stream_.get()) |
| 68 return false; | 64 return false; |
| 69 | 65 |
| 70 // TODO(phajdan.jr): get rid of this check. | 66 // TODO(phajdan.jr): get rid of this check. |
| 71 if (data_len == 0) | 67 if (data_len == 0) |
| 72 return true; | 68 return true; |
| 73 | 69 |
| 74 bytes_so_far_ += data_len; | 70 bytes_so_far_ += data_len; |
| 75 | 71 |
| 76 // TODO(phajdan.jr): handle errors on file writes. http://crbug.com/58355 | 72 // TODO(phajdan.jr): handle errors on file writes. http://crbug.com/58355 |
| 77 size_t written = file_stream_->Write(data, data_len, NULL); | 73 size_t written = file_stream_->Write(data, data_len, NULL); |
| 78 if (written != data_len) | 74 if (written != data_len) |
| 79 return false; | 75 return false; |
| 80 | 76 |
| 81 if (calculate_hash_) { | 77 if (calculate_hash_) |
| 82 SHA256_Update(sha_context_.get(), | 78 secure_hash_->Update(std::string(data, data_len)); |
| 83 reinterpret_cast<const unsigned char*>(data), | |
| 84 data_len); | |
| 85 } | |
| 86 | 79 |
| 87 return true; | 80 return true; |
| 88 } | 81 } |
| 89 | 82 |
| 90 bool BaseFile::Rename(const FilePath& new_path, bool is_final_rename) { | 83 bool BaseFile::Rename(const FilePath& new_path, bool is_final_rename) { |
| 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 92 | 85 |
| 93 // Save the information whether the download is in progress because | 86 // Save the information whether the download is in progress because |
| 94 // it will be overwritten by closing the file. | 87 // it will be overwritten by closing the file. |
| 95 bool saved_in_progress = in_progress(); | 88 bool saved_in_progress = in_progress(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 156 Close(); | 149 Close(); |
| 157 if (!full_path_.empty()) | 150 if (!full_path_.empty()) |
| 158 file_util::Delete(full_path_, false); | 151 file_util::Delete(full_path_, false); |
| 159 } | 152 } |
| 160 | 153 |
| 161 void BaseFile::Finish() { | 154 void BaseFile::Finish() { |
| 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 163 | 156 |
| 164 if (calculate_hash_) | 157 if (calculate_hash_) |
| 165 SHA256_End(sha_context_.get(), sha256_hash_, NULL, kSha256HashLen); | 158 secure_hash_->Finish(sha256_hash_, kSha256HashLen); |
| 166 | 159 |
| 167 Close(); | 160 Close(); |
| 168 } | 161 } |
| 169 | 162 |
| 170 bool BaseFile::GetSha256Hash(std::string* hash) { | 163 bool BaseFile::GetSha256Hash(std::string* hash) { |
| 171 if (!calculate_hash_ || in_progress()) | 164 if (!calculate_hash_ || in_progress()) |
| 172 return false; | 165 return false; |
| 173 hash->assign(reinterpret_cast<const char*>(sha256_hash_), | 166 hash->assign(reinterpret_cast<const char*>(sha256_hash_), |
| 174 sizeof(sha256_hash_)); | 167 sizeof(sha256_hash_)); |
| 175 return true; | 168 return true; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 file_stream_->Close(); | 221 file_stream_->Close(); |
| 229 file_stream_.reset(); | 222 file_stream_.reset(); |
| 230 } | 223 } |
| 231 } | 224 } |
| 232 | 225 |
| 233 std::string BaseFile::DebugString() const { | 226 std::string BaseFile::DebugString() const { |
| 234 return base::StringPrintf("{ source_url_ = \"%s\" full_path_ = \"%s\" }", | 227 return base::StringPrintf("{ source_url_ = \"%s\" full_path_ = \"%s\" }", |
| 235 source_url_.spec().c_str(), | 228 source_url_.spec().c_str(), |
| 236 full_path_.value().c_str()); | 229 full_path_.value().c_str()); |
| 237 } | 230 } |
| OLD | NEW |