| 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 #ifndef CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ | 5 #ifndef CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ |
| 6 #define CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ | 6 #define CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 // location as determined by ContentBrowserClient. | 54 // location as determined by ContentBrowserClient. |
| 55 // | 55 // |
| 56 // |file|: The base::File handle to use. If specified, BaseFile will not open | 56 // |file|: The base::File handle to use. If specified, BaseFile will not open |
| 57 // a file and will use this handle. The file should be opened for both | 57 // a file and will use this handle. The file should be opened for both |
| 58 // read and write. Only makes sense if |full_path| is non-empty since it | 58 // read and write. Only makes sense if |full_path| is non-empty since it |
| 59 // implies that the caller already knows the path to the file. There's no | 59 // implies that the caller already knows the path to the file. There's no |
| 60 // perfect way to come up with a canonical path for a file. So BaseFile | 60 // perfect way to come up with a canonical path for a file. So BaseFile |
| 61 // will not attempt to determine the |full_path|. | 61 // will not attempt to determine the |full_path|. |
| 62 // | 62 // |
| 63 // |bytes_so_far|: If a file is provided (via |full_path| or |file|), then | 63 // |bytes_so_far|: If a file is provided (via |full_path| or |file|), then |
| 64 // this argument specifies the size of the file to expect. It is legal for | 64 // this argument specifies the amount of data that has been written to |
| 65 // the file to be larger, in which case the file will be truncated down to | 65 // the file. If |is_sparse_file| is false, this value should be the size |
| 66 // this size. However, if the file is shorter, then the operation will | 66 // of the file to expect. It is legal for the file to be larger, in which |
| 67 // case the file will be truncated down to this size if |is_sparse_file| |
| 68 // is false. However, if the file is shorter, then the operation will |
| 67 // fail with DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT. | 69 // fail with DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT. |
| 70 |
| 68 // | 71 // |
| 69 // |hash_so_far|: If |bytes_so_far| is non-zero, this specifies the SHA-256 | 72 // |hash_so_far|: If |bytes_so_far| is non-zero and |is_sparse_file| is |
| 70 // hash of the first |bytes_so_far| bytes of the target file. If | 73 // false, this specifies the SHA-256 hash of the first |bytes_so_far| |
| 71 // specified, BaseFile will read the first |bytes_so_far| of the target | 74 // bytes of the target file. If specified, BaseFile will read the first |
| 72 // file in order to calculate the hash and verify that the file matches. | 75 // |bytes_so_far| of the target file in order to calculate the hash and |
| 73 // If there's a mismatch, then the operation fails with | 76 // verify that the file matches. If there's a mismatch, then the operation |
| 74 // DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH. Not used if |hash_state| | 77 // fails with DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH. Not used if |
| 75 // is also specified. | 78 // |hash_state| is also specified. |
| 76 // | 79 // |
| 77 // |hash_state|: The partial hash object to use. Only meaningful if there's a | 80 // |hash_state|: The partial hash object to use. Only meaningful if there's a |
| 78 // preexisting target file and it is non-empty (i.e. bytes_so_far is | 81 // preexisting target file and it is non-empty (i.e. bytes_so_far is |
| 79 // non-zero). If specified, BaseFile will assume that the bytes up to | 82 // non-zero). If specified, BaseFile will assume that the bytes up to |
| 80 // |bytes_so_far| has been accurately hashed into |hash_state| and will | 83 // |bytes_so_far| has been accurately hashed into |hash_state| and will |
| 81 // ignore |hash_so_far|. | 84 // ignore |hash_so_far|. Not used if |is_sparse_file| is true. |
| 85 // |
| 86 // |is_sparse_file|: Specifies whether the file is a sparse file. If so, it is |
| 87 // possible that a write can happen at an offset that is larger than the |
| 88 // file size, thus creating holes in it. |
| 82 DownloadInterruptReason Initialize( | 89 DownloadInterruptReason Initialize( |
| 83 const base::FilePath& full_path, | 90 const base::FilePath& full_path, |
| 84 const base::FilePath& default_directory, | 91 const base::FilePath& default_directory, |
| 85 base::File file, | 92 base::File file, |
| 86 int64_t bytes_so_far, | 93 int64_t bytes_so_far, |
| 87 const std::string& hash_so_far, | 94 const std::string& hash_so_far, |
| 88 std::unique_ptr<crypto::SecureHash> hash_state); | 95 std::unique_ptr<crypto::SecureHash> hash_state, |
| 96 bool is_sparse_file); |
| 97 |
| 98 // Write a new chunk of data to the file. Returns a DownloadInterruptReason |
| 99 // indicating the result of the operation. Works only if |is_sparse_file| is |
| 100 // false. |
| 101 DownloadInterruptReason AppendDataToFile(const char* data, size_t data_len); |
| 89 | 102 |
| 90 // Write a new chunk of data to the file. Returns a DownloadInterruptReason | 103 // Write a new chunk of data to the file. Returns a DownloadInterruptReason |
| 91 // indicating the result of the operation. | 104 // indicating the result of the operation. |
| 92 DownloadInterruptReason AppendDataToFile(const char* data, size_t data_len); | 105 DownloadInterruptReason WriteDataToFile( |
| 106 int64_t offset, |
| 107 const char* data, |
| 108 size_t data_len); |
| 93 | 109 |
| 94 // Rename the download file. Returns a DownloadInterruptReason indicating the | 110 // Rename the download file. Returns a DownloadInterruptReason indicating the |
| 95 // result of the operation. A return code of NONE indicates that the rename | 111 // result of the operation. A return code of NONE indicates that the rename |
| 96 // was successful. After a failure, the full_path() and in_progress() can be | 112 // was successful. After a failure, the full_path() and in_progress() can be |
| 97 // used to determine the last known filename and whether the file is available | 113 // used to determine the last known filename and whether the file is available |
| 98 // for writing or retrying the rename. Call Finish() to obtain the last known | 114 // for writing or retrying the rename. Call Finish() to obtain the last known |
| 99 // hash state. | 115 // hash state. |
| 100 DownloadInterruptReason Rename(const base::FilePath& full_path); | 116 DownloadInterruptReason Rename(const base::FilePath& full_path); |
| 101 | 117 |
| 102 // Mark the file as detached. Up until this method is called, BaseFile assumes | 118 // Mark the file as detached. Up until this method is called, BaseFile assumes |
| 103 // ownership of the file and hence will delete the file if the BaseFile object | 119 // ownership of the file and hence will delete the file if the BaseFile object |
| 104 // is destroyed. Calling Detach() causes BaseFile to assume that it no longer | 120 // is destroyed. Calling Detach() causes BaseFile to assume that it no longer |
| 105 // owns the file. Detach() can be called at any time. Close() must still be | 121 // owns the file. Detach() can be called at any time. Close() must still be |
| 106 // called to close the file if it is open. | 122 // called to close the file if it is open. |
| 107 void Detach(); | 123 void Detach(); |
| 108 | 124 |
| 109 // Abort the download and automatically close and delete the file. | 125 // Abort the download and automatically close and delete the file. |
| 110 void Cancel(); | 126 void Cancel(); |
| 111 | 127 |
| 112 // Indicate that the download has finished. No new data will be received. | 128 // Indicate that the download has finished. No new data will be received. |
| 113 // Returns the SecureHash object representing the state of the hash function | 129 // Returns the SecureHash object representing the state of the hash function |
| 114 // at the end of the operation. | 130 // at the end of the operation. If |is_sparse_file_| is true, calling this |
| 131 // will cause |secure_hash_| to get calculated. |
| 115 std::unique_ptr<crypto::SecureHash> Finish(); | 132 std::unique_ptr<crypto::SecureHash> Finish(); |
| 116 | 133 |
| 117 // Informs the OS that this file came from the internet. Returns a | 134 // Informs the OS that this file came from the internet. Returns a |
| 118 // DownloadInterruptReason indicating the result of the operation. | 135 // DownloadInterruptReason indicating the result of the operation. |
| 119 // | 136 // |
| 120 // |client_guid|: The client GUID which will be used to identify the caller to | 137 // |client_guid|: The client GUID which will be used to identify the caller to |
| 121 // the system AV scanning function. | 138 // the system AV scanning function. |
| 122 // | 139 // |
| 123 // |source_url| / |referrer_url|: Source and referrer for the network request | 140 // |source_url| / |referrer_url|: Source and referrer for the network request |
| 124 // that originated this download. Will be used to annotate source | 141 // that originated this download. Will be used to annotate source |
| 125 // information and also to determine the relative danger level of the | 142 // information and also to determine the relative danger level of the |
| 126 // file. | 143 // file. |
| 127 DownloadInterruptReason AnnotateWithSourceInformation( | 144 DownloadInterruptReason AnnotateWithSourceInformation( |
| 128 const std::string& client_guid, | 145 const std::string& client_guid, |
| 129 const GURL& source_url, | 146 const GURL& source_url, |
| 130 const GURL& referrer_url); | 147 const GURL& referrer_url); |
| 131 | 148 |
| 132 // Returns the last known path to the download file. Can be empty if there's | 149 // Returns the last known path to the download file. Can be empty if there's |
| 133 // no file. | 150 // no file. |
| 134 const base::FilePath& full_path() const { return full_path_; } | 151 const base::FilePath& full_path() const { return full_path_; } |
| 135 | 152 |
| 136 // Returns true if the file is open. If true, the file can be written to or | 153 // Returns true if the file is open. If true, the file can be written to or |
| 137 // renamed. | 154 // renamed. |
| 138 bool in_progress() const { return file_.IsValid(); } | 155 bool in_progress() const { return file_.IsValid(); } |
| 139 | 156 |
| 140 // Returns the number of bytes in the file pointed to by full_path(). | 157 // Returns the number of bytes that has been written so far. If |
| 158 // |is_sparse_file_| is false, this should always be equal to the file size. |
| 159 // If |is_sparse_file_| is true, this should not be larger than the file size |
| 160 // as the file may contain holes in it. |
| 141 int64_t bytes_so_far() const { return bytes_so_far_; } | 161 int64_t bytes_so_far() const { return bytes_so_far_; } |
| 142 | 162 |
| 143 std::string DebugString() const; | 163 std::string DebugString() const; |
| 144 | 164 |
| 145 private: | 165 private: |
| 146 friend class BaseFileTest; | 166 friend class BaseFileTest; |
| 147 FRIEND_TEST_ALL_PREFIXES(BaseFileTest, IsEmptyHash); | 167 FRIEND_TEST_ALL_PREFIXES(BaseFileTest, IsEmptyHash); |
| 148 | 168 |
| 149 // Creates and opens the file_ if it is invalid. | 169 // Creates and opens the file_ if it is invalid. |
| 150 // | 170 // |
| 151 // If |hash_so_far| is not empty, then it must match the SHA-256 hash of the | 171 // If |is_sparse_file_| is false and |hash_so_far| is not empty, then it must |
| 152 // first |bytes_so_far_| bytes of |file_|. If there's a hash mismatch, Open() | 172 // match the SHA-256 hash of the first |bytes_so_far_| bytes of |file_|. If |
| 153 // fails with DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH. | 173 // there's a hash mismatch, Open() fails with |
| 174 // DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH. |
| 154 // | 175 // |
| 155 // If the opened file is shorter than |bytes_so_far_| bytes, then Open() fails | 176 // If the opened file is shorter than |bytes_so_far_| bytes, then Open() fails |
| 156 // with DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT. If the opened file is | 177 // with DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT. If the opened file is longer |
| 157 // longer, then the file is truncated to |bytes_so_far_|. | 178 // and |is_sparse_file_| is false, then the file is truncated to |
| 179 // |bytes_so_far_|. |
| 158 // | 180 // |
| 159 // Open() can fail for other reasons as well. In that case, it returns a | 181 // Open() can fail for other reasons as well. In that case, it returns a |
| 160 // relevant interrupt reason. Unless Open() return | 182 // relevant interrupt reason. Unless Open() return |
| 161 // DOWNLOAD_INTERRUPT_REASON_NONE, it should be assumed that |file_| is not | 183 // DOWNLOAD_INTERRUPT_REASON_NONE, it should be assumed that |file_| is not |
| 162 // valid. | 184 // valid. |
| 163 DownloadInterruptReason Open(const std::string& hash_so_far); | 185 DownloadInterruptReason Open(const std::string& hash_so_far); |
| 164 | 186 |
| 165 // Closes and resets file_. | 187 // Closes and resets file_. |
| 166 void Close(); | 188 void Close(); |
| 167 | 189 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 178 int64_t CurrentSpeedAtTime(base::TimeTicks current_time) const; | 200 int64_t CurrentSpeedAtTime(base::TimeTicks current_time) const; |
| 179 | 201 |
| 180 // Verifies that: | 202 // Verifies that: |
| 181 // * Size of the file represented by |file_| is at least |bytes_so_far_|. | 203 // * Size of the file represented by |file_| is at least |bytes_so_far_|. |
| 182 // | 204 // |
| 183 // * If |hash_to_expect| is not empty, then the result of hashing the first | 205 // * If |hash_to_expect| is not empty, then the result of hashing the first |
| 184 // |bytes_so_far_| bytes of |file_| matches |hash_to_expect|. | 206 // |bytes_so_far_| bytes of |file_| matches |hash_to_expect|. |
| 185 // | 207 // |
| 186 // If the result is REASON_NONE, then on return |secure_hash_| is valid and | 208 // If the result is REASON_NONE, then on return |secure_hash_| is valid and |
| 187 // is ready to hash bytes from offset |bytes_so_far_| + 1. | 209 // is ready to hash bytes from offset |bytes_so_far_| + 1. |
| 210 // If |is_sparse_file_| is true, this function is only called when Finish() |
| 211 // is called. |
| 188 DownloadInterruptReason CalculatePartialHash( | 212 DownloadInterruptReason CalculatePartialHash( |
| 189 const std::string& hash_to_expect); | 213 const std::string& hash_to_expect); |
| 190 | 214 |
| 191 // Log a TYPE_DOWNLOAD_FILE_ERROR NetLog event with |error| and passes error | 215 // Log a TYPE_DOWNLOAD_FILE_ERROR NetLog event with |error| and passes error |
| 192 // on through, converting to a |DownloadInterruptReason|. | 216 // on through, converting to a |DownloadInterruptReason|. |
| 193 DownloadInterruptReason LogNetError(const char* operation, net::Error error); | 217 DownloadInterruptReason LogNetError(const char* operation, net::Error error); |
| 194 | 218 |
| 195 // Log the system error in |os_error| and converts it into a | 219 // Log the system error in |os_error| and converts it into a |
| 196 // |DownloadInterruptReason|. | 220 // |DownloadInterruptReason|. |
| 197 DownloadInterruptReason LogSystemError(const char* operation, | 221 DownloadInterruptReason LogSystemError(const char* operation, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 215 // Used to calculate hash for the file when calculate_hash_ is set. | 239 // Used to calculate hash for the file when calculate_hash_ is set. |
| 216 std::unique_ptr<crypto::SecureHash> secure_hash_; | 240 std::unique_ptr<crypto::SecureHash> secure_hash_; |
| 217 | 241 |
| 218 // Start time for calculating speed. | 242 // Start time for calculating speed. |
| 219 base::TimeTicks start_tick_; | 243 base::TimeTicks start_tick_; |
| 220 | 244 |
| 221 // Indicates that this class no longer owns the associated file, and so | 245 // Indicates that this class no longer owns the associated file, and so |
| 222 // won't delete it on destruction. | 246 // won't delete it on destruction. |
| 223 bool detached_ = false; | 247 bool detached_ = false; |
| 224 | 248 |
| 249 // Whether the file is sparse. |
| 250 // TODO(qinmin): pass the slice information to this class so that we can |
| 251 // verify that writes are not overlapping. |
| 252 bool is_sparse_file_ = false; |
| 253 |
| 225 net::NetLogWithSource net_log_; | 254 net::NetLogWithSource net_log_; |
| 226 | 255 |
| 227 DISALLOW_COPY_AND_ASSIGN(BaseFile); | 256 DISALLOW_COPY_AND_ASSIGN(BaseFile); |
| 228 }; | 257 }; |
| 229 | 258 |
| 230 } // namespace content | 259 } // namespace content |
| 231 | 260 |
| 232 #endif // CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ | 261 #endif // CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_ |
| OLD | NEW |