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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ 6 #define CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ 7 8 #include <string> 9 10 #include "base/files/file.h" 11 #include "base/files/file_path.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/logging.h" 14 #include "base/memory/linked_ptr.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/time/time.h" 17 #include "content/common/content_export.h" 18 #include "content/public/browser/download_interrupt_reasons.h" 19 #include "crypto/sha2.h" 20 #include "net/base/net_errors.h" 21 #include "net/base/net_log.h" 22 #include "url/gurl.h" 23 24 namespace crypto { 25 class SecureHash; 26 } 27 28 namespace content { 29 30 // File being downloaded and saved to disk. This is a base class 31 // for DownloadFile and SaveFile, which keep more state information. 32 class CONTENT_EXPORT BaseFile { 33 public: 34 // May be constructed on any thread. All other routines (including 35 // destruction) must occur on the FILE thread. 36 BaseFile(const base::FilePath& full_path, 37 const GURL& source_url, 38 const GURL& referrer_url, 39 int64 received_bytes, 40 bool calculate_hash, 41 const std::string& hash_state, 42 base::File file, 43 const net::BoundNetLog& bound_net_log); 44 virtual ~BaseFile(); 45 46 // Returns DOWNLOAD_INTERRUPT_REASON_NONE on success, or a 47 // DownloadInterruptReason on failure. |default_directory| specifies the 48 // directory to create the temporary file in if |full_path()| is empty. If 49 // |default_directory| and |full_path()| are empty, then a temporary file will 50 // be created in the default download location as determined by 51 // ContentBrowserClient. 52 DownloadInterruptReason Initialize(const base::FilePath& default_directory); 53 54 // Write a new chunk of data to the file. Returns a DownloadInterruptReason 55 // indicating the result of the operation. 56 DownloadInterruptReason AppendDataToFile(const char* data, size_t data_len); 57 58 // Rename the download file. Returns a DownloadInterruptReason indicating the 59 // result of the operation. A return code of NONE indicates that the rename 60 // was successful. After a failure, the full_path() and in_progress() can be 61 // used to determine the last known filename and whether the file is available 62 // for writing or retrying the rename. 63 virtual DownloadInterruptReason Rename(const base::FilePath& full_path); 64 65 // Detach the file so it is not deleted on destruction. 66 virtual void Detach(); 67 68 // Abort the download and automatically close the file. 69 void Cancel(); 70 71 // Indicate that the download has finished. No new data will be received. 72 void Finish(); 73 74 // Set the client guid which will be used to identify the app to the 75 // system AV scanning function. Should be called before 76 // AnnotateWithSourceInformation() to take effect. 77 void SetClientGuid(const std::string& guid); 78 79 // Informs the OS that this file came from the internet. Returns a 80 // DownloadInterruptReason indicating the result of the operation. 81 // Note: SetClientGuid() should be called before this function on 82 // Windows to ensure the correct app client ID is available. 83 DownloadInterruptReason AnnotateWithSourceInformation(); 84 85 // Returns the last known path to the download file. Can be empty if there's 86 // no file. 87 const base::FilePath& full_path() const { return full_path_; } 88 89 // Returns true if the file is open. If true, the file can be written to or 90 // renamed. 91 bool in_progress() const { return file_.IsValid(); } 92 93 // Returns the number of bytes in the file pointed to by full_path(). 94 int64 bytes_so_far() const { return bytes_so_far_; } 95 96 // Fills |hash| with the hash digest for the file. 97 // Returns true if digest is successfully calculated. 98 virtual bool GetHash(std::string* hash); 99 100 // Returns the current (intermediate) state of the hash as a byte string. 101 virtual std::string GetHashState(); 102 103 // Returns true if the given hash is considered empty. An empty hash is 104 // a string of size crypto::kSHA256Length that contains only zeros (initial 105 // value for the hash). 106 static bool IsEmptyHash(const std::string& hash); 107 108 virtual std::string DebugString() const; 109 110 private: 111 friend class BaseFileTest; 112 FRIEND_TEST_ALL_PREFIXES(BaseFileTest, IsEmptyHash); 113 114 // Creates and opens the file_ if it is NULL. 115 DownloadInterruptReason Open(); 116 117 // Closes and resets file_. 118 void Close(); 119 120 // Resets file_. 121 void ClearFile(); 122 123 // Platform specific method that moves a file to a new path and adjusts the 124 // security descriptor / permissions on the file to match the defaults for the 125 // new directory. 126 DownloadInterruptReason MoveFileAndAdjustPermissions( 127 const base::FilePath& new_path); 128 129 // Split out from CurrentSpeed to enable testing. 130 int64 CurrentSpeedAtTime(base::TimeTicks current_time) const; 131 132 // Log a TYPE_DOWNLOAD_FILE_ERROR NetLog event with |error| and passes error 133 // on through, converting to a |DownloadInterruptReason|. 134 DownloadInterruptReason LogNetError(const char* operation, net::Error error); 135 136 // Log the system error in |os_error| and converts it into a 137 // |DownloadInterruptReason|. 138 DownloadInterruptReason LogSystemError(const char* operation, 139 logging::SystemErrorCode os_error); 140 141 // Log a TYPE_DOWNLOAD_FILE_ERROR NetLog event with |os_error| and |reason|. 142 // Returns |reason|. 143 DownloadInterruptReason LogInterruptReason( 144 const char* operation, int os_error, 145 DownloadInterruptReason reason); 146 147 static const unsigned char kEmptySha256Hash[crypto::kSHA256Length]; 148 149 // Full path to the file including the file name. 150 base::FilePath full_path_; 151 152 // Source URL for the file being downloaded. 153 GURL source_url_; 154 155 // The URL where the download was initiated. 156 GURL referrer_url_; 157 158 std::string client_guid_; 159 160 // OS file for writing 161 base::File file_; 162 163 // Amount of data received up so far, in bytes. 164 int64 bytes_so_far_; 165 166 // Start time for calculating speed. 167 base::TimeTicks start_tick_; 168 169 // Indicates if hash should be calculated for the file. 170 bool calculate_hash_; 171 172 // Used to calculate hash for the file when calculate_hash_ 173 // is set. 174 scoped_ptr<crypto::SecureHash> secure_hash_; 175 176 unsigned char sha256_hash_[crypto::kSHA256Length]; 177 178 // Indicates that this class no longer owns the associated file, and so 179 // won't delete it on destruction. 180 bool detached_; 181 182 net::BoundNetLog bound_net_log_; 183 184 DISALLOW_COPY_AND_ASSIGN(BaseFile); 185 }; 186 187 } // namespace content 188 189 #endif // CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ 190