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. 60 virtual DownloadInterruptReason Rename(const base::FilePath& full_path); 61 62 // Detach the file so it is not deleted on destruction. 63 virtual void Detach(); 64 65 // Abort the download and automatically close the file. 66 void Cancel(); 67 68 // Indicate that the download has finished. No new data will be received. 69 void Finish(); 70 71 // Set the client guid which will be used to identify the app to the 72 // system AV scanning function. Should be called before 73 // AnnotateWithSourceInformation() to take effect. 74 void SetClientGuid(const std::string& guid); 75 76 // Informs the OS that this file came from the internet. Returns a 77 // DownloadInterruptReason indicating the result of the operation. 78 // Note: SetClientGuid() should be called before this function on 79 // Windows to ensure the correct app client ID is available. 80 DownloadInterruptReason AnnotateWithSourceInformation(); 81 full_path()82 base::FilePath full_path() const { return full_path_; } in_progress()83 bool in_progress() const { return file_.IsValid(); } bytes_so_far()84 int64 bytes_so_far() const { return bytes_so_far_; } 85 86 // Fills |hash| with the hash digest for the file. 87 // Returns true if digest is successfully calculated. 88 virtual bool GetHash(std::string* hash); 89 90 // Returns the current (intermediate) state of the hash as a byte string. 91 virtual std::string GetHashState(); 92 93 // Returns true if the given hash is considered empty. An empty hash is 94 // a string of size crypto::kSHA256Length that contains only zeros (initial 95 // value for the hash). 96 static bool IsEmptyHash(const std::string& hash); 97 98 virtual std::string DebugString() const; 99 100 private: 101 friend class BaseFileTest; 102 FRIEND_TEST_ALL_PREFIXES(BaseFileTest, IsEmptyHash); 103 104 // Creates and opens the file_ if it is NULL. 105 DownloadInterruptReason Open(); 106 107 // Closes and resets file_. 108 void Close(); 109 110 // Resets file_. 111 void ClearFile(); 112 113 // Platform specific method that moves a file to a new path and adjusts the 114 // security descriptor / permissions on the file to match the defaults for the 115 // new directory. 116 DownloadInterruptReason MoveFileAndAdjustPermissions( 117 const base::FilePath& new_path); 118 119 // Split out from CurrentSpeed to enable testing. 120 int64 CurrentSpeedAtTime(base::TimeTicks current_time) const; 121 122 // Log a TYPE_DOWNLOAD_FILE_ERROR NetLog event with |error| and passes error 123 // on through, converting to a |DownloadInterruptReason|. 124 DownloadInterruptReason LogNetError(const char* operation, net::Error error); 125 126 // Log the system error in |os_error| and converts it into a 127 // |DownloadInterruptReason|. 128 DownloadInterruptReason LogSystemError(const char* operation, 129 logging::SystemErrorCode os_error); 130 131 // Log a TYPE_DOWNLOAD_FILE_ERROR NetLog event with |os_error| and |reason|. 132 // Returns |reason|. 133 DownloadInterruptReason LogInterruptReason( 134 const char* operation, int os_error, 135 DownloadInterruptReason reason); 136 137 static const unsigned char kEmptySha256Hash[crypto::kSHA256Length]; 138 139 // Full path to the file including the file name. 140 base::FilePath full_path_; 141 142 // Source URL for the file being downloaded. 143 GURL source_url_; 144 145 // The URL where the download was initiated. 146 GURL referrer_url_; 147 148 std::string client_guid_; 149 150 // OS file for writing 151 base::File file_; 152 153 // Amount of data received up so far, in bytes. 154 int64 bytes_so_far_; 155 156 // Start time for calculating speed. 157 base::TimeTicks start_tick_; 158 159 // Indicates if hash should be calculated for the file. 160 bool calculate_hash_; 161 162 // Used to calculate hash for the file when calculate_hash_ 163 // is set. 164 scoped_ptr<crypto::SecureHash> secure_hash_; 165 166 unsigned char sha256_hash_[crypto::kSHA256Length]; 167 168 // Indicates that this class no longer owns the associated file, and so 169 // won't delete it on destruction. 170 bool detached_; 171 172 net::BoundNetLog bound_net_log_; 173 174 DISALLOW_COPY_AND_ASSIGN(BaseFile); 175 }; 176 177 } // namespace content 178 179 #endif // CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ 180