Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "chrome/browser/chromeos/fileapi/external_file_url_request_job.h" | 5 #include "chrome/browser/chromeos/fileapi/external_file_url_request_job.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/chromeos/drive/file_system_util.h" | 14 #include "chrome/browser/chromeos/drive/file_system_util.h" |
| 15 #include "chrome/browser/chromeos/fileapi/external_file_url_util.h" | 15 #include "chrome/browser/chromeos/fileapi/external_file_url_util.h" |
| 16 #include "chrome/browser/extensions/api/file_handlers/mime_util.h" | 16 #include "chrome/browser/extensions/api/file_handlers/mime_util.h" |
| 17 #include "chrome/browser/profiles/profile_manager.h" | 17 #include "chrome/browser/profiles/profile_manager.h" |
| 18 #include "chrome/common/url_constants.h" | 18 #include "chrome/common/url_constants.h" |
| 19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 20 #include "content/public/browser/storage_partition.h" | 20 #include "content/public/browser/storage_partition.h" |
| 21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 22 #include "net/http/http_byte_range.h" | 22 #include "net/http/http_byte_range.h" |
| 23 #include "net/http/http_request_headers.h" | 23 #include "net/http/http_request_headers.h" |
| 24 #include "net/http/http_response_info.h" | 24 #include "net/http/http_response_info.h" |
| 25 #include "net/http/http_util.h" | 25 #include "net/http/http_util.h" |
| 26 #include "net/url_request/url_request.h" | 26 #include "net/url_request/url_request.h" |
| 27 #include "net/url_request/url_request_status.h" | 27 #include "net/url_request/url_request_status.h" |
| 28 #include "storage/browser/fileapi/external_mount_points.h" | |
| 28 #include "storage/browser/fileapi/file_system_backend.h" | 29 #include "storage/browser/fileapi/file_system_backend.h" |
| 29 #include "storage/browser/fileapi/file_system_context.h" | 30 #include "storage/browser/fileapi/file_system_context.h" |
| 30 #include "storage/browser/fileapi/file_system_operation_runner.h" | 31 #include "storage/browser/fileapi/file_system_operation_runner.h" |
| 32 #include "storage/browser/fileapi/isolated_context.h" | |
| 31 | 33 |
| 32 using content::BrowserThread; | 34 using content::BrowserThread; |
| 33 | 35 |
| 34 namespace chromeos { | 36 namespace chromeos { |
| 35 namespace { | 37 namespace { |
| 36 | 38 |
| 37 const char kMimeTypeForRFC822[] = "message/rfc822"; | 39 const char kMimeTypeForRFC822[] = "message/rfc822"; |
| 38 const char kMimeTypeForMHTML[] = "multipart/related"; | 40 const char kMimeTypeForMHTML[] = "multipart/related"; |
| 39 | 41 |
| 42 storage::FileSystemURL CreateIsolatedURLFromVirtualPath( | |
| 43 const storage::FileSystemContext& context, | |
| 44 const base::FilePath& virtual_path) { | |
| 45 std::string file_system_id; | |
| 46 storage::FileSystemType file_system_type; | |
| 47 base::FilePath path; | |
| 48 { | |
| 49 std::string cracked_id; | |
| 50 storage::FileSystemMountOption option; | |
| 51 storage::ExternalMountPoints::GetSystemInstance()->CrackVirtualPath( | |
| 52 virtual_path, | |
| 53 &file_system_id, | |
| 54 &file_system_type, | |
| 55 &cracked_id, | |
| 56 &path, | |
| 57 &option); | |
| 58 } | |
| 59 if (!IsExternalFileURLType(file_system_type)) | |
| 60 return storage::FileSystemURL(); | |
| 61 std::string register_name; | |
| 62 const std::string isolated_file_system_id = | |
| 63 storage::IsolatedContext::GetInstance()->RegisterFileSystemForPath( | |
| 64 file_system_type, file_system_id, path, ®ister_name); | |
| 65 storage::FileSystemURL file_system_url = context.CreateCrackedFileSystemURL( | |
| 66 GURL(""), | |
|
mtomasz
2014/09/29 12:47:40
nit: Maybe just GURL()?
hirono
2014/09/29 13:24:02
Done.
| |
| 67 storage::kFileSystemTypeIsolated, | |
| 68 base::FilePath(isolated_file_system_id).Append(register_name)); | |
| 69 DCHECK(file_system_url.is_valid()); | |
| 70 return file_system_url; | |
| 71 } | |
| 72 | |
| 40 // Helper for obtaining FileSystemContext, FileSystemURL, and mime type on the | 73 // Helper for obtaining FileSystemContext, FileSystemURL, and mime type on the |
| 41 // UI thread. | 74 // UI thread. |
| 42 class URLHelper { | 75 class URLHelper { |
| 43 public: | 76 public: |
| 44 // The scoped pointer to control lifetime of the instance itself. The pointer | 77 // The scoped pointer to control lifetime of the instance itself. The pointer |
| 45 // is passed to callback functions and binds the lifetime of the instance to | 78 // is passed to callback functions and binds the lifetime of the instance to |
| 46 // the callback's lifetime. | 79 // the callback's lifetime. |
| 47 typedef scoped_ptr<URLHelper> Lifetime; | 80 typedef scoped_ptr<URLHelper> Lifetime; |
| 48 | 81 |
| 49 URLHelper(void* profile_id, | 82 URLHelper(void* profile_id, |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 72 DCHECK(storage); | 105 DCHECK(storage); |
| 73 | 106 |
| 74 scoped_refptr<storage::FileSystemContext> context = | 107 scoped_refptr<storage::FileSystemContext> context = |
| 75 storage->GetFileSystemContext(); | 108 storage->GetFileSystemContext(); |
| 76 DCHECK(context.get()); | 109 DCHECK(context.get()); |
| 77 | 110 |
| 78 // Obtain the absolute path in the file system. | 111 // Obtain the absolute path in the file system. |
| 79 const base::FilePath virtual_path = ExternalFileURLToVirtualPath(url_); | 112 const base::FilePath virtual_path = ExternalFileURLToVirtualPath(url_); |
| 80 | 113 |
| 81 // Obtain the file system URL. | 114 // Obtain the file system URL. |
| 82 // TODO(hirono): After removing MHTML support, stop to use the special | 115 file_system_url_ = CreateIsolatedURLFromVirtualPath(*context, virtual_path); |
| 83 // drive: scheme and use filesystem: URL directly. crbug.com/415455 | |
| 84 file_system_url_ = context->CreateCrackedFileSystemURL( | |
| 85 GURL(std::string(chrome::kExternalFileScheme) + ":"), | |
| 86 storage::kFileSystemTypeExternal, | |
| 87 virtual_path); | |
| 88 | 116 |
| 89 // Check if the obtained path providing external file URL or not. | 117 // Check if the obtained path providing external file URL or not. |
| 90 if (FileSystemURLToExternalFileURL(file_system_url_).is_empty()) { | 118 if (!file_system_url_.is_valid()) { |
| 91 ReplyResult(net::ERR_INVALID_URL); | 119 ReplyResult(net::ERR_INVALID_URL); |
| 92 return; | 120 return; |
| 93 } | 121 } |
| 94 | 122 |
| 123 isolated_file_system_scope_.reset( | |
| 124 new ExternalFileURLRequestJob::IsolatedFileSystemScope( | |
| 125 file_system_url_.filesystem_id())); | |
| 95 file_system_context_ = context; | 126 file_system_context_ = context; |
| 96 | 127 |
| 97 extensions::app_file_handler_util::GetMimeTypeForLocalPath( | 128 extensions::app_file_handler_util::GetMimeTypeForLocalPath( |
| 98 profile, | 129 profile, |
| 99 file_system_url_.path(), | 130 file_system_url_.path(), |
| 100 base::Bind(&URLHelper::OnGotMimeTypeOnUIThread, | 131 base::Bind(&URLHelper::OnGotMimeTypeOnUIThread, |
| 101 base::Unretained(this), | 132 base::Unretained(this), |
| 102 base::Passed(&lifetime))); | 133 base::Passed(&lifetime))); |
| 103 } | 134 } |
| 104 | 135 |
| 105 void OnGotMimeTypeOnUIThread(Lifetime lifetime, | 136 void OnGotMimeTypeOnUIThread(Lifetime lifetime, |
| 106 const std::string& mime_type) { | 137 const std::string& mime_type) { |
| 107 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 138 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 108 mime_type_ = mime_type; | 139 mime_type_ = mime_type; |
| 109 | 140 |
| 110 if (mime_type_ == kMimeTypeForRFC822) | 141 if (mime_type_ == kMimeTypeForRFC822) |
| 111 mime_type_ = kMimeTypeForMHTML; | 142 mime_type_ = kMimeTypeForMHTML; |
| 112 | 143 |
| 113 ReplyResult(net::OK); | 144 ReplyResult(net::OK); |
| 114 } | 145 } |
| 115 | 146 |
| 116 void ReplyResult(net::Error error) { | 147 void ReplyResult(net::Error error) { |
| 117 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 148 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 118 | 149 |
| 119 BrowserThread::PostTask(BrowserThread::IO, | 150 BrowserThread::PostTask( |
| 120 FROM_HERE, | 151 BrowserThread::IO, |
| 121 base::Bind(callback_, | 152 FROM_HERE, |
| 122 error, | 153 base::Bind(callback_, |
| 123 file_system_context_, | 154 error, |
| 124 file_system_url_, | 155 file_system_context_, |
| 125 mime_type_)); | 156 base::Passed(&isolated_file_system_scope_), |
| 157 file_system_url_, | |
| 158 mime_type_)); | |
| 126 } | 159 } |
| 127 | 160 |
| 128 void* const profile_id_; | 161 void* const profile_id_; |
| 129 const GURL url_; | 162 const GURL url_; |
| 130 const ExternalFileURLRequestJob::HelperCallback callback_; | 163 const ExternalFileURLRequestJob::HelperCallback callback_; |
| 131 scoped_refptr<storage::FileSystemContext> file_system_context_; | 164 scoped_refptr<storage::FileSystemContext> file_system_context_; |
| 165 scoped_ptr<ExternalFileURLRequestJob::IsolatedFileSystemScope> | |
| 166 isolated_file_system_scope_; | |
| 132 storage::FileSystemURL file_system_url_; | 167 storage::FileSystemURL file_system_url_; |
| 133 std::string mime_type_; | 168 std::string mime_type_; |
| 134 | 169 |
| 135 DISALLOW_COPY_AND_ASSIGN(URLHelper); | 170 DISALLOW_COPY_AND_ASSIGN(URLHelper); |
| 136 }; | 171 }; |
| 137 | 172 |
| 138 } // namespace | 173 } // namespace |
| 139 | 174 |
| 175 ExternalFileURLRequestJob::IsolatedFileSystemScope::IsolatedFileSystemScope( | |
| 176 const std::string& file_system_id) | |
| 177 : file_system_id_(file_system_id) { | |
| 178 } | |
| 179 | |
| 180 ExternalFileURLRequestJob::IsolatedFileSystemScope::~IsolatedFileSystemScope() { | |
| 181 storage::IsolatedContext::GetInstance()->RevokeFileSystem(file_system_id_); | |
| 182 } | |
| 183 | |
| 140 ExternalFileURLRequestJob::ExternalFileURLRequestJob( | 184 ExternalFileURLRequestJob::ExternalFileURLRequestJob( |
| 141 void* profile_id, | 185 void* profile_id, |
| 142 net::URLRequest* request, | 186 net::URLRequest* request, |
| 143 net::NetworkDelegate* network_delegate) | 187 net::NetworkDelegate* network_delegate) |
| 144 : net::URLRequestJob(request, network_delegate), | 188 : net::URLRequestJob(request, network_delegate), |
| 145 profile_id_(profile_id), | 189 profile_id_(profile_id), |
| 146 remaining_bytes_(0), | 190 remaining_bytes_(0), |
| 147 weak_ptr_factory_(this) { | 191 weak_ptr_factory_(this) { |
| 148 } | 192 } |
| 149 | 193 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 // Owned by itself. | 232 // Owned by itself. |
| 189 new URLHelper(profile_id_, | 233 new URLHelper(profile_id_, |
| 190 request()->url(), | 234 request()->url(), |
| 191 base::Bind(&ExternalFileURLRequestJob::OnHelperResultObtained, | 235 base::Bind(&ExternalFileURLRequestJob::OnHelperResultObtained, |
| 192 weak_ptr_factory_.GetWeakPtr())); | 236 weak_ptr_factory_.GetWeakPtr())); |
| 193 } | 237 } |
| 194 | 238 |
| 195 void ExternalFileURLRequestJob::OnHelperResultObtained( | 239 void ExternalFileURLRequestJob::OnHelperResultObtained( |
| 196 net::Error error, | 240 net::Error error, |
| 197 const scoped_refptr<storage::FileSystemContext>& file_system_context, | 241 const scoped_refptr<storage::FileSystemContext>& file_system_context, |
| 242 scoped_ptr<IsolatedFileSystemScope> isolated_file_system_scope, | |
| 198 const storage::FileSystemURL& file_system_url, | 243 const storage::FileSystemURL& file_system_url, |
| 199 const std::string& mime_type) { | 244 const std::string& mime_type) { |
| 200 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 245 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 201 | 246 |
| 202 if (error != net::OK) { | 247 if (error != net::OK) { |
| 203 NotifyStartError( | 248 NotifyStartError( |
| 204 net::URLRequestStatus(net::URLRequestStatus::FAILED, error)); | 249 net::URLRequestStatus(net::URLRequestStatus::FAILED, error)); |
| 205 return; | 250 return; |
| 206 } | 251 } |
| 207 | 252 |
| 208 DCHECK(file_system_context.get()); | 253 DCHECK(file_system_context.get()); |
| 209 file_system_context_ = file_system_context; | 254 file_system_context_ = file_system_context; |
| 255 isolated_file_system_scope_ = isolated_file_system_scope.Pass(); | |
| 210 file_system_url_ = file_system_url; | 256 file_system_url_ = file_system_url; |
| 211 mime_type_ = mime_type; | 257 mime_type_ = mime_type; |
| 212 | 258 |
| 213 // Check if the entry has a redirect URL. | 259 // Check if the entry has a redirect URL. |
| 214 file_system_context_->external_backend()->GetRedirectURLForContents( | 260 file_system_context_->external_backend()->GetRedirectURLForContents( |
| 215 file_system_url_, | 261 file_system_url_, |
| 216 base::Bind(&ExternalFileURLRequestJob::OnRedirectURLObtained, | 262 base::Bind(&ExternalFileURLRequestJob::OnRedirectURLObtained, |
| 217 weak_ptr_factory_.GetWeakPtr())); | 263 weak_ptr_factory_.GetWeakPtr())); |
| 218 } | 264 } |
| 219 | 265 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 return; | 304 return; |
| 259 } | 305 } |
| 260 const int64 offset = byte_range_.first_byte_position(); | 306 const int64 offset = byte_range_.first_byte_position(); |
| 261 const int64 size = | 307 const int64 size = |
| 262 byte_range_.last_byte_position() + 1 - byte_range_.first_byte_position(); | 308 byte_range_.last_byte_position() + 1 - byte_range_.first_byte_position(); |
| 263 set_expected_content_size(size); | 309 set_expected_content_size(size); |
| 264 remaining_bytes_ = size; | 310 remaining_bytes_ = size; |
| 265 | 311 |
| 266 // Create file stream reader. | 312 // Create file stream reader. |
| 267 stream_reader_ = file_system_context_->CreateFileStreamReader( | 313 stream_reader_ = file_system_context_->CreateFileStreamReader( |
| 268 file_system_url_, offset, size, base::Time()); | 314 file_system_url_, offset, size, base::Time()); |
|
mtomasz
2014/09/29 12:47:40
Could you briefly explain how it works? We're pass
hirono
2014/09/29 13:24:02
CreateFileStreamReader basically refers two member
mtomasz
2014/09/29 13:35:45
Got it. Thanks for the explanation.
| |
| 269 if (!stream_reader_) { | 315 if (!stream_reader_) { |
| 270 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, | 316 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 271 net::ERR_FILE_NOT_FOUND)); | 317 net::ERR_FILE_NOT_FOUND)); |
| 272 return; | 318 return; |
| 273 } | 319 } |
| 274 | 320 |
| 275 NotifyHeadersComplete(); | 321 NotifyHeadersComplete(); |
| 276 } | 322 } |
| 277 | 323 |
| 278 void ExternalFileURLRequestJob::Kill() { | 324 void ExternalFileURLRequestJob::Kill() { |
| 279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 280 | 326 |
| 281 stream_reader_.reset(); | 327 stream_reader_.reset(); |
| 328 isolated_file_system_scope_.reset(); | |
| 282 file_system_context_ = NULL; | 329 file_system_context_ = NULL; |
| 283 net::URLRequestJob::Kill(); | 330 net::URLRequestJob::Kill(); |
| 284 weak_ptr_factory_.InvalidateWeakPtrs(); | 331 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 285 } | 332 } |
| 286 | 333 |
| 287 bool ExternalFileURLRequestJob::GetMimeType(std::string* mime_type) const { | 334 bool ExternalFileURLRequestJob::GetMimeType(std::string* mime_type) const { |
| 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 289 mime_type->assign(mime_type_); | 336 mime_type->assign(mime_type_); |
| 290 return !mime_type->empty(); | 337 return !mime_type->empty(); |
| 291 } | 338 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 NotifyDone( | 395 NotifyDone( |
| 349 net::URLRequestStatus(net::URLRequestStatus::FAILED, read_result)); | 396 net::URLRequestStatus(net::URLRequestStatus::FAILED, read_result)); |
| 350 } | 397 } |
| 351 | 398 |
| 352 remaining_bytes_ -= read_result; | 399 remaining_bytes_ -= read_result; |
| 353 SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status. | 400 SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status. |
| 354 NotifyReadComplete(read_result); | 401 NotifyReadComplete(read_result); |
| 355 } | 402 } |
| 356 | 403 |
| 357 } // namespace chromeos | 404 } // namespace chromeos |
| OLD | NEW |