| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 #include "base/compiler_specific.h" | 22 #include "base/compiler_specific.h" |
| 23 #include "base/message_loop.h" | 23 #include "base/message_loop.h" |
| 24 #include "base/string_util.h" | 24 #include "base/string_util.h" |
| 25 #include "base/worker_pool.h" | 25 #include "base/worker_pool.h" |
| 26 #include "googleurl/src/gurl.h" | 26 #include "googleurl/src/gurl.h" |
| 27 #include "net/base/mime_util.h" | 27 #include "net/base/mime_util.h" |
| 28 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 29 #include "net/base/net_util.h" | 29 #include "net/base/net_util.h" |
| 30 #include "net/url_request/url_request.h" | 30 #include "net/url_request/url_request.h" |
| 31 #if defined(OS_WIN) |
| 31 #include "net/url_request/url_request_file_dir_job.h" | 32 #include "net/url_request/url_request_file_dir_job.h" |
| 33 #endif |
| 32 | 34 |
| 33 #if defined(OS_WIN) | 35 #if defined(OS_WIN) |
| 34 class URLRequestFileJob::AsyncResolver : | 36 class URLRequestFileJob::AsyncResolver : |
| 35 public base::RefCountedThreadSafe<URLRequestFileJob::AsyncResolver> { | 37 public base::RefCountedThreadSafe<URLRequestFileJob::AsyncResolver> { |
| 36 public: | 38 public: |
| 37 explicit AsyncResolver(URLRequestFileJob* owner) | 39 explicit AsyncResolver(URLRequestFileJob* owner) |
| 38 : owner_(owner), owner_loop_(MessageLoop::current()) { | 40 : owner_(owner), owner_loop_(MessageLoop::current()) { |
| 39 } | 41 } |
| 40 | 42 |
| 41 void Resolve(const std::wstring& file_path) { | 43 void Resolve(const std::wstring& file_path) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 67 MessageLoop* owner_loop_; | 69 MessageLoop* owner_loop_; |
| 68 }; | 70 }; |
| 69 #endif | 71 #endif |
| 70 | 72 |
| 71 // static | 73 // static |
| 72 URLRequestJob* URLRequestFileJob::Factory( | 74 URLRequestJob* URLRequestFileJob::Factory( |
| 73 URLRequest* request, const std::string& scheme) { | 75 URLRequest* request, const std::string& scheme) { |
| 74 std::wstring file_path; | 76 std::wstring file_path; |
| 75 if (net::FileURLToFilePath(request->url(), &file_path)) { | 77 if (net::FileURLToFilePath(request->url(), &file_path)) { |
| 76 if (file_path[file_path.size() - 1] == file_util::kPathSeparator) { | 78 if (file_path[file_path.size() - 1] == file_util::kPathSeparator) { |
| 79 #if defined(OS_WIN) |
| 77 // Only directories have trailing slashes. | 80 // Only directories have trailing slashes. |
| 78 return new URLRequestFileDirJob(request, file_path); | 81 return new URLRequestFileDirJob(request, file_path); |
| 82 #endif |
| 79 } | 83 } |
| 80 } | 84 } |
| 81 | 85 |
| 82 // Use a regular file request job for all non-directories (including invalid | 86 // Use a regular file request job for all non-directories (including invalid |
| 83 // file names). | 87 // file names). |
| 84 URLRequestFileJob* job = new URLRequestFileJob(request); | 88 URLRequestFileJob* job = new URLRequestFileJob(request); |
| 85 job->file_path_ = file_path; | 89 job->file_path_ = file_path; |
| 86 return job; | 90 return job; |
| 87 } | 91 } |
| 88 | 92 |
| 89 URLRequestFileJob::URLRequestFileJob(URLRequest* request) | 93 URLRequestFileJob::URLRequestFileJob(URLRequest* request) |
| 90 : URLRequestJob(request), | 94 : URLRequestJob(request), |
| 91 ALLOW_THIS_IN_INITIALIZER_LIST( | 95 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 92 io_callback_(this, &URLRequestFileJob::DidRead)), | 96 io_callback_(this, &URLRequestFileJob::DidRead)), |
| 93 is_directory_(false) { | 97 is_directory_(false) { |
| 94 } | 98 } |
| 95 | 99 |
| 96 URLRequestFileJob::~URLRequestFileJob() { | 100 URLRequestFileJob::~URLRequestFileJob() { |
| 97 #if defined(OS_WIN) | 101 #if defined(OS_WIN) |
| 98 DCHECK(!async_resolver_); | 102 DCHECK(!async_resolver_); |
| 99 #endif | 103 #endif |
| 100 } | 104 } |
| 101 | 105 |
| 102 void URLRequestFileJob::Start() { | 106 void URLRequestFileJob::Start() { |
| 107 #if defined(OS_WIN) |
| 103 // Resolve UNC paths on a background thread. | 108 // Resolve UNC paths on a background thread. |
| 104 if (!file_path_.compare(0, 2, L"\\\\")) { | 109 if (!file_path_.compare(0, 2, L"\\\\")) { |
| 105 DCHECK(!async_resolver_); | 110 DCHECK(!async_resolver_); |
| 106 async_resolver_ = new AsyncResolver(this); | 111 async_resolver_ = new AsyncResolver(this); |
| 107 WorkerPool::PostTask(FROM_HERE, NewRunnableMethod( | 112 WorkerPool::PostTask(FROM_HERE, NewRunnableMethod( |
| 108 async_resolver_.get(), &AsyncResolver::Resolve, file_path_), true); | 113 async_resolver_.get(), &AsyncResolver::Resolve, file_path_), true); |
| 109 } else { | 114 return; |
| 110 file_util::FileInfo file_info; | 115 } |
| 111 bool exists = file_util::GetFileInfo(file_path_, &file_info); | 116 #endif |
| 117 file_util::FileInfo file_info; |
| 118 bool exists = file_util::GetFileInfo(file_path_, &file_info); |
| 112 | 119 |
| 113 // Continue asynchronously. | 120 // Continue asynchronously. |
| 114 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | 121 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
| 115 this, &URLRequestFileJob::DidResolve, exists, file_info)); | 122 this, &URLRequestFileJob::DidResolve, exists, file_info)); |
| 116 } | |
| 117 } | 123 } |
| 118 | 124 |
| 119 void URLRequestFileJob::Kill() { | 125 void URLRequestFileJob::Kill() { |
| 120 stream_.Close(); | 126 stream_.Close(); |
| 121 | 127 |
| 122 #if defined(OS_WIN) | 128 #if defined(OS_WIN) |
| 123 if (async_resolver_) { | 129 if (async_resolver_) { |
| 124 async_resolver_->Cancel(); | 130 async_resolver_->Cancel(); |
| 125 async_resolver_ = NULL; | 131 async_resolver_ = NULL; |
| 126 } | 132 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 return false; | 233 return false; |
| 228 | 234 |
| 229 *location = net::FilePathToFileURL(new_path); | 235 *location = net::FilePathToFileURL(new_path); |
| 230 *http_status_code = 301; | 236 *http_status_code = 301; |
| 231 return true; | 237 return true; |
| 232 #else | 238 #else |
| 233 return false; | 239 return false; |
| 234 #endif | 240 #endif |
| 235 } | 241 } |
| 236 | 242 |
| OLD | NEW |