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 |