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