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 // For loading files, we make use of overlapped i/o to ensure that reading from | 5 // For loading files, we make use of overlapped i/o to ensure that reading from |
6 // the filesystem (e.g., a network filesystem) does not block the calling | 6 // the filesystem (e.g., a network filesystem) does not block the calling |
7 // thread. An alternative approach would be to use a background thread or pool | 7 // thread. An alternative approach would be to use a background thread or pool |
8 // of threads, but it seems better to leverage the operating system's ability | 8 // of threads, but it seems better to leverage the operating system's ability |
9 // to do background file reads for us. | 9 // to do background file reads for us. |
10 // | 10 // |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 URLRequestFileJob::URLRequestFileJob( | 56 URLRequestFileJob::URLRequestFileJob( |
57 URLRequest* request, | 57 URLRequest* request, |
58 NetworkDelegate* network_delegate, | 58 NetworkDelegate* network_delegate, |
59 const base::FilePath& file_path, | 59 const base::FilePath& file_path, |
60 const scoped_refptr<base::TaskRunner>& file_task_runner) | 60 const scoped_refptr<base::TaskRunner>& file_task_runner) |
61 : URLRequestJob(request, network_delegate), | 61 : URLRequestJob(request, network_delegate), |
62 file_path_(file_path), | 62 file_path_(file_path), |
63 stream_(new FileStream(file_task_runner)), | 63 stream_(new FileStream(file_task_runner)), |
64 file_task_runner_(file_task_runner), | 64 file_task_runner_(file_task_runner), |
65 remaining_bytes_(0), | 65 remaining_bytes_(0), |
66 weak_ptr_factory_(this) {} | 66 weak_ptr_factory_(this) { |
| 67 } |
67 | 68 |
68 void URLRequestFileJob::Start() { | 69 void URLRequestFileJob::Start() { |
69 FileMetaInfo* meta_info = new FileMetaInfo(); | 70 FileMetaInfo* meta_info = new FileMetaInfo(); |
70 file_task_runner_->PostTaskAndReply( | 71 file_task_runner_->PostTaskAndReply( |
71 FROM_HERE, | 72 FROM_HERE, |
72 base::Bind(&URLRequestFileJob::FetchMetaInfo, file_path_, | 73 base::Bind(&URLRequestFileJob::FetchMetaInfo, |
| 74 file_path_, |
73 base::Unretained(meta_info)), | 75 base::Unretained(meta_info)), |
74 base::Bind(&URLRequestFileJob::DidFetchMetaInfo, | 76 base::Bind(&URLRequestFileJob::DidFetchMetaInfo, |
75 weak_ptr_factory_.GetWeakPtr(), | 77 weak_ptr_factory_.GetWeakPtr(), |
76 base::Owned(meta_info))); | 78 base::Owned(meta_info))); |
77 } | 79 } |
78 | 80 |
79 void URLRequestFileJob::Kill() { | 81 void URLRequestFileJob::Kill() { |
80 stream_.reset(); | 82 stream_.reset(); |
81 weak_ptr_factory_.InvalidateWeakPtrs(); | 83 weak_ptr_factory_.InvalidateWeakPtrs(); |
82 | 84 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 *http_status_code = 301; | 157 *http_status_code = 301; |
156 return true; | 158 return true; |
157 #else | 159 #else |
158 return false; | 160 return false; |
159 #endif | 161 #endif |
160 } | 162 } |
161 | 163 |
162 Filter* URLRequestFileJob::SetupFilter() const { | 164 Filter* URLRequestFileJob::SetupFilter() const { |
163 // Bug 9936 - .svgz files needs to be decompressed. | 165 // Bug 9936 - .svgz files needs to be decompressed. |
164 return LowerCaseEqualsASCII(file_path_.Extension(), ".svgz") | 166 return LowerCaseEqualsASCII(file_path_.Extension(), ".svgz") |
165 ? Filter::GZipFactory() : NULL; | 167 ? Filter::GZipFactory() |
| 168 : NULL; |
166 } | 169 } |
167 | 170 |
168 bool URLRequestFileJob::GetMimeType(std::string* mime_type) const { | 171 bool URLRequestFileJob::GetMimeType(std::string* mime_type) const { |
169 DCHECK(request_); | 172 DCHECK(request_); |
170 if (meta_info_.mime_type_result) { | 173 if (meta_info_.mime_type_result) { |
171 *mime_type = meta_info_.mime_type; | 174 *mime_type = meta_info_.mime_type; |
172 return true; | 175 return true; |
173 } | 176 } |
174 return false; | 177 return false; |
175 } | 178 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 void URLRequestFileJob::FetchMetaInfo(const base::FilePath& file_path, | 210 void URLRequestFileJob::FetchMetaInfo(const base::FilePath& file_path, |
208 FileMetaInfo* meta_info) { | 211 FileMetaInfo* meta_info) { |
209 base::File::Info file_info; | 212 base::File::Info file_info; |
210 meta_info->file_exists = base::GetFileInfo(file_path, &file_info); | 213 meta_info->file_exists = base::GetFileInfo(file_path, &file_info); |
211 if (meta_info->file_exists) { | 214 if (meta_info->file_exists) { |
212 meta_info->file_size = file_info.size; | 215 meta_info->file_size = file_info.size; |
213 meta_info->is_directory = file_info.is_directory; | 216 meta_info->is_directory = file_info.is_directory; |
214 } | 217 } |
215 // On Windows GetMimeTypeFromFile() goes to the registry. Thus it should be | 218 // On Windows GetMimeTypeFromFile() goes to the registry. Thus it should be |
216 // done in WorkerPool. | 219 // done in WorkerPool. |
217 meta_info->mime_type_result = GetMimeTypeFromFile(file_path, | 220 meta_info->mime_type_result = |
218 &meta_info->mime_type); | 221 GetMimeTypeFromFile(file_path, &meta_info->mime_type); |
219 } | 222 } |
220 | 223 |
221 void URLRequestFileJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) { | 224 void URLRequestFileJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) { |
222 meta_info_ = *meta_info; | 225 meta_info_ = *meta_info; |
223 | 226 |
224 // We use URLRequestFileJob to handle files as well as directories without | 227 // We use URLRequestFileJob to handle files as well as directories without |
225 // trailing slash. | 228 // trailing slash. |
226 // If a directory does not exist, we return ERR_FILE_NOT_FOUND. Otherwise, | 229 // If a directory does not exist, we return ERR_FILE_NOT_FOUND. Otherwise, |
227 // we will append trailing slash and redirect to FileDirJob. | 230 // we will append trailing slash and redirect to FileDirJob. |
228 // A special case is "\" on Windows. We should resolve as invalid. | 231 // A special case is "\" on Windows. We should resolve as invalid. |
229 // However, Windows resolves "\" to "C:\", thus reports it as existent. | 232 // However, Windows resolves "\" to "C:\", thus reports it as existent. |
230 // So what happens is we append it with trailing slash and redirect it to | 233 // So what happens is we append it with trailing slash and redirect it to |
231 // FileDirJob where it is resolved as invalid. | 234 // FileDirJob where it is resolved as invalid. |
232 if (!meta_info_.file_exists) { | 235 if (!meta_info_.file_exists) { |
233 DidOpen(ERR_FILE_NOT_FOUND); | 236 DidOpen(ERR_FILE_NOT_FOUND); |
234 return; | 237 return; |
235 } | 238 } |
236 if (meta_info_.is_directory) { | 239 if (meta_info_.is_directory) { |
237 DidOpen(OK); | 240 DidOpen(OK); |
238 return; | 241 return; |
239 } | 242 } |
240 | 243 |
241 int flags = base::File::FLAG_OPEN | | 244 int flags = |
242 base::File::FLAG_READ | | 245 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_ASYNC; |
243 base::File::FLAG_ASYNC; | 246 int rv = stream_->Open( |
244 int rv = stream_->Open(file_path_, flags, | 247 file_path_, |
245 base::Bind(&URLRequestFileJob::DidOpen, | 248 flags, |
246 weak_ptr_factory_.GetWeakPtr())); | 249 base::Bind(&URLRequestFileJob::DidOpen, weak_ptr_factory_.GetWeakPtr())); |
247 if (rv != ERR_IO_PENDING) | 250 if (rv != ERR_IO_PENDING) |
248 DidOpen(rv); | 251 DidOpen(rv); |
249 } | 252 } |
250 | 253 |
251 void URLRequestFileJob::DidOpen(int result) { | 254 void URLRequestFileJob::DidOpen(int result) { |
252 if (result != OK) { | 255 if (result != OK) { |
253 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); | 256 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); |
254 return; | 257 return; |
255 } | 258 } |
256 | 259 |
257 if (!byte_range_.ComputeBounds(meta_info_.file_size)) { | 260 if (!byte_range_.ComputeBounds(meta_info_.file_size)) { |
258 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, | 261 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, |
259 ERR_REQUEST_RANGE_NOT_SATISFIABLE)); | 262 ERR_REQUEST_RANGE_NOT_SATISFIABLE)); |
260 return; | 263 return; |
261 } | 264 } |
262 | 265 |
263 remaining_bytes_ = byte_range_.last_byte_position() - | 266 remaining_bytes_ = |
264 byte_range_.first_byte_position() + 1; | 267 byte_range_.last_byte_position() - byte_range_.first_byte_position() + 1; |
265 DCHECK_GE(remaining_bytes_, 0); | 268 DCHECK_GE(remaining_bytes_, 0); |
266 | 269 |
267 if (remaining_bytes_ > 0 && byte_range_.first_byte_position() != 0) { | 270 if (remaining_bytes_ > 0 && byte_range_.first_byte_position() != 0) { |
268 int rv = stream_->Seek(FROM_BEGIN, byte_range_.first_byte_position(), | 271 int rv = stream_->Seek(FROM_BEGIN, |
| 272 byte_range_.first_byte_position(), |
269 base::Bind(&URLRequestFileJob::DidSeek, | 273 base::Bind(&URLRequestFileJob::DidSeek, |
270 weak_ptr_factory_.GetWeakPtr())); | 274 weak_ptr_factory_.GetWeakPtr())); |
271 if (rv != ERR_IO_PENDING) { | 275 if (rv != ERR_IO_PENDING) { |
272 // stream_->Seek() failed, so pass an intentionally erroneous value | 276 // stream_->Seek() failed, so pass an intentionally erroneous value |
273 // into DidSeek(). | 277 // into DidSeek(). |
274 DidSeek(-1); | 278 DidSeek(-1); |
275 } | 279 } |
276 } else { | 280 } else { |
277 // We didn't need to call stream_->Seek() at all, so we pass to DidSeek() | 281 // We didn't need to call stream_->Seek() at all, so we pass to DidSeek() |
278 // the value that would mean seek success. This way we skip the code | 282 // the value that would mean seek success. This way we skip the code |
(...skipping 25 matching lines...) Expand all Loading... |
304 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); | 308 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); |
305 } | 309 } |
306 | 310 |
307 remaining_bytes_ -= result; | 311 remaining_bytes_ -= result; |
308 DCHECK_GE(remaining_bytes_, 0); | 312 DCHECK_GE(remaining_bytes_, 0); |
309 | 313 |
310 NotifyReadComplete(result); | 314 NotifyReadComplete(result); |
311 } | 315 } |
312 | 316 |
313 } // namespace net | 317 } // namespace net |
OLD | NEW |